wifi: rtw89: mcc: pass whom to stop at when pausing chanctx
authorZong-Zhe Yang <kevin_yang@realtek.com>
Sun, 11 May 2025 03:52:12 +0000 (11:52 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Fri, 16 May 2025 00:42:43 +0000 (08:42 +0800)
When stopping MCC, FW can stop at a given MCC role following H2C command.
When pausing chanctx during MCC, in general, the caller expects to process
things with its chanctx. So, pass the caller as target and let FW stop MCC
at it.

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

index 871befa63889eaaeaa3e3b749afd615182e2bf1e..ff476bde39abfc819a182bafa0fb6b3a4b16e430 100644 (file)
@@ -2107,6 +2107,12 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
 }
 
 struct rtw89_mcc_stop_sel {
+       struct {
+               const struct rtw89_vif_link *target;
+       } hint;
+
+       /* selection content */
+       bool filled;
        u8 mac_id;
        u8 slot_idx;
 };
@@ -2116,6 +2122,7 @@ static void rtw89_mcc_stop_sel_fill(struct rtw89_mcc_stop_sel *sel,
 {
        sel->mac_id = mcc_role->rtwvif_link->mac_id;
        sel->slot_idx = mcc_role->slot_idx;
+       sel->filled = true;
 }
 
 static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev,
@@ -2125,23 +2132,35 @@ static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev,
 {
        struct rtw89_mcc_stop_sel *sel = data;
 
+       if (mcc_role->rtwvif_link == sel->hint.target) {
+               rtw89_mcc_stop_sel_fill(sel, mcc_role);
+               return 1; /* break iteration */
+       }
+
+       if (sel->filled)
+               return 0;
+
        if (!mcc_role->rtwvif_link->chanctx_assigned)
                return 0;
 
        rtw89_mcc_stop_sel_fill(sel, mcc_role);
-       return 1; /* break iteration */
+       return 0;
 }
 
-static void rtw89_mcc_stop(struct rtw89_dev *rtwdev)
+static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
+                          const struct rtw89_chanctx_pause_parm *pause)
 {
        struct rtw89_mcc_info *mcc = &rtwdev->mcc;
        struct rtw89_mcc_role *ref = &mcc->role_ref;
-       struct rtw89_mcc_stop_sel sel;
+       struct rtw89_mcc_stop_sel sel = {
+               .hint.target = pause ? pause->trigger : NULL,
+       };
        int ret;
 
        /* by default, stop at ref */
-       rtw89_mcc_stop_sel_fill(&sel, ref);
        rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_stop_sel_iterator, &sel);
+       if (!sel.filled)
+               rtw89_mcc_stop_sel_fill(&sel, ref);
 
        rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC stop at <macid %d>\n", sel.mac_id);
 
@@ -2492,7 +2511,7 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
 }
 
 void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
-                        enum rtw89_chanctx_pause_reasons rsn)
+                        const struct rtw89_chanctx_pause_parm *pause_parm)
 {
        struct rtw89_hal *hal = &rtwdev->hal;
        enum rtw89_entity_mode mode;
@@ -2502,12 +2521,12 @@ void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
        if (hal->entity_pause)
                return;
 
-       rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", rsn);
+       rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", pause_parm->rsn);
 
        mode = rtw89_get_entity_mode(rtwdev);
        switch (mode) {
        case RTW89_ENTITY_MODE_MCC:
-               rtw89_mcc_stop(rtwdev);
+               rtw89_mcc_stop(rtwdev, pause_parm);
                break;
        default:
                break;
@@ -2732,7 +2751,7 @@ out:
                cur = rtw89_get_entity_mode(rtwdev);
                switch (cur) {
                case RTW89_ENTITY_MODE_MCC:
-                       rtw89_mcc_stop(rtwdev);
+                       rtw89_mcc_stop(rtwdev, NULL);
                        break;
                default:
                        break;
index b42e044d7927224e9e40f0204f943cf33d382646..2a25563593af93ccbafb1ce3fcf922831fa16b43 100644 (file)
@@ -46,6 +46,11 @@ enum rtw89_chanctx_pause_reasons {
        RTW89_CHANCTX_PAUSE_REASON_ROC,
 };
 
+struct rtw89_chanctx_pause_parm {
+       const struct rtw89_vif_link *trigger;
+       enum rtw89_chanctx_pause_reasons rsn;
+};
+
 struct rtw89_chanctx_cb_parm {
        int (*cb)(struct rtw89_dev *rtwdev, void *data);
        void *data;
@@ -113,7 +118,7 @@ void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
                                enum rtw89_chanctx_changes change);
 void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
 void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
-                        enum rtw89_chanctx_pause_reasons rsn);
+                        const struct rtw89_chanctx_pause_parm *parm);
 void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
                           const struct rtw89_chanctx_cb_parm *cb_parm);
 
index 0b6fb30cbf52c8835b80565102977ebcb88f432e..3b2a2c6b9a440c19509452eb0be555ad321c3f3d 100644 (file)
@@ -3389,6 +3389,9 @@ out:
 void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+       struct rtw89_chanctx_pause_parm pause_parm = {
+               .rsn = RTW89_CHANCTX_PAUSE_REASON_ROC,
+       };
        struct ieee80211_hw *hw = rtwdev->hw;
        struct rtw89_roc *roc = &rtwvif->roc;
        struct rtw89_vif_link *rtwvif_link;
@@ -3410,7 +3413,8 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 
        roc->link_id = rtwvif_link->link_id;
 
-       rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC);
+       pause_parm.trigger = rtwvif_link;
+       rtw89_chanctx_pause(rtwdev, &pause_parm);
 
        ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true);
        if (ret)
index 76350351dfb2b9eeb8d0d6e99e3824a57ef41a3b..1abf69818fc690ecc904d4545225d029a66690c0 100644 (file)
@@ -7446,6 +7446,10 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
        const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
                                                       rtwvif_link->chanctx_idx);
        struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+       struct rtw89_chanctx_pause_parm pause_parm = {
+               .rsn = RTW89_CHANCTX_PAUSE_REASON_HW_SCAN,
+               .trigger = rtwvif_link,
+       };
        u32 rx_fltr = rtwdev->hal.rx_fltr;
        u8 mac_addr[ETH_ALEN];
        u32 reg;
@@ -7484,7 +7488,7 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
        reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
        rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
 
-       rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN);
+       rtw89_chanctx_pause(rtwdev, &pause_parm);
 
        if (mode == RTW89_ENTITY_MODE_MCC)
                rtw89_hw_scan_update_beacon_noa(rtwdev, req);