Message ID | 20250120114551.1542812-1-pmartin-gomez@freebox.fr |
---|---|
State | New |
Headers | show |
Series | ieee80211: fix interopt issue with MT7927 chipset | expand |
On 20/01/2025 12:45, Pablo Martin-Gomez wrote: > - /* 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] & This patch is still reading reserved bits depending on the band being used. I wanted to do a new version of the patch to avoid doing that by passing the current band to ieee80211_eht_mcs_nss_size(). Unfortunately, ieee80211_eht_mcs_nss_size() is called by ieee80211_eht_capa_size_ok() which itself is called in places where the band is not known. So I'm not sure I can do better than this. Best regards, Pablo MG
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] &
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(-)