]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: mlo: fix missing TX null-data 1 during link switch
authorKuan-Chung Chen <damon.chen@realtek.com>
Tue, 23 Dec 2025 03:06:41 +0000 (11:06 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Fri, 26 Dec 2025 02:52:54 +0000 (10:52 +0800)
Fix missing null-data 1 when switching links. The FW should send a
null-data 1 to notify AP before disabling the old link. Adjust the
position of the H2C rtw89_fw_h2c_mlo_link_cfg to ensure proper FW
behavior during link transition.

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

index f39ca1c2ed100f72c7a18ceaf7cf961955b3e917..e4fc513aa158c3ae7321feece254843e09b43bc4 100644 (file)
@@ -1612,12 +1612,23 @@ static int __rtw89_ops_set_vif_links(struct rtw89_dev *rtwdev,
        return 0;
 }
 
-static void rtw89_vif_cfg_fw_links(struct rtw89_dev *rtwdev,
-                                  struct rtw89_vif *rtwvif,
-                                  unsigned long links, bool en)
+static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev,
+                                     struct rtw89_vif *rtwvif,
+                                     u16 current_links, bool en)
 {
+       struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans;
        struct rtw89_vif_link *rtwvif_link;
        unsigned int link_id;
+       unsigned long links;
+
+       /* Do follow-up when all updating links exist. */
+       if (current_links != trans->mediate_links)
+               return;
+
+       if (en)
+               links = trans->links_to_add;
+       else
+               links = trans->links_to_del;
 
        for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
                rtwvif_link = rtwvif->links[link_id];
@@ -1628,20 +1639,6 @@ static void rtw89_vif_cfg_fw_links(struct rtw89_dev *rtwdev,
        }
 }
 
-static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev,
-                                     struct rtw89_vif *rtwvif,
-                                     u16 current_links)
-{
-       struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans;
-
-       /* Do follow-up when all updating links exist. */
-       if (current_links != trans->mediate_links)
-               return;
-
-       rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_del, false);
-       rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_add, true);
-}
-
 static
 int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
                               struct ieee80211_vif *vif,
@@ -1683,7 +1680,7 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
        if (rtwdev->scanning)
                rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
 
-       rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links);
+       rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links, true);
 
        if (!old_links)
                __rtw89_ops_clr_vif_links(rtwdev, rtwvif,
@@ -1716,6 +1713,9 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
                                                  BIT(RTW89_VIF_IDLE_LINK_ID));
        }
 
+       if (!ret)
+               rtw89_vif_update_fw_links(rtwdev, rtwvif, new_links, false);
+
        rtw89_enter_ips_by_hwflags(rtwdev);
        return ret;
 }