[openwrt/openwrt] mac80211: Fix wifi throughput

LEDE Commits lede-commits at lists.infradead.org
Fri Jul 26 15:39:48 PDT 2024


hauke pushed a commit to openwrt/openwrt.git, branch openwrt-23.05:
https://git.openwrt.org/56a84b3c4754f96a64a17bcc9730358ac48ba993

commit 56a84b3c4754f96a64a17bcc9730358ac48ba993
Author: Hauke Mehrtens <hauke at hauke-m.de>
AuthorDate: Fri Jul 26 01:13:51 2024 +0200

    mac80211: Fix wifi throughput
    
    Backport 2 patches from upstream Linux to fix a Wifi throughput
    problem.
    
    Fixes: 323e249ce8ed ("mac80211: Update to version 6.1.97-1")
    Link: https://github.com/openwrt/openwrt/pull/16007
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 ...11-Allow-NSS-change-only-up-to-capability.patch |  69 ++++++++
 ...11-track-capability-opmode-NSS-separately.patch | 186 +++++++++++++++++++++
 2 files changed, 255 insertions(+)

diff --git a/package/kernel/mac80211/patches/subsys/350-v6.3-wifi-mac80211-Allow-NSS-change-only-up-to-capability.patch b/package/kernel/mac80211/patches/subsys/350-v6.3-wifi-mac80211-Allow-NSS-change-only-up-to-capability.patch
new file mode 100644
index 0000000000..c8e0dd62b4
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/350-v6.3-wifi-mac80211-Allow-NSS-change-only-up-to-capability.patch
@@ -0,0 +1,69 @@
+From 1b7c710a8e912d54a24742ed5a87a047be64141a Mon Sep 17 00:00:00 2001
+From: Rameshkumar Sundaram <quic_ramess at quicinc.com>
+Date: Tue, 7 Feb 2023 17:11:46 +0530
+Subject: [PATCH 350/351] wifi: mac80211: Allow NSS change only up to
+ capability
+
+Stations can update bandwidth/NSS change in
+VHT action frame with action type Operating Mode Notification.
+(IEEE Std 802.11-2020 - 9.4.1.53 Operating Mode field)
+
+For Operating Mode Notification, an RX NSS change to a value
+greater than AP's maximum NSS should not be allowed.
+During fuzz testing, by forcefully sending VHT Op. mode notif.
+frames from STA with random rx_nss values, it is found that AP
+accepts rx_nss values greater that APs maximum NSS instead of
+discarding such NSS change.
+
+Hence allow NSS change only up to maximum NSS that is negotiated
+and capped to AP's capability during association.
+
+Signed-off-by: Rameshkumar Sundaram <quic_ramess at quicinc.com>
+Link: https://lore.kernel.org/r/20230207114146.10567-1-quic_ramess@quicinc.com
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+(cherry picked from commit 57b341e9ab13e5688491bfd54f8b5502416c8905)
+---
+ net/mac80211/vht.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+--- a/net/mac80211/vht.c
++++ b/net/mac80211/vht.c
+@@ -637,7 +637,7 @@ u32 __ieee80211_vht_handle_opmode(struct
+ 	enum ieee80211_sta_rx_bandwidth new_bw;
+ 	struct sta_opmode_info sta_opmode = {};
+ 	u32 changed = 0;
+-	u8 nss;
++	u8 nss, cur_nss;
+ 
+ 	/* ignore - no support for BF yet */
+ 	if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)
+@@ -648,10 +648,25 @@ u32 __ieee80211_vht_handle_opmode(struct
+ 	nss += 1;
+ 
+ 	if (link_sta->pub->rx_nss != nss) {
+-		link_sta->pub->rx_nss = nss;
+-		sta_opmode.rx_nss = nss;
+-		changed |= IEEE80211_RC_NSS_CHANGED;
+-		sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
++		cur_nss = link_sta->pub->rx_nss;
++		/* Reset rx_nss and call ieee80211_sta_set_rx_nss() which
++		 * will set the same to max nss value calculated based on capability.
++		 */
++		link_sta->pub->rx_nss = 0;
++		ieee80211_sta_set_rx_nss(link_sta);
++		/* Do not allow an nss change to rx_nss greater than max_nss
++		 * negotiated and capped to APs capability during association.
++		 */
++		if (nss <= link_sta->pub->rx_nss) {
++			link_sta->pub->rx_nss = nss;
++			sta_opmode.rx_nss = nss;
++			changed |= IEEE80211_RC_NSS_CHANGED;
++			sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
++		} else {
++			link_sta->pub->rx_nss = cur_nss;
++			pr_warn_ratelimited("Ignoring NSS change in VHT Operating Mode Notification from %pM with invalid nss %d",
++					    link_sta->pub->addr, nss);
++		}
+ 	}
+ 
+ 	switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
diff --git a/package/kernel/mac80211/patches/subsys/351-v6.9-wifi-mac80211-track-capability-opmode-NSS-separately.patch b/package/kernel/mac80211/patches/subsys/351-v6.9-wifi-mac80211-track-capability-opmode-NSS-separately.patch
new file mode 100644
index 0000000000..968e7171d2
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/351-v6.9-wifi-mac80211-track-capability-opmode-NSS-separately.patch
@@ -0,0 +1,186 @@
+From 32d043fc10f1814e421c0ff90c0ee6b303f2821c Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg at intel.com>
+Date: Wed, 28 Feb 2024 12:01:57 +0100
+Subject: [PATCH 351/351] wifi: mac80211: track capability/opmode NSS
+ separately
+
+We're currently tracking rx_nss for each station, and that
+is meant to be initialized to the capability NSS and later
+reduced by the operating mode notification NSS.
+
+However, we're mixing up capabilities and operating mode
+NSS in the same variable. This forces us to recalculate
+the NSS capability on operating mode notification RX,
+which is a bit strange; due to the previous fix I had to
+never keep rx_nss as zero, it also means that the capa is
+never taken into account properly.
+
+Fix all this by storing the capability value, that can be
+recalculated unconditionally whenever needed, and storing
+the operating mode notification NSS separately, taking it
+into account when assigning the final rx_nss value.
+
+Cc: stable at vger.kernel.org
+Fixes: dd6c064cfc3f ("wifi: mac80211: set station RX-NSS on reconfig")
+Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit at intel.com>
+Link: https://msgid.link/20240228120157.0e1c41924d1d.I0acaa234e0267227b7e3ef81a59117c8792116bc@changeid
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+(cherry picked from commit a8bca3e9371dc5e276af4168be099b2a05554c2a)
+---
+ net/mac80211/cfg.c         |  2 +-
+ net/mac80211/ieee80211_i.h |  2 +-
+ net/mac80211/rate.c        |  2 +-
+ net/mac80211/sta_info.h    |  6 ++++-
+ net/mac80211/vht.c         | 46 ++++++++++++++++++--------------------
+ 5 files changed, 30 insertions(+), 28 deletions(-)
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1836,7 +1836,7 @@ static int sta_link_apply_parameters(str
+ 					      sband->band);
+ 	}
+ 
+-	ieee80211_sta_set_rx_nss(link_sta);
++	ieee80211_sta_init_nss(link_sta);
+ 
+ 	return ret;
+ }
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -2101,7 +2101,7 @@ enum ieee80211_sta_rx_bandwidth
+ ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta);
+ enum ieee80211_sta_rx_bandwidth
+ ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta);
+-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta);
++void ieee80211_sta_init_nss(struct link_sta_info *link_sta);
+ enum ieee80211_sta_rx_bandwidth
+ ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
+ enum nl80211_chan_width
+--- a/net/mac80211/rate.c
++++ b/net/mac80211/rate.c
+@@ -37,7 +37,7 @@ void rate_control_rate_init(struct sta_i
+ 	struct ieee80211_supported_band *sband;
+ 	struct ieee80211_chanctx_conf *chanctx_conf;
+ 
+-	ieee80211_sta_set_rx_nss(&sta->deflink);
++	ieee80211_sta_init_nss(&sta->deflink);
+ 
+ 	if (!ref)
+ 		return;
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -3,7 +3,7 @@
+  * Copyright 2002-2005, Devicescape Software, Inc.
+  * Copyright 2013-2014  Intel Mobile Communications GmbH
+  * Copyright(c) 2015-2017 Intel Deutschland GmbH
+- * Copyright(c) 2020-2022 Intel Corporation
++ * Copyright(c) 2020-2024 Intel Corporation
+  */
+ 
+ #ifndef STA_INFO_H
+@@ -485,6 +485,8 @@ struct ieee80211_fragment_cache {
+  *	same for non-MLD STA. This is used as key for searching link STA
+  * @link_id: Link ID uniquely identifying the link STA. This is 0 for non-MLD
+  *	and set to the corresponding vif LinkId for MLD STA
++ * @op_mode_nss: NSS limit as set by operating mode notification, or 0
++ * @capa_nss: NSS limit as determined by local and peer capabilities
+  * @link_hash_node: hash node for rhashtable
+  * @sta: Points to the STA info
+  * @gtk: group keys negotiated with this station, if any
+@@ -520,6 +522,8 @@ struct link_sta_info {
+ 	u8 addr[ETH_ALEN];
+ 	u8 link_id;
+ 
++	u8 op_mode_nss, capa_nss;
++
+ 	struct rhlist_head link_hash_node;
+ 
+ 	struct sta_info *sta;
+--- a/net/mac80211/vht.c
++++ b/net/mac80211/vht.c
+@@ -4,7 +4,7 @@
+  *
+  * Portions of this file
+  * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
+- * Copyright (C) 2018 - 2023 Intel Corporation
++ * Copyright (C) 2018 - 2024 Intel Corporation
+  */
+ 
+ #include <linux/ieee80211.h>
+@@ -541,15 +541,11 @@ ieee80211_sta_cur_vht_bw(struct link_sta
+ 	return bw;
+ }
+ 
+-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta)
++void ieee80211_sta_init_nss(struct link_sta_info *link_sta)
+ {
+ 	u8 ht_rx_nss = 0, vht_rx_nss = 0, he_rx_nss = 0, eht_rx_nss = 0, rx_nss;
+ 	bool support_160;
+ 
+-	/* if we received a notification already don't overwrite it */
+-	if (link_sta->pub->rx_nss)
+-		return;
+-
+ 	if (link_sta->pub->eht_cap.has_eht) {
+ 		int i;
+ 		const u8 *rx_nss_mcs = (void *)&link_sta->pub->eht_cap.eht_mcs_nss_supp;
+@@ -627,7 +623,15 @@ void ieee80211_sta_set_rx_nss(struct lin
+ 	rx_nss = max(vht_rx_nss, ht_rx_nss);
+ 	rx_nss = max(he_rx_nss, rx_nss);
+ 	rx_nss = max(eht_rx_nss, rx_nss);
+-	link_sta->pub->rx_nss = max_t(u8, 1, rx_nss);
++	rx_nss = max_t(u8, 1, rx_nss);
++	link_sta->capa_nss = rx_nss;
++
++	/* that shouldn't be set yet, but we can handle it anyway */
++	if (link_sta->op_mode_nss)
++		link_sta->pub->rx_nss =
++			min_t(u8, rx_nss, link_sta->op_mode_nss);
++	else
++		link_sta->pub->rx_nss = rx_nss;
+ }
+ 
+ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
+@@ -637,7 +641,7 @@ u32 __ieee80211_vht_handle_opmode(struct
+ 	enum ieee80211_sta_rx_bandwidth new_bw;
+ 	struct sta_opmode_info sta_opmode = {};
+ 	u32 changed = 0;
+-	u8 nss, cur_nss;
++	u8 nss;
+ 
+ 	/* ignore - no support for BF yet */
+ 	if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)
+@@ -647,23 +651,17 @@ u32 __ieee80211_vht_handle_opmode(struct
+ 	nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
+ 	nss += 1;
+ 
+-	if (link_sta->pub->rx_nss != nss) {
+-		cur_nss = link_sta->pub->rx_nss;
+-		/* Reset rx_nss and call ieee80211_sta_set_rx_nss() which
+-		 * will set the same to max nss value calculated based on capability.
+-		 */
+-		link_sta->pub->rx_nss = 0;
+-		ieee80211_sta_set_rx_nss(link_sta);
+-		/* Do not allow an nss change to rx_nss greater than max_nss
+-		 * negotiated and capped to APs capability during association.
+-		 */
+-		if (nss <= link_sta->pub->rx_nss) {
+-			link_sta->pub->rx_nss = nss;
+-			sta_opmode.rx_nss = nss;
+-			changed |= IEEE80211_RC_NSS_CHANGED;
+-			sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
++	if (link_sta->op_mode_nss != nss) {
++		if (nss <= link_sta->capa_nss) {
++			link_sta->op_mode_nss = nss;
++
++			if (nss != link_sta->pub->rx_nss) {
++				link_sta->pub->rx_nss = nss;
++				changed |= IEEE80211_RC_NSS_CHANGED;
++				sta_opmode.rx_nss = link_sta->pub->rx_nss;
++				sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
++			}
+ 		} else {
+-			link_sta->pub->rx_nss = cur_nss;
+ 			pr_warn_ratelimited("Ignoring NSS change in VHT Operating Mode Notification from %pM with invalid nss %d",
+ 					    link_sta->pub->addr, nss);
+ 		}




More information about the lede-commits mailing list