From 6332feafe37fdd0a336ab01b42fdfb5e6b8ee083 Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Thu, 10 Jul 2025 12:24:13 +0800 Subject: [PATCH] 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 --- drivers/net/wireless/realtek/rtw89/chan.c | 8 ++++++++ drivers/net/wireless/realtek/rtw89/core.h | 3 ++- drivers/net/wireless/realtek/rtw89/fw.c | 21 ++++++++++++++++++--- drivers/net/wireless/realtek/rtw89/mac.c | 1 + drivers/net/wireless/realtek/rtw89/wow.c | 2 +- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index e5ef4f6ab5ca1..6c80e08ae99dd 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 e0992c12c4ca7..c003a31477bb0 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 ae38ea6403840..1fd88dc7da85c 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 ff4335ef4033e..37b113e3bd26e 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 c935d6683d833..4f759c75389e9 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; -- 2.51.0