]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw89: mcc: when MCC stop forcing to stay at GO role
authorChih-Kang Chang <gary.chang@realtek.com>
Thu, 10 Jul 2025 04:24:13 +0000 (12:24 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Tue, 15 Jul 2025 01:26:52 +0000 (09:26 +0800)
MCC stop might triggered by scan, and need to force to stay at GO role
to keep TX beacon. Also, AX chips need to TX more 3 beacons to ensure
GC can receive once NoA beacon before scan when GC in courtesy mode.
BE chips no needs to TX 3 more beacon because it can TX beacon every
200TU during scan, even GC in courtesy mode can receive beacon every
600TU.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250710042423.73617-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/chan.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/wow.c

index e5ef4f6ab5ca12cd743ee79bbfb33dbf0f1d22d7..6c80e08ae99ddd2093077bf7454b6f0dd918d371 100644 (file)
@@ -2336,9 +2336,11 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
        struct rtw89_hal *hal = &rtwdev->hal;
        struct rtw89_mcc_info *mcc = &rtwdev->mcc;
        struct rtw89_mcc_role *ref = &mcc->role_ref;
+       struct rtw89_mcc_role *aux = &mcc->role_aux;
        struct rtw89_mcc_stop_sel sel = {
                .hint.target = pause ? pause->trigger : NULL,
        };
+       bool rsn_scan;
        int ret;
 
        if (!pause) {
@@ -2346,6 +2348,12 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
                bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
        }
 
+       rsn_scan = pause && pause->rsn == RTW89_CHANCTX_PAUSE_REASON_HW_SCAN;
+       if (rsn_scan && ref->is_go)
+               sel.hint.target = ref->rtwvif_link;
+       else if (rsn_scan && aux->is_go)
+               sel.hint.target = aux->rtwvif_link;
+
        /* by default, stop at ref */
        rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_stop_sel_iterator, &sel);
        if (!sel.filled)
index e0992c12c4ca7e7697f70bde6e0396f8c5086a89..c003a31477bb0d3300b46b9299729d5db74ad09a 100644 (file)
@@ -3860,7 +3860,7 @@ struct rtw89_scan_option {
        u16 slow_pd;
        u16 norm_cy;
        u8 opch_end;
-       u16 delay;
+       u16 delay; /* in unit of ms */
        u64 prohib_chan;
        enum rtw89_phy_idx band;
        enum rtw89_scan_be_operation operation;
@@ -5550,6 +5550,7 @@ struct rtw89_hw_scan_info {
        struct rtw89_hw_scan_extra_op extra_op;
        bool connected;
        bool abort;
+       u16 delay; /* in unit of ms */
 };
 
 enum rtw89_phy_bb_gain_band {
index ae38ea6403840d86cb7e312876cdd4992ef4a04c..1fd88dc7da85c00444d952aaa2dd3cc2b24bba29 100644 (file)
@@ -5583,7 +5583,6 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
        return 0;
 }
 
-#define RTW89_SCAN_DELAY_TSF_UNIT 1000000
 int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
                                 struct rtw89_scan_option *option,
                                 struct rtw89_vif_link *rtwvif_link,
@@ -5615,7 +5614,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
                        scan_mode = RTW89_SCAN_IMMEDIATE;
                } else {
                        scan_mode = RTW89_SCAN_DELAY;
-                       tsf += (u64)option->delay * RTW89_SCAN_DELAY_TSF_UNIT;
+                       tsf += (u64)option->delay * 1000;
                }
        }
 
@@ -5781,7 +5780,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
                                   RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) |
                  le32_encode_bits(probe_id[NL80211_BAND_6GHZ],
                                   RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) |
-                 le32_encode_bits(option->delay, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
+                 le32_encode_bits(option->delay / 1000, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
 
        h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE);
 
@@ -6826,6 +6825,7 @@ static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev,
        scan_info->scanning_vif = NULL;
        scan_info->abort = false;
        scan_info->connected = false;
+       scan_info->delay = 0;
 }
 
 static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
@@ -7628,9 +7628,22 @@ static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev,
                                                 u16 tu)
 {
        struct ieee80211_p2p_noa_desc noa_desc = {};
+       struct ieee80211_bss_conf *bss_conf;
+       u16 beacon_int;
        u64 tsf;
        int ret;
 
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       beacon_int = bss_conf->beacon_int;
+
+       rcu_read_unlock();
+
+       tu += beacon_int * 3;
+       if (rtwdev->chip->chip_gen == RTW89_CHIP_AX)
+               rtwdev->scan_info.delay = ieee80211_tu_to_usec(beacon_int * 3) / 1000;
+
        ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
        if (ret) {
                rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__);
@@ -7770,6 +7783,7 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
        rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
        rtwdev->scan_info.scanning_vif = rtwvif_link;
        rtwdev->scan_info.abort = false;
+       rtwdev->scan_info.delay = 0;
        rtwvif->scan_ies = &scan_req->ies;
        rtwvif->scan_req = req;
 
@@ -7912,6 +7926,7 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
        connected = rtwdev->scan_info.connected;
        opt.enable = enable;
        opt.target_ch_mode = connected;
+       opt.delay = rtwdev->scan_info.delay;
        if (enable) {
                ret = mac->add_chan_list(rtwdev, rtwvif_link);
                if (ret)
index ff4335ef4033e6c024709a4d6267ede5b5dbb23e..37b113e3bd26e5a82b13b7de6cd2e4a174d85f9a 100644 (file)
@@ -5049,6 +5049,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 
                if (rtwvif_link && rtwvif->scan_req &&
                    !list_empty(&rtwdev->scan_info.chan_list)) {
+                       rtwdev->scan_info.delay = 0;
                        ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
                        if (ret) {
                                rtw89_hw_scan_abort(rtwdev, rtwvif_link);
index c935d6683d833c567de67075798e296425f25e4a..4f759c75389e90cbc20820326aba30ec47176cdd 100644 (file)
@@ -1477,7 +1477,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
        opt.enable = enable;
        opt.repeat = RTW89_SCAN_NORMAL;
        opt.norm_pd = max(interval, 1) * 10; /* in unit of 100ms */
-       opt.delay = max(rtw_wow->nd_config->delay, 1);
+       opt.delay = max(rtw_wow->nd_config->delay, 1) * 1000;
 
        if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
                opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP;