wifi: rtw89: Correct EHT TX rate on 20MHz connection
authorDian-Syuan Yang <dian_syuan0116@realtek.com>
Tue, 5 Mar 2024 00:45:02 +0000 (08:45 +0800)
committerKalle Valo <kvalo@kernel.org>
Tue, 12 Mar 2024 15:30:42 +0000 (17:30 +0200)
We used EHT capability of 20MHz-only as rate mask to RA (rate adaptive)
H2C command when connecting with AP set EHT 20MHz. It would get the
wrong rate mask and the MCS rate can only reach MCS11.

According to the description of 802.11be spec, if all supported channel
bandwidth field of HE PHY capabilities are zero, then the EHT capability
of 20MHz-only is valid. As a result, we adjust the code to set correct
rate mask based on HE PHY bandwidth capability.

Signed-off-by: Dian-Syuan Yang <dian_syuan0116@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240305004502.6655-1-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/phy.c

index 12da63d643072bf832a51d1c8a7e707d5cf9fd46..eaa18140d1a8325f7b4de83164840590ef1feb24 100644 (file)
@@ -122,6 +122,7 @@ static u64 get_eht_ra_mask(struct ieee80211_sta *sta)
        struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap;
        struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz;
        struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss;
+       u8 *he_phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
 
        switch (sta->deflink.bandwidth) {
        case IEEE80211_STA_RX_BW_320:
@@ -132,15 +133,19 @@ static u64 get_eht_ra_mask(struct ieee80211_sta *sta)
                mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._160;
                /* MCS 9, 11, 13 */
                return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
+       case IEEE80211_STA_RX_BW_20:
+               if (!(he_phy_cap[0] &
+                     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
+                       mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz;
+                       /* MCS 7, 9, 11, 13 */
+                       return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4);
+               }
+               fallthrough;
        case IEEE80211_STA_RX_BW_80:
        default:
                mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._80;
                /* MCS 9, 11, 13 */
                return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
-       case IEEE80211_STA_RX_BW_20:
-               mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz;
-               /* MCS 7, 9, 11, 13 */
-               return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4);
        }
 }