wifi: rtw89: add DIG suspend/resume flow when scan and connection

The PD lower bound set after one interface is connected, If second
interface needs to connect, packets might not be detected because the
PD lower bound is too high. Therefore, a DIG suspend/resume flow is
added to decrease the PD lower bound during scanning or connection,
and the original PD level is resumed afterward.

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-3-pkshih@realtek.com
This commit is contained in:
Chih-Kang Chang
2025-07-10 12:24:11 +08:00
committed by Ping-Ke Shih
parent ad22869bc5
commit 9126020ab0
6 changed files with 62 additions and 0 deletions

View File

@@ -7,6 +7,7 @@
#include "debug.h"
#include "fw.h"
#include "mac.h"
#include "phy.h"
#include "ps.h"
#include "sar.h"
#include "util.h"
@@ -2281,6 +2282,7 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START);
rtw89_mcc_start_beacon_noa(rtwdev);
rtw89_phy_dig_suspend(rtwdev);
rtw89_mcc_prepare(rtwdev, true);
return 0;
@@ -2372,6 +2374,7 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
rtw89_mcc_stop_beacon_noa(rtwdev);
rtw89_fw_h2c_mcc_dig(rtwdev, RTW89_CHANCTX_0, 0, 0, false);
rtw89_phy_dig_resume(rtwdev, true);
rtw89_mcc_prepare(rtwdev, false);
}
@@ -2715,6 +2718,7 @@ void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
return;
case RTW89_ENTITY_MODE_MCC_PREPARE:
delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC_PREPARE);
rtw89_phy_dig_suspend(rtwdev);
break;
case RTW89_ENTITY_MODE_MCC:
delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC);

View File

@@ -4082,6 +4082,7 @@ int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
&rtwsta_link->tx_retry);
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, 60);
}
rtw89_phy_dig_suspend(rtwdev);
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false);
if (ret) {
@@ -4270,6 +4271,7 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
if (vif->p2p)
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false,
rtwsta_link->tx_retry);
rtw89_phy_dig_resume(rtwdev, false);
}
rtw89_assoc_link_set(rtwsta_link);

View File

@@ -5243,8 +5243,10 @@ struct rtw89_dig_info {
s8 tia_gain_a[TIA_GAIN_NUM];
s8 tia_gain_g[TIA_GAIN_NUM];
s8 *tia_gain;
u32 bak_dig;
bool is_linked_pre;
bool bypass_dig;
bool pause_dig;
};
enum rtw89_multi_cfo_mode {

View File

@@ -7798,6 +7798,7 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
rtw89_chanctx_pause(rtwdev, &pause_parm);
rtw89_phy_dig_suspend(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC)
rtw89_hw_scan_update_beacon_noa(rtwdev, req);
@@ -7831,6 +7832,7 @@ static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
ieee80211_wake_queues(rtwdev->hw);
rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true);
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
rtw89_phy_dig_resume(rtwdev, true);
rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);

View File

@@ -6390,6 +6390,7 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
u32 pd_val;
pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi, enable, chan);
dig->bak_dig = pd_val;
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx);
@@ -6532,6 +6533,52 @@ static void rtw89_phy_dig_mcc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
}
}
static void rtw89_phy_dig_ctrl(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb,
bool pause_dig, bool restore)
{
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
struct rtw89_dig_info *dig = &bb->dig;
bool en_dig;
u32 pd_val;
if (dig->pause_dig == pause_dig)
return;
if (pause_dig) {
en_dig = false;
pd_val = 0;
} else {
en_dig = rtwdev->total_sta_assoc > 0;
pd_val = restore ? dig->bak_dig : 0;
}
rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s <%s> PD_low=%d", __func__,
pause_dig ? "suspend" : "resume", pd_val);
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx);
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
dig_regs->pd_spatial_reuse_en, en_dig, bb->phy_idx);
dig->pause_dig = pause_dig;
}
void rtw89_phy_dig_suspend(struct rtw89_dev *rtwdev)
{
struct rtw89_bb_ctx *bb;
rtw89_for_each_active_bb(rtwdev, bb)
rtw89_phy_dig_ctrl(rtwdev, bb, true, false);
}
void rtw89_phy_dig_resume(struct rtw89_dev *rtwdev, bool restore)
{
struct rtw89_bb_ctx *bb;
rtw89_for_each_active_bb(rtwdev, bb)
rtw89_phy_dig_ctrl(rtwdev, bb, false, restore);
}
static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
struct rtw89_dig_info *dig = &bb->dig;
@@ -6553,6 +6600,9 @@ static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
return;
}
if (unlikely(dig->pause_dig))
return;
if (!dig->is_linked_pre && is_linked) {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n");
rtw89_phy_dig_update_para(rtwdev, bb);

View File

@@ -1010,6 +1010,8 @@ void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 val);
void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb);
void rtw89_phy_dig(struct rtw89_dev *rtwdev);
void rtw89_phy_dig_suspend(struct rtw89_dev *rtwdev);
void rtw89_phy_dig_resume(struct rtw89_dev *rtwdev, bool restore);
void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);