diff mbox series

ieee80211: fix interopt issue with MT7927 chipset

Message ID 20250120114551.1542812-1-pmartin-gomez@freebox.fr (mailing list archive)
State New
Delegated to: Johannes Berg
Headers show
Series ieee80211: fix interopt issue with MT7927 chipset | expand

Commit Message

Pablo Martin-Gomez Jan. 20, 2025, 11:45 a.m. UTC
Mediatek's chipsets MT7927 and MT7925 with Windows driver 5.4.0.3044
(and earlier versions) set the IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G
bit in 5 & 6Ghz band, which is supposed to be reserved. Currently, the
kernel assumes a reserved bit to be set to 0 and uses the bit value to
deduce that the current band used is 2.4GHz.

This causes the kernel to miscalculate mcs_nss_size to 3 bytes,
resulting in incorrect rx/tx nss map, so the sta is believed to have
0 NSS for 160/320.

Signed-off-by: Pablo Martin-Gomez <pmartin-gomez@freebox.fr>
---
 include/linux/ieee80211.h | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 16741e542e81..2e813824d52a 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -3196,14 +3196,17 @@  ieee80211_eht_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap,
 {
 	u8 count = 0;
 
-	/* on 2.4 GHz, if it supports 40 MHz, the result is 3 */
-	if (he_cap->phy_cap_info[0] &
-	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G)
-		return 3;
+	/* 20 MHz-only non-AP STA */
+	if (!from_ap && (he_cap->phy_cap_info[0] &
+	    (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
+	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
+	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
+	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)) == 0)
+		return 4;
 
-	/* on 2.4 GHz, these three bits are reserved, so should be 0 */
 	if (he_cap->phy_cap_info[0] &
-	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)
+	    (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
+	     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G))
 		count += 3;
 
 	if (he_cap->phy_cap_info[0] &