]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: rtw89: introduce helper to get designated link for MLO
authorZong-Zhe Yang <kevin_yang@realtek.com>
Mon, 28 Apr 2025 11:24:56 +0000 (19:24 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 5 May 2025 01:51:28 +0000 (09:51 +0800)
A link bound to HW band 0 was previously always assumed to exist, because
it's true on non-MLD connection, and MLO connection is not supported yet.
Now, start to consider MLO cases and prepare to enable MLO support in the
following. Add skeleton of designated link. For single-link cases, helper
returns the one. For multi-link cases, priorities can be scheduled. Then,
drop assumption of link bound to HW band 0.

One exception is that MCC doesn't work with MLD yet, so it still expects
link on HW band 0 somewhere.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250428112456.13165-11-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/chan.c
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/mac80211.c
drivers/net/wireless/realtek/rtw89/wow.c

index 6d17456046d52376c3eeb67dda3eb85069b02c0c..4fec61ed3454c1bcf14f666b8dc969dfe1091f4f 100644 (file)
@@ -694,19 +694,13 @@ static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta)
        struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif;
        struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
        struct rtw89_vif *rtwvif = rtwsta->rtwvif;
-       struct rtw89_dev *rtwdev = rtwsta->rtwdev;
-       struct rtw89_sta_link *rtwsta_link;
+       u8 macid;
 
        if (rtwvif != target)
                return;
 
-       rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
-       if (unlikely(!rtwsta_link)) {
-               rtw89_err(rtwdev, "mcc sta macid: find no link on HW-0\n");
-               return;
-       }
-
-       rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta_link->mac_id);
+       macid = rtw89_sta_get_main_macid(rtwsta);
+       rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, macid);
 }
 
 static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev,
index 268107b1e0393bec378cad31fff275a477b12e33..57fb3cfc0a0d9790ef98c3be9f121345f5da0581 100644 (file)
@@ -1133,22 +1133,20 @@ int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
        struct rtw89_vif_link *rtwvif_link;
        int ret;
 
-       /* By default, driver writes tx via the link on HW-0. And then,
-        * according to links' status, HW can change tx to another link.
-        */
-
        if (rtwsta) {
-               rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+               rtwsta_link = rtw89_get_designated_link(rtwsta);
                if (unlikely(!rtwsta_link)) {
-                       rtw89_err(rtwdev, "tx: find no sta link on HW-0\n");
+                       rtw89_err(rtwdev, "tx: find no sta designated link\n");
                        return -ENOLINK;
                }
-       }
 
-       rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
-       if (unlikely(!rtwvif_link)) {
-               rtw89_err(rtwdev, "tx: find no vif link on HW-0\n");
-               return -ENOLINK;
+               rtwvif_link = rtwsta_link->rtwvif_link;
+       } else {
+               rtwvif_link = rtw89_get_designated_link(rtwvif);
+               if (unlikely(!rtwvif_link)) {
+                       rtw89_err(rtwdev, "tx: find no vif designated link\n");
+                       return -ENOLINK;
+               }
        }
 
        tx_req.skb = skb;
@@ -3147,9 +3145,9 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev,
        if (!rtwsta)
                return false;
 
-       rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+       rtwsta_link = rtw89_get_designated_link(rtwsta);
        if (unlikely(!rtwsta_link)) {
-               rtw89_err(rtwdev, "agg wait: find no link on HW-0\n");
+               rtw89_err(rtwdev, "agg wait: find no designated link\n");
                return false;
        }
 
@@ -3372,10 +3370,9 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
        rtw89_leave_ips_by_hwflags(rtwdev);
        rtw89_leave_lps(rtwdev);
 
-       rtwvif_link = rtw89_vif_get_link_inst(rtwvif, RTW89_ROC_BY_LINK_INDEX);
+       rtwvif_link = rtw89_get_designated_link(rtwvif);
        if (unlikely(!rtwvif_link)) {
-               rtw89_err(rtwdev, "roc start: find no link on HW-%u\n",
-                         RTW89_ROC_BY_LINK_INDEX);
+               rtw89_err(rtwdev, "roc start: find no designated link\n");
                return;
        }
 
@@ -4806,6 +4803,7 @@ struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif,
 
        set_bit(index, rtwvif->links_inst_map);
        rtwvif->links[link_id] = rtwvif_link;
+       list_add_tail(&rtwvif_link->dlink_schd, &rtwvif->dlink_pool);
        return rtwvif_link;
 
 err:
@@ -4826,6 +4824,7 @@ void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id)
        index = rtw89_vif_link_inst_get_index(link);
        clear_bit(index, rtwvif->links_inst_map);
        *container = NULL;
+       list_del(&link->dlink_schd);
 }
 
 struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
@@ -4856,6 +4855,7 @@ struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
 
        set_bit(index, rtwsta->links_inst_map);
        rtwsta->links[link_id] = rtwsta_link;
+       list_add_tail(&rtwsta_link->dlink_schd, &rtwsta->dlink_pool);
        return rtwsta_link;
 
 err:
@@ -4876,6 +4876,7 @@ void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id)
        index = rtw89_sta_link_inst_get_index(link);
        clear_bit(index, rtwsta->links_inst_map);
        *container = NULL;
+       list_del(&link->dlink_schd);
 }
 
 int rtw89_core_init(struct rtw89_dev *rtwdev)
index 5e4b096f42fc1c8c5f237c93dd37c05e6634ee73..20c0bab2600a8c18ed2c57d70bdab23990a5403e 100644 (file)
@@ -3380,6 +3380,7 @@ struct rtw89_sec_cam_entry {
 
 struct rtw89_sta_link {
        struct rtw89_sta *rtwsta;
+       struct list_head dlink_schd;
        unsigned int link_id;
 
        u8 mac_id;
@@ -3446,8 +3447,6 @@ enum rtw89_roc_state {
        RTW89_ROC_MGMT,
 };
 
-#define RTW89_ROC_BY_LINK_INDEX 0
-
 struct rtw89_roc {
        struct ieee80211_channel chan;
        struct wiphy_delayed_work roc_work;
@@ -3487,6 +3486,7 @@ struct rtw89_p2p_noa_setter {
 
 struct rtw89_vif_link {
        struct rtw89_vif *rtwvif;
+       struct list_head dlink_schd;
        unsigned int link_id;
 
        bool chanctx_assigned; /* only valid when running with chanctx_ops */
@@ -5878,6 +5878,7 @@ struct rtw89_vif {
        struct rtw89_roc roc;
        bool offchan;
 
+       struct list_head dlink_pool;
        u8 links_inst_valid_num;
        DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
        struct rtw89_vif_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
@@ -5917,6 +5918,7 @@ struct rtw89_sta {
 
        DECLARE_BITMAP(pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM);
 
+       struct list_head dlink_pool;
        u8 links_inst_valid_num;
        DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
        struct rtw89_sta_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
@@ -6012,6 +6014,12 @@ rtw89_assoc_link_rcu_dereference(struct rtw89_dev *rtwdev, u8 macid)
        return rcu_dereference(rtwdev->assoc_link_on_macid[macid]);
 }
 
+#define rtw89_get_designated_link(links_holder) \
+({ \
+       typeof(links_holder) p = links_holder; \
+       list_first_entry_or_null(&p->dlink_pool, typeof(*p->links_inst), dlink_schd); \
+})
+
 static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev,
                                     struct rtw89_core_tx_request *tx_req)
 {
index f4384c1c8cb0841c6e3aa6fca7699e7cef1da7c6..182a952127c4568d7084c9d8a889142b1186c94e 100644 (file)
@@ -187,6 +187,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
        if (!rtw89_rtwvif_in_list(rtwdev, rtwvif)) {
                list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
                INIT_LIST_HEAD(&rtwvif->mgnt_entry);
+               INIT_LIST_HEAD(&rtwvif->dlink_pool);
        }
 
        ether_addr_copy(rtwvif->mac_addr, vif->addr);
@@ -495,6 +496,8 @@ static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev,
        for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
                rtw89_core_txq_init(rtwdev, sta->txq[i]);
 
+       INIT_LIST_HEAD(&rtwsta->dlink_pool);
+
        skb_queue_head_init(&rtwsta->roc_queue);
        bitmap_zero(rtwsta->pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM);
 
@@ -1019,7 +1022,7 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
        struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
        struct rtw89_sta_link *rtwsta_link;
 
-       rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
+       rtwsta_link = rtw89_get_designated_link(rtwsta);
        if (unlikely(!rtwsta_link))
                return;
 
@@ -1154,9 +1157,9 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
 
        lockdep_assert_wiphy(hw->wiphy);
 
-       rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+       rtwvif_link = rtw89_get_designated_link(rtwvif);
        if (unlikely(!rtwvif_link)) {
-               rtw89_err(rtwdev, "sw scan start: find no link on HW-0\n");
+               rtw89_err(rtwdev, "sw scan start: find no designated link\n");
                return;
        }
 
@@ -1174,9 +1177,9 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
 
        lockdep_assert_wiphy(hw->wiphy);
 
-       rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+       rtwvif_link = rtw89_get_designated_link(rtwvif);
        if (unlikely(!rtwvif_link)) {
-               rtw89_err(rtwdev, "sw scan complete: find no link on HW-0\n");
+               rtw89_err(rtwdev, "sw scan complete: find no designated link\n");
                return;
        }
 
@@ -1208,9 +1211,9 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        if (rtwdev->scanning || rtwvif->offchan)
                return -EBUSY;
 
-       rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+       rtwvif_link = rtw89_get_designated_link(rtwvif);
        if (unlikely(!rtwvif_link)) {
-               rtw89_err(rtwdev, "hw scan: find no link on HW-0\n");
+               rtw89_err(rtwdev, "hw scan: find no designated link\n");
                return -ENOLINK;
        }
 
@@ -1245,9 +1248,9 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
        if (!rtwdev->scanning)
                return;
 
-       rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+       rtwvif_link = rtw89_get_designated_link(rtwvif);
        if (unlikely(!rtwvif_link)) {
-               rtw89_err(rtwdev, "cancel hw scan: find no link on HW-0\n");
+               rtw89_err(rtwdev, "cancel hw scan: find no designated link\n");
                return;
        }
 
index 17eee58503cb36ec8214b5b6305c3aaa944410f1..34a0ab49bd7a9e064701d9a5da135dc4a3c1f9c1 100644 (file)
@@ -1086,8 +1086,7 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev,
                rtw89_wow_init_pno(rtwdev, wowlan->nd_config);
 
        rtw89_for_each_rtwvif(rtwdev, rtwvif) {
-               /* use the link on HW-0 to do wow flow */
-               rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+               rtwvif_link = rtw89_get_designated_link(rtwvif);
                if (!rtwvif_link)
                        continue;