wifi: rtw89: use hardware CFO to improve performance
authorEric Huang <echuang@realtek.com>
Thu, 30 Mar 2023 13:23:52 +0000 (21:23 +0800)
committerKalle Valo <kvalo@kernel.org>
Fri, 14 Apr 2023 12:23:09 +0000 (15:23 +0300)
Turn on hardware CFO (central frequency offset) compensation based on IC
capability, and improve digital CFO compensation accuracy by using
more fixed points number.

Signed-off-by: Eric Huang <echuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230330132352.13647-1-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/phy.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c

index e0c8b3a4c43fd80dc69b20882b30ad9a92ad80ed..7d0433be55721ea621859da2361474a53f0cdc9f 100644 (file)
@@ -3202,6 +3202,7 @@ struct rtw89_chip_info {
        struct rtw89_reg_def c2h_counter_reg;
        const struct rtw89_page_regs *page_regs;
        bool cfo_src_fd;
+       bool cfo_hw_comp;
        const struct rtw89_reg_def *dcfo_comp;
        u8 dcfo_comp_sft;
        const struct rtw89_imr_info *imr_info;
@@ -3684,6 +3685,8 @@ struct rtw89_cfo_tracking_info {
        s32 cfo_avg_pre;
        s32 cfo_avg[CFO_TRACK_MAX_USER];
        s32 pre_cfo_avg[CFO_TRACK_MAX_USER];
+       s32 dcfo_avg;
+       s32 dcfo_avg_pre;
        u32 packet_count;
        u32 packet_count_pre;
        s32 residual_cfo_acc;
index 53f0d964b7ae68a7242fa97d9568fc0de9da5bd6..c7e906123416998232f55b53002fbd86bb63fab5 100644 (file)
@@ -2417,7 +2417,6 @@ static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo)
        bool is_linked = rtwdev->total_sta_assoc > 0;
        s32 cfo_avg_312;
        s32 dcfo_comp_val;
-       u8 dcfo_comp_sft = rtwdev->chip->dcfo_comp_sft;
        int sign;
 
        if (!is_linked) {
@@ -2430,8 +2429,8 @@ static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo)
                return;
        dcfo_comp_val = rtw89_phy_read32_mask(rtwdev, R_DCFO, B_DCFO);
        sign = curr_cfo > 0 ? 1 : -1;
-       cfo_avg_312 = (curr_cfo << dcfo_comp_sft) / 5 + sign * dcfo_comp_val;
-       rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: avg_cfo=%d\n", cfo_avg_312);
+       cfo_avg_312 = curr_cfo / 625 + sign * dcfo_comp_val;
+       rtw89_debug(rtwdev, RTW89_DBG_CFO, "avg_cfo_312=%d step\n", cfo_avg_312);
        if (rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV)
                cfo_avg_312 = -cfo_avg_312;
        rtw89_phy_set_phy_regs(rtwdev, dcfo_comp->addr, dcfo_comp->mask,
@@ -2440,9 +2439,16 @@ static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo)
 
 static void rtw89_dcfo_comp_init(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
        rtw89_phy_set_phy_regs(rtwdev, R_DCFO_OPT, B_DCFO_OPT_EN, 1);
        rtw89_phy_set_phy_regs(rtwdev, R_DCFO_WEIGHT, B_DCFO_WEIGHT_MSK, 8);
-       rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2, B_AX_PWR_UL_CFO_MASK);
+
+       if (chip->cfo_hw_comp)
+               rtw89_write32_mask(rtwdev, R_AX_PWR_UL_CTRL2,
+                                  B_AX_PWR_UL_CFO_MASK, 0x6);
+       else
+               rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2, B_AX_PWR_UL_CFO_MASK);
 }
 
 static void rtw89_phy_cfo_init(struct rtw89_dev *rtwdev)
@@ -2512,6 +2518,7 @@ static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev,
 
 static s32 rtw89_phy_average_cfo_calc(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
        struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
        s32 cfo_khz_all = 0;
        s32 cfo_cnt_all = 0;
@@ -2528,6 +2535,8 @@ static s32 rtw89_phy_average_cfo_calc(struct rtw89_dev *rtwdev)
                cfo_cnt_all += cfo->cfo_cnt[i];
                cfo_all_avg = phy_div(cfo_khz_all, cfo_cnt_all);
                cfo->pre_cfo_avg[i] = cfo->cfo_avg[i];
+               cfo->dcfo_avg = phy_div(cfo_khz_all << chip->dcfo_comp_sft,
+                                       cfo_cnt_all);
        }
        rtw89_debug(rtwdev, RTW89_DBG_CFO,
                    "CFO track for macid = %d\n", i);
@@ -2654,7 +2663,9 @@ static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev)
        s32 new_cfo = 0;
        bool x_cap_update = false;
        u8 pre_x_cap = cfo->crystal_cap;
+       u8 dcfo_comp_sft = rtwdev->chip->dcfo_comp_sft;
 
+       cfo->dcfo_avg = 0;
        rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n",
                    rtwdev->total_sta_assoc);
        if (rtwdev->total_sta_assoc == 0) {
@@ -2696,18 +2707,19 @@ static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev)
 
        rtw89_phy_cfo_crystal_cap_adjust(rtwdev, new_cfo);
        cfo->cfo_avg_pre = new_cfo;
+       cfo->dcfo_avg_pre = cfo->dcfo_avg;
        x_cap_update =  cfo->crystal_cap != pre_x_cap;
        rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap_up=%d\n", x_cap_update);
        rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap: D:%x C:%x->%x, ofst=%d\n",
                    cfo->def_x_cap, pre_x_cap, cfo->crystal_cap,
                    cfo->x_cap_ofst);
        if (x_cap_update) {
-               if (new_cfo > 0)
-                       new_cfo -= CFO_SW_COMP_FINE_TUNE;
+               if (cfo->dcfo_avg > 0)
+                       cfo->dcfo_avg -= CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft;
                else
-                       new_cfo += CFO_SW_COMP_FINE_TUNE;
+                       cfo->dcfo_avg += CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft;
        }
-       rtw89_dcfo_comp(rtwdev, new_cfo);
+       rtw89_dcfo_comp(rtwdev, cfo->dcfo_avg);
        rtw89_phy_cfo_statistics_reset(rtwdev);
 }
 
index 499625338a6441002095318d0355cce3067d5df9..eb7a8340f6330f25f5e085fd9ad95c3244e26ea2 100644 (file)
@@ -2147,8 +2147,9 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
        .c2h_counter_reg        = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
        .page_regs              = &rtw8852a_page_regs,
        .cfo_src_fd             = false,
+       .cfo_hw_comp            = false,
        .dcfo_comp              = &rtw8852a_dcfo_comp,
-       .dcfo_comp_sft          = 3,
+       .dcfo_comp_sft          = 10,
        .imr_info               = &rtw8852a_imr_info,
        .rrsr_cfgs              = &rtw8852a_rrsr_cfgs,
        .bss_clr_map_reg        = R_BSS_CLR_MAP,
index 55b83aad2410302c89364afa052cfe59bc3242c9..7ac7aa997a96fbe4a3ab10d88806f95d4e24f125 100644 (file)
@@ -2568,8 +2568,9 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
        .c2h_regs               = rtw8852b_c2h_regs,
        .page_regs              = &rtw8852b_page_regs,
        .cfo_src_fd             = true,
+       .cfo_hw_comp            = true,
        .dcfo_comp              = &rtw8852b_dcfo_comp,
-       .dcfo_comp_sft          = 3,
+       .dcfo_comp_sft          = 10,
        .imr_info               = &rtw8852b_imr_info,
        .rrsr_cfgs              = &rtw8852b_rrsr_cfgs,
        .bss_clr_map_reg        = R_BSS_CLR_MAP_V1,
index 2be9e89b1965cd5e2fda4f3c2a1adbd7e20f06c6..011b1957b7129f53911fedb4968ec401055f022e 100644 (file)
@@ -2881,8 +2881,9 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
        .c2h_regs               = rtw8852c_c2h_regs,
        .page_regs              = &rtw8852c_page_regs,
        .cfo_src_fd             = false,
+       .cfo_hw_comp            = false,
        .dcfo_comp              = &rtw8852c_dcfo_comp,
-       .dcfo_comp_sft          = 5,
+       .dcfo_comp_sft          = 12,
        .imr_info               = &rtw8852c_imr_info,
        .rrsr_cfgs              = &rtw8852c_rrsr_cfgs,
        .bss_clr_map_reg        = R_BSS_CLR_MAP,