Similar to TX IQK, when connected to an AP and a scan is triggered, the FW may fail to receive frames because switching channels may load an uninitialized RX IQK table. Therefore, bypass RXIQK during scanning to avoid using invalid calibration values. Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/phy.c | 5 ++ drivers/net/wireless/realtek/rtw89/reg.h | 4 ++ drivers/net/wireless/realtek/rtw89/rtw8922d.c | 60 +++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index ebf6ecf08c35..cd56f9164cf4 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -3575,6 +3575,8 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, "[IQK] iqk->fwk_status = %x\n", iqk->fwk_status); for (i = 0; i < 2; i++) { + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] ======== Path %x ========\n", i); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_band[%d] = %x\n", @@ -3593,6 +3595,9 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev, i, iqk->iqk_tx_fail[i]); rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_rx_fail[%d] = %x\n", i, iqk->iqk_rx_fail[i]); + + iqk_info->iqk_rx_fail[0][i] = iqk->iqk_rx_fail[i]; + for (j = 0; j < 6; j++) rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->rftxgain[%d][%d] = %x\n", diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 7a3ca9c82548..4291e8115f10 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -11072,13 +11072,17 @@ #define B_KTBL0_RST BIT(31) #define R_CFIR_CTRL_A_BE4 0x38124 #define R_CFIR_CTRL_B_BE4 0x38224 +#define B_CFIR_CTRL_RXKIDX0_EN BIT(0) #define B_CFIR_CTRL_KIDX0_EN BIT(8) +#define B_CFIR_CTRL_RXKIDX1_EN BIT(16) #define B_CFIR_CTRL_KIDX1_EN BIT(24) #define R_TX_IQC_A_BE4 0x38138 #define R_TX_IQC_B_BE4 0x38238 #define B_TX_IQC_X GENMASK(31, 20) #define B_TX_IQC_Y GENMASK(19, 8) #define B_TX_IQC_DPK BIT(3) +#define R_RX_IQC_A_BE4 0x3813c +#define R_RX_IQC_B_BE4 0x3823c #define R_KTBL1A_BE4 0x38154 #define R_KTBL1B_BE4 0x38254 #define B_KTBL1_TBL0 BIT(3) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c index 4d003b303ae7..287a9476bb77 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c @@ -2864,6 +2864,64 @@ static void __rtw8922d_txiqk_enable(struct rtw89_dev *rtwdev) } } +static void __rtw8922d_rxiqk_disable(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + u8 path, kidx; + + for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + kidx = rfk_mcc[path].table_idx; + + if (kidx == 0) { + rtw89_phy_write32_clr(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_RXKIDX0_EN); + } else if (kidx == 1) { + rtw89_phy_write32_clr(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_RXKIDX1_EN); + } else { + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x1); + rtw89_phy_write32_clr(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_RXKIDX0_EN); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x0); + } + + rtw89_phy_write32(rtwdev, R_RX_IQC_A_BE4 + (path << 8), 0x40000002); + } +} + +static void __rtw8922d_rxiqk_enable(struct rtw89_dev *rtwdev) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; + u8 path, kidx; + + for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + if (iqk_info->iqk_rx_fail[0][path]) + continue; + + kidx = rfk_mcc[path].table_idx; + + if (kidx == 0) { + rtw89_phy_write32_set(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_RXKIDX0_EN); + } else if (kidx == 1) { + rtw89_phy_write32_set(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_RXKIDX1_EN); + } else { + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x1); + rtw89_phy_write32_set(rtwdev, R_CFIR_CTRL_A_BE4 + (path << 8), + B_CFIR_CTRL_RXKIDX0_EN); + rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG_BE4, + B_NCTL_CFG_BE4_SPAGE, 0x0); + } + + rtw89_phy_write32(rtwdev, R_RX_IQC_A_BE4 + (path << 8), 0x40000000); + } +} + static void rtw8922d_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool start) @@ -2871,9 +2929,11 @@ static void rtw8922d_rfk_scan(struct rtw89_dev *rtwdev, if (start) { __rtw8922d_tssi_disable(rtwdev, rtwvif_link->phy_idx); __rtw8922d_txiqk_disable(rtwdev); + __rtw8922d_rxiqk_disable(rtwdev); } else { __rtw8922d_tssi_enable(rtwdev, rtwvif_link->phy_idx); __rtw8922d_txiqk_enable(rtwdev); + __rtw8922d_rxiqk_enable(rtwdev); } } -- 2.25.1