Skip to contentSkip to conversation

add 6GHz radio support in ath11k driver

PATCH Superseded Pradeep Kumar Chitrapu 2 participants 13 messages May 22, 2020 – May 25, 2020

Subsystems (2)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover add 6GHz radio support in ath11k driver

his patch series adds 6GHz frequency listing in ath11k driver and mac80211 registration for the 6GHz band. Also, extends some of wmi command tlvs for supporting 6GHz.

In cfg80211, a new channel flag is added for identifying Preferred Scanning Channels (PSC) in 6GHz band.

changes in v2:
- Fixed ath11k_phymode to be set in 6GHZ band

Pradeep Kumar Chitrapu (9):
cfg80211: Add new channel flag to identify 6GHz PSC channel
ath11k: add 6G frequency list supported by driver
ath11k: add support for 6GHz radio in driver
ath11k: Use freq instead of channel number in rx path
ath11k: extend peer_assoc_cmd for 6GHz band
ath11k: set psc channel flag when sending channel list to firmware.
ath11k: Add 6G scan dwell time parameter in scan request command
ath11k: Send multiple scan_chan_list messages if required
ath11k: Add support for 6g scan hint

 drivers/net/wireless/ath/ath11k/core.h  |   6 +-
 drivers/net/wireless/ath/ath11k/dp_rx.c |   6 +-
 drivers/net/wireless/ath/ath11k/mac.c   | 174 +++++++++++++--
 drivers/net/wireless/ath/ath11k/reg.c   |   4 +
 drivers/net/wireless/ath/ath11k/wmi.c   | 269 +++++++++++++++++-------
 drivers/net/wireless/ath/ath11k/wmi.h   |  40 +++-
 include/net/cfg80211.h                  |   2 +
 net/wireless/reg.c                      |  19 ++
 8 files changed, 422 insertions(+), 98 deletions(-)
Signature · 6 lines
2.17.1

_______________________________________________
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
#1 lore raw

PATCH v2 1/9 cfg80211: Add new channel flag to identify 6GHz PSC channel

6GHz channels are divided into preferred scanning channels(PSC) and non-PSC channels. One in every four 20MHz channels is a PSC. Spec mandates to use only PSC channels as primary channels for setting up BSS on 6GHz only AP.

The set of 20 MHz channels in the 6 GHz band, with channel center frequency, ch_a = Channel starting frequency – 55 + 80 × n (MHz) are referred to as preferred scanning channels (PSCs) where, n = 1, …, 15 as per IEEE P802.11ax/D6.0.

This flag also will be used when making scanning decision on 6GHz channels.

---
 include/net/cfg80211.h |  2 ++
 net/wireless/reg.c     | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)
include/net/cfg80211.h +2 -0
index fd6a973b1249..ca3e9df7adfe 100644
@@ -96,6 +96,7 @@ struct wiphy;
  * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted
  *	on this channel.
  * @IEEE80211_CHAN_NO_HE: HE operation is not permitted on this channel.
+ * @IEEE80211_CHAN_PSC: 6GHz Channel is Preferred Scanning Channel(PSC)
  *
  */
 enum ieee80211_channel_flags {
@@ -113,6 +114,7 @@ enum ieee80211_channel_flags {
 	IEEE80211_CHAN_NO_20MHZ		= 1<<11,
 	IEEE80211_CHAN_NO_10MHZ		= 1<<12,
 	IEEE80211_CHAN_NO_HE		= 1<<13,
+	IEEE80211_CHAN_PSC		= 1<<14,
 };
 
 #define IEEE80211_CHAN_NO_HT40 \
net/wireless/reg.c +19 -0
index 0d74a31ef0ab..4ebaa57e60e4 100644
@@ -2023,6 +2023,21 @@ static bool is_ht40_allowed(struct ieee80211_channel *chan)
 	return true;
 }
 
+static bool reg_is_6ghz_channel_psc(struct ieee80211_channel *chan)
+{
+	/*
+	 * From IEEE P802.11ax/D6.0: The set of 20 MHz channels in the 6 GHz
+	 * band, with channel center frequency, ch_a = Channel starting
+	 * frequency – 55 + 80 × n (MHz) are referred to as preferred scanning
+	 * channels (PSCs). Channel starting frequency is defined in 27.3.23.2
+	 * (Channel allocation in the 6 GHz band), and n = 1, …, 15.
+	 */
+	if (!(((chan->center_freq - 5940 + 55) >> 4) % 5))
+		return true;
+
+	return false;
+}
+
 static void reg_process_ht_flags_channel(struct wiphy *wiphy,
 					 struct ieee80211_channel *channel)
 {
@@ -2305,6 +2320,10 @@ static void handle_channel_custom(struct wiphy *wiphy,
 	else
 		chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
 
+	if (chan->band == NL80211_BAND_6GHZ &&
+	    reg_is_6ghz_channel_psc(chan))
+		chan->flags |= IEEE80211_CHAN_PSC;
+
 	chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
 	chan->max_reg_power = chan->max_power =
 		(int) MBM_TO_DBM(power_rule->max_eirp);
Signature · 1 line
2.17.1
maintainer
#2 lore raw

Re: [PATCH v2 1/9] cfg80211: Add new channel flag to identify 6GHz PSC channel

Quoted 5 lines · Pradeep Kumar Chitrapu

6GHz channels are divided into preferred scanning channels(PSC) and non-PSC channels. One in every four 20MHz channels is a PSC. Spec mandates to use only PSC channels as primary channels for setting up BSS on 6GHz only AP.

Quoted 7 lines

The set of 20 MHz channels in the 6 GHz band, with channel center frequency, ch_a = Channel starting frequency – 55 + 80 × n (MHz) are referred to as preferred scanning channels (PSCs) where, n = 1, …, 15 as per IEEE P802.11ax/D6.0.

This flag also will be used when making scanning decision on 6GHz channels.

Is there much value in exposing this as a *flag*?

We have a similar patch, but it just adds the function and everyone who cares can call it. Do we really need to precalculate that?

johannes

_______________________________________________
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k

#3 lore raw

Re: [PATCH v2 1/9] cfg80211: Add new channel flag to identify 6GHz PSC channel

Quoted 14 lines · Johannes Berg
Quoted 5 lines · Pradeep Kumar Chitrapu

6GHz channels are divided into preferred scanning channels(PSC) and non-PSC channels. One in every four 20MHz channels is a PSC. Spec mandates to use only PSC channels as primary channels for setting up BSS on 6GHz only AP.

Quoted 7 lines

The set of 20 MHz channels in the 6 GHz band, with channel center frequency, ch_a = Channel starting frequency – 55 + 80 × n (MHz) are referred to as preferred scanning channels (PSCs) where, n = 1, …, 15 as per IEEE P802.11ax/D6.0.

This flag also will be used when making scanning decision on 6GHz channels.

Quoted 6 lines

Is there much value in exposing this as a *flag*?

We have a similar patch, but it just adds the function and everyone who cares can call it. Do we really need to precalculate that?

johannes

Thanks Johannes for the review..

IMO, accessing flag would be faster instead of computation, as this info is handy (already in cache) when accessing ieee80211_channel. However, considering general usage for this info would be only for control path, it should be ok to expose function instead of maintaining separate flag. Please let me know your suggestion..

Thanks
Pradeep

_______________________________________________
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k

maintainer
#4 lore raw

Re: [PATCH v2 1/9] cfg80211: Add new channel flag to identify 6GHz PSC channel

Quoted 2 lines · Pradeep Kumar Chitrapu

IMO, accessing flag would be faster instead of computation, as this info is handy (already in cache) when accessing ieee80211_channel.

True.

Quoted 4 lines

However, considering general usage for this info would be only for control
path, it should be ok to expose function instead of maintaining separate flag.

Yeah, I can't really see where we'd care ... this is used only when we set up a scan, etc.

Quoted 1 line

Please let me know your suggestion..

I'll now go and try to consolidate all your changes and ours, we'll see what falls out.

johannes

_______________________________________________
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k

#5 lore raw

PATCH v2 2/9 ath11k: add 6G frequency list supported by driver

In reply to Pradeep Kumar Chitrapu

This patch adds support for 6GHz frequency listing.

---
 drivers/net/wireless/ath/ath11k/mac.c | 71 +++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
drivers/net/wireless/ath/ath11k/mac.c +71 -0
index 36882562b976..f699e882949b 100644
@@ -33,6 +33,15 @@
 	.max_power              = 30, \
 }
 
+#define CHAN6G(_channel, _freq, _flags) { \
+	.band                   = NL80211_BAND_6GHZ, \
+	.hw_value               = (_channel), \
+	.center_freq            = (_freq), \
+	.flags                  = (_flags), \
+	.max_antenna_gain       = 0, \
+	.max_power              = 30, \
+}
+
 /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
 static unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
@@ -86,6 +95,68 @@ static const struct ieee80211_channel ath11k_5ghz_channels[] = {
 	CHAN5G(173, 5865, 0),
 };
 
+static const struct ieee80211_channel ath11k_6ghz_channels[] = {
+	CHAN6G(1, 5945, 0),
+	CHAN6G(5, 5965, 0),
+	CHAN6G(9, 5985, 0),
+	CHAN6G(13, 6005, 0),
+	CHAN6G(17, 6025, 0),
+	CHAN6G(21, 6045, 0),
+	CHAN6G(25, 6065, 0),
+	CHAN6G(29, 6085, 0),
+	CHAN6G(33, 6105, 0),
+	CHAN6G(37, 6125, 0),
+	CHAN6G(41, 6145, 0),
+	CHAN6G(45, 6165, 0),
+	CHAN6G(49, 6185, 0),
+	CHAN6G(53, 6205, 0),
+	CHAN6G(57, 6225, 0),
+	CHAN6G(61, 6245, 0),
+	CHAN6G(65, 6265, 0),
+	CHAN6G(69, 6285, 0),
+	CHAN6G(73, 6305, 0),
+	CHAN6G(77, 6325, 0),
+	CHAN6G(81, 6345, 0),
+	CHAN6G(85, 6365, 0),
+	CHAN6G(89, 6385, 0),
+	CHAN6G(93, 6405, 0),
+	CHAN6G(97, 6425, 0),
+	CHAN6G(101, 6445, 0),
+	CHAN6G(105, 6465, 0),
+	CHAN6G(109, 6485, 0),
+	CHAN6G(113, 6505, 0),
+	CHAN6G(117, 6525, 0),
+	CHAN6G(121, 6545, 0),
+	CHAN6G(125, 6565, 0),
+	CHAN6G(129, 6585, 0),
+	CHAN6G(133, 6605, 0),
+	CHAN6G(137, 6625, 0),
+	CHAN6G(141, 6645, 0),
+	CHAN6G(145, 6665, 0),
+	CHAN6G(149, 6685, 0),
+	CHAN6G(153, 6705, 0),
+	CHAN6G(157, 6725, 0),
+	CHAN6G(161, 6745, 0),
+	CHAN6G(165, 6765, 0),
+	CHAN6G(169, 6785, 0),
+	CHAN6G(173, 6805, 0),
+	CHAN6G(177, 6825, 0),
+	CHAN6G(181, 6845, 0),
+	CHAN6G(185, 6865, 0),
+	CHAN6G(189, 6885, 0),
+	CHAN6G(193, 6905, 0),
+	CHAN6G(197, 6925, 0),
+	CHAN6G(201, 6945, 0),
+	CHAN6G(205, 6965, 0),
+	CHAN6G(209, 6985, 0),
+	CHAN6G(213, 7005, 0),
+	CHAN6G(217, 7025, 0),
+	CHAN6G(221, 7045, 0),
+	CHAN6G(225, 7065, 0),
+	CHAN6G(229, 7085, 0),
+	CHAN6G(233, 7105, 0),
+};
+
 static struct ieee80211_rate ath11k_legacy_rates[] = {
 	{ .bitrate = 10,
 	  .hw_value = ATH11K_HW_RATE_CCK_LP_1M },
Signature · 1 line
2.17.1
#6 lore raw

PATCH v2 3/9 ath11k: add support for 6GHz radio in driver

In reply to Pradeep Kumar Chitrapu

This patch adds 6GHz band support and mac80211 registration for the 6G phy radio.

---
v2:
- fixed phymode to be set in 6ghz band

 drivers/net/wireless/ath/ath11k/core.h |   6 +-
 drivers/net/wireless/ath/ath11k/mac.c  | 103 +++++++++++++++++++++----
 drivers/net/wireless/ath/ath11k/wmi.c  |  16 +++-
 3 files changed, 105 insertions(+), 20 deletions(-)
drivers/net/wireless/ath/ath11k/core.h +5 -1
index 7e51445cfa20..83bffd7f633a 100644
@@ -353,7 +353,10 @@ struct ath11k_sta {
 #endif
 };
 
-#define ATH11K_NUM_CHANS 41
+#define ATH11K_MIN_5G_FREQ 4150
+#define ATH11K_MIN_6G_FREQ 5935
+#define ATH11K_MAX_6G_FREQ 7105
+#define ATH11K_NUM_CHANS 100
 #define ATH11K_MAX_5G_CHAN 173
 
 enum ath11k_state {
@@ -431,6 +434,7 @@ struct ath11k {
 	u32 vht_cap_info;
 	struct ath11k_he ar_he;
 	enum ath11k_state state;
+	bool supports_6ghz;
 	struct {
 		struct completion started;
 		struct completion completed;
drivers/net/wireless/ath/ath11k/mac.c +86 -17

165 lines not on this page · raw message

drivers/net/wireless/ath/ath11k/wmi.c +14 -2
index c2a972377687..291fb274134f 100644
@@ -368,6 +368,17 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
 	memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
 	       sizeof(struct ath11k_ppe_threshold));
 
+	cap_band = &pdev_cap->band[NL80211_BAND_6GHZ];
+	cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
+	cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
+	cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
+	cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
+	cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
+	memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
+	       sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
+	memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
+	       sizeof(struct ath11k_ppe_threshold));
+
 	return 0;
 }
 
@@ -5206,9 +5217,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
 		goto exit;
 	}
 
-	if (rx_ev.phy_mode == MODE_11B && status->band == NL80211_BAND_5GHZ)
+	if (rx_ev.phy_mode == MODE_11B &&
+	    (status->band == NL80211_BAND_5GHZ || status->band == NL80211_BAND_6GHZ))
 		ath11k_dbg(ab, ATH11K_DBG_WMI,
-			   "wmi mgmt rx 11b (CCK) on 5GHz\n");
+			   "wmi mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status->band);
 
 	sband = &ar->mac.sbands[status->band];
 
Signature · 1 line
2.17.1
#7 lore raw

PATCH v2 4/9 ath11k: Use freq instead of channel number in rx path

In reply to Pradeep Kumar Chitrapu

As 6GHz cahnnel numbers overlap with those of 5GHz and 2GHz bands, it is necessary to use frequency when determining the band info in rx path.

---
 drivers/net/wireless/ath/ath11k/dp_rx.c | 6 +++++-
 drivers/net/wireless/ath/ath11k/wmi.c   | 5 ++++-
 drivers/net/wireless/ath/ath11k/wmi.h   | 2 ++
 3 files changed, 11 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath11k/dp_rx.c +5 -1
index a54610d75c40..c8f1ea69ea9d 100644
@@ -2162,6 +2162,7 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
 				struct ieee80211_rx_status *rx_status)
 {
 	u8 channel_num;
+	u32 center_freq;
 
 	rx_status->freq = 0;
 	rx_status->rate_idx = 0;
@@ -2172,8 +2173,11 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
 	rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
 
 	channel_num = ath11k_dp_rx_h_msdu_start_freq(rx_desc);
+	center_freq = ath11k_dp_rx_h_msdu_start_freq(rx_desc) >> 16;
 
-	if (channel_num >= 1 && channel_num <= 14) {
+	if (center_freq >= 5935 && center_freq <= 7105)
+		rx_status->band = NL80211_BAND_6GHZ;
+	else if (channel_num >= 1 && channel_num <= 14) {
 		rx_status->band = NL80211_BAND_2GHZ;
 	} else if (channel_num >= 36 && channel_num <= 173) {
 		rx_status->band = NL80211_BAND_5GHZ;
drivers/net/wireless/ath/ath11k/wmi.c +4 -1
index 291fb274134f..500108fa59d9 100644
@@ -3833,6 +3833,7 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
 	}
 
 	hdr->pdev_id =  ev->pdev_id;
+	hdr->chan_freq = ev->chan_freq;
 	hdr->channel =  ev->channel;
 	hdr->snr =  ev->snr;
 	hdr->rate =  ev->rate;
@@ -5204,7 +5205,9 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
 	if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
 		status->flag |= RX_FLAG_MMIC_ERROR;
 
-	if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
+	if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) {
+		status->band = NL80211_BAND_6GHZ;
+	} else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
 		status->band = NL80211_BAND_2GHZ;
 	} else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) {
 		status->band = NL80211_BAND_5GHZ;
drivers/net/wireless/ath/ath11k/wmi.h +2 -0
index b9f3e559ced7..afa3c4cf90e9 100644
@@ -4228,6 +4228,7 @@ struct wmi_pdev_temperature_event {
 #define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4
 
 struct mgmt_rx_event_params {
+	u32 chan_freq;
 	u32 channel;
 	u32 snr;
 	u8 rssi_ctl[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
@@ -4257,6 +4258,7 @@ struct wmi_mgmt_rx_hdr {
 	u32 rx_tsf_l32;
 	u32 rx_tsf_u32;
 	u32 pdev_id;
+	u32 chan_freq;
 } __packed;
 
 #define MAX_ANTENNA_EIGHT 8
Signature · 6 lines
2.17.1

_______________________________________________
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
#8 lore raw

PATCH v2 5/9 ath11k: extend peer_assoc_cmd for 6GHz band

In reply to Pradeep Kumar Chitrapu

This adds support required for configuring min_data_rate of 6GHz oper IE and peer_he_caps_6ghz in peer assoc command. The Minimum Rate field indicates the minimum rate, in units of 1 Mb/s, that the non-AP STA is allowed to use for sending PPDUs as defined in IEEE P802.11ax™/D6.0.

---
 drivers/net/wireless/ath/ath11k/wmi.c | 2 ++
 drivers/net/wireless/ath/ath11k/wmi.h | 5 +++++
 2 files changed, 7 insertions(+)
drivers/net/wireless/ath/ath11k/wmi.c +2 -0
index 500108fa59d9..a6bbb3badd1f 100644
@@ -1789,6 +1789,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
 	cmd->peer_he_cap_info = param->peer_he_cap_macinfo[0];
 	cmd->peer_he_cap_info_ext = param->peer_he_cap_macinfo[1];
 	cmd->peer_he_cap_info_internal = param->peer_he_cap_macinfo_internal;
+	cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz;
 	cmd->peer_he_ops = param->peer_he_ops;
 	memcpy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
 	       sizeof(param->peer_he_cap_phyinfo));
@@ -1842,6 +1843,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
 
 	/* HE Rates */
 	cmd->peer_he_mcs = param->peer_he_mcs_count;
+	cmd->min_data_rate = param->min_data_rate;
 
 	ptr += sizeof(*mcs);
 
drivers/net/wireless/ath/ath11k/wmi.h +5 -0
index afa3c4cf90e9..fd82cff7537b 100644
@@ -1011,6 +1011,7 @@ enum wmi_tlv_vdev_param {
 	WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
 	WMI_VDEV_PARAM_BA_MODE = 0x7e,
 	WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
+	WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99,
 	WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
 	WMI_VDEV_PARAM_BSS_COLOR,
 	WMI_VDEV_PARAM_SET_HEMU_MODE,
@@ -3444,6 +3445,7 @@ struct peer_assoc_params {
 	u32 tx_max_rate;
 	u32 tx_mcs_set;
 	u8 vht_capable;
+	u8 min_data_rate;
 	u32 tx_max_mcs_nss;
 	u32 peer_bw_rxnss_override;
 	bool is_pmf_enabled;
@@ -3472,6 +3474,7 @@ struct peer_assoc_params {
 	bool he_flag;
 	u32 peer_he_cap_macinfo[2];
 	u32 peer_he_cap_macinfo_internal;
+	u32 peer_he_caps_6ghz;
 	u32 peer_he_ops;
 	u32 peer_he_cap_phyinfo[WMI_HOST_MAX_HECAP_PHY_SIZE];
 	u32 peer_he_mcs_count;
@@ -3509,6 +3512,8 @@ struct  wmi_peer_assoc_complete_cmd {
 	u32 peer_he_mcs;
 	u32 peer_he_cap_info_ext;
 	u32 peer_he_cap_info_internal;
+	u32 min_data_rate;
+	u32 peer_he_caps_6ghz;
 } __packed;
 
 struct wmi_stop_scan_cmd {
Signature · 1 line
2.17.1
#9 lore raw

PATCH v2 6/9 ath11k: set psc channel flag when sending channel list to firmware.

In reply to Pradeep Kumar Chitrapu

If 6 ghz channel is a Preferred Scanning Channel(PSC), mark the channel flag accordingly when updating channel list to firmware. This will be used when making scanning decision in 6GHz channels.

---
 drivers/net/wireless/ath/ath11k/reg.c | 4 ++++
 drivers/net/wireless/ath/ath11k/wmi.h | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath11k/reg.c +4 -0
index 453aa9c06969..50d13a5d7cf8 100644
@@ -161,6 +161,10 @@ int ath11k_reg_update_chan_list(struct ath11k *ar)
 			else
 				ch->phy_mode = MODE_11A;
 
+			if (channel->band == NL80211_BAND_6GHZ &&
+			    channel->flags & IEEE80211_CHAN_PSC)
+				ch->psc_channel = true;
+
 			ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
 				   "mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
 				   i, params->nallchans,
drivers/net/wireless/ath/ath11k/wmi.h +2 -1
index fd82cff7537b..76c2da2c5db7 100644
@@ -2520,7 +2520,8 @@ struct channel_param {
 	    allow_ht:1,
 	    allow_vht:1,
 	    allow_he:1,
-	    set_agile:1;
+	    set_agile:1,
+	    psc_channel:1;
 	u32 phy_mode;
 	u32 cfreq1;
 	u32 cfreq2;
Signature · 1 line
2.17.1
#10 lore raw

PATCH v2 7/9 ath11k: Add 6G scan dwell time parameter in scan request command

In reply to Pradeep Kumar Chitrapu

Add 6G scan active and passive dwell time parameter to scan request.

---
 drivers/net/wireless/ath/ath11k/wmi.c | 4 ++++
 drivers/net/wireless/ath/ath11k/wmi.h | 5 +++++
 2 files changed, 9 insertions(+)
drivers/net/wireless/ath/ath11k/wmi.c +4 -0
index a6bbb3badd1f..239a336f55f4 100644
@@ -1899,6 +1899,8 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar,
 	arg->dwell_time_active = 50;
 	arg->dwell_time_active_2g = 0;
 	arg->dwell_time_passive = 150;
+	arg->dwell_time_active_6g = 40;
+	arg->dwell_time_passive_6g = 30;
 	arg->min_rest_time = 50;
 	arg->max_rest_time = 500;
 	arg->repeat_probe_time = 0;
@@ -2045,6 +2047,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
 	cmd->dwell_time_active = params->dwell_time_active;
 	cmd->dwell_time_active_2g = params->dwell_time_active_2g;
 	cmd->dwell_time_passive = params->dwell_time_passive;
+	cmd->dwell_time_active_6g = params->dwell_time_active_6g;
+	cmd->dwell_time_passive_6g = params->dwell_time_passive_6g;
 	cmd->min_rest_time = params->min_rest_time;
 	cmd->max_rest_time = params->max_rest_time;
 	cmd->repeat_probe_time = params->repeat_probe_time;
drivers/net/wireless/ath/ath11k/wmi.h +5 -0
index 76c2da2c5db7..4937d02839fc 100644
@@ -3061,6 +3061,9 @@ struct  wmi_start_scan_cmd {
 	u32 num_vendor_oui;
 	u32 scan_ctrl_flags_ext;
 	u32 dwell_time_active_2g;
+	u32 dwell_time_active_6g;
+	u32 dwell_time_passive_6g;
+	u32 scan_start_offset;
 } __packed;
 
 #define WMI_SCAN_FLAG_PASSIVE        0x1
@@ -3127,6 +3130,8 @@ struct scan_req_params {
 	u32 dwell_time_active;
 	u32 dwell_time_active_2g;
 	u32 dwell_time_passive;
+	u32 dwell_time_active_6g;
+	u32 dwell_time_passive_6g;
 	u32 min_rest_time;
 	u32 max_rest_time;
 	u32 repeat_probe_time;
Signature · 1 line
2.17.1
#11 lore raw

PATCH v2 8/9 ath11k: Send multiple scan_chan_list messages if required

In reply to Pradeep Kumar Chitrapu

With addition of 6Ghz channels, it is possible that wmi buffer size can exceed the maximum wmi buffer size. So iterate over the channel list, and send multiple messages till channel list is empty.
Also mark PSC channel flag for 6GHz channels accordingly.

---
 drivers/net/wireless/ath/ath11k/wmi.c | 170 ++++++++++++++------------
 drivers/net/wireless/ath/ath11k/wmi.h |   3 +
 2 files changed, 98 insertions(+), 75 deletions(-)
drivers/net/wireless/ath/ath11k/wmi.c +95 -75
index 239a336f55f4..ad3a7b68d308 100644
@@ -2194,91 +2194,111 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
 	struct channel_param *tchan_info;
 	struct wmi_tlv *tlv;
 	void *ptr;
-	int i, ret, len;
+	int i, ret = 0, len;
+	u16 num_send_chans, num_sends = 0, max_chan_limit = 0;
 	u32 *reg1, *reg2;
 
-	len = sizeof(*cmd) + TLV_HDR_SIZE +
-		 sizeof(*chan_info) * chan_list->nallchans;
-
-	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
-	if (!skb)
-		return -ENOMEM;
-
-	cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
-	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) |
-			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
-
-	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
-		   "WMI no.of chan = %d len = %d\n", chan_list->nallchans, len);
-	cmd->pdev_id = chan_list->pdev_id;
-	cmd->num_scan_chans = chan_list->nallchans;
-
-	ptr = skb->data + sizeof(*cmd);
-
-	len = sizeof(*chan_info) * chan_list->nallchans;
-	tlv = ptr;
-	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
-		      FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
-	ptr += TLV_HDR_SIZE;
-
 	tchan_info = &chan_list->ch_param[0];
+	while (chan_list->nallchans) {
+		len = sizeof(*cmd) + TLV_HDR_SIZE;
+		max_chan_limit =
+			(wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) /
+			sizeof(*chan_info);
+
+		if (chan_list->nallchans > max_chan_limit)
+			num_send_chans = max_chan_limit;
+		else
+			num_send_chans = chan_list->nallchans;
+
+		chan_list->nallchans -= num_send_chans;
+		len += sizeof(*chan_info) * num_send_chans;
+
+		skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
+		if (!skb)
+			return -ENOMEM;
 
-	for (i = 0; i < chan_list->nallchans; ++i) {
-		chan_info = ptr;
-		memset(chan_info, 0, sizeof(*chan_info));
-		len = sizeof(*chan_info);
-		chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
-						   WMI_TAG_CHANNEL) |
-					FIELD_PREP(WMI_TLV_LEN,
-						   len - TLV_HDR_SIZE);
-
-		reg1 = &chan_info->reg_info_1;
-		reg2 = &chan_info->reg_info_2;
-		chan_info->mhz = tchan_info->mhz;
-		chan_info->band_center_freq1 = tchan_info->cfreq1;
-		chan_info->band_center_freq2 = tchan_info->cfreq2;
-
-		if (tchan_info->is_chan_passive)
-			chan_info->info |= WMI_CHAN_INFO_PASSIVE;
-		if (tchan_info->allow_he)
-			chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
-		else if (tchan_info->allow_vht)
-			chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
-		else if (tchan_info->allow_ht)
-			chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
-		if (tchan_info->half_rate)
-			chan_info->info |= WMI_CHAN_INFO_HALF_RATE;
-		if (tchan_info->quarter_rate)
-			chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
-
-		chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
-					      tchan_info->phy_mode);
-		*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR,
-				    tchan_info->minpower);
-		*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
-				    tchan_info->maxpower);
-		*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
-				    tchan_info->maxregpower);
-		*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS,
-				    tchan_info->reg_class_id);
-		*reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
-				    tchan_info->antennamax);
+		cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
+		cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) |
+			FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+		cmd->pdev_id = chan_list->pdev_id;
+		cmd->num_scan_chans = num_send_chans;
+		if (num_sends)
+			cmd->flags |= WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG;
 
 		ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
-			   "WMI chan scan list chan[%d] = %u\n",
-			   i, chan_info->mhz);
+			   "WMI no.of chan = %d len = %d pdev_id = %d num_sends = %d\n",
+			   num_send_chans, len, cmd->pdev_id, num_sends);
 
-		ptr += sizeof(*chan_info);
+		ptr = skb->data + sizeof(*cmd);
 
-		tchan_info++;
-	}
+		len = sizeof(*chan_info) * num_send_chans;
+		tlv = ptr;
+		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
+			      FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
+		ptr += TLV_HDR_SIZE;
 
-	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID);
-	if (ret) {
-		ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
-		dev_kfree_skb(skb);
-	}
+		for (i = 0; i < num_send_chans; ++i) {
+			chan_info = ptr;
+			memset(chan_info, 0, sizeof(*chan_info));
+			len = sizeof(*chan_info);
+			chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
+							   WMI_TAG_CHANNEL) |
+						FIELD_PREP(WMI_TLV_LEN,
+							   len - TLV_HDR_SIZE);
+
+			reg1 = &chan_info->reg_info_1;
+			reg2 = &chan_info->reg_info_2;
+			chan_info->mhz = tchan_info->mhz;
+			chan_info->band_center_freq1 = tchan_info->cfreq1;
+			chan_info->band_center_freq2 = tchan_info->cfreq2;
+
+			if (tchan_info->is_chan_passive)
+				chan_info->info |= WMI_CHAN_INFO_PASSIVE;
+			if (tchan_info->allow_he)
+				chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
+			else if (tchan_info->allow_vht)
+				chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
+			else if (tchan_info->allow_ht)
+				chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
+			if (tchan_info->half_rate)
+				chan_info->info |= WMI_CHAN_INFO_HALF_RATE;
+			if (tchan_info->quarter_rate)
+				chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
+			if (tchan_info->psc_channel)
+				chan_info->info |= WMI_CHAN_INFO_PSC;
+
+			chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
+						      tchan_info->phy_mode);
+			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR,
+					    tchan_info->minpower);
+			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
+					    tchan_info->maxpower);
+			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
+					    tchan_info->maxregpower);
+			*reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS,
+					    tchan_info->reg_class_id);
+			*reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
+					    tchan_info->antennamax);
+
+			ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+				   "WMI chan scan list chan[%d] = %u, chan_info->info %8x\n",
+				   i, chan_info->mhz, chan_info->info);
+
+			ptr += sizeof(*chan_info);
+
+			tchan_info++;
+		}
 
+		ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID);
+		if (ret) {
+			ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
+			dev_kfree_skb(skb);
+			goto end;
+		}
+
+		num_sends++;
+	}
+end:
 	return ret;
 }
 
drivers/net/wireless/ath/ath11k/wmi.h +3 -0
index 4937d02839fc..319ad7241e01 100644
@@ -54,6 +54,8 @@ struct wmi_tlv {
 #define WLAN_SCAN_PARAMS_MAX_BSSID   4
 #define WLAN_SCAN_PARAMS_MAX_IE_LEN  256
 
+#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1
+
 #define WMI_BA_MODE_BUFFER_SIZE_256  3
 /*
  * HW mode config type replicated from FW header
@@ -3271,6 +3273,7 @@ struct  wmi_bcn_send_from_host_cmd {
 #define WMI_CHAN_INFO_QUARTER_RATE	BIT(15)
 #define WMI_CHAN_INFO_DFS_FREQ2		BIT(16)
 #define WMI_CHAN_INFO_ALLOW_HE		BIT(17)
+#define WMI_CHAN_INFO_PSC		BIT(18)
 
 #define WMI_CHAN_REG_INFO1_MIN_PWR	GENMASK(7, 0)
 #define WMI_CHAN_REG_INFO1_MAX_PWR	GENMASK(15, 8)
Signature · 6 lines
2.17.1

_______________________________________________
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
#12 lore raw

PATCH v2 9/9 ath11k: Add support for 6g scan hint

In reply to Pradeep Kumar Chitrapu

Add support for 6Ghz short ssid and bssid hint mechanism as part of scan command.

---
 drivers/net/wireless/ath/ath11k/wmi.c | 72 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/wmi.h | 22 ++++++++
 2 files changed, 94 insertions(+)
drivers/net/wireless/ath/ath11k/wmi.c +72 -0
index ad3a7b68d308..317376a4eb6e 100644
@@ -2005,6 +2005,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
 	int i, ret, len;
 	u32 *tmp_ptr;
 	u8 extraie_len_with_pad = 0;
+	struct hint_short_ssid *s_ssid = NULL;
+	struct hint_bssid *hint_bssid = NULL;
 
 	len = sizeof(*cmd);
 
@@ -2026,6 +2028,14 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
 			roundup(params->extraie.len, sizeof(u32));
 	len += extraie_len_with_pad;
 
+	if (params->num_hint_bssid)
+		len += TLV_HDR_SIZE +
+		       params->num_hint_bssid * sizeof(struct hint_bssid);
+
+	if (params->num_hint_s_ssid)
+		len += TLV_HDR_SIZE +
+		       params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
+
 	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
 	if (!skb)
 		return -ENOMEM;
@@ -2126,6 +2136,68 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
 
 	ptr += extraie_len_with_pad;
 
+	if (params->num_hint_s_ssid) {
+		len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
+		tlv = ptr;
+		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+			      FIELD_PREP(WMI_TLV_LEN, len);
+		ptr += TLV_HDR_SIZE;
+		s_ssid = ptr;
+		for (i = 0; i < params->num_hint_s_ssid; ++i) {
+			s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
+			s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
+			s_ssid++;
+		}
+		ptr += len;
+	}
+
+	if (params->num_hint_bssid) {
+		len = params->num_hint_bssid * sizeof(struct hint_bssid);
+		tlv = ptr;
+		tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+			      FIELD_PREP(WMI_TLV_LEN, len);
+		ptr += TLV_HDR_SIZE;
+		hint_bssid = ptr;
+		for (i = 0; i < params->num_hint_bssid; ++i) {
+			hint_bssid->freq_flags =
+				params->hint_bssid[i].freq_flags;
+			ether_addr_copy(&params->hint_bssid[i].bssid.addr[0],
+					&hint_bssid->bssid.addr[0]);
+			hint_bssid++;
+		}
+	}
+
+	len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
+	tlv = ptr;
+	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+		      FIELD_PREP(WMI_TLV_LEN, len);
+	ptr += TLV_HDR_SIZE;
+	if (params->num_hint_s_ssid) {
+		s_ssid = ptr;
+		for (i = 0; i < params->num_hint_s_ssid; ++i) {
+			s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
+			s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
+			s_ssid++;
+		}
+	}
+	ptr += len;
+
+	len = params->num_hint_bssid * sizeof(struct hint_bssid);
+	tlv = ptr;
+	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+		      FIELD_PREP(WMI_TLV_LEN, len);
+	ptr += TLV_HDR_SIZE;
+	if (params->num_hint_bssid) {
+		hint_bssid = ptr;
+		for (i = 0; i < params->num_hint_bssid; ++i) {
+			hint_bssid->freq_flags =
+				params->hint_bssid[i].freq_flags;
+			ether_addr_copy(&params->hint_bssid[i].bssid.addr[0],
+					&hint_bssid->bssid.addr[0]);
+			hint_bssid++;
+		}
+	}
+
 	ret = ath11k_wmi_cmd_send(wmi, skb,
 				  WMI_START_SCAN_CMDID);
 	if (ret) {
drivers/net/wireless/ath/ath11k/wmi.h +22 -0
index 319ad7241e01..1162bd7a5f87 100644
@@ -50,6 +50,14 @@ struct wmi_tlv {
 #define WMI_MAX_MEM_REQS        32
 #define ATH11K_MAX_HW_LISTEN_INTERVAL 5
 
+#define WLAN_SCAN_MAX_HINT_S_SSID        10
+#define WLAN_SCAN_MAX_HINT_BSSID         10
+#define MAX_RNR_BSS                    5
+
+#define WLAN_SCAN_MAX_HINT_S_SSID        10
+#define WLAN_SCAN_MAX_HINT_BSSID         10
+#define MAX_RNR_BSS                    5
+
 #define WLAN_SCAN_PARAMS_MAX_SSID    16
 #define WLAN_SCAN_PARAMS_MAX_BSSID   4
 #define WLAN_SCAN_PARAMS_MAX_IE_LEN  256
@@ -3105,6 +3113,16 @@ enum {
 	((flag) |= (((mode) << WMI_SCAN_DWELL_MODE_SHIFT) & \
 		    WMI_SCAN_DWELL_MODE_MASK))
 
+struct hint_short_ssid {
+	u32 freq_flags;
+	u32 short_ssid;
+};
+
+struct hint_bssid {
+	u32 freq_flags;
+	struct wmi_mac_addr bssid;
+};
+
 struct scan_req_params {
 	u32 scan_id;
 	u32 scan_req_id;
@@ -3184,6 +3202,10 @@ struct scan_req_params {
 	struct element_info extraie;
 	struct element_info htcap;
 	struct element_info vhtcap;
+	u32 num_hint_s_ssid;
+	u32 num_hint_bssid;
+	struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_S_SSID];
+	struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID];
 };
 
 struct wmi_ssid_arg {
Signature · 1 line
2.17.1