From: Yi-Tang Chiu <chiuyitang@xxxxxxxxxxx> Set the boundaries of x'tal value to avoid extremely adjusted results, causing severely unexpected CFO. Signed-off-by: Yi-Tang Chiu <chiuyitang@xxxxxxxxxxx> Signed-off-by: Yuan-Han Zhang <yuanhan1020@xxxxxxxxxxx> Signed-off-by: Ping-Ke Shih <pkshih@xxxxxxxxxxx> --- drivers/net/wireless/realtek/rtw89/core.h | 4 ++++ drivers/net/wireless/realtek/rtw89/phy.c | 21 +++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/phy.h | 1 + 3 files changed, 26 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 2c81e19d4b51c..6a88578898e01 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2613,6 +2613,10 @@ struct rtw89_cfo_tracking_info { s32 residual_cfo_acc; u8 phy_cfotrk_state; u8 phy_cfotrk_cnt; + bool divergence_lock_en; + u8 x_cap_lb; + u8 x_cap_ub; + u8 lock_cnt; }; /* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */ diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 719a2d6be0be9..c6953a78658ae 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -1743,8 +1743,12 @@ static void rtw89_phy_cfo_init(struct rtw89_dev *rtwdev) cfo->crystal_cap_default = efuse->xtal_cap & B_AX_XTAL_SC_MASK; cfo->crystal_cap = cfo->crystal_cap_default; cfo->def_x_cap = cfo->crystal_cap; + cfo->x_cap_ub = min_t(int, cfo->def_x_cap + CFO_BOUND, 0x7f); + cfo->x_cap_lb = max_t(int, cfo->def_x_cap - CFO_BOUND, 0x1); cfo->is_adjust = false; + cfo->divergence_lock_en = false; cfo->x_cap_ofst = 0; + cfo->lock_cnt = 0; cfo->rtw89_multi_cfo_mode = RTW89_TP_BASED_AVG_MODE; cfo->apply_compensation = false; cfo->residual_cfo_acc = 0; @@ -1962,6 +1966,23 @@ static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev) rtw89_debug(rtwdev, RTW89_DBG_CFO, "curr_cfo=0\n"); return; } + if (cfo->divergence_lock_en) { + cfo->lock_cnt++; + if (cfo->lock_cnt > CFO_PERIOD_CNT) { + cfo->divergence_lock_en = false; + cfo->lock_cnt = 0; + } else { + rtw89_phy_cfo_reset(rtwdev); + } + return; + } + if (cfo->crystal_cap >= cfo->x_cap_ub || + cfo->crystal_cap <= cfo->x_cap_lb) { + cfo->divergence_lock_en = true; + rtw89_phy_cfo_reset(rtwdev); + return; + } + rtw89_phy_cfo_crystal_cap_adjust(rtwdev, new_cfo); cfo->cfo_avg_pre = new_cfo; x_cap_update = cfo->crystal_cap != pre_x_cap; diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 1fb2d96fbca31..d6bc84ae6cd71 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -55,6 +55,7 @@ #define CFO_TRK_STOP_TH (2 << 2) #define CFO_SW_COMP_FINE_TUNE (2 << 2) #define CFO_PERIOD_CNT 15 +#define CFO_BOUND 32 #define CFO_TP_UPPER 100 #define CFO_TP_LOWER 50 #define CFO_COMP_PERIOD 250 -- 2.25.1