Skip to contentSkip to conversation

cfg80211/mac80211: Add support for 6GHZ STA for various modes : LPI, SP and VLP

PATCH In review Wen Gong 2 participants 13 messages Sep 24, 2021 – Sep 28, 2021

Subsystems (4)
lore
Share & tools
lore

Wen Gong

author
#0 lore raw

v4 cover cfg80211/mac80211: Add support for 6GHZ STA for various modes : LPI, SP and VLP

v4:
1. rebased to top commit id 9e263e193af7 kernel/git/jberg/mac80211-next.git
2. add NULL check for "mac80211: use ieee802_11_parse_elems() to find ies instead of ieee80211_bss_get_ie()"
3. remove the 3 patches which already upstream:
"mac80211: parse transmit power envelope element"
"ieee80211: add definition for transmit power envelope element"
"ieee80211: add definition of regulatory info in 6 GHz operation information"

v3: change per comments of Johannes.
1. add patch "mac80211: use ieee802_11_parse_elems() to find ies instead of ieee80211_bss_get_ie()"
2. move nl80211_ap_reg_power to ieee80211
3. change some comments, length check, stack big size variable...

v2: change per comments of johannes.
including code style, code logic, patch merge, commit log...

It introduced some new concept:
power type of AP(STANDARD_POWER_AP, INDOOR_AP, VERY_LOW_POWER_AP) power type of STATION(DEFAULT_CLIENT, SUBORDINATE_CLIENT) power spectral density(psd)

This patchset for cfg80211/mac80211 is to add the definition of new concept of 6G and add basic parse of IE(transmit power envelope element) in beacon and save power spectral density(psd) reported by lower-driver for 6G channel, the info will be passed to lower driver when connecting to 6G AP.

Wen Gong (6):
mac80211: add power type definition for 6 GHz
mac80211: add parse regulatory info in 6 GHz operation information
cfg80211: add definition for 6 GHz power spectral density(psd)
cfg80211: save power spectral density(psd) of regulatory rule
mac80211: use ieee802_11_parse_elems() to find ies instead of

    ieee80211_bss_get_ie()

mac80211: save transmit power envelope element and power constraint

 include/linux/ieee80211.h    | 34 +++++++++++++++
 include/net/cfg80211.h       |  5 +++
 include/net/mac80211.h       |  8 ++++
 include/net/regulatory.h     |  1 +
 include/uapi/linux/nl80211.h |  2 +
 net/mac80211/mlme.c          | 82 +++++++++++++++++++++++++++++-------
 net/mac80211/util.c          | 13 ++++++
 net/wireless/reg.c           | 17 ++++++++
 8 files changed, 146 insertions(+), 16 deletions(-)

base-commit: 9e263e193af73d2509dc3102a680a11130f44e20

Signature · 7 lines
2.31.1


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

PATCH v4 1/6 mac80211: add power type definition for 6 GHz

6 GHz regulatory domains introduces different modes for 6 GHz AP operations Low Power Indoor(LPI), Standard Power(SP) and Very Low Power(VLP). 6 GHz STAs could be operated as either Regular or Subordinate clients. This patch is define the flags for power type of AP and STATION mode.

---
 include/linux/ieee80211.h | 34 ++++++++++++++++++++++++++++++++++
 include/net/mac80211.h    |  2 ++
 2 files changed, 36 insertions(+)
include/linux/ieee80211.h +34 -0
index 694264503119..1e2d7f25d4f9 100644
@@ -1988,6 +1988,40 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
 			      int mcs, bool ext_nss_bw_capable,
 			      unsigned int max_vht_nss);
 
+/**
+ * enum ieee80211_ap_reg_power - regulatory power for a Access Point
+ *
+ * @IEEE80211_REG_UNSET_AP: Access Point has no regulatory power mode
+ * @IEEE80211_REG_LPI: Indoor Access Point
+ * @IEEE80211_REG_SP: Standard power Access Point
+ * @IEEE80211_REG_VLP: Very low power Access Point
+ */
+enum ieee80211_ap_reg_power {
+	IEEE80211_REG_UNSET_AP,
+	IEEE80211_REG_LPI_AP,
+	IEEE80211_REG_SP_AP,
+	IEEE80211_REG_VLP_AP,
+	IEEE80211_REG_AP_POWER_AFTER_LAST,
+	IEEE80211_REG_AP_POWER_MAX =
+		IEEE80211_REG_AP_POWER_AFTER_LAST - 1,
+};
+
+/**
+ * enum ieee80211_client_reg_power - regulatory power for a client
+ *
+ * @IEEE80211_REG_UNSET_CLIENT: Client has no regulatory power mode
+ * @IEEE80211_REG_DEFAULT_CLIENT: Default Client
+ * @IEEE80211_REG_SUBORDINATE_CLIENT: Subordinate Client
+ */
+enum ieee80211_client_reg_power {
+	IEEE80211_REG_UNSET_CLIENT,
+	IEEE80211_REG_DEFAULT_CLIENT,
+	IEEE80211_REG_SUBORDINATE_CLIENT,
+	IEEE80211_REG_CLIENT_POWER_AFTER_LAST,
+	IEEE80211_REG_CLIENT_POWER_MAX =
+		IEEE80211_REG_CLIENT_POWER_AFTER_LAST - 1,
+};
+
 /* 802.11ax HE MAC capabilities */
 #define IEEE80211_HE_MAC_CAP0_HTC_HE				0x01
 #define IEEE80211_HE_MAC_CAP0_TWT_REQ				0x02
include/net/mac80211.h +2 -0
index af0fc13cea34..8923a9fc4126 100644
@@ -632,6 +632,7 @@ struct ieee80211_fils_discovery {
  * @s1g: BSS is S1G BSS (affects Association Request format).
  * @beacon_tx_rate: The configured beacon transmit rate that needs to be passed
  *	to driver when rate control is offloaded to firmware.
+ * @power_type: power type of BSS for 6 GHz
  */
 struct ieee80211_bss_conf {
 	const u8 *bssid;
@@ -702,6 +703,7 @@ struct ieee80211_bss_conf {
 	u32 unsol_bcast_probe_resp_interval;
 	bool s1g;
 	struct cfg80211_bitrate_mask beacon_tx_rate;
+	enum ieee80211_ap_reg_power power_type;
 };
 
 /**
Signature · 1 line
2.31.1
author
#2 lore raw

PATCH v4 2/6 mac80211: add parse regulatory info in 6 GHz operation information

In reply to Wen Gong

This patch is to convert the regulatory info subfield in HE operation element to power type and save in struct cfg80211_chan_def.

---
 net/mac80211/util.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
net/mac80211/util.c +13 -0
index ca8008ba9b1f..66e48f29495a 100644
@@ -3385,6 +3385,7 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
 	const struct ieee80211_sta_he_cap *he_cap;
 	struct cfg80211_chan_def he_chandef = *chandef;
 	const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
+	struct ieee80211_bss_conf *bss_conf;
 	bool support_80_80, support_160;
 	u8 he_phy_cap;
 	u32 freq;
@@ -3428,6 +3429,18 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
 					      NL80211_BAND_6GHZ);
 	he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
 
+	bss_conf = &sdata->vif.bss_conf;
+
+	switch (u8_get_bits(he_6ghz_oper->control,
+			    IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) {
+	case IEEE80211_6GHZ_CTRL_REG_LPI_AP:
+		bss_conf->power_type = IEEE80211_REG_LPI_AP;
+		break;
+	case IEEE80211_6GHZ_CTRL_REG_SP_AP:
+		bss_conf->power_type = IEEE80211_REG_SP_AP;
+		break;
+	}
+
 	switch (u8_get_bits(he_6ghz_oper->control,
 			    IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH)) {
 	case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ:
Signature · 7 lines
2.31.1


-- 
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
maintainer
#3 lore raw

Re: [PATCH v4 2/6] mac80211: add parse regulatory info in 6 GHz operation information

Quoted 28 lines · Wen Gong

This patch is to convert the regulatory info subfield in HE operation element to power type and save in struct cfg80211_chan_def.

---
 net/mac80211/util.c | 13 +++++++++++++

 1 file changed, 13 insertions(+)
net/mac80211/util.c +1 -0
index ca8008ba9b1f..66e48f29495a 100644
@@ -3385,6 +3385,7 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
  	const struct ieee80211_sta_he_cap *he_cap;
  	struct cfg80211_chan_def he_chandef = *chandef;
  	const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
+	struct ieee80211_bss_conf *bss_conf;
  	bool support_80_80, support_160;
  	u8 he_phy_cap;
  	u32 freq;
@@ -3428,6 +3429,18 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
  					      NL80211_BAND_6GHZ);
  	he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq);

net/mac80211/util.c +1 -0
+	bss_conf = &sdata->vif.bss_conf;

net/mac80211/util.c bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, · line 3442

Quoted 10 lines
net/mac80211/util.c +10 -0
+
+	switch (u8_get_bits(he_6ghz_oper->control,
+			    IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) {
+	case IEEE80211_6GHZ_CTRL_REG_LPI_AP:
+		bss_conf->power_type = IEEE80211_REG_LPI_AP;
+		break;
+	case IEEE80211_6GHZ_CTRL_REG_SP_AP:
+		bss_conf->power_type = IEEE80211_REG_SP_AP;
+		break;
+	}

I added a default case here to set it to UNSET, so that if you disconnect and reconnect etc. you don't get stale data.

johannes

author
#4 lore raw

PATCH v4 3/6 cfg80211: add definition for 6 GHz power spectral density(psd)

In reply to Wen Gong

6 GHz regulatory domains introduces power spectral density(psd). This patch is define the flags for psd.

---
 include/net/cfg80211.h       | 5 +++++
 include/net/regulatory.h     | 1 +
 include/uapi/linux/nl80211.h | 2 ++
 3 files changed, 8 insertions(+)
include/net/cfg80211.h +5 -0
index 62dd8422e0dc..f8e0cc19e0ce 100644
@@ -109,6 +109,8 @@ struct wiphy;
  *	on this channel.
  * @IEEE80211_CHAN_16MHZ: 16 MHz bandwidth is permitted
  *	on this channel.
+ * @IEEE80211_CHAN_PSD: power spectral density (in dBm)
+ *	on this channel.
  *
  */
 enum ieee80211_channel_flags {
@@ -131,6 +133,7 @@ enum ieee80211_channel_flags {
 	IEEE80211_CHAN_4MHZ		= 1<<16,
 	IEEE80211_CHAN_8MHZ		= 1<<17,
 	IEEE80211_CHAN_16MHZ		= 1<<18,
+	IEEE80211_CHAN_PSD		= 1<<19,
 };
 
 #define IEEE80211_CHAN_NO_HT40 \
@@ -164,6 +167,7 @@ enum ieee80211_channel_flags {
  *	on this channel.
  * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
  * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
+ * @psd: power spectral density (in dBm)
  */
 struct ieee80211_channel {
 	enum nl80211_band band;
@@ -180,6 +184,7 @@ struct ieee80211_channel {
 	enum nl80211_dfs_state dfs_state;
 	unsigned long dfs_state_entered;
 	unsigned int dfs_cac_ms;
+	s8 psd;
 };
 
 /**
include/net/regulatory.h +1 -0
index 47f06f6f5a67..ed20004fb6a9 100644
@@ -221,6 +221,7 @@ struct ieee80211_reg_rule {
 	u32 flags;
 	u32 dfs_cac_ms;
 	bool has_wmm;
+	s8 psd;
 };
 
 struct ieee80211_regdomain {
include/uapi/linux/nl80211.h +2 -0
index c2efea98e060..2ca8fa06f536 100644
@@ -4085,6 +4085,7 @@ enum nl80211_sched_scan_match_attr {
  * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
  * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
  * @NL80211_RRF_NO_HE: HE operation not allowed
+ * @NL80211_RRF_PSD: channels has power spectral density value
  */
 enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_OFDM		= 1<<0,
@@ -4103,6 +4104,7 @@ enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_80MHZ		= 1<<15,
 	NL80211_RRF_NO_160MHZ		= 1<<16,
 	NL80211_RRF_NO_HE		= 1<<17,
+	NL80211_RRF_PSD		= 1<<18,
 };
 
 #define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
Signature · 1 line
2.31.1
maintainer
#5 lore raw

Re: [PATCH v4 3/6] cfg80211: add definition for 6 GHz power spectral density(psd)

include/uapi/linux/nl80211.h enum nl80211_reg_rule_flags { · line 4107

Quoted 5 lines · Wen Gong

  NL80211_RRF_NO_80MHZ = 1<<15,
  NL80211_RRF_NO_160MHZ = 1<<16,
  NL80211_RRF_NO_HE = 1<<17,

include/uapi/linux/nl80211.h +1 -0
+	NL80211_RRF_PSD		= 1<<18,

Indentation seems to be missing a tab here.

johannes

Signature · 3 lines
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
author
#6 lore raw

PATCH v4 4/6 cfg80211: save power spectral density(psd) of regulatory rule

In reply to Wen Gong

The power spectral density(psd) of regulatory rule should be take effect to the channels. This patch is to save the values to the channel which has psd value.

---
 net/wireless/reg.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
net/wireless/reg.c +17 -0
index df87c7f3a049..8f765befb9bc 100644
@@ -1590,6 +1590,8 @@ static u32 map_regdom_flags(u32 rd_flags)
 		channel_flags |= IEEE80211_CHAN_NO_160MHZ;
 	if (rd_flags & NL80211_RRF_NO_HE)
 		channel_flags |= IEEE80211_CHAN_NO_HE;
+	if (rd_flags & NL80211_RRF_PSD)
+		channel_flags |= IEEE80211_CHAN_PSD;
 	return channel_flags;
 }
 
@@ -1794,6 +1796,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy,
 				chan->dfs_cac_ms = reg_rule->dfs_cac_ms;
 		}
 
+		if (chan->flags & IEEE80211_CHAN_PSD)
+			chan->psd = reg_rule->psd;
+
 		return;
 	}
 
@@ -1814,6 +1819,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy,
 			chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
 	}
 
+	if (chan->flags & IEEE80211_CHAN_PSD)
+		chan->psd = reg_rule->psd;
+
 	if (chan->orig_mpwr) {
 		/*
 		 * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
@@ -1883,6 +1891,12 @@ static void handle_channel_adjacent_rules(struct wiphy *wiphy,
 							 rrule2->dfs_cac_ms);
 		}
 
+		if ((rrule1->flags & NL80211_RRF_PSD) &&
+		    (rrule2->flags & NL80211_RRF_PSD))
+			chan->psd = min_t(s8, rrule1->psd, rrule2->psd);
+		else
+			chan->flags &= ~NL80211_RRF_PSD;
+
 		return;
 	}
 
@@ -2540,6 +2554,9 @@ static void handle_channel_custom(struct wiphy *wiphy,
 			chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
 	}
 
+	if (chan->flags & IEEE80211_CHAN_PSD)
+		chan->psd = reg_rule->psd;
+
 	chan->max_power = chan->max_reg_power;
 }
 
Signature · 7 lines
2.31.1


-- 
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
maintainer
#7 lore raw

Re: [PATCH v4 4/6] cfg80211: save power spectral density(psd) of regulatory rule

Quoted 14 lines · Wen Gong

The power spectral density(psd) of regulatory rule should be take effect to the channels. This patch is to save the values to the channel which has psd value.

---
 net/wireless/reg.c | 17 +++++++++++++++++

 1 file changed, 17 insertions(+)
net/wireless/reg.c +0 -0
index df87c7f3a049..8f765befb9bc 100644

net/wireless/reg.c static u32 map_regdom_flags(u32 rd_flags) · line 1594

Quoted 5 lines
net/wireless/reg.c +2 -0
@@ -1590,6 +1590,8 @@ static u32 map_regdom_flags(u32 rd_flags)
  		channel_flags |= IEEE80211_CHAN_NO_160MHZ;
  	if (rd_flags & NL80211_RRF_NO_HE)
  		channel_flags |= IEEE80211_CHAN_NO_HE;
+	if (rd_flags & NL80211_RRF_PSD)
+		channel_flags |= IEEE80211_CHAN_PSD;

I went to go squash this with patch 3 and took a closer look, and then I realized you're doing this weird.

Please when you resend also squash this - it's a bit weird to read in two patches.

However, I think this is missing a lot of things - we already talked about the regulatory database, and while that'd be nice, I guess I conceded that you don't really have to do it now.

However, for visibility reasons, I *really* think you need to add nl80211 attributes for all of this data - when the regdomain is dumped in nl80211_put_regdom() you would have the flag now (it dumps the value of reg_rule->flags in NL80211_ATTR_REG_RULE_FLAGS), but you didn't add the value of reg_rule->psd which you've added.

Similarly, you're not adding the PSD flag nor the PSD value for the *channel* in nl80211_msg_put_channel(), both of which I think you should have for visibility into what's going on in the kernel/driver.

I've applied all the other patches, so please just resend 3 and 4, squashed into a single patch, with the fixes.

johannes

Signature · 3 lines
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
author
#8 lore raw

Re: [PATCH v4 4/6] cfg80211: save power spectral density(psd) of regulatory rule

Quoted 37 lines · Johannes Berg
Quoted 14 lines · Wen Gong

The power spectral density(psd) of regulatory rule should be take effect to the channels. This patch is to save the values to the channel which has psd value.

---
 net/wireless/reg.c | 17 +++++++++++++++++

 1 file changed, 17 insertions(+)
net/wireless/reg.c +0 -0
index df87c7f3a049..8f765befb9bc 100644

net/wireless/reg.c static u32 map_regdom_flags(u32 rd_flags) · line 1594

Quoted 5 lines
net/wireless/reg.c +2 -0
@@ -1590,6 +1590,8 @@ static u32 map_regdom_flags(u32 rd_flags)
  		channel_flags |= IEEE80211_CHAN_NO_160MHZ;
  	if (rd_flags & NL80211_RRF_NO_HE)
  		channel_flags |= IEEE80211_CHAN_NO_HE;
+	if (rd_flags & NL80211_RRF_PSD)
+		channel_flags |= IEEE80211_CHAN_PSD;

I went to go squash this with patch 3 and took a closer look, and then I realized you're doing this weird.

Please when you resend also squash this - it's a bit weird to read in two patches.

However, I think this is missing a lot of things - we already talked about the regulatory database, and while that'd be nice, I guess I conceded that you don't really have to do it now.

However, for visibility reasons, I *really* think you need to add nl80211 attributes for all of this data - when the regdomain is dumped in nl80211_put_regdom() you would have the flag now (it dumps the value of reg_rule->flags in NL80211_ATTR_REG_RULE_FLAGS), but you didn't add the value of reg_rule->psd which you've added.

Quoted 7 lines

Similarly, you're not adding the PSD flag nor the PSD value for the *channel* in nl80211_msg_put_channel(), both of which I think you should have for visibility into what's going on in the kernel/driver.

I've applied all the other patches, so please just resend 3 and 4, squashed into a single patch, with the fixes.

Thanks

I have sent "[PATCH v5] cfg80211: save power spectral density(psd) of regulatory rule" for this.

Quoted 1 line

johannes

author
#9 lore raw

PATCH v4 5/6 mac80211: use ieee802_11_parse_elems() to find ies instead of ieee80211_bss_get_ie()

In reply to Wen Gong

In function ieee80211_prep_channel(), it has some ieee80211_bss_get_ie() and cfg80211_find_ext_ie() to get the IE, this is to use another function ieee802_11_parse_elems() to get all the IEs in one time.

---
 net/mac80211/mlme.c | 52 +++++++++++++++++++++++++++++++--------------
 1 file changed, 36 insertions(+), 16 deletions(-)
net/mac80211/mlme.c +36 -16
index e80f3388b0c5..6e8e90ee8b6c 100644
@@ -4998,10 +4998,22 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 	bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
 	bool is_5ghz = cbss->channel->band == NL80211_BAND_5GHZ;
 	struct ieee80211_bss *bss = (void *)cbss->priv;
+	struct ieee802_11_elems *elems;
+	const struct cfg80211_bss_ies *ies;
 	int ret;
 	u32 i;
 	bool have_80mhz;
 
+	rcu_read_lock();
+
+	ies = rcu_dereference(cbss->ies);
+	elems = ieee802_11_parse_elems(ies->data, ies->len, false,
+				       NULL, NULL);
+	if (!elems) {
+		rcu_read_unlock();
+		return -EINVAL;
+	}
+
 	sband = local->hw.wiphy->bands[cbss->channel->band];
 
 	ifmgd->flags &= ~(IEEE80211_STA_DISABLE_40MHZ |
@@ -5024,16 +5036,18 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 					 ieee80211_vif_type_p2p(&sdata->vif)))
 		ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
 
-	rcu_read_lock();
-
 	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && !is_6ghz) {
 		const u8 *ht_oper_ie, *ht_cap_ie;
 
-		ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
+		ht_oper_ie = elems->ht_operation ?
+			((const u8 *)elems->ht_operation) - 2 :
+			NULL;
 		if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
 			ht_oper = (void *)(ht_oper_ie + 2);
 
-		ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY);
+		ht_cap_ie = elems->ht_cap_elem ?
+			((const u8 *)elems->ht_cap_elem) - 2 :
+			NULL;
 		if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap))
 			ht_cap = (void *)(ht_cap_ie + 2);
 
@@ -5046,8 +5060,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && !is_6ghz) {
 		const u8 *vht_oper_ie, *vht_cap;
 
-		vht_oper_ie = ieee80211_bss_get_ie(cbss,
-						   WLAN_EID_VHT_OPERATION);
+		vht_oper_ie = elems->vht_operation ?
+			((const u8 *)elems->vht_operation) - 2 :
+			NULL;
 		if (vht_oper_ie && vht_oper_ie[1] >= sizeof(*vht_oper))
 			vht_oper = (void *)(vht_oper_ie + 2);
 		if (vht_oper && !ht_oper) {
@@ -5059,7 +5074,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 			ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
 		}
 
-		vht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_VHT_CAPABILITY);
+		vht_cap = elems->vht_cap_elem ?
+			((const u8 *)elems->vht_cap_elem) - 2 :
+			NULL;
 		if (!vht_cap || vht_cap[1] < sizeof(struct ieee80211_vht_cap)) {
 			ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
 			vht_oper = NULL;
@@ -5067,12 +5084,11 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 	}
 
 	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE)) {
-		const struct cfg80211_bss_ies *ies;
 		const u8 *he_oper_ie;
 
-		ies = rcu_dereference(cbss->ies);
-		he_oper_ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION,
-						  ies->data, ies->len);
+		he_oper_ie = elems->he_operation ?
+			((const u8 *)elems->he_operation) - 3 :
+			NULL;
 		if (he_oper_ie &&
 		    he_oper_ie[1] >= ieee80211_he_oper_size(&he_oper_ie[3]))
 			he_oper = (void *)(he_oper_ie + 3);
@@ -5100,8 +5116,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 	if (sband->band == NL80211_BAND_S1GHZ) {
 		const u8 *s1g_oper_ie;
 
-		s1g_oper_ie = ieee80211_bss_get_ie(cbss,
-						   WLAN_EID_S1G_OPERATION);
+		s1g_oper_ie = elems->s1g_oper ?
+			((const u8 *)elems->s1g_oper) - 2 :
+			NULL;
 		if (s1g_oper_ie && s1g_oper_ie[1] >= sizeof(*s1g_oper))
 			s1g_oper = (void *)(s1g_oper_ie + 2);
 		else
@@ -5123,7 +5140,8 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 
 	if (ifmgd->flags & IEEE80211_STA_DISABLE_HE && is_6ghz) {
 		sdata_info(sdata, "Rejecting non-HE 6/7 GHz connection");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_no_lock;
 	}
 
 	/* will change later if needed */
@@ -5141,15 +5159,17 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 	/* don't downgrade for 5 and 10 MHz channels, though. */
 	if (chandef.width == NL80211_CHAN_WIDTH_5 ||
 	    chandef.width == NL80211_CHAN_WIDTH_10)
-		goto out;
+		goto out_lock;
 
 	while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
 		ifmgd->flags |= ieee80211_chandef_downgrade(&chandef);
 		ret = ieee80211_vif_use_channel(sdata, &chandef,
 						IEEE80211_CHANCTX_SHARED);
 	}
- out:
+ out_lock:
 	mutex_unlock(&local->mtx);
+ out_no_lock:
+	kfree(elems);
 	return ret;
 }
 
Signature · 1 line
2.31.1
maintainer
#10 lore raw

Re: [PATCH v4 5/6] mac80211: use ieee802_11_parse_elems() to find ies instead of ieee80211_bss_get_ie()

Taking a brief look before lunch,

Quoted 10 lines

  if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && !is_6ghz) { const u8 *ht_oper_ie, *ht_cap_ie;

net/mac80211/mlme.c +3 -1
-		ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
+		ht_oper_ie = elems->ht_operation ?
+			((const u8 *)elems->ht_operation) - 2 :
+			NULL;
Quoted 2 lines

  if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) ht_oper = (void *)(ht_oper_ie + 2);

Can't we drop these checks, and simply do

ht_oper = elems->ht_operation?

After all, ieee802_11_parse_elems() should already be doing the necessary length checks? We just didn't have that with ieee80211_bss_get_ie().

Quoted 6 lines
net/mac80211/mlme.c +3 -1
-		ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY);
+		ht_cap_ie = elems->ht_cap_elem ?
+			((const u8 *)elems->ht_cap_elem) - 2 :
+			NULL;

  if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) ht_cap = (void *)(ht_cap_ie + 2);

Likewise for all the others.

johannes

maintainer
#11 lore raw

Re: [PATCH v4 5/6] mac80211: use ieee802_11_parse_elems() to find ies instead of ieee80211_bss_get_ie()

Quoted 17 lines · Johannes Berg

Taking a brief look before lunch,

Quoted 10 lines

  if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && !is_6ghz) { const u8 *ht_oper_ie, *ht_cap_ie;

net/mac80211/mlme.c +3 -1
-		ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
+		ht_oper_ie = elems->ht_operation ?
+			((const u8 *)elems->ht_operation) - 2 :
+			NULL;
Quoted 2 lines

  if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) ht_oper = (void *)(ht_oper_ie + 2);

Can't we drop these checks, and simply do

Quoted 1 line

ht_oper = elems->ht_operation?

I checked, yes, we can do that. Since I just did it anyway, no need to resend.

johannes

Signature · 3 lines
ath11k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath11k
author
#12 lore raw

PATCH v4 6/6 mac80211: save transmit power envelope element and power constraint

In reply to Wen Gong

This is to save the transmit power envelope element and power constraint in struct ieee80211_bss_conf for 6 GHz. Lower driver will use this info to calculate the power limit.

---
 include/net/mac80211.h |  6 ++++++
 net/mac80211/mlme.c    | 30 ++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)
include/net/mac80211.h +6 -0
index 8923a9fc4126..16a965262a4f 100644
@@ -633,6 +633,9 @@ struct ieee80211_fils_discovery {
  * @beacon_tx_rate: The configured beacon transmit rate that needs to be passed
  *	to driver when rate control is offloaded to firmware.
  * @power_type: power type of BSS for 6 GHz
+ * @tx_pwr_env: transmit power envelope array of BSS.
+ * @tx_pwr_env_num: number of @tx_pwr_env.
+ * @pwr_reduction: power constraint of BSS.
  */
 struct ieee80211_bss_conf {
 	const u8 *bssid;
@@ -704,6 +707,9 @@ struct ieee80211_bss_conf {
 	bool s1g;
 	struct cfg80211_bitrate_mask beacon_tx_rate;
 	enum ieee80211_ap_reg_power power_type;
+	struct ieee80211_tx_pwr_env tx_pwr_env[IEEE80211_TPE_MAX_IE_COUNT];
+	u8 tx_pwr_env_num;
+	u8 pwr_reduction;
 };
 
 /**
net/mac80211/mlme.c +30 -0
index 6e8e90ee8b6c..b72fa1f6116a 100644
@@ -2258,6 +2258,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_bss_conf *bss_conf;
 	u32 changed = 0;
 	struct ieee80211_prep_tx_info info = {
 		.subtype = stype,
@@ -2407,6 +2408,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 	cancel_delayed_work_sync(&ifmgd->tx_tspec_wk);
 
 	sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
+
+	bss_conf = &sdata->vif.bss_conf;
+	bss_conf->pwr_reduction = 0;
+	bss_conf->tx_pwr_env_num = 0;
+	memset(bss_conf->tx_pwr_env, 0, sizeof(bss_conf->tx_pwr_env));
 }
 
 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
@@ -5095,6 +5101,30 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 		else
 			he_oper = NULL;
 
+		if (is_6ghz) {
+			struct ieee80211_bss_conf *bss_conf;
+			u8 i, j = 0;
+
+			bss_conf = &sdata->vif.bss_conf;
+
+			if (elems->pwr_constr_elem)
+				bss_conf->pwr_reduction = *elems->pwr_constr_elem;
+
+			BUILD_BUG_ON(ARRAY_SIZE(bss_conf->tx_pwr_env) !=
+				     ARRAY_SIZE(elems->tx_pwr_env));
+
+			for (i = 0; i < elems->tx_pwr_env_num; i++) {
+				if (elems->tx_pwr_env_len[i] >
+				    sizeof(bss_conf->tx_pwr_env[j]))
+					continue;
+
+				bss_conf->tx_pwr_env_num++;
+				memcpy(&bss_conf->tx_pwr_env[j], elems->tx_pwr_env[i],
+				       elems->tx_pwr_env_len[i]);
+				j++;
+			}
+		}
+
 		if (!ieee80211_verify_sta_he_mcs_support(sdata, sband, he_oper))
 			ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
 	}
Signature · 7 lines
2.31.1


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