]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: 8852c: disable ER SU when 4x HE-LTF and 0.8 GI capability differ
authorKuan-Chung Chen <damon.chen@realtek.com>
Fri, 6 Dec 2024 05:57:14 +0000 (13:57 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Thu, 12 Dec 2024 02:20:27 +0000 (10:20 +0800)
Since hardware only has single one register for HE-LTF setting,
to prevent interoperability issues, 8852CE disables ER SU when
the AP can handle SU/MU with 4x HE-LTF and 0.8 GI, but does
not support ER SU with the same settings.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20241206055716.18598-6-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h

index ee6ad185135c34f1b1acf60e52479d325a15b418..f848185e2cede6a2bc9e578ea847b2221b8c23d4 100644 (file)
@@ -3844,6 +3844,22 @@ int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev,
        return ret;
 }
 
+static bool rtw89_sta_link_can_er(struct rtw89_dev *rtwdev,
+                                 struct ieee80211_bss_conf *bss_conf,
+                                 struct ieee80211_link_sta *link_sta)
+{
+       if (!bss_conf->he_support ||
+           bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)
+               return false;
+
+       if (rtwdev->chip->chip_id == RTL8852C &&
+           rtw89_sta_link_has_su_mu_4xhe08(link_sta) &&
+           !rtw89_sta_link_has_er_su_4xhe08(link_sta))
+               return false;
+
+       return true;
+}
+
 int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
                              struct rtw89_vif_link *rtwvif_link,
                              struct rtw89_sta_link *rtwsta_link)
@@ -3854,12 +3870,11 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
                                                                         rtwsta_link);
        const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
                                                       rtwvif_link->chanctx_idx);
+       struct ieee80211_link_sta *link_sta;
        int ret;
 
        if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
                if (sta->tdls) {
-                       struct ieee80211_link_sta *link_sta;
-
                        rcu_read_lock();
 
                        link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
@@ -3910,9 +3925,8 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
                rcu_read_lock();
 
                bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
-               if (bss_conf->he_support &&
-                   !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE))
-                       rtwsta_link->er_cap = true;
+               link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+               rtwsta_link->er_cap = rtw89_sta_link_can_er(rtwdev, bss_conf, link_sta);
 
                rcu_read_unlock();
 
index 15967978bf4ae0bc51503f732f665773b07293de..c2b5eeb4a4f14749d42ec0105b0e52da702e2b6b 100644 (file)
@@ -6885,6 +6885,16 @@ bool rtw89_sta_link_has_su_mu_4xhe08(struct ieee80211_link_sta *link_sta)
        return false;
 }
 
+static inline
+bool rtw89_sta_link_has_er_su_4xhe08(struct ieee80211_link_sta *link_sta)
+{
+       if (link_sta->he_cap.he_cap_elem.phy_cap_info[8] &
+           IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
+               return true;
+
+       return false;
+}
+
 static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev,
                                                      enum rtw89_fw_type type)
 {