From: Chih-Kang Chang Date: Thu, 10 Jul 2025 04:24:13 +0000 (+0800) Subject: wifi: rtw89: mcc: when MCC stop forcing to stay at GO role X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=6332feafe37fdd0a336ab01b42fdfb5e6b8ee083;p=users%2Fjedix%2Flinux-maple.git wifi: rtw89: mcc: when MCC stop forcing to stay at GO role 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 Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250710042423.73617-5-pkshih@realtek.com --- diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index e5ef4f6ab5ca..6c80e08ae99d 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -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) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index e0992c12c4ca..c003a31477bb 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -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 { diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index ae38ea640384..1fd88dc7da85 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -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) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index ff4335ef4033..37b113e3bd26 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -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); diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index c935d6683d83..4f759c75389e 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -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;