mac80211: fix wrong 160/80+80 Mhz setting
diff mbox series

Message ID 20200209152818.4630-1-shay.bar@celeno.com
State Superseded
Delegated to: Johannes Berg
Headers show
Series
  • mac80211: fix wrong 160/80+80 Mhz setting
Related show

Commit Message

Shay Bar Feb. 9, 2020, 3:28 p.m. UTC
Before this patch, STA's would set new width of 160/80+80 Mhz based on AP capability only.
This is wrong because STA may not support > 80Mhz BW.
Fix is to verify STA has 160/80+80 Mhz capability before increasing its width to > 80Mhz.

Signed-off-by: Aviad Brikman <aviad.brikman@celeno.com>
Signed-off-by: Shay Bar <shay.bar@celeno.com>
---
 net/mac80211/util.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Comments

Shay Bar Feb. 10, 2020, 12:38 p.m. UTC | #1
The "support_80_80" and "support_160" setting is based on:
"Table 9-272-Setting of the Supported Channel Width Set subfield and Extended NSS BW
Support subfield at a STA transmitting the VHT Capabilities Information field"
From "Draft P802.11REVmd_D3.0.pdf"

-----Original Message-----
From: Shay Bar <shay.bar@celeno.com>
Sent: Sunday, 9 February 2020 17:28
To: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-wireless@vger.kernel.org; Shay Bar <Shay.Bar@celeno.com>; Aviad Brikman <Aviad.Brikman@celeno.com>
Subject: [PATCH] [PATCH] mac80211: fix wrong 160/80+80 Mhz setting

External Email


Before this patch, STA's would set new width of 160/80+80 Mhz based on AP capability only.
This is wrong because STA may not support > 80Mhz BW.
Fix is to verify STA has 160/80+80 Mhz capability before increasing its width to > 80Mhz.

Signed-off-by: Aviad Brikman <aviad.brikman@celeno.com>
Signed-off-by: Shay Bar <shay.bar@celeno.com>
---
 net/mac80211/util.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 32a7a53833c0..950fa4741d98 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2987,10 +2987,22 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
        int cf0, cf1;
        int ccfs0, ccfs1, ccfs2;
        int ccf0, ccf1;
+       u32 vht_cap;
+       bool support_80_80 = false;
+       bool support_160 = false;

        if (!oper || !htop)
                return false;

+       vht_cap = hw->wiphy->bands[chandef->chan->band]->vht_cap.cap;
+       support_160 = (vht_cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
+                                 IEEE80211_VHT_CAP_EXT_NSS_BW_MASK));
+       support_80_80 = ((vht_cap &
+                        IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) ||
+                       (vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
+                        vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) ||
+                       ((vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >>
+                                   IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT > 1));
        ccfs0 = oper->center_freq_seg0_idx;
        ccfs1 = oper->center_freq_seg1_idx;
        ccfs2 = (le16_to_cpu(htop->operation_mode) &
@@ -3018,10 +3030,10 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
                        unsigned int diff;

                        diff = abs(ccf1 - ccf0);
-                       if (diff == 8) {
+                       if ((diff == 8) && support_160) {
                                new.width = NL80211_CHAN_WIDTH_160;
                                new.center_freq1 = cf1;
-                       } else if (diff > 8) {
+                       } else if ((diff > 8) && support_80_80) {
                                new.width = NL80211_CHAN_WIDTH_80P80;
                                new.center_freq2 = cf1;
                        }
--
2.17.1

Patch
diff mbox series

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 32a7a53833c0..950fa4741d98 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2987,10 +2987,22 @@  bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
 	int cf0, cf1;
 	int ccfs0, ccfs1, ccfs2;
 	int ccf0, ccf1;
+	u32 vht_cap;
+	bool support_80_80 = false;
+	bool support_160 = false;
 
 	if (!oper || !htop)
 		return false;
 
+	vht_cap = hw->wiphy->bands[chandef->chan->band]->vht_cap.cap;
+	support_160 = (vht_cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
+				  IEEE80211_VHT_CAP_EXT_NSS_BW_MASK));
+	support_80_80 = ((vht_cap &
+			 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) ||
+			(vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
+			 vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) ||
+			((vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >>
+				    IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT > 1));
 	ccfs0 = oper->center_freq_seg0_idx;
 	ccfs1 = oper->center_freq_seg1_idx;
 	ccfs2 = (le16_to_cpu(htop->operation_mode) &
@@ -3018,10 +3030,10 @@  bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
 			unsigned int diff;
 
 			diff = abs(ccf1 - ccf0);
-			if (diff == 8) {
+			if ((diff == 8) && support_160) {
 				new.width = NL80211_CHAN_WIDTH_160;
 				new.center_freq1 = cf1;
-			} else if (diff > 8) {
+			} else if ((diff > 8) && support_80_80) {
 				new.width = NL80211_CHAN_WIDTH_80P80;
 				new.center_freq2 = cf1;
 			}