]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw89: fix EHT 20MHz TX rate for non-AP STA
authorKuan-Chung Chen <damon.chen@realtek.com>
Thu, 5 Jun 2025 11:42:07 +0000 (19:42 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Tue, 10 Jun 2025 01:49:00 +0000 (09:49 +0800)
The 4-octet EHT MCS/NSS subfield is only used for 20 MHz-only
non-AP STA. Correct the interpretation of this subfield to
prevent improper rate limitations.

Fixes: f1dfcee2eae9 ("wifi: rtw89: Correct EHT TX rate on 20MHz connection")
Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250605114207.12381-6-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/phy.c

index 158550485797cad266b64859d255517912cbad3a..a05841304e0efd7217a831bfd627fac2df980823 100644 (file)
@@ -119,10 +119,12 @@ static u64 get_eht_mcs_ra_mask(u8 *max_nss, u8 start_mcs, u8 n_nss)
        return mask;
 }
 
-static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta)
+static u64 get_eht_ra_mask(struct rtw89_vif_link *rtwvif_link,
+                          struct ieee80211_link_sta *link_sta)
 {
-       struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
+       struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
        struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz;
+       struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
        struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss;
        u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
 
@@ -136,8 +138,8 @@ static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta)
                /* 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)) {
+               if (vif->type == NL80211_IFTYPE_AP &&
+                   !(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);
@@ -332,7 +334,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
        /* Set the ra mask from sta's capability */
        if (link_sta->eht_cap.has_eht) {
                mode |= RTW89_RA_MODE_EHT;
-               ra_mask |= get_eht_ra_mask(link_sta);
+               ra_mask |= get_eht_ra_mask(rtwvif_link, link_sta);
 
                if (rtwdev->hal.no_mcs_12_13)
                        high_rate_masks = rtw89_ra_mask_eht_mcs0_11;