The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/rtw89/rtw8852c.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    2 /* Copyright(c) 2019-2022  Realtek Corporation
    3  */
    4 
    5 #include "coex.h"
    6 #include "debug.h"
    7 #include "fw.h"
    8 #include "mac.h"
    9 #include "phy.h"
   10 #include "reg.h"
   11 #include "rtw8852c.h"
   12 #include "rtw8852c_rfk.h"
   13 #include "rtw8852c_table.h"
   14 #include "util.h"
   15 
   16 static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = {
   17         {13, 1614, grp_0}, /* ACH 0 */
   18         {13, 1614, grp_0}, /* ACH 1 */
   19         {13, 1614, grp_0}, /* ACH 2 */
   20         {13, 1614, grp_0}, /* ACH 3 */
   21         {13, 1614, grp_1}, /* ACH 4 */
   22         {13, 1614, grp_1}, /* ACH 5 */
   23         {13, 1614, grp_1}, /* ACH 6 */
   24         {13, 1614, grp_1}, /* ACH 7 */
   25         {13, 1614, grp_0}, /* B0MGQ */
   26         {13, 1614, grp_0}, /* B0HIQ */
   27         {13, 1614, grp_1}, /* B1MGQ */
   28         {13, 1614, grp_1}, /* B1HIQ */
   29         {40, 0, 0} /* FWCMDQ */
   30 };
   31 
   32 static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_pcie = {
   33         1614, /* Group 0 */
   34         1614, /* Group 1 */
   35         3228, /* Public Max */
   36         0 /* WP threshold */
   37 };
   38 
   39 static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_pcie[] = {
   40         [RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_pcie, &rtw8852c_hfc_pubcfg_pcie,
   41                            &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH},
   42         [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie,
   43                             RTW89_HCIFC_POH},
   44         [RTW89_QTA_INVALID] = {NULL},
   45 };
   46 
   47 static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
   48         [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19,
   49                            &rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18,
   50                            &rtw89_mac_size.wde_qt18, &rtw89_mac_size.ple_qt46,
   51                            &rtw89_mac_size.ple_qt47},
   52         [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18,
   53                             &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17,
   54                             &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44,
   55                             &rtw89_mac_size.ple_qt45},
   56         [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
   57                                NULL},
   58 };
   59 
   60 static const u32 rtw8852c_h2c_regs[RTW89_H2CREG_MAX] = {
   61         R_AX_H2CREG_DATA0_V1, R_AX_H2CREG_DATA1_V1, R_AX_H2CREG_DATA2_V1,
   62         R_AX_H2CREG_DATA3_V1
   63 };
   64 
   65 static const u32 rtw8852c_c2h_regs[RTW89_H2CREG_MAX] = {
   66         R_AX_C2HREG_DATA0_V1, R_AX_C2HREG_DATA1_V1, R_AX_C2HREG_DATA2_V1,
   67         R_AX_C2HREG_DATA3_V1
   68 };
   69 
   70 static const struct rtw89_page_regs rtw8852c_page_regs = {
   71         .hci_fc_ctrl    = R_AX_HCI_FC_CTRL_V1,
   72         .ch_page_ctrl   = R_AX_CH_PAGE_CTRL_V1,
   73         .ach_page_ctrl  = R_AX_ACH0_PAGE_CTRL_V1,
   74         .ach_page_info  = R_AX_ACH0_PAGE_INFO_V1,
   75         .pub_page_info3 = R_AX_PUB_PAGE_INFO3_V1,
   76         .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1_V1,
   77         .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2_V1,
   78         .pub_page_info1 = R_AX_PUB_PAGE_INFO1_V1,
   79         .pub_page_info2 = R_AX_PUB_PAGE_INFO2_V1,
   80         .wp_page_ctrl1  = R_AX_WP_PAGE_CTRL1_V1,
   81         .wp_page_ctrl2  = R_AX_WP_PAGE_CTRL2_V1,
   82         .wp_page_info1  = R_AX_WP_PAGE_INFO1_V1,
   83 };
   84 
   85 static const struct rtw89_reg_def rtw8852c_dcfo_comp = {
   86         R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK
   87 };
   88 
   89 static const struct rtw89_imr_info rtw8852c_imr_info = {
   90         .wdrls_imr_set          = B_AX_WDRLS_IMR_SET_V1,
   91         .wsec_imr_reg           = R_AX_SEC_ERROR_FLAG_IMR,
   92         .wsec_imr_set           = B_AX_TX_HANG_IMR | B_AX_RX_HANG_IMR,
   93         .mpdu_tx_imr_set        = B_AX_MPDU_TX_IMR_SET_V1,
   94         .mpdu_rx_imr_set        = B_AX_MPDU_RX_IMR_SET_V1,
   95         .sta_sch_imr_set        = B_AX_STA_SCHEDULER_IMR_SET,
   96         .txpktctl_imr_b0_reg    = R_AX_TXPKTCTL_B0_ERRFLAG_IMR,
   97         .txpktctl_imr_b0_clr    = B_AX_TXPKTCTL_IMR_B0_CLR_V1,
   98         .txpktctl_imr_b0_set    = B_AX_TXPKTCTL_IMR_B0_SET_V1,
   99         .txpktctl_imr_b1_reg    = R_AX_TXPKTCTL_B1_ERRFLAG_IMR,
  100         .txpktctl_imr_b1_clr    = B_AX_TXPKTCTL_IMR_B1_CLR_V1,
  101         .txpktctl_imr_b1_set    = B_AX_TXPKTCTL_IMR_B1_SET_V1,
  102         .wde_imr_clr            = B_AX_WDE_IMR_CLR_V1,
  103         .wde_imr_set            = B_AX_WDE_IMR_SET_V1,
  104         .ple_imr_clr            = B_AX_PLE_IMR_CLR_V1,
  105         .ple_imr_set            = B_AX_PLE_IMR_SET_V1,
  106         .host_disp_imr_clr      = B_AX_HOST_DISP_IMR_CLR_V1,
  107         .host_disp_imr_set      = B_AX_HOST_DISP_IMR_SET_V1,
  108         .cpu_disp_imr_clr       = B_AX_CPU_DISP_IMR_CLR_V1,
  109         .cpu_disp_imr_set       = B_AX_CPU_DISP_IMR_SET_V1,
  110         .other_disp_imr_clr     = B_AX_OTHER_DISP_IMR_CLR_V1,
  111         .other_disp_imr_set     = B_AX_OTHER_DISP_IMR_SET_V1,
  112         .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR,
  113         .bbrpt_err_imr_set      = R_AX_BBRPT_CHINFO_IMR_SET_V1,
  114         .bbrpt_dfs_err_imr_reg  = R_AX_BBRPT_DFS_ERR_IMR,
  115         .ptcl_imr_clr           = B_AX_PTCL_IMR_CLR_V1,
  116         .ptcl_imr_set           = B_AX_PTCL_IMR_SET_V1,
  117         .cdma_imr_0_reg         = R_AX_RX_ERR_FLAG_IMR,
  118         .cdma_imr_0_clr         = B_AX_RX_ERR_IMR_CLR_V1,
  119         .cdma_imr_0_set         = B_AX_RX_ERR_IMR_SET_V1,
  120         .cdma_imr_1_reg         = R_AX_TX_ERR_FLAG_IMR,
  121         .cdma_imr_1_clr         = B_AX_TX_ERR_IMR_CLR_V1,
  122         .cdma_imr_1_set         = B_AX_TX_ERR_IMR_SET_V1,
  123         .phy_intf_imr_reg       = R_AX_PHYINFO_ERR_IMR_V1,
  124         .phy_intf_imr_clr       = B_AX_PHYINFO_IMR_CLR_V1,
  125         .phy_intf_imr_set       = B_AX_PHYINFO_IMR_SET_V1,
  126         .rmac_imr_reg           = R_AX_RX_ERR_IMR,
  127         .rmac_imr_clr           = B_AX_RMAC_IMR_CLR_V1,
  128         .rmac_imr_set           = B_AX_RMAC_IMR_SET_V1,
  129         .tmac_imr_reg           = R_AX_TRXPTCL_ERROR_INDICA_MASK,
  130         .tmac_imr_clr           = B_AX_TMAC_IMR_CLR_V1,
  131         .tmac_imr_set           = B_AX_TMAC_IMR_SET_V1,
  132 };
  133 
  134 static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg);
  135 
  136 static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
  137 {
  138         u32 val32;
  139         u32 ret;
  140 
  141         val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
  142         if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
  143                 rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
  144 
  145         rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
  146                                                     B_AX_AFSM_PCIE_SUS_EN);
  147         rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC);
  148         rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC);
  149         rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
  150         rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
  151 
  152         ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
  153                                 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
  154         if (ret)
  155                 return ret;
  156 
  157         rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
  158         rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
  159 
  160         ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC),
  161                                 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
  162         if (ret)
  163                 return ret;
  164 
  165         rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
  166         rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
  167         rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
  168         rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
  169 
  170         rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
  171         rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
  172 
  173         rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN);
  174         rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP);
  175         rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, B_AX_R_SYM_WLCMAC1_P4_PC_EN |
  176                                                   B_AX_R_SYM_WLCMAC1_P3_PC_EN |
  177                                                   B_AX_R_SYM_WLCMAC1_P2_PC_EN |
  178                                                   B_AX_R_SYM_WLCMAC1_P1_PC_EN |
  179                                                   B_AX_R_SYM_WLCMAC1_PC_EN);
  180         rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
  181 
  182         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
  183                                       XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL);
  184         if (ret)
  185                 return ret;
  186 
  187         rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
  188 
  189         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
  190                                       XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL);
  191         if (ret)
  192                 return ret;
  193         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI,
  194                                       XTAL_SI_OFF_WEI);
  195         if (ret)
  196                 return ret;
  197         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI,
  198                                       XTAL_SI_OFF_EI);
  199         if (ret)
  200                 return ret;
  201         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF);
  202         if (ret)
  203                 return ret;
  204         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI,
  205                                       XTAL_SI_PON_WEI);
  206         if (ret)
  207                 return ret;
  208         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI,
  209                                       XTAL_SI_PON_EI);
  210         if (ret)
  211                 return ret;
  212         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC);
  213         if (ret)
  214                 return ret;
  215         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS);
  216         if (ret)
  217                 return ret;
  218         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP);
  219         if (ret)
  220                 return ret;
  221 
  222         rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
  223         rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
  224         rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
  225 
  226         fsleep(1000);
  227 
  228         rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
  229         rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
  230         rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN,
  231                           B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN |
  232                           B_AX_LED1_PULL_LOW_EN);
  233 
  234         rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
  235                           B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN |
  236                           B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN |
  237                           B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN |
  238                           B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN |
  239                           B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN |
  240                           B_AX_MAC_UN_EN | B_AX_H_AXIDMA_EN);
  241 
  242         rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN,
  243                           B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
  244                           B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN |
  245                           B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN |
  246                           B_AX_TMAC_EN | B_AX_RMAC_EN);
  247 
  248         return 0;
  249 }
  250 
  251 static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
  252 {
  253         u32 val32;
  254         u32 ret;
  255 
  256         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
  257                                       XTAL_SI_RFC2RF);
  258         if (ret)
  259                 return ret;
  260         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI);
  261         if (ret)
  262                 return ret;
  263         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI);
  264         if (ret)
  265                 return ret;
  266         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00);
  267         if (ret)
  268                 return ret;
  269         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10);
  270         if (ret)
  271                 return ret;
  272         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC,
  273                                       XTAL_SI_SRAM2RFC);
  274         if (ret)
  275                 return ret;
  276         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI);
  277         if (ret)
  278                 return ret;
  279         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI);
  280         if (ret)
  281                 return ret;
  282 
  283         rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
  284         rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
  285         rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
  286                           B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1);
  287         rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
  288 
  289         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL);
  290         if (ret)
  291                 return ret;
  292 
  293         rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
  294 
  295         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL);
  296         if (ret)
  297                 return ret;
  298 
  299         rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC);
  300 
  301         ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC),
  302                                 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
  303         if (ret)
  304                 return ret;
  305 
  306         rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, 0x0001A0B0);
  307         rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
  308         rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
  309 
  310         return 0;
  311 }
  312 
  313 static void rtw8852c_e_efuse_parsing(struct rtw89_efuse *efuse,
  314                                      struct rtw8852c_efuse *map)
  315 {
  316         ether_addr_copy(efuse->addr, map->e.mac_addr);
  317         efuse->rfe_type = map->rfe_type;
  318         efuse->xtal_cap = map->xtal_k;
  319 }
  320 
  321 static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
  322                                         struct rtw8852c_efuse *map)
  323 {
  324         struct rtw89_tssi_info *tssi = &rtwdev->tssi;
  325         struct rtw8852c_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
  326         u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b};
  327         u8 i, j;
  328 
  329         tssi->thermal[RF_PATH_A] = map->path_a_therm;
  330         tssi->thermal[RF_PATH_B] = map->path_b_therm;
  331 
  332         for (i = 0; i < RF_PATH_NUM_8852C; i++) {
  333                 memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
  334                        sizeof(ofst[i]->cck_tssi));
  335 
  336                 for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
  337                         rtw89_debug(rtwdev, RTW89_DBG_TSSI,
  338                                     "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
  339                                     i, j, tssi->tssi_cck[i][j]);
  340 
  341                 memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
  342                        sizeof(ofst[i]->bw40_tssi));
  343                 memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
  344                        ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
  345                 memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i],
  346                        sizeof(tssi->tssi_6g_mcs[i]));
  347 
  348                 for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
  349                         rtw89_debug(rtwdev, RTW89_DBG_TSSI,
  350                                     "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
  351                                     i, j, tssi->tssi_mcs[i][j]);
  352         }
  353 }
  354 
  355 static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low)
  356 {
  357         if (high)
  358                 *high = sign_extend32(FIELD_GET(GENMASK(7,  4), data), 3);
  359         if (low)
  360                 *low = sign_extend32(FIELD_GET(GENMASK(3,  0), data), 3);
  361 
  362         return data != 0xff;
  363 }
  364 
  365 static void rtw8852c_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
  366                                                struct rtw8852c_efuse *map)
  367 {
  368         struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
  369         bool valid = false;
  370 
  371         valid |= _decode_efuse_gain(map->rx_gain_2g_cck,
  372                                     &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK],
  373                                     &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]);
  374         valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm,
  375                                     &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM],
  376                                     &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]);
  377         valid |= _decode_efuse_gain(map->rx_gain_5g_low,
  378                                     &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW],
  379                                     &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]);
  380         valid |= _decode_efuse_gain(map->rx_gain_5g_mid,
  381                                     &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID],
  382                                     &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]);
  383         valid |= _decode_efuse_gain(map->rx_gain_5g_high,
  384                                     &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH],
  385                                     &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]);
  386 
  387         gain->offset_valid = valid;
  388 }
  389 
  390 static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map)
  391 {
  392         struct rtw89_efuse *efuse = &rtwdev->efuse;
  393         struct rtw8852c_efuse *map;
  394 
  395         map = (struct rtw8852c_efuse *)log_map;
  396 
  397         efuse->country_code[0] = map->country_code[0];
  398         efuse->country_code[1] = map->country_code[1];
  399         rtw8852c_efuse_parsing_tssi(rtwdev, map);
  400         rtw8852c_efuse_parsing_gain_offset(rtwdev, map);
  401 
  402         switch (rtwdev->hci.type) {
  403         case RTW89_HCI_TYPE_PCIE:
  404                 rtw8852c_e_efuse_parsing(efuse, map);
  405                 break;
  406         default:
  407                 return -ENOTSUPP;
  408         }
  409 
  410         rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
  411 
  412         return 0;
  413 }
  414 
  415 static void rtw8852c_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
  416 {
  417         struct rtw89_tssi_info *tssi = &rtwdev->tssi;
  418         static const u32 tssi_trim_addr[RF_PATH_NUM_8852C] = {0x5D6, 0x5AB};
  419         static const u32 tssi_trim_addr_6g[RF_PATH_NUM_8852C] = {0x5CE, 0x5A3};
  420         u32 addr = rtwdev->chip->phycap_addr;
  421         bool pg = false;
  422         u32 ofst;
  423         u8 i, j;
  424 
  425         for (i = 0; i < RF_PATH_NUM_8852C; i++) {
  426                 for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
  427                         /* addrs are in decreasing order */
  428                         ofst = tssi_trim_addr[i] - addr - j;
  429                         tssi->tssi_trim[i][j] = phycap_map[ofst];
  430 
  431                         if (phycap_map[ofst] != 0xff)
  432                                 pg = true;
  433                 }
  434 
  435                 for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM_6G; j++) {
  436                         /* addrs are in decreasing order */
  437                         ofst = tssi_trim_addr_6g[i] - addr - j;
  438                         tssi->tssi_trim_6g[i][j] = phycap_map[ofst];
  439 
  440                         if (phycap_map[ofst] != 0xff)
  441                                 pg = true;
  442                 }
  443         }
  444 
  445         if (!pg) {
  446                 memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
  447                 memset(tssi->tssi_trim_6g, 0, sizeof(tssi->tssi_trim_6g));
  448                 rtw89_debug(rtwdev, RTW89_DBG_TSSI,
  449                             "[TSSI][TRIM] no PG, set all trim info to 0\n");
  450         }
  451 
  452         for (i = 0; i < RF_PATH_NUM_8852C; i++)
  453                 for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
  454                         rtw89_debug(rtwdev, RTW89_DBG_TSSI,
  455                                     "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
  456                                     i, j, tssi->tssi_trim[i][j],
  457                                     tssi_trim_addr[i] - j);
  458 }
  459 
  460 static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
  461                                                  u8 *phycap_map)
  462 {
  463         struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
  464         static const u32 thm_trim_addr[RF_PATH_NUM_8852C] = {0x5DF, 0x5DC};
  465         u32 addr = rtwdev->chip->phycap_addr;
  466         u8 i;
  467 
  468         for (i = 0; i < RF_PATH_NUM_8852C; i++) {
  469                 info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
  470 
  471                 rtw89_debug(rtwdev, RTW89_DBG_RFK,
  472                             "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
  473                             i, info->thermal_trim[i]);
  474 
  475                 if (info->thermal_trim[i] != 0xff)
  476                         info->pg_thermal_trim = true;
  477         }
  478 }
  479 
  480 static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev)
  481 {
  482 #define __thm_setting(raw)                              \
  483 ({                                                      \
  484         u8 __v = (raw);                                 \
  485         ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1);       \
  486 })
  487         struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
  488         u8 i, val;
  489 
  490         if (!info->pg_thermal_trim) {
  491                 rtw89_debug(rtwdev, RTW89_DBG_RFK,
  492                             "[THERMAL][TRIM] no PG, do nothing\n");
  493 
  494                 return;
  495         }
  496 
  497         for (i = 0; i < RF_PATH_NUM_8852C; i++) {
  498                 val = __thm_setting(info->thermal_trim[i]);
  499                 rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val);
  500 
  501                 rtw89_debug(rtwdev, RTW89_DBG_RFK,
  502                             "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
  503                             i, val);
  504         }
  505 #undef __thm_setting
  506 }
  507 
  508 static void rtw8852c_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
  509                                                  u8 *phycap_map)
  510 {
  511         struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
  512         static const u32 pabias_trim_addr[RF_PATH_NUM_8852C] = {0x5DE, 0x5DB};
  513         u32 addr = rtwdev->chip->phycap_addr;
  514         u8 i;
  515 
  516         for (i = 0; i < RF_PATH_NUM_8852C; i++) {
  517                 info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
  518 
  519                 rtw89_debug(rtwdev, RTW89_DBG_RFK,
  520                             "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
  521                             i, info->pa_bias_trim[i]);
  522 
  523                 if (info->pa_bias_trim[i] != 0xff)
  524                         info->pg_pa_bias_trim = true;
  525         }
  526 }
  527 
  528 static void rtw8852c_pa_bias_trim(struct rtw89_dev *rtwdev)
  529 {
  530         struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
  531         u8 pabias_2g, pabias_5g;
  532         u8 i;
  533 
  534         if (!info->pg_pa_bias_trim) {
  535                 rtw89_debug(rtwdev, RTW89_DBG_RFK,
  536                             "[PA_BIAS][TRIM] no PG, do nothing\n");
  537 
  538                 return;
  539         }
  540 
  541         for (i = 0; i < RF_PATH_NUM_8852C; i++) {
  542                 pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
  543                 pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
  544 
  545                 rtw89_debug(rtwdev, RTW89_DBG_RFK,
  546                             "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
  547                             i, pabias_2g, pabias_5g);
  548 
  549                 rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g);
  550                 rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g);
  551         }
  552 }
  553 
  554 static int rtw8852c_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
  555 {
  556         rtw8852c_phycap_parsing_tssi(rtwdev, phycap_map);
  557         rtw8852c_phycap_parsing_thermal_trim(rtwdev, phycap_map);
  558         rtw8852c_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
  559 
  560         return 0;
  561 }
  562 
  563 static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
  564 {
  565         rtw8852c_thermal_trim(rtwdev);
  566         rtw8852c_pa_bias_trim(rtwdev);
  567 }
  568 
  569 static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
  570                                      const struct rtw89_chan *chan,
  571                                      u8 mac_idx)
  572 {
  573         u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
  574         u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE,
  575                                              mac_idx);
  576         u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx);
  577         u8 txsc20 = 0, txsc40 = 0, txsc80 = 0;
  578         u8 rf_mod_val = 0, chk_rate_mask = 0;
  579         u32 txsc;
  580 
  581         switch (chan->band_width) {
  582         case RTW89_CHANNEL_WIDTH_160:
  583                 txsc80 = rtw89_phy_get_txsc(rtwdev, chan,
  584                                             RTW89_CHANNEL_WIDTH_80);
  585                 fallthrough;
  586         case RTW89_CHANNEL_WIDTH_80:
  587                 txsc40 = rtw89_phy_get_txsc(rtwdev, chan,
  588                                             RTW89_CHANNEL_WIDTH_40);
  589                 fallthrough;
  590         case RTW89_CHANNEL_WIDTH_40:
  591                 txsc20 = rtw89_phy_get_txsc(rtwdev, chan,
  592                                             RTW89_CHANNEL_WIDTH_20);
  593                 break;
  594         default:
  595                 break;
  596         }
  597 
  598         switch (chan->band_width) {
  599         case RTW89_CHANNEL_WIDTH_160:
  600                 rf_mod_val = AX_WMAC_RFMOD_160M;
  601                 txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
  602                        FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40) |
  603                        FIELD_PREP(B_AX_TXSC_80M_MASK, txsc80);
  604                 break;
  605         case RTW89_CHANNEL_WIDTH_80:
  606                 rf_mod_val = AX_WMAC_RFMOD_80M;
  607                 txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
  608                        FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40);
  609                 break;
  610         case RTW89_CHANNEL_WIDTH_40:
  611                 rf_mod_val = AX_WMAC_RFMOD_40M;
  612                 txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20);
  613                 break;
  614         case RTW89_CHANNEL_WIDTH_20:
  615         default:
  616                 rf_mod_val = AX_WMAC_RFMOD_20M;
  617                 txsc = 0;
  618                 break;
  619         }
  620         rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, rf_mod_val);
  621         rtw89_write32(rtwdev, sub_carr, txsc);
  622 
  623         switch (chan->band_type) {
  624         case RTW89_BAND_2G:
  625                 chk_rate_mask = B_AX_BAND_MODE;
  626                 break;
  627         case RTW89_BAND_5G:
  628         case RTW89_BAND_6G:
  629                 chk_rate_mask = B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6;
  630                 break;
  631         default:
  632                 rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type);
  633                 return;
  634         }
  635         rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE | B_AX_CHECK_CCK_EN |
  636                                            B_AX_RTS_LIMIT_IN_OFDM6);
  637         rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask);
  638 }
  639 
  640 static const u32 rtw8852c_sco_barker_threshold[14] = {
  641         0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6,
  642         0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a
  643 };
  644 
  645 static const u32 rtw8852c_sco_cck_threshold[14] = {
  646         0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db,
  647         0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e
  648 };
  649 
  650 static int rtw8852c_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch,
  651                                  u8 primary_ch, enum rtw89_bandwidth bw)
  652 {
  653         u8 ch_element;
  654 
  655         if (bw == RTW89_CHANNEL_WIDTH_20) {
  656                 ch_element = central_ch - 1;
  657         } else if (bw == RTW89_CHANNEL_WIDTH_40) {
  658                 if (primary_ch == 1)
  659                         ch_element = central_ch - 1 + 2;
  660                 else
  661                         ch_element = central_ch - 1 - 2;
  662         } else {
  663                 rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw);
  664                 return -EINVAL;
  665         }
  666         rtw89_phy_write32_mask(rtwdev, R_BK_FC0_INV_V1, B_BK_FC0_INV_MSK_V1,
  667                                rtw8852c_sco_barker_threshold[ch_element]);
  668         rtw89_phy_write32_mask(rtwdev, R_CCK_FC0_INV_V1, B_CCK_FC0_INV_MSK_V1,
  669                                rtw8852c_sco_cck_threshold[ch_element]);
  670 
  671         return 0;
  672 }
  673 
  674 struct rtw8852c_bb_gain {
  675         u32 gain_g[BB_PATH_NUM_8852C];
  676         u32 gain_a[BB_PATH_NUM_8852C];
  677         u32 gain_mask;
  678 };
  679 
  680 static const struct rtw8852c_bb_gain bb_gain_lna[LNA_GAIN_NUM] = {
  681         { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
  682           .gain_mask = 0x00ff0000 },
  683         { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
  684           .gain_mask = 0xff000000 },
  685         { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
  686           .gain_mask = 0x000000ff },
  687         { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
  688           .gain_mask = 0x0000ff00 },
  689         { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
  690           .gain_mask = 0x00ff0000 },
  691         { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
  692           .gain_mask = 0xff000000 },
  693         { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
  694           .gain_mask = 0x000000ff },
  695 };
  696 
  697 static const struct rtw8852c_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
  698         { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
  699           .gain_mask = 0x00ff0000 },
  700         { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
  701           .gain_mask = 0xff000000 },
  702 };
  703 
  704 struct rtw8852c_bb_gain_bypass {
  705         u32 gain_g[BB_PATH_NUM_8852C];
  706         u32 gain_a[BB_PATH_NUM_8852C];
  707         u32 gain_mask_g;
  708         u32 gain_mask_a;
  709 };
  710 
  711 static
  712 const struct rtw8852c_bb_gain_bypass bb_gain_bypass_lna[LNA_GAIN_NUM] = {
  713         { .gain_g = {0x4BB8, 0x4C7C}, .gain_a = {0x4BB4, 0x4C78},
  714           .gain_mask_g = 0xff000000, .gain_mask_a = 0xff},
  715         { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
  716           .gain_mask_g = 0xff, .gain_mask_a = 0xff00},
  717         { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
  718           .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000},
  719         { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB4, 0x4C78},
  720           .gain_mask_g = 0xff0000, .gain_mask_a = 0xff000000},
  721         { .gain_g = {0x4BBC, 0x4C80}, .gain_a = {0x4BB8, 0x4C7C},
  722           .gain_mask_g = 0xff000000, .gain_mask_a = 0xff},
  723         { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C},
  724           .gain_mask_g = 0xff, .gain_mask_a = 0xff00},
  725         { .gain_g = {0x4BC0, 0x4C84}, .gain_a = {0x4BB8, 0x4C7C},
  726           .gain_mask_g = 0xff00, .gain_mask_a = 0xff0000},
  727 };
  728 
  729 struct rtw8852c_bb_gain_op1db {
  730         struct {
  731                 u32 lna[BB_PATH_NUM_8852C];
  732                 u32 tia_lna[BB_PATH_NUM_8852C];
  733                 u32 mask;
  734         } reg[LNA_GAIN_NUM];
  735         u32 reg_tia0_lna6[BB_PATH_NUM_8852C];
  736         u32 mask_tia0_lna6;
  737 };
  738 
  739 static const struct rtw8852c_bb_gain_op1db bb_gain_op1db_a = {
  740         .reg = {
  741                 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
  742                   .mask = 0xff},
  743                 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
  744                   .mask = 0xff00},
  745                 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
  746                   .mask = 0xff0000},
  747                 { .lna = {0x4668, 0x474c}, .tia_lna = {0x4670, 0x4754},
  748                   .mask = 0xff000000},
  749                 { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
  750                   .mask = 0xff},
  751                 { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
  752                   .mask = 0xff00},
  753                 { .lna = {0x466c, 0x4750}, .tia_lna = {0x4674, 0x4758},
  754                   .mask = 0xff0000},
  755         },
  756         .reg_tia0_lna6 = {0x4674, 0x4758},
  757         .mask_tia0_lna6 = 0xff000000,
  758 };
  759 
  760 static enum rtw89_phy_bb_gain_band
  761 rtw8852c_mapping_gain_band(enum rtw89_subband subband)
  762 {
  763         switch (subband) {
  764         default:
  765         case RTW89_CH_2G:
  766                 return RTW89_BB_GAIN_BAND_2G;
  767         case RTW89_CH_5G_BAND_1:
  768                 return RTW89_BB_GAIN_BAND_5G_L;
  769         case RTW89_CH_5G_BAND_3:
  770                 return RTW89_BB_GAIN_BAND_5G_M;
  771         case RTW89_CH_5G_BAND_4:
  772                 return RTW89_BB_GAIN_BAND_5G_H;
  773         case RTW89_CH_6G_BAND_IDX0:
  774         case RTW89_CH_6G_BAND_IDX1:
  775                 return RTW89_BB_GAIN_BAND_6G_L;
  776         case RTW89_CH_6G_BAND_IDX2:
  777         case RTW89_CH_6G_BAND_IDX3:
  778                 return RTW89_BB_GAIN_BAND_6G_M;
  779         case RTW89_CH_6G_BAND_IDX4:
  780         case RTW89_CH_6G_BAND_IDX5:
  781                 return RTW89_BB_GAIN_BAND_6G_H;
  782         case RTW89_CH_6G_BAND_IDX6:
  783         case RTW89_CH_6G_BAND_IDX7:
  784                 return RTW89_BB_GAIN_BAND_6G_UH;
  785         }
  786 }
  787 
  788 static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev,
  789                                     enum rtw89_subband subband,
  790                                     enum rtw89_rf_path path)
  791 {
  792         const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain;
  793         u8 gain_band = rtw8852c_mapping_gain_band(subband);
  794         s32 val;
  795         u32 reg;
  796         u32 mask;
  797         int i;
  798 
  799         for (i = 0; i < LNA_GAIN_NUM; i++) {
  800                 if (subband == RTW89_CH_2G)
  801                         reg = bb_gain_lna[i].gain_g[path];
  802                 else
  803                         reg = bb_gain_lna[i].gain_a[path];
  804 
  805                 mask = bb_gain_lna[i].gain_mask;
  806                 val = gain->lna_gain[gain_band][path][i];
  807                 rtw89_phy_write32_mask(rtwdev, reg, mask, val);
  808 
  809                 if (subband == RTW89_CH_2G) {
  810                         reg = bb_gain_bypass_lna[i].gain_g[path];
  811                         mask = bb_gain_bypass_lna[i].gain_mask_g;
  812                 } else {
  813                         reg = bb_gain_bypass_lna[i].gain_a[path];
  814                         mask = bb_gain_bypass_lna[i].gain_mask_a;
  815                 }
  816 
  817                 val = gain->lna_gain_bypass[gain_band][path][i];
  818                 rtw89_phy_write32_mask(rtwdev, reg, mask, val);
  819 
  820                 if (subband != RTW89_CH_2G) {
  821                         reg = bb_gain_op1db_a.reg[i].lna[path];
  822                         mask = bb_gain_op1db_a.reg[i].mask;
  823                         val = gain->lna_op1db[gain_band][path][i];
  824                         rtw89_phy_write32_mask(rtwdev, reg, mask, val);
  825 
  826                         reg = bb_gain_op1db_a.reg[i].tia_lna[path];
  827                         mask = bb_gain_op1db_a.reg[i].mask;
  828                         val = gain->tia_lna_op1db[gain_band][path][i];
  829                         rtw89_phy_write32_mask(rtwdev, reg, mask, val);
  830                 }
  831         }
  832 
  833         if (subband != RTW89_CH_2G) {
  834                 reg = bb_gain_op1db_a.reg_tia0_lna6[path];
  835                 mask = bb_gain_op1db_a.mask_tia0_lna6;
  836                 val = gain->tia_lna_op1db[gain_band][path][7];
  837                 rtw89_phy_write32_mask(rtwdev, reg, mask, val);
  838         }
  839 
  840         for (i = 0; i < TIA_GAIN_NUM; i++) {
  841                 if (subband == RTW89_CH_2G)
  842                         reg = bb_gain_tia[i].gain_g[path];
  843                 else
  844                         reg = bb_gain_tia[i].gain_a[path];
  845 
  846                 mask = bb_gain_tia[i].gain_mask;
  847                 val = gain->tia_gain[gain_band][path][i];
  848                 rtw89_phy_write32_mask(rtwdev, reg, mask, val);
  849         }
  850 }
  851 
  852 static
  853 const u8 rtw8852c_ch_base_table[16] = {1, 0xff,
  854                                        36, 100, 132, 149, 0xff,
  855                                        1, 33, 65, 97, 129, 161, 193, 225, 0xff};
  856 #define RTW8852C_CH_BASE_IDX_2G         0
  857 #define RTW8852C_CH_BASE_IDX_5G_FIRST   2
  858 #define RTW8852C_CH_BASE_IDX_5G_LAST    5
  859 #define RTW8852C_CH_BASE_IDX_6G_FIRST   7
  860 #define RTW8852C_CH_BASE_IDX_6G_LAST    14
  861 
  862 #define RTW8852C_CH_BASE_IDX_MASK       GENMASK(7, 4)
  863 #define RTW8852C_CH_OFFSET_MASK         GENMASK(3, 0)
  864 
  865 static u8 rtw8852c_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band)
  866 {
  867         u8 chan_idx;
  868         u8 last, first;
  869         u8 idx;
  870 
  871         switch (band) {
  872         case RTW89_BAND_2G:
  873                 chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, RTW8852C_CH_BASE_IDX_2G) |
  874                            FIELD_PREP(RTW8852C_CH_OFFSET_MASK, central_ch);
  875                 return chan_idx;
  876         case RTW89_BAND_5G:
  877                 first = RTW8852C_CH_BASE_IDX_5G_FIRST;
  878                 last = RTW8852C_CH_BASE_IDX_5G_LAST;
  879                 break;
  880         case RTW89_BAND_6G:
  881                 first = RTW8852C_CH_BASE_IDX_6G_FIRST;
  882                 last = RTW8852C_CH_BASE_IDX_6G_LAST;
  883                 break;
  884         default:
  885                 rtw89_warn(rtwdev, "Unsupported band %d\n", band);
  886                 return 0;
  887         }
  888 
  889         for (idx = last; idx >= first; idx--)
  890                 if (central_ch >= rtw8852c_ch_base_table[idx])
  891                         break;
  892 
  893         if (idx < first) {
  894                 rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch);
  895                 return 0;
  896         }
  897 
  898         chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, idx) |
  899                    FIELD_PREP(RTW8852C_CH_OFFSET_MASK,
  900                               (central_ch - rtw8852c_ch_base_table[idx]) >> 1);
  901         return chan_idx;
  902 }
  903 
  904 static void rtw8852c_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
  905                                      u8 *ch, enum nl80211_band *band)
  906 {
  907         u8 idx, offset;
  908 
  909         idx = FIELD_GET(RTW8852C_CH_BASE_IDX_MASK, chan_idx);
  910         offset = FIELD_GET(RTW8852C_CH_OFFSET_MASK, chan_idx);
  911 
  912         if (idx == RTW8852C_CH_BASE_IDX_2G) {
  913                 *band = NL80211_BAND_2GHZ;
  914                 *ch = offset;
  915                 return;
  916         }
  917 
  918         *band = idx <= RTW8852C_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ;
  919         *ch = rtw8852c_ch_base_table[idx] + (offset << 1);
  920 }
  921 
  922 static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
  923                                      const struct rtw89_chan *chan,
  924                                      enum rtw89_phy_idx phy_idx,
  925                                      enum rtw89_rf_path path)
  926 {
  927         static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA0_LNA6_OP1DB_V1,
  928                                               R_PATH1_G_TIA0_LNA6_OP1DB_V1};
  929         static const u32 rpl_mask[2] = {B_RPL_PATHA_MASK, B_RPL_PATHB_MASK};
  930         static const u32 rpl_tb_mask[2] = {B_RSSI_M_PATHA_MASK, B_RSSI_M_PATHB_MASK};
  931         struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain;
  932         enum rtw89_gain_offset gain_band;
  933         s32 offset_q0, offset_base_q4;
  934         s32 tmp = 0;
  935 
  936         if (!efuse_gain->offset_valid)
  937                 return;
  938 
  939         if (rtwdev->dbcc_en && path == RF_PATH_B)
  940                 phy_idx = RTW89_PHY_1;
  941 
  942         if (chan->band_type == RTW89_BAND_2G) {
  943                 offset_q0 = efuse_gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK];
  944                 offset_base_q4 = efuse_gain->offset_base[phy_idx];
  945 
  946                 tmp = clamp_t(s32, (-offset_q0 << 3) + (offset_base_q4 >> 1),
  947                               S8_MIN >> 1, S8_MAX >> 1);
  948                 rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f);
  949         }
  950 
  951         switch (chan->subband_type) {
  952         default:
  953         case RTW89_CH_2G:
  954                 gain_band = RTW89_GAIN_OFFSET_2G_OFDM;
  955                 break;
  956         case RTW89_CH_5G_BAND_1:
  957                 gain_band = RTW89_GAIN_OFFSET_5G_LOW;
  958                 break;
  959         case RTW89_CH_5G_BAND_3:
  960                 gain_band = RTW89_GAIN_OFFSET_5G_MID;
  961                 break;
  962         case RTW89_CH_5G_BAND_4:
  963                 gain_band = RTW89_GAIN_OFFSET_5G_HIGH;
  964                 break;
  965         }
  966 
  967         offset_q0 = -efuse_gain->offset[path][gain_band];
  968         offset_base_q4 = efuse_gain->offset_base[phy_idx];
  969 
  970         tmp = (offset_q0 << 2) + (offset_base_q4 >> 2);
  971         tmp = clamp_t(s32, -tmp, S8_MIN, S8_MAX);
  972         rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[path], B_PATH0_R_G_OFST_MASK, tmp & 0xff);
  973 
  974         tmp = clamp_t(s32, offset_q0 << 4, S8_MIN, S8_MAX);
  975         rtw89_phy_write32_idx(rtwdev, R_RPL_PATHAB, rpl_mask[path], tmp & 0xff, phy_idx);
  976         rtw89_phy_write32_idx(rtwdev, R_RSSI_M_PATHAB, rpl_tb_mask[path], tmp & 0xff, phy_idx);
  977 }
  978 
  979 static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
  980                              const struct rtw89_chan *chan,
  981                              enum rtw89_phy_idx phy_idx)
  982 {
  983         u8 sco;
  984         u16 central_freq = chan->freq;
  985         u8 central_ch = chan->channel;
  986         u8 band = chan->band_type;
  987         u8 subband = chan->subband_type;
  988         bool is_2g = band == RTW89_BAND_2G;
  989         u8 chan_idx;
  990 
  991         if (!central_freq) {
  992                 rtw89_warn(rtwdev, "Invalid central_freq\n");
  993                 return;
  994         }
  995 
  996         if (phy_idx == RTW89_PHY_0) {
  997                 /* Path A */
  998                 rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_A);
  999                 rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_A);
 1000 
 1001                 if (is_2g)
 1002                         rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
 1003                                               B_PATH0_BAND_SEL_MSK_V1, 1,
 1004                                               phy_idx);
 1005                 else
 1006                         rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
 1007                                               B_PATH0_BAND_SEL_MSK_V1, 0,
 1008                                               phy_idx);
 1009                 /* Path B */
 1010                 if (!rtwdev->dbcc_en) {
 1011                         rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B);
 1012                         rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B);
 1013 
 1014                         if (is_2g)
 1015                                 rtw89_phy_write32_idx(rtwdev,
 1016                                                       R_PATH1_BAND_SEL_V1,
 1017                                                       B_PATH1_BAND_SEL_MSK_V1,
 1018                                                       1, phy_idx);
 1019                         else
 1020                                 rtw89_phy_write32_idx(rtwdev,
 1021                                                       R_PATH1_BAND_SEL_V1,
 1022                                                       B_PATH1_BAND_SEL_MSK_V1,
 1023                                                       0, phy_idx);
 1024                         rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
 1025                 } else {
 1026                         if (is_2g)
 1027                                 rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
 1028                         else
 1029                                 rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL);
 1030                 }
 1031                 /* SCO compensate FC setting */
 1032                 rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1,
 1033                                       central_freq, phy_idx);
 1034                 /* round_up((1/fc0)*pow(2,18)) */
 1035                 sco = DIV_ROUND_CLOSEST(1 << 18, central_freq);
 1036                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco,
 1037                                       phy_idx);
 1038         } else {
 1039                 /* Path B */
 1040                 rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B);
 1041                 rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B);
 1042 
 1043                 if (is_2g)
 1044                         rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
 1045                                               B_PATH1_BAND_SEL_MSK_V1,
 1046                                               1, phy_idx);
 1047                 else
 1048                         rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
 1049                                               B_PATH1_BAND_SEL_MSK_V1,
 1050                                               0, phy_idx);
 1051                 /* SCO compensate FC setting */
 1052                 rtw89_phy_write32_idx(rtwdev, R_FC0_V1, B_FC0_MSK_V1,
 1053                                       central_freq, phy_idx);
 1054                 /* round_up((1/fc0)*pow(2,18)) */
 1055                 sco = DIV_ROUND_CLOSEST(1 << 18, central_freq);
 1056                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, sco,
 1057                                       phy_idx);
 1058         }
 1059         /* CCK parameters */
 1060         if (band == RTW89_BAND_2G) {
 1061                 if (central_ch == 14) {
 1062                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1,
 1063                                                B_PCOEFF01_MSK_V1, 0x3b13ff);
 1064                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1,
 1065                                                B_PCOEFF23_MSK_V1, 0x1c42de);
 1066                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1,
 1067                                                B_PCOEFF45_MSK_V1, 0xfdb0ad);
 1068                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1,
 1069                                                B_PCOEFF67_MSK_V1, 0xf60f6e);
 1070                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1,
 1071                                                B_PCOEFF89_MSK_V1, 0xfd8f92);
 1072                         rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1,
 1073                                                B_PCOEFFAB_MSK_V1, 0x2d011);
 1074                         rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1,
 1075                                                B_PCOEFFCD_MSK_V1, 0x1c02c);
 1076                         rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1,
 1077                                                B_PCOEFFEF_MSK_V1, 0xfff00a);
 1078                 } else {
 1079                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF0_V1,
 1080                                                B_PCOEFF01_MSK_V1, 0x3d23ff);
 1081                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF2_V1,
 1082                                                B_PCOEFF23_MSK_V1, 0x29b354);
 1083                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF4_V1,
 1084                                                B_PCOEFF45_MSK_V1, 0xfc1c8);
 1085                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF6_V1,
 1086                                                B_PCOEFF67_MSK_V1, 0xfdb053);
 1087                         rtw89_phy_write32_mask(rtwdev, R_PCOEFF8_V1,
 1088                                                B_PCOEFF89_MSK_V1, 0xf86f9a);
 1089                         rtw89_phy_write32_mask(rtwdev, R_PCOEFFA_V1,
 1090                                                B_PCOEFFAB_MSK_V1, 0xfaef92);
 1091                         rtw89_phy_write32_mask(rtwdev, R_PCOEFFC_V1,
 1092                                                B_PCOEFFCD_MSK_V1, 0xfe5fcc);
 1093                         rtw89_phy_write32_mask(rtwdev, R_PCOEFFE_V1,
 1094                                                B_PCOEFFEF_MSK_V1, 0xffdff5);
 1095                 }
 1096         }
 1097 
 1098         chan_idx = rtw8852c_encode_chan_idx(rtwdev, chan->primary_channel, band);
 1099         rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx);
 1100 }
 1101 
 1102 static void rtw8852c_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path)
 1103 {
 1104         static const u32 adc_sel[2] = {0xC0EC, 0xC1EC};
 1105         static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
 1106 
 1107         switch (bw) {
 1108         case RTW89_CHANNEL_WIDTH_5:
 1109                 rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1);
 1110                 rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0);
 1111                 break;
 1112         case RTW89_CHANNEL_WIDTH_10:
 1113                 rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2);
 1114                 rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1);
 1115                 break;
 1116         case RTW89_CHANNEL_WIDTH_20:
 1117         case RTW89_CHANNEL_WIDTH_40:
 1118         case RTW89_CHANNEL_WIDTH_80:
 1119         case RTW89_CHANNEL_WIDTH_160:
 1120                 rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
 1121                 rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
 1122                 break;
 1123         default:
 1124                 rtw89_warn(rtwdev, "Fail to set ADC\n");
 1125         }
 1126 }
 1127 
 1128 static void rtw8852c_edcca_per20_bitmap_sifs(struct rtw89_dev *rtwdev, u8 bw,
 1129                                              enum rtw89_phy_idx phy_idx)
 1130 {
 1131         if (bw == RTW89_CHANNEL_WIDTH_20) {
 1132                 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0xff, phy_idx);
 1133                 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx);
 1134         } else {
 1135                 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A1, B_SNDCCA_A1_EN, 0, phy_idx);
 1136                 rtw89_phy_write32_idx(rtwdev, R_SNDCCA_A2, B_SNDCCA_A2_VAL, 0, phy_idx);
 1137         }
 1138 }
 1139 
 1140 static void
 1141 rtw8852c_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
 1142                  enum rtw89_phy_idx phy_idx)
 1143 {
 1144         u8 mod_sbw = 0;
 1145 
 1146         switch (bw) {
 1147         case RTW89_CHANNEL_WIDTH_5:
 1148         case RTW89_CHANNEL_WIDTH_10:
 1149         case RTW89_CHANNEL_WIDTH_20:
 1150                 if (bw == RTW89_CHANNEL_WIDTH_5)
 1151                         mod_sbw = 0x1;
 1152                 else if (bw == RTW89_CHANNEL_WIDTH_10)
 1153                         mod_sbw = 0x2;
 1154                 else if (bw == RTW89_CHANNEL_WIDTH_20)
 1155                         mod_sbw = 0x0;
 1156                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0,
 1157                                       phy_idx);
 1158                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW,
 1159                                       mod_sbw, phy_idx);
 1160                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, 0x0,
 1161                                       phy_idx);
 1162                 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
 1163                                        B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3);
 1164                 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
 1165                                        B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3);
 1166                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
 1167                                        B_PATH0_BW_SEL_MSK_V1, 0xf);
 1168                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
 1169                                        B_PATH1_BW_SEL_MSK_V1, 0xf);
 1170                 break;
 1171         case RTW89_CHANNEL_WIDTH_40:
 1172                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x1,
 1173                                       phy_idx);
 1174                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0,
 1175                                       phy_idx);
 1176                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
 1177                                       pri_ch,
 1178                                       phy_idx);
 1179                 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
 1180                                        B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3);
 1181                 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
 1182                                        B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3);
 1183                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
 1184                                        B_PATH0_BW_SEL_MSK_V1, 0xf);
 1185                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
 1186                                        B_PATH1_BW_SEL_MSK_V1, 0xf);
 1187                 break;
 1188         case RTW89_CHANNEL_WIDTH_80:
 1189                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x2,
 1190                                       phy_idx);
 1191                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0,
 1192                                       phy_idx);
 1193                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
 1194                                       pri_ch,
 1195                                       phy_idx);
 1196                 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
 1197                                        B_PATH0_SAMPL_DLY_T_MSK_V1, 0x2);
 1198                 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
 1199                                        B_PATH1_SAMPL_DLY_T_MSK_V1, 0x2);
 1200                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
 1201                                        B_PATH0_BW_SEL_MSK_V1, 0xd);
 1202                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
 1203                                        B_PATH1_BW_SEL_MSK_V1, 0xd);
 1204                 break;
 1205         case RTW89_CHANNEL_WIDTH_160:
 1206                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x3,
 1207                                       phy_idx);
 1208                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0,
 1209                                       phy_idx);
 1210                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH,
 1211                                       pri_ch,
 1212                                       phy_idx);
 1213                 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
 1214                                        B_PATH0_SAMPL_DLY_T_MSK_V1, 0x1);
 1215                 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
 1216                                        B_PATH1_SAMPL_DLY_T_MSK_V1, 0x1);
 1217                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BW_SEL_V1,
 1218                                        B_PATH0_BW_SEL_MSK_V1, 0xb);
 1219                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
 1220                                        B_PATH1_BW_SEL_MSK_V1, 0xb);
 1221                 break;
 1222         default:
 1223                 rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw,
 1224                            pri_ch);
 1225         }
 1226 
 1227         if (bw == RTW89_CHANNEL_WIDTH_40) {
 1228                 rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1,
 1229                                       B_RX_BW40_2XFFT_EN_MSK_V1, 0x1, phy_idx);
 1230                 rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 1, phy_idx);
 1231         } else {
 1232                 rtw89_phy_write32_idx(rtwdev, R_RX_BW40_2XFFT_EN_V1,
 1233                                       B_RX_BW40_2XFFT_EN_MSK_V1, 0x0, phy_idx);
 1234                 rtw89_phy_write32_idx(rtwdev, R_T2F_GI_COMB, B_T2F_GI_COMB_EN, 0, phy_idx);
 1235         }
 1236 
 1237         if (phy_idx == RTW89_PHY_0) {
 1238                 rtw8852c_bw_setting(rtwdev, bw, RF_PATH_A);
 1239                 if (!rtwdev->dbcc_en)
 1240                         rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B);
 1241         } else {
 1242                 rtw8852c_bw_setting(rtwdev, bw, RF_PATH_B);
 1243         }
 1244 
 1245         rtw8852c_edcca_per20_bitmap_sifs(rtwdev, bw, phy_idx);
 1246 }
 1247 
 1248 static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev,
 1249                               const struct rtw89_chan *chan)
 1250 {
 1251         u8 center_chan = chan->channel;
 1252         u8 bw = chan->band_width;
 1253 
 1254         switch (chan->band_type) {
 1255         case RTW89_BAND_2G:
 1256                 if (bw == RTW89_CHANNEL_WIDTH_20) {
 1257                         if (center_chan >= 5 && center_chan <= 8)
 1258                                 return 2440;
 1259                         if (center_chan == 13)
 1260                                 return 2480;
 1261                 } else if (bw == RTW89_CHANNEL_WIDTH_40) {
 1262                         if (center_chan >= 3 && center_chan <= 10)
 1263                                 return 2440;
 1264                 }
 1265                 break;
 1266         case RTW89_BAND_5G:
 1267                 if (center_chan == 151 || center_chan == 153 ||
 1268                     center_chan == 155 || center_chan == 163)
 1269                         return 5760;
 1270                 break;
 1271         case RTW89_BAND_6G:
 1272                 if (center_chan == 195 || center_chan == 197 ||
 1273                     center_chan == 199 || center_chan == 207)
 1274                         return 6920;
 1275                 break;
 1276         default:
 1277                 break;
 1278         }
 1279 
 1280         return 0;
 1281 }
 1282 
 1283 #define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */
 1284 #define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */
 1285 #define MAX_TONE_NUM 2048
 1286 
 1287 static void rtw8852c_set_csi_tone_idx(struct rtw89_dev *rtwdev,
 1288                                       const struct rtw89_chan *chan,
 1289                                       enum rtw89_phy_idx phy_idx)
 1290 {
 1291         u32 spur_freq;
 1292         s32 freq_diff, csi_idx, csi_tone_idx;
 1293 
 1294         spur_freq = rtw8852c_spur_freq(rtwdev, chan);
 1295         if (spur_freq == 0) {
 1296                 rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 0, phy_idx);
 1297                 return;
 1298         }
 1299 
 1300         freq_diff = (spur_freq - chan->freq) * 1000000;
 1301         csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125);
 1302         s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx);
 1303 
 1304         rtw89_phy_write32_idx(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, csi_tone_idx, phy_idx);
 1305         rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 1, phy_idx);
 1306 }
 1307 
 1308 static const struct rtw89_nbi_reg_def rtw8852c_nbi_reg_def[] = {
 1309         [RF_PATH_A] = {
 1310                 .notch1_idx = {0x4C14, 0xFF},
 1311                 .notch1_frac_idx = {0x4C14, 0xC00},
 1312                 .notch1_en = {0x4C14, 0x1000},
 1313                 .notch2_idx = {0x4C20, 0xFF},
 1314                 .notch2_frac_idx = {0x4C20, 0xC00},
 1315                 .notch2_en = {0x4C20, 0x1000},
 1316         },
 1317         [RF_PATH_B] = {
 1318                 .notch1_idx = {0x4CD8, 0xFF},
 1319                 .notch1_frac_idx = {0x4CD8, 0xC00},
 1320                 .notch1_en = {0x4CD8, 0x1000},
 1321                 .notch2_idx = {0x4CE4, 0xFF},
 1322                 .notch2_frac_idx = {0x4CE4, 0xC00},
 1323                 .notch2_en = {0x4CE4, 0x1000},
 1324         },
 1325 };
 1326 
 1327 static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
 1328                                       const struct rtw89_chan *chan,
 1329                                       enum rtw89_rf_path path)
 1330 {
 1331         const struct rtw89_nbi_reg_def *nbi = &rtw8852c_nbi_reg_def[path];
 1332         u32 spur_freq, fc;
 1333         s32 freq_diff;
 1334         s32 nbi_idx, nbi_tone_idx;
 1335         s32 nbi_frac_idx, nbi_frac_tone_idx;
 1336         bool notch2_chk = false;
 1337 
 1338         spur_freq = rtw8852c_spur_freq(rtwdev, chan);
 1339         if (spur_freq == 0) {
 1340                 rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
 1341                 rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
 1342                 return;
 1343         }
 1344 
 1345         fc = chan->freq;
 1346         if (chan->band_width == RTW89_CHANNEL_WIDTH_160) {
 1347                 fc = (spur_freq > fc) ? fc + 40 : fc - 40;
 1348                 if ((fc > spur_freq &&
 1349                      chan->channel < chan->primary_channel) ||
 1350                     (fc < spur_freq &&
 1351                      chan->channel > chan->primary_channel))
 1352                         notch2_chk = true;
 1353         }
 1354 
 1355         freq_diff = (spur_freq - fc) * 1000000;
 1356         nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, &nbi_frac_idx);
 1357 
 1358         if (chan->band_width == RTW89_CHANNEL_WIDTH_20) {
 1359                 s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx);
 1360         } else {
 1361                 u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ?
 1362                                 128 : 256;
 1363 
 1364                 s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx);
 1365         }
 1366         nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125);
 1367 
 1368         if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
 1369                 rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr,
 1370                                        nbi->notch2_idx.mask, nbi_tone_idx);
 1371                 rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr,
 1372                                        nbi->notch2_frac_idx.mask, nbi_frac_tone_idx);
 1373                 rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0);
 1374                 rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 1);
 1375                 rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
 1376         } else {
 1377                 rtw89_phy_write32_mask(rtwdev, nbi->notch1_idx.addr,
 1378                                        nbi->notch1_idx.mask, nbi_tone_idx);
 1379                 rtw89_phy_write32_mask(rtwdev, nbi->notch1_frac_idx.addr,
 1380                                        nbi->notch1_frac_idx.mask, nbi_frac_tone_idx);
 1381                 rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
 1382                 rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 1);
 1383                 rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0);
 1384         }
 1385 }
 1386 
 1387 static void rtw8852c_spur_notch(struct rtw89_dev *rtwdev, u32 val,
 1388                                 enum rtw89_phy_idx phy_idx)
 1389 {
 1390         u32 notch;
 1391         u32 notch2;
 1392 
 1393         if (phy_idx == RTW89_PHY_0) {
 1394                 notch = R_PATH0_NOTCH;
 1395                 notch2 = R_PATH0_NOTCH2;
 1396         } else {
 1397                 notch = R_PATH1_NOTCH;
 1398                 notch2 = R_PATH1_NOTCH2;
 1399         }
 1400 
 1401         rtw89_phy_write32_mask(rtwdev, notch,
 1402                                B_PATH0_NOTCH_VAL | B_PATH0_NOTCH_EN, val);
 1403         rtw89_phy_write32_set(rtwdev, notch, B_PATH0_NOTCH_EN);
 1404         rtw89_phy_write32_mask(rtwdev, notch2,
 1405                                B_PATH0_NOTCH2_VAL | B_PATH0_NOTCH2_EN, val);
 1406         rtw89_phy_write32_set(rtwdev, notch2, B_PATH0_NOTCH2_EN);
 1407 }
 1408 
 1409 static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev,
 1410                                       const struct rtw89_chan *chan,
 1411                                       u8 pri_ch_idx,
 1412                                       enum rtw89_phy_idx phy_idx)
 1413 {
 1414         rtw8852c_set_csi_tone_idx(rtwdev, chan, phy_idx);
 1415 
 1416         if (phy_idx == RTW89_PHY_0) {
 1417                 if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
 1418                     (pri_ch_idx == RTW89_SC_20_LOWER ||
 1419                      pri_ch_idx == RTW89_SC_20_UP3X)) {
 1420                         rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_0);
 1421                         if (!rtwdev->dbcc_en)
 1422                                 rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
 1423                 } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
 1424                            (pri_ch_idx == RTW89_SC_20_UPPER ||
 1425                             pri_ch_idx == RTW89_SC_20_LOW3X)) {
 1426                         rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_0);
 1427                         if (!rtwdev->dbcc_en)
 1428                                 rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
 1429                 } else {
 1430                         rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A);
 1431                         if (!rtwdev->dbcc_en)
 1432                                 rtw8852c_set_nbi_tone_idx(rtwdev, chan,
 1433                                                           RF_PATH_B);
 1434                 }
 1435         } else {
 1436                 if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
 1437                     (pri_ch_idx == RTW89_SC_20_LOWER ||
 1438                      pri_ch_idx == RTW89_SC_20_UP3X)) {
 1439                         rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
 1440                 } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
 1441                            (pri_ch_idx == RTW89_SC_20_UPPER ||
 1442                             pri_ch_idx == RTW89_SC_20_LOW3X)) {
 1443                         rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
 1444                 } else {
 1445                         rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B);
 1446                 }
 1447         }
 1448 
 1449         if (pri_ch_idx == RTW89_SC_20_UP3X || pri_ch_idx == RTW89_SC_20_LOW3X)
 1450                 rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 0, phy_idx);
 1451         else
 1452                 rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 1, phy_idx);
 1453 }
 1454 
 1455 static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev,
 1456                              const struct rtw89_chan *chan,
 1457                              enum rtw89_phy_idx phy_idx)
 1458 {
 1459         u8 pri_ch = chan->primary_channel;
 1460         bool mask_5m_low;
 1461         bool mask_5m_en;
 1462 
 1463         switch (chan->band_width) {
 1464         case RTW89_CHANNEL_WIDTH_40:
 1465                 mask_5m_en = true;
 1466                 mask_5m_low = pri_ch == 2;
 1467                 break;
 1468         case RTW89_CHANNEL_WIDTH_80:
 1469                 mask_5m_en = ((pri_ch == 3) || (pri_ch == 4));
 1470                 mask_5m_low = pri_ch == 4;
 1471                 break;
 1472         default:
 1473                 mask_5m_en = false;
 1474                 mask_5m_low = false;
 1475                 break;
 1476         }
 1477 
 1478         if (!mask_5m_en) {
 1479                 rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x0);
 1480                 rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x0);
 1481                 rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT,
 1482                                       B_ASSIGN_SBD_OPT_EN, 0x0, phy_idx);
 1483         } else {
 1484                 if (mask_5m_low) {
 1485                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4);
 1486                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1);
 1487                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x0);
 1488                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x1);
 1489                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4);
 1490                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1);
 1491                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x0);
 1492                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x1);
 1493                 } else {
 1494                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4);
 1495                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1);
 1496                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x1);
 1497                         rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x0);
 1498                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4);
 1499                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1);
 1500                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x1);
 1501                         rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x0);
 1502                 }
 1503                 rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, B_ASSIGN_SBD_OPT_EN, 0x1, phy_idx);
 1504         }
 1505 }
 1506 
 1507 static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev,
 1508                                   enum rtw89_phy_idx phy_idx)
 1509 {
 1510         /*HW SI reset*/
 1511         rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
 1512                                0x7);
 1513         rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
 1514                                0x7);
 1515 
 1516         udelay(1);
 1517 
 1518         rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
 1519                               phy_idx);
 1520         rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0,
 1521                               phy_idx);
 1522         /*HW SI reset*/
 1523         rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
 1524                                0x0);
 1525         rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
 1526                                0x0);
 1527 
 1528         rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
 1529                               phy_idx);
 1530 }
 1531 
 1532 static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band,
 1533                                  enum rtw89_phy_idx phy_idx, bool en)
 1534 {
 1535         if (en) {
 1536                 rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
 1537                                       B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
 1538                 rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
 1539                                       B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
 1540                 rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
 1541                                       phy_idx);
 1542                 if (band == RTW89_BAND_2G)
 1543                         rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x0);
 1544                 rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
 1545         } else {
 1546                 rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x1);
 1547                 rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1);
 1548                 rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
 1549                                       B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
 1550                 rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
 1551                                       B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
 1552                 fsleep(1);
 1553                 rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0,
 1554                                       phy_idx);
 1555         }
 1556 }
 1557 
 1558 static void rtw8852c_bb_reset(struct rtw89_dev *rtwdev,
 1559                               enum rtw89_phy_idx phy_idx)
 1560 {
 1561         rtw8852c_bb_reset_all(rtwdev, phy_idx);
 1562 }
 1563 
 1564 static
 1565 void rtw8852c_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
 1566                            u8 tx_path_en, u8 trsw_tx,
 1567                            u8 trsw_rx, u8 trsw, u8 trsw_b)
 1568 {
 1569         static const u32 path_cr_bases[] = {0x5868, 0x7868};
 1570         u32 mask_ofst = 16;
 1571         u32 cr;
 1572         u32 val;
 1573 
 1574         if (path >= ARRAY_SIZE(path_cr_bases))
 1575                 return;
 1576 
 1577         cr = path_cr_bases[path];
 1578 
 1579         mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2;
 1580         val = FIELD_PREP(B_P0_TRSW_A, trsw) | FIELD_PREP(B_P0_TRSW_B, trsw_b);
 1581 
 1582         rtw89_phy_write32_mask(rtwdev, cr, (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, val);
 1583 }
 1584 
 1585 enum rtw8852c_rfe_src {
 1586         PAPE_RFM,
 1587         TRSW_RFM,
 1588         LNAON_RFM,
 1589 };
 1590 
 1591 static
 1592 void rtw8852c_bb_gpio_rfm(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
 1593                           enum rtw8852c_rfe_src src, u8 dis_tx_gnt_wl,
 1594                           u8 active_tx_opt, u8 act_bt_en, u8 rfm_output_val)
 1595 {
 1596         static const u32 path_cr_bases[] = {0x5894, 0x7894};
 1597         static const u32 masks[] = {0, 8, 16};
 1598         u32 mask, mask_ofst;
 1599         u32 cr;
 1600         u32 val;
 1601 
 1602         if (src >= ARRAY_SIZE(masks) || path >= ARRAY_SIZE(path_cr_bases))
 1603                 return;
 1604 
 1605         mask_ofst = masks[src];
 1606         cr = path_cr_bases[path];
 1607 
 1608         val = FIELD_PREP(B_P0_RFM_DIS_WL, dis_tx_gnt_wl) |
 1609               FIELD_PREP(B_P0_RFM_TX_OPT, active_tx_opt) |
 1610               FIELD_PREP(B_P0_RFM_BT_EN, act_bt_en) |
 1611               FIELD_PREP(B_P0_RFM_OUT, rfm_output_val);
 1612         mask = 0xff << mask_ofst;
 1613 
 1614         rtw89_phy_write32_mask(rtwdev, cr, mask, val);
 1615 }
 1616 
 1617 static void rtw8852c_bb_gpio_init(struct rtw89_dev *rtwdev)
 1618 {
 1619         static const u32 cr_bases[] = {0x5800, 0x7800};
 1620         u32 addr;
 1621         u8 i;
 1622 
 1623         for (i = 0; i < ARRAY_SIZE(cr_bases); i++) {
 1624                 addr = cr_bases[i];
 1625                 rtw89_phy_write32_set(rtwdev, (addr | 0x68), B_P0_TRSW_A);
 1626                 rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_X);
 1627                 rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_SO_A2);
 1628                 rtw89_phy_write32(rtwdev, (addr | 0x80), 0x77777777);
 1629                 rtw89_phy_write32(rtwdev, (addr | 0x84), 0x77777777);
 1630         }
 1631 
 1632         rtw89_phy_write32(rtwdev, R_RFE_E_A2, 0xffffffff);
 1633         rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, 0);
 1634         rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, 0);
 1635         rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, 0);
 1636 
 1637         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 0, 0, 1);
 1638         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 1, 1, 0);
 1639         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 0, 1, 0);
 1640         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 1, 1, 0);
 1641         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 0, 0, 1);
 1642         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 1, 1, 0);
 1643         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 0, 1, 0);
 1644         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 1, 1, 0);
 1645 
 1646         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 0, 0, 1);
 1647         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 1, 1, 0);
 1648         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 0, 1, 0);
 1649         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 1, 1, 0);
 1650         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 0, 0, 1);
 1651         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 1, 1, 0);
 1652         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 0, 1, 0);
 1653         rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 1, 1, 0);
 1654 
 1655         rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, PAPE_RFM, 0, 0, 0, 0x0);
 1656         rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, TRSW_RFM, 0, 0, 0, 0x4);
 1657         rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, LNAON_RFM, 0, 0, 0, 0x8);
 1658 
 1659         rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, PAPE_RFM, 0, 0, 0, 0x0);
 1660         rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, TRSW_RFM, 0, 0, 0, 0x4);
 1661         rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, LNAON_RFM, 0, 0, 0, 0x8);
 1662 }
 1663 
 1664 static void rtw8852c_bb_macid_ctrl_init(struct rtw89_dev *rtwdev,
 1665                                         enum rtw89_phy_idx phy_idx)
 1666 {
 1667         u32 addr;
 1668 
 1669         for (addr = R_AX_PWR_MACID_LMT_TABLE0;
 1670              addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4)
 1671                 rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
 1672 }
 1673 
 1674 static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev)
 1675 {
 1676         struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
 1677 
 1678         rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT,
 1679                               B_DBCC_80P80_SEL_EVM_RPT_EN);
 1680         rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT2,
 1681                               B_DBCC_80P80_SEL_EVM_RPT2_EN);
 1682 
 1683         rtw8852c_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0);
 1684         rtw8852c_bb_gpio_init(rtwdev);
 1685 
 1686         /* read these registers after loading BB parameters */
 1687         gain->offset_base[RTW89_PHY_0] =
 1688                 rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP, B_RPL_BIAS_COMP_MASK);
 1689         gain->offset_base[RTW89_PHY_1] =
 1690                 rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP1, B_RPL_BIAS_COMP1_MASK);
 1691 }
 1692 
 1693 static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
 1694                                     const struct rtw89_chan *chan,
 1695                                     enum rtw89_phy_idx phy_idx)
 1696 {
 1697         bool cck_en = chan->band_type == RTW89_BAND_2G;
 1698         u8 pri_ch_idx = chan->pri_ch_idx;
 1699         u32 mask, reg;
 1700         u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0,
 1701                                B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1};
 1702 
 1703         if (chan->band_type == RTW89_BAND_2G)
 1704                 rtw8852c_ctrl_sco_cck(rtwdev, chan->channel,
 1705                                       chan->primary_channel,
 1706                                       chan->band_width);
 1707 
 1708         rtw8852c_ctrl_ch(rtwdev, chan, phy_idx);
 1709         rtw8852c_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx);
 1710         if (cck_en) {
 1711                 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1);
 1712                 rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0);
 1713                 rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
 1714                                       B_PD_ARBITER_OFF, 0x0, phy_idx);
 1715         } else {
 1716                 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0);
 1717                 rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 1);
 1718                 rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
 1719                                       B_PD_ARBITER_OFF, 0x1, phy_idx);
 1720         }
 1721 
 1722         rtw8852c_spur_elimination(rtwdev, chan, pri_ch_idx, phy_idx);
 1723         rtw8852c_ctrl_btg(rtwdev, chan->band_type == RTW89_BAND_2G);
 1724         rtw8852c_5m_mask(rtwdev, chan, phy_idx);
 1725 
 1726         if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
 1727             rtwdev->hal.cv != CHIP_CAV) {
 1728                 rtw89_phy_write32_idx(rtwdev, R_P80_AT_HIGH_FREQ,
 1729                                       B_P80_AT_HIGH_FREQ, 0x0, phy_idx);
 1730                 reg = rtw89_mac_reg_by_idx(R_P80_AT_HIGH_FREQ_BB_WRP,
 1731                                            phy_idx);
 1732                 if (chan->primary_channel > chan->channel) {
 1733                         rtw89_phy_write32_mask(rtwdev,
 1734                                                R_P80_AT_HIGH_FREQ_RU_ALLOC,
 1735                                                ru_alloc_msk[phy_idx], 1);
 1736                         rtw89_write32_mask(rtwdev, reg,
 1737                                            B_P80_AT_HIGH_FREQ_BB_WRP, 1);
 1738                 } else {
 1739                         rtw89_phy_write32_mask(rtwdev,
 1740                                                R_P80_AT_HIGH_FREQ_RU_ALLOC,
 1741                                                ru_alloc_msk[phy_idx], 0);
 1742                         rtw89_write32_mask(rtwdev, reg,
 1743                                            B_P80_AT_HIGH_FREQ_BB_WRP, 0);
 1744                 }
 1745         }
 1746 
 1747         if (chan->band_type == RTW89_BAND_6G &&
 1748             chan->band_width == RTW89_CHANNEL_WIDTH_160)
 1749                 rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
 1750                                       B_CDD_EVM_CHK_EN, 0, phy_idx);
 1751         else
 1752                 rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
 1753                                       B_CDD_EVM_CHK_EN, 1, phy_idx);
 1754 
 1755         if (!rtwdev->dbcc_en) {
 1756                 mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
 1757                 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1);
 1758                 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3);
 1759                 mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
 1760                 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1);
 1761                 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3);
 1762         } else {
 1763                 if (phy_idx == RTW89_PHY_0) {
 1764                         mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
 1765                         rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1);
 1766                         rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3);
 1767                 } else {
 1768                         mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
 1769                         rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1);
 1770                         rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3);
 1771                 }
 1772         }
 1773 
 1774         rtw8852c_bb_reset_all(rtwdev, phy_idx);
 1775 }
 1776 
 1777 static void rtw8852c_set_channel(struct rtw89_dev *rtwdev,
 1778                                  const struct rtw89_chan *chan,
 1779                                  enum rtw89_mac_idx mac_idx,
 1780                                  enum rtw89_phy_idx phy_idx)
 1781 {
 1782         rtw8852c_set_channel_mac(rtwdev, chan, mac_idx);
 1783         rtw8852c_set_channel_bb(rtwdev, chan, phy_idx);
 1784         rtw8852c_set_channel_rf(rtwdev, chan, phy_idx);
 1785 }
 1786 
 1787 static void rtw8852c_dfs_en(struct rtw89_dev *rtwdev, bool en)
 1788 {
 1789         if (en)
 1790                 rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1);
 1791         else
 1792                 rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0);
 1793 }
 1794 
 1795 static void rtw8852c_adc_en(struct rtw89_dev *rtwdev, bool en)
 1796 {
 1797         if (en)
 1798                 rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
 1799                                        0x0);
 1800         else
 1801                 rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
 1802                                        0xf);
 1803 }
 1804 
 1805 static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
 1806                                       struct rtw89_channel_help_params *p,
 1807                                       const struct rtw89_chan *chan,
 1808                                       enum rtw89_mac_idx mac_idx,
 1809                                       enum rtw89_phy_idx phy_idx)
 1810 {
 1811         if (enter) {
 1812                 rtw89_chip_stop_sch_tx(rtwdev, mac_idx, &p->tx_en,
 1813                                        RTW89_SCH_TX_SEL_ALL);
 1814                 rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false);
 1815                 rtw8852c_dfs_en(rtwdev, false);
 1816                 rtw8852c_tssi_cont_en_phyidx(rtwdev, false, phy_idx);
 1817                 rtw8852c_adc_en(rtwdev, false);
 1818                 fsleep(40);
 1819                 rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, false);
 1820         } else {
 1821                 rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true);
 1822                 rtw8852c_adc_en(rtwdev, true);
 1823                 rtw8852c_dfs_en(rtwdev, true);
 1824                 rtw8852c_tssi_cont_en_phyidx(rtwdev, true, phy_idx);
 1825                 rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, true);
 1826                 rtw89_chip_resume_sch_tx(rtwdev, mac_idx, p->tx_en);
 1827         }
 1828 }
 1829 
 1830 static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
 1831 {
 1832         struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
 1833 
 1834         rtwdev->is_tssi_mode[RF_PATH_A] = false;
 1835         rtwdev->is_tssi_mode[RF_PATH_B] = false;
 1836         memset(mcc_info, 0, sizeof(*mcc_info));
 1837         rtw8852c_lck_init(rtwdev);
 1838 
 1839         rtw8852c_rck(rtwdev);
 1840         rtw8852c_dack(rtwdev);
 1841         rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
 1842 }
 1843 
 1844 static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev)
 1845 {
 1846         enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
 1847 
 1848         rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
 1849         rtw8852c_rx_dck(rtwdev, phy_idx, false);
 1850         rtw8852c_iqk(rtwdev, phy_idx);
 1851         rtw8852c_tssi(rtwdev, phy_idx);
 1852         rtw8852c_dpk(rtwdev, phy_idx);
 1853         rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
 1854 }
 1855 
 1856 static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev,
 1857                                       enum rtw89_phy_idx phy_idx)
 1858 {
 1859         rtw8852c_tssi_scan(rtwdev, phy_idx);
 1860 }
 1861 
 1862 static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, bool start)
 1863 {
 1864         rtw8852c_wifi_scan_notify(rtwdev, start, RTW89_PHY_0);
 1865 }
 1866 
 1867 static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
 1868 {
 1869         rtw8852c_dpk_track(rtwdev);
 1870         rtw8852c_lck_track(rtwdev);
 1871         rtw8852c_rx_dck_track(rtwdev);
 1872 }
 1873 
 1874 static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
 1875                                      enum rtw89_phy_idx phy_idx, s16 ref)
 1876 {
 1877         s8 ofst_int = 0;
 1878         u8 base_cw_0db = 0x27;
 1879         u16 tssi_16dbm_cw = 0x12c;
 1880         s16 pwr_s10_3 = 0;
 1881         s16 rf_pwr_cw = 0;
 1882         u16 bb_pwr_cw = 0;
 1883         u32 pwr_cw = 0;
 1884         u32 tssi_ofst_cw = 0;
 1885 
 1886         pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3);
 1887         bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3);
 1888         rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3);
 1889         rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
 1890         pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
 1891 
 1892         tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3));
 1893         rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
 1894                     "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
 1895                     tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
 1896 
 1897         return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0));
 1898 }
 1899 
 1900 static
 1901 void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
 1902                                      s8 pw_ofst, enum rtw89_mac_idx mac_idx)
 1903 {
 1904         s8 pw_ofst_2tx;
 1905         s8 val_1t;
 1906         s8 val_2t;
 1907         u32 reg;
 1908         u8 i;
 1909 
 1910         if (pw_ofst < -32 || pw_ofst > 31) {
 1911                 rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
 1912                 return;
 1913         }
 1914         val_1t = pw_ofst << 2;
 1915         pw_ofst_2tx = max(pw_ofst - 3, -32);
 1916         val_2t = pw_ofst_2tx << 2;
 1917 
 1918         rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_1tx=0x%x\n", val_1t);
 1919         rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_2tx=0x%x\n", val_2t);
 1920 
 1921         for (i = 0; i < 4; i++) {
 1922                 /* 1TX */
 1923                 reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
 1924                 rtw89_write32_mask(rtwdev, reg,
 1925                                    B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i),
 1926                                    val_1t);
 1927                 /* 2TX */
 1928                 reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
 1929                 rtw89_write32_mask(rtwdev, reg,
 1930                                    B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i),
 1931                                    val_2t);
 1932         }
 1933 }
 1934 
 1935 static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
 1936                                    enum rtw89_phy_idx phy_idx)
 1937 {
 1938         static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800};
 1939         const u32 mask = 0x7FFFFFF;
 1940         const u8 ofst_ofdm = 0x4;
 1941         const u8 ofst_cck = 0x8;
 1942         s16 ref_ofdm = 0;
 1943         s16 ref_cck = 0;
 1944         u32 val;
 1945         u8 i;
 1946 
 1947         rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n");
 1948 
 1949         rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
 1950                                      GENMASK(27, 10), 0x0);
 1951 
 1952         rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
 1953         val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm);
 1954 
 1955         for (i = 0; i < RF_PATH_NUM_8852C; i++)
 1956                 rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val,
 1957                                       phy_idx);
 1958 
 1959         rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
 1960         val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck);
 1961 
 1962         for (i = 0; i < RF_PATH_NUM_8852C; i++)
 1963                 rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val,
 1964                                       phy_idx);
 1965 }
 1966 
 1967 static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
 1968                                       const struct rtw89_chan *chan,
 1969                                       enum rtw89_phy_idx phy_idx)
 1970 {
 1971         u8 band = chan->band_type;
 1972         u8 ch = chan->channel;
 1973         static const u8 rs[] = {
 1974                 RTW89_RS_CCK,
 1975                 RTW89_RS_OFDM,
 1976                 RTW89_RS_MCS,
 1977                 RTW89_RS_HEDCM,
 1978         };
 1979         s8 tmp;
 1980         u8 i, j;
 1981         u32 val, shf, addr = R_AX_PWR_BY_RATE;
 1982         struct rtw89_rate_desc cur;
 1983 
 1984         rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
 1985                     "[TXPWR] set txpwr byrate with ch=%d\n", ch);
 1986 
 1987         for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) {
 1988                 for (i = 0; i < ARRAY_SIZE(rs); i++) {
 1989                         if (cur.nss >= rtw89_rs_nss_max[rs[i]])
 1990                                 continue;
 1991 
 1992                         val = 0;
 1993                         cur.rs = rs[i];
 1994 
 1995                         for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) {
 1996                                 cur.idx = j;
 1997                                 shf = (j % 4) * 8;
 1998                                 tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band,
 1999                                                                   &cur);
 2000                                 val |= (tmp << shf);
 2001 
 2002                                 if ((j + 1) % 4)
 2003                                         continue;
 2004 
 2005                                 rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
 2006                                 val = 0;
 2007                                 addr += 4;
 2008                         }
 2009                 }
 2010         }
 2011 }
 2012 
 2013 static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev,
 2014                                       const struct rtw89_chan *chan,
 2015                                       enum rtw89_phy_idx phy_idx)
 2016 {
 2017         u8 band = chan->band_type;
 2018         struct rtw89_rate_desc desc = {
 2019                 .nss = RTW89_NSS_1,
 2020                 .rs = RTW89_RS_OFFSET,
 2021         };
 2022         u32 val = 0;
 2023         s8 v;
 2024 
 2025         rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n");
 2026 
 2027         for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) {
 2028                 v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc);
 2029                 val |= ((v & 0xf) << (4 * desc.idx));
 2030         }
 2031 
 2032         rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL,
 2033                                      GENMASK(19, 0), val);
 2034 }
 2035 
 2036 static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
 2037                                           u8 tx_shape_idx,
 2038                                           enum rtw89_phy_idx phy_idx)
 2039 {
 2040 #define __DFIR_CFG_MASK 0xffffff
 2041 #define __DFIR_CFG_NR 8
 2042 #if defined(__linux__)
 2043 #define __DECL_DFIR_VAR(_prefix, _name, _val...) \
 2044         static const u32 _prefix ## _ ## _name[] = {_val}; \
 2045         static_assert(ARRAY_SIZE(_prefix ## _ ## _name) == __DFIR_CFG_NR)
 2046 #elif defined(__FreeBSD__)
 2047 #define __DECL_DFIR_VAR(_prefix, _name, _val...) \
 2048         static const u32 _prefix ## _ ## _name[] = {_val}; \
 2049         rtw89_static_assert(ARRAY_SIZE(_prefix ## _ ## _name) == __DFIR_CFG_NR)
 2050 #endif
 2051 #define __DECL_DFIR_PARAM(_name, _val...) __DECL_DFIR_VAR(param, _name, _val)
 2052 #define __DECL_DFIR_ADDR(_name, _val...) __DECL_DFIR_VAR(addr, _name, _val)
 2053 
 2054         __DECL_DFIR_PARAM(flat,
 2055                           0x003D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053,
 2056                           0x00F86F9A, 0x00FAEF92, 0x00FE5FCC, 0x00FFDFF5);
 2057         __DECL_DFIR_PARAM(sharp,
 2058                           0x003D83FF, 0x002C636A, 0x0013F204, 0x00008090,
 2059                           0x00F87FB0, 0x00F99F83, 0x00FDBFBA, 0x00003FF5);
 2060         __DECL_DFIR_PARAM(sharp_14,
 2061                           0x003B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E,
 2062                           0x00FD8F92, 0x0002D011, 0x0001C02C, 0x00FFF00A);
 2063         __DECL_DFIR_ADDR(filter,
 2064                          0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0,
 2065                          0x45C4, 0x45C8);
 2066         const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 2067         u8 ch = chan->channel;
 2068         const u32 *param;
 2069         int i;
 2070 
 2071         if (ch > 14) {
 2072                 rtw89_warn(rtwdev,
 2073                            "set tx shape dfir by unknown ch: %d on 2G\n", ch);
 2074                 return;
 2075         }
 2076 
 2077         if (ch == 14)
 2078                 param = param_sharp_14;
 2079         else
 2080                 param = tx_shape_idx == 0 ? param_flat : param_sharp;
 2081 
 2082         for (i = 0; i < __DFIR_CFG_NR; i++) {
 2083                 rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
 2084                             "set tx shape dfir: 0x%x: 0x%x\n", addr_filter[i],
 2085                             param[i]);
 2086                 rtw89_phy_write32_idx(rtwdev, addr_filter[i], __DFIR_CFG_MASK,
 2087                                       param[i], phy_idx);
 2088         }
 2089 
 2090 #undef __DECL_DFIR_ADDR
 2091 #undef __DECL_DFIR_PARAM
 2092 #undef __DECL_DFIR_VAR
 2093 #undef __DFIR_CFG_NR
 2094 #undef __DFIR_CFG_MASK
 2095 }
 2096 
 2097 static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
 2098                                   const struct rtw89_chan *chan,
 2099                                   enum rtw89_phy_idx phy_idx)
 2100 {
 2101         u8 band = chan->band_type;
 2102         u8 regd = rtw89_regd_get(rtwdev, band);
 2103         u8 tx_shape_cck = rtw89_8852c_tx_shape[band][RTW89_RS_CCK][regd];
 2104         u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd];
 2105 
 2106         if (band == RTW89_BAND_2G)
 2107                 rtw8852c_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx);
 2108 
 2109         rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
 2110                                              (enum rtw89_mac_idx)phy_idx,
 2111                                              tx_shape_ofdm);
 2112 }
 2113 
 2114 static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev,
 2115                                      const struct rtw89_chan *chan,
 2116                                      enum rtw89_phy_idx phy_idx)
 2117 {
 2118 #define __MAC_TXPWR_LMT_PAGE_SIZE 40
 2119         u8 ch = chan->channel;
 2120         u8 bw = chan->band_width;
 2121         struct rtw89_txpwr_limit lmt[NTX_NUM_8852C];
 2122         u32 addr, val;
 2123         const s8 *ptr;
 2124         u8 i, j;
 2125 
 2126         rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
 2127                     "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw);
 2128 
 2129         for (i = 0; i < NTX_NUM_8852C; i++) {
 2130                 rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i);
 2131 
 2132                 for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) {
 2133                         addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i;
 2134                         ptr = (s8 *)&lmt[i] + j;
 2135 
 2136                         val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
 2137                               FIELD_PREP(GENMASK(15, 8), ptr[1]) |
 2138                               FIELD_PREP(GENMASK(23, 16), ptr[2]) |
 2139                               FIELD_PREP(GENMASK(31, 24), ptr[3]);
 2140 
 2141                         rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
 2142                 }
 2143         }
 2144 #undef __MAC_TXPWR_LMT_PAGE_SIZE
 2145 }
 2146 
 2147 static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
 2148                                         const struct rtw89_chan *chan,
 2149                                         enum rtw89_phy_idx phy_idx)
 2150 {
 2151 #define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
 2152         u8 ch = chan->channel;
 2153         u8 bw = chan->band_width;
 2154         struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C];
 2155         u32 addr, val;
 2156         const s8 *ptr;
 2157         u8 i, j;
 2158 
 2159         rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
 2160                     "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw);
 2161 
 2162         for (i = 0; i < NTX_NUM_8852C; i++) {
 2163                 rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i);
 2164 
 2165                 for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) {
 2166                         addr = R_AX_PWR_RU_LMT + j +
 2167                                __MAC_TXPWR_LMT_RU_PAGE_SIZE * i;
 2168                         ptr = (s8 *)&lmt_ru[i] + j;
 2169 
 2170                         val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
 2171                               FIELD_PREP(GENMASK(15, 8), ptr[1]) |
 2172                               FIELD_PREP(GENMASK(23, 16), ptr[2]) |
 2173                               FIELD_PREP(GENMASK(31, 24), ptr[3]);
 2174 
 2175                         rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
 2176                 }
 2177         }
 2178 
 2179 #undef __MAC_TXPWR_LMT_RU_PAGE_SIZE
 2180 }
 2181 
 2182 static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
 2183                                const struct rtw89_chan *chan,
 2184                                enum rtw89_phy_idx phy_idx)
 2185 {
 2186         rtw8852c_set_txpwr_byrate(rtwdev, chan, phy_idx);
 2187         rtw8852c_set_txpwr_offset(rtwdev, chan, phy_idx);
 2188         rtw8852c_set_tx_shape(rtwdev, chan, phy_idx);
 2189         rtw8852c_set_txpwr_limit(rtwdev, chan, phy_idx);
 2190         rtw8852c_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
 2191 }
 2192 
 2193 static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
 2194                                     enum rtw89_phy_idx phy_idx)
 2195 {
 2196         rtw8852c_set_txpwr_ref(rtwdev, phy_idx);
 2197 }
 2198 
 2199 static void
 2200 rtw8852c_init_tssi_ctrl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 2201 {
 2202         static const struct rtw89_reg2_def ctrl_ini[] = {
 2203                 {0xD938, 0x00010100},
 2204                 {0xD93C, 0x0500D500},
 2205                 {0xD940, 0x00000500},
 2206                 {0xD944, 0x00000005},
 2207                 {0xD94C, 0x00220000},
 2208                 {0xD950, 0x00030000},
 2209         };
 2210         u32 addr;
 2211         int i;
 2212 
 2213         for (addr = R_AX_TSSI_CTRL_HEAD; addr <= R_AX_TSSI_CTRL_TAIL; addr += 4)
 2214                 rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
 2215 
 2216         for (i = 0; i < ARRAY_SIZE(ctrl_ini); i++)
 2217                 rtw89_mac_txpwr_write32(rtwdev, phy_idx, ctrl_ini[i].addr,
 2218                                         ctrl_ini[i].data);
 2219 
 2220         rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
 2221                                              (enum rtw89_mac_idx)phy_idx,
 2222                                              RTW89_TSSI_BANDEDGE_FLAT);
 2223 }
 2224 
 2225 static int
 2226 rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 2227 {
 2228         int ret;
 2229 
 2230         ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333);
 2231         if (ret)
 2232                 return ret;
 2233 
 2234         ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000);
 2235         if (ret)
 2236                 return ret;
 2237 
 2238         ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff);
 2239         if (ret)
 2240                 return ret;
 2241 
 2242         rtw8852c_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ?
 2243                                                               RTW89_MAC_1 :
 2244                                                               RTW89_MAC_0);
 2245         rtw8852c_init_tssi_ctrl(rtwdev, phy_idx);
 2246 
 2247         return 0;
 2248 }
 2249 
 2250 static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
 2251 {
 2252         const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 2253         u8 band = chan->band_type;
 2254         u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
 2255         u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
 2256 
 2257         if (rtwdev->dbcc_en) {
 2258                 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 1);
 2259                 rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 2,
 2260                                       RTW89_PHY_1);
 2261 
 2262                 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0,
 2263                                        1);
 2264                 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1,
 2265                                        1);
 2266                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, 2,
 2267                                       RTW89_PHY_1);
 2268                 rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, 2,
 2269                                       RTW89_PHY_1);
 2270 
 2271                 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
 2272                                        B_RXHT_MCS_LIMIT, 0);
 2273                 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
 2274                                        B_RXVHT_MCS_LIMIT, 0);
 2275                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
 2276                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
 2277                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
 2278 
 2279                 rtw89_phy_write32_idx(rtwdev, R_RXHT_MCS_LIMIT,
 2280                                       B_RXHT_MCS_LIMIT, 0, RTW89_PHY_1);
 2281                 rtw89_phy_write32_idx(rtwdev, R_RXVHT_MCS_LIMIT,
 2282                                       B_RXVHT_MCS_LIMIT, 0, RTW89_PHY_1);
 2283                 rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_USER_MAX, 1,
 2284                                       RTW89_PHY_1);
 2285                 rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0,
 2286                                       RTW89_PHY_1);
 2287                 rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0,
 2288                                       RTW89_PHY_1);
 2289                 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1);
 2290                 rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3);
 2291                 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1);
 2292                 rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3);
 2293         } else {
 2294                 if (rx_path == RF_PATH_A) {
 2295                         rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
 2296                                                B_ANT_RX_SEG0, 1);
 2297                         rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
 2298                                                B_ANT_RX_1RCCA_SEG0, 1);
 2299                         rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
 2300                                                B_ANT_RX_1RCCA_SEG1, 1);
 2301                         rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
 2302                                                B_RXHT_MCS_LIMIT, 0);
 2303                         rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
 2304                                                B_RXVHT_MCS_LIMIT, 0);
 2305                         rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
 2306                                                0);
 2307                         rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
 2308                                                0);
 2309                         rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
 2310                                                rst_mask0, 1);
 2311                         rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
 2312                                                rst_mask0, 3);
 2313                 } else if (rx_path == RF_PATH_B) {
 2314                         rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
 2315                                                B_ANT_RX_SEG0, 2);
 2316                         rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
 2317                                                B_ANT_RX_1RCCA_SEG0, 2);
 2318                         rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
 2319                                                B_ANT_RX_1RCCA_SEG1, 2);
 2320                         rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
 2321                                                B_RXHT_MCS_LIMIT, 0);
 2322                         rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
 2323                                                B_RXVHT_MCS_LIMIT, 0);
 2324                         rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
 2325                                                0);
 2326                         rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
 2327                                                0);
 2328                         rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
 2329                                                rst_mask1, 1);
 2330                         rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
 2331                                                rst_mask1, 3);
 2332                 } else {
 2333                         rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
 2334                                                B_ANT_RX_SEG0, 3);
 2335                         rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
 2336                                                B_ANT_RX_1RCCA_SEG0, 3);
 2337                         rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
 2338                                                B_ANT_RX_1RCCA_SEG1, 3);
 2339                         rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
 2340                                                B_RXHT_MCS_LIMIT, 1);
 2341                         rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
 2342                                                B_RXVHT_MCS_LIMIT, 1);
 2343                         rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
 2344                                                1);
 2345                         rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
 2346                                                1);
 2347                         rtw8852c_ctrl_btg(rtwdev, band == RTW89_BAND_2G);
 2348                         rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
 2349                                                rst_mask0, 1);
 2350                         rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
 2351                                                rst_mask0, 3);
 2352                         rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
 2353                                                rst_mask1, 1);
 2354                         rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
 2355                                                rst_mask1, 3);
 2356                 }
 2357                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
 2358         }
 2359 }
 2360 
 2361 static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
 2362                                        enum rtw89_mac_idx mac_idx)
 2363 {
 2364         struct rtw89_reg2_def path_com[] = {
 2365                 {R_AX_PATH_COM0, AX_PATH_COM0_DFVAL},
 2366                 {R_AX_PATH_COM1, AX_PATH_COM1_DFVAL},
 2367                 {R_AX_PATH_COM2, AX_PATH_COM2_DFVAL},
 2368                 {R_AX_PATH_COM3, AX_PATH_COM3_DFVAL},
 2369                 {R_AX_PATH_COM4, AX_PATH_COM4_DFVAL},
 2370                 {R_AX_PATH_COM5, AX_PATH_COM5_DFVAL},
 2371                 {R_AX_PATH_COM6, AX_PATH_COM6_DFVAL},
 2372                 {R_AX_PATH_COM7, AX_PATH_COM7_DFVAL},
 2373                 {R_AX_PATH_COM8, AX_PATH_COM8_DFVAL},
 2374                 {R_AX_PATH_COM9, AX_PATH_COM9_DFVAL},
 2375                 {R_AX_PATH_COM10, AX_PATH_COM10_DFVAL},
 2376                 {R_AX_PATH_COM11, AX_PATH_COM11_DFVAL},
 2377         };
 2378         u32 addr;
 2379         u32 reg;
 2380         u8 cr_size = ARRAY_SIZE(path_com);
 2381         u8 i = 0;
 2382 
 2383         rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_0);
 2384         rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_1);
 2385 
 2386         for (addr = R_AX_MACID_ANT_TABLE;
 2387              addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) {
 2388                 reg = rtw89_mac_reg_by_idx(addr, mac_idx);
 2389                 rtw89_write32(rtwdev, reg, 0);
 2390         }
 2391 
 2392         if (tx_path == RF_A) {
 2393                 path_com[0].data = AX_PATH_COM0_PATHA;
 2394                 path_com[1].data = AX_PATH_COM1_PATHA;
 2395                 path_com[2].data = AX_PATH_COM2_PATHA;
 2396                 path_com[7].data = AX_PATH_COM7_PATHA;
 2397                 path_com[8].data = AX_PATH_COM8_PATHA;
 2398         } else if (tx_path == RF_B) {
 2399                 path_com[0].data = AX_PATH_COM0_PATHB;
 2400                 path_com[1].data = AX_PATH_COM1_PATHB;
 2401                 path_com[2].data = AX_PATH_COM2_PATHB;
 2402                 path_com[7].data = AX_PATH_COM7_PATHB;
 2403                 path_com[8].data = AX_PATH_COM8_PATHB;
 2404         } else if (tx_path == RF_AB) {
 2405                 path_com[0].data = AX_PATH_COM0_PATHAB;
 2406                 path_com[1].data = AX_PATH_COM1_PATHAB;
 2407                 path_com[2].data = AX_PATH_COM2_PATHAB;
 2408                 path_com[7].data = AX_PATH_COM7_PATHAB;
 2409                 path_com[8].data = AX_PATH_COM8_PATHAB;
 2410         } else {
 2411                 rtw89_warn(rtwdev, "[Invalid Tx Path]Tx Path: %d\n", tx_path);
 2412                 return;
 2413         }
 2414 
 2415         for (i = 0; i < cr_size; i++) {
 2416                 rtw89_debug(rtwdev, RTW89_DBG_TSSI, "0x%x = 0x%x\n",
 2417                             path_com[i].addr, path_com[i].data);
 2418                 reg = rtw89_mac_reg_by_idx(path_com[i].addr, mac_idx);
 2419                 rtw89_write32(rtwdev, reg, path_com[i].data);
 2420         }
 2421 }
 2422 
 2423 static void rtw8852c_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en)
 2424 {
 2425         if (bt_en) {
 2426                 rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
 2427                                        B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x3);
 2428                 rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
 2429                                        B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x3);
 2430                 rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
 2431                                        B_PATH0_RXBB_MSK_V1, 0xf);
 2432                 rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
 2433                                        B_PATH1_RXBB_MSK_V1, 0xf);
 2434                 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
 2435                                        B_PATH0_G_LNA6_OP1DB_V1, 0x80);
 2436                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
 2437                                        B_PATH1_G_LNA6_OP1DB_V1, 0x80);
 2438                 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
 2439                                        B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x80);
 2440                 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
 2441                                        B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x80);
 2442                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
 2443                                        B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x80);
 2444                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
 2445                                        B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x80);
 2446                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
 2447                                        B_PATH0_BT_BACKOFF_V1, 0x780D1E);
 2448                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
 2449                                        B_PATH1_BT_BACKOFF_V1, 0x780D1E);
 2450                 rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
 2451                                        B_P0_BACKOFF_IBADC_V1, 0x34);
 2452                 rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
 2453                                        B_P1_BACKOFF_IBADC_V1, 0x34);
 2454         } else {
 2455                 rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
 2456                                        B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x0);
 2457                 rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
 2458                                        B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x0);
 2459                 rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
 2460                                        B_PATH0_RXBB_MSK_V1, 0x60);
 2461                 rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
 2462                                        B_PATH1_RXBB_MSK_V1, 0x60);
 2463                 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
 2464                                        B_PATH0_G_LNA6_OP1DB_V1, 0x1a);
 2465                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
 2466                                        B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
 2467                 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
 2468                                        B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a);
 2469                 rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
 2470                                        B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x2a);
 2471                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
 2472                                        B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
 2473                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
 2474                                        B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x2a);
 2475                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
 2476                                        B_PATH0_BT_BACKOFF_V1, 0x79E99E);
 2477                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
 2478                                        B_PATH1_BT_BACKOFF_V1, 0x79E99E);
 2479                 rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
 2480                                        B_P0_BACKOFF_IBADC_V1, 0x26);
 2481                 rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
 2482                                        B_P1_BACKOFF_IBADC_V1, 0x26);
 2483         }
 2484 }
 2485 
 2486 static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
 2487 {
 2488         struct rtw89_hal *hal = &rtwdev->hal;
 2489         u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB;
 2490 
 2491         rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB);
 2492 
 2493         if (hal->rx_nss == 1) {
 2494                 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
 2495                 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
 2496                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
 2497                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
 2498         } else {
 2499                 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
 2500                 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
 2501                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
 2502                 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
 2503         }
 2504 
 2505         rtw8852c_ctrl_tx_path_tmac(rtwdev, ntx_path, RTW89_MAC_0);
 2506 }
 2507 
 2508 static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
 2509 {
 2510         rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
 2511         rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0);
 2512         rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
 2513 
 2514         fsleep(200);
 2515 
 2516         return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
 2517 }
 2518 
 2519 static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev)
 2520 {
 2521         struct rtw89_btc *btc = &rtwdev->btc;
 2522         struct rtw89_btc_module *module = &btc->mdinfo;
 2523 
 2524         module->rfe_type = rtwdev->efuse.rfe_type;
 2525         module->cv = rtwdev->hal.cv;
 2526         module->bt_solo = 0;
 2527         module->switch_type = BTC_SWITCH_INTERNAL;
 2528 
 2529         if (module->rfe_type > 0)
 2530                 module->ant.num = (module->rfe_type % 2 ? 2 : 3);
 2531         else
 2532                 module->ant.num = 2;
 2533 
 2534         module->ant.diversity = 0;
 2535         module->ant.isolation = 10;
 2536 
 2537         if (module->ant.num == 3) {
 2538                 module->ant.type = BTC_ANT_DEDICATED;
 2539                 module->bt_pos = BTC_BT_ALONE;
 2540         } else {
 2541                 module->ant.type = BTC_ANT_SHARED;
 2542                 module->bt_pos = BTC_BT_BTG;
 2543         }
 2544 }
 2545 
 2546 static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg)
 2547 {
 2548         if (btg) {
 2549                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
 2550                                        B_PATH0_BT_SHARE_V1, 0x1);
 2551                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
 2552                                        B_PATH0_BTG_PATH_V1, 0x0);
 2553                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
 2554                                        B_PATH1_G_LNA6_OP1DB_V1, 0x20);
 2555                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
 2556                                        B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30);
 2557                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
 2558                                        B_PATH1_BT_SHARE_V1, 0x1);
 2559                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
 2560                                        B_PATH1_BTG_PATH_V1, 0x1);
 2561                 rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0);
 2562                 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x1);
 2563                 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x2);
 2564                 rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
 2565                                        B_BT_DYN_DC_EST_EN_MSK, 0x1);
 2566                 rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
 2567                                        0x1);
 2568         } else {
 2569                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
 2570                                        B_PATH0_BT_SHARE_V1, 0x0);
 2571                 rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
 2572                                        B_PATH0_BTG_PATH_V1, 0x0);
 2573                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
 2574                                        B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
 2575                 rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
 2576                                        B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
 2577                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
 2578                                        B_PATH1_BT_SHARE_V1, 0x0);
 2579                 rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
 2580                                        B_PATH1_BTG_PATH_V1, 0x0);
 2581                 rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf);
 2582                 rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4);
 2583                 rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x0);
 2584                 rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x0);
 2585                 rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
 2586                                        B_BT_DYN_DC_EST_EN_MSK, 0x0);
 2587                 rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
 2588                                        0x0);
 2589         }
 2590 }
 2591 
 2592 static
 2593 void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
 2594 {
 2595         rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000);
 2596         rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group);
 2597         rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val);
 2598         rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0);
 2599 }
 2600 
 2601 static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev)
 2602 {
 2603         struct rtw89_btc *btc = &rtwdev->btc;
 2604         struct rtw89_btc_module *module = &btc->mdinfo;
 2605         const struct rtw89_chip_info *chip = rtwdev->chip;
 2606         const struct rtw89_mac_ax_coex coex_params = {
 2607                 .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE,
 2608                 .direction = RTW89_MAC_AX_COEX_INNER,
 2609         };
 2610 
 2611         /* PTA init  */
 2612         rtw89_mac_coex_init_v1(rtwdev, &coex_params);
 2613 
 2614         /* set WL Tx response = Hi-Pri */
 2615         chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true);
 2616         chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true);
 2617 
 2618         /* set rf gnt debug off */
 2619         rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0);
 2620         rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0);
 2621 
 2622         /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */
 2623         if (module->ant.type == BTC_ANT_SHARED) {
 2624                 rtw8852c_set_trx_mask(rtwdev,
 2625                                       RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff);
 2626                 rtw8852c_set_trx_mask(rtwdev,
 2627                                       RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff);
 2628                 /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
 2629                 rtw8852c_set_trx_mask(rtwdev,
 2630                                       RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
 2631         } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
 2632                 rtw8852c_set_trx_mask(rtwdev,
 2633                                       RF_PATH_A, BTC_BT_SS_GROUP, 0x5df);
 2634                 rtw8852c_set_trx_mask(rtwdev,
 2635                                       RF_PATH_B, BTC_BT_SS_GROUP, 0x5df);
 2636         }
 2637 
 2638         /* set PTA break table */
 2639         rtw89_write32(rtwdev, R_AX_BT_BREAK_TABLE, BTC_BREAK_PARAM);
 2640 
 2641          /* enable BT counter 0xda10[1:0] = 2b'11 */
 2642         rtw89_write32_set(rtwdev,
 2643                           R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN |
 2644                           B_AX_BT_CNT_RST_V1);
 2645         btc->cx.wl.status.map.init_ok = true;
 2646 }
 2647 
 2648 static
 2649 void rtw8852c_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state)
 2650 {
 2651         u32 bitmap = 0;
 2652         u32 reg = 0;
 2653 
 2654         switch (map) {
 2655         case BTC_PRI_MASK_TX_RESP:
 2656                 reg = R_BTC_COEX_WL_REQ;
 2657                 bitmap = B_BTC_RSP_ACK_HI;
 2658                 break;
 2659         case BTC_PRI_MASK_BEACON:
 2660                 reg = R_BTC_COEX_WL_REQ;
 2661                 bitmap = B_BTC_TX_BCN_HI;
 2662                 break;
 2663         default:
 2664                 return;
 2665         }
 2666 
 2667         if (state)
 2668                 rtw89_write32_set(rtwdev, reg, bitmap);
 2669         else
 2670                 rtw89_write32_clr(rtwdev, reg, bitmap);
 2671 }
 2672 
 2673 union rtw8852c_btc_wl_txpwr_ctrl {
 2674         u32 txpwr_val;
 2675         struct {
 2676                 union {
 2677                         u16 ctrl_all_time;
 2678                         struct {
 2679                                 s16 data:9;
 2680                                 u16 rsvd:6;
 2681                                 u16 flag:1;
 2682                         } all_time;
 2683                 };
 2684                 union {
 2685                         u16 ctrl_gnt_bt;
 2686                         struct {
 2687                                 s16 data:9;
 2688                                 u16 rsvd:7;
 2689                         } gnt_bt;
 2690                 };
 2691         };
 2692 } __packed;
 2693 
 2694 static void
 2695 rtw8852c_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
 2696 {
 2697         union rtw8852c_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val };
 2698         s32 val;
 2699 
 2700 #define __write_ctrl(_reg, _msk, _val, _en, _cond)              \
 2701 do {                                                            \
 2702         u32 _wrt = FIELD_PREP(_msk, _val);                      \
 2703         BUILD_BUG_ON((_msk & _en) != 0);                        \
 2704         if (_cond)                                              \
 2705                 _wrt |= _en;                                    \
 2706         else                                                    \
 2707                 _wrt &= ~_en;                                   \
 2708         rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \
 2709                                      _msk | _en, _wrt);         \
 2710 } while (0)
 2711 
 2712         switch (arg.ctrl_all_time) {
 2713         case 0xffff:
 2714                 val = 0;
 2715                 break;
 2716         default:
 2717                 val = arg.all_time.data;
 2718                 break;
 2719         }
 2720 
 2721         __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
 2722                      val, B_AX_FORCE_PWR_BY_RATE_EN,
 2723                      arg.ctrl_all_time != 0xffff);
 2724 
 2725         switch (arg.ctrl_gnt_bt) {
 2726         case 0xffff:
 2727                 val = 0;
 2728                 break;
 2729         default:
 2730                 val = arg.gnt_bt.data;
 2731                 break;
 2732         }
 2733 
 2734         __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val,
 2735                      B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff);
 2736 
 2737 #undef __write_ctrl
 2738 }
 2739 
 2740 static
 2741 s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
 2742 {
 2743         return clamp_t(s8, val, -100, 0) + 100;
 2744 }
 2745 
 2746 static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
 2747         {255, 0, 0, 7}, /* 0 -> original */
 2748         {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
 2749         {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
 2750         {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
 2751         {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
 2752         {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */
 2753         {6, 1, 0, 7},
 2754         {13, 1, 0, 7},
 2755         {13, 1, 0, 7}
 2756 };
 2757 
 2758 static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_dl[] = {
 2759         {255, 0, 0, 7}, /* 0 -> original */
 2760         {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
 2761         {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
 2762         {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
 2763         {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
 2764         {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */
 2765         {255, 1, 0, 7},
 2766         {255, 1, 0, 7},
 2767         {255, 1, 0, 7}
 2768 };
 2769 
 2770 static const u8 rtw89_btc_8852c_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30};
 2771 static const u8 rtw89_btc_8852c_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28};
 2772 
 2773 static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852c_mon_reg[] = {
 2774         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda00),
 2775         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda04),
 2776         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24),
 2777         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30),
 2778         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34),
 2779         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda38),
 2780         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda44),
 2781         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda48),
 2782         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c),
 2783         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200),
 2784         RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220),
 2785         RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
 2786 };
 2787 
 2788 static
 2789 void rtw8852c_btc_bt_aci_imp(struct rtw89_dev *rtwdev)
 2790 {
 2791         struct rtw89_btc *btc = &rtwdev->btc;
 2792         struct rtw89_btc_dm *dm = &btc->dm;
 2793         struct rtw89_btc_bt_info *bt = &btc->cx.bt;
 2794         struct rtw89_btc_bt_link_info *b = &bt->link_info;
 2795 
 2796         /* fix LNA2 = level-5 for BT ACI issue at BTG */
 2797         if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0)
 2798                 dm->trx_para_level = 1;
 2799 }
 2800 
 2801 static
 2802 void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
 2803 {
 2804         /* Feature move to firmware */
 2805 }
 2806 
 2807 static
 2808 void rtw8852c_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
 2809 {
 2810         rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
 2811         rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
 2812         rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x620);
 2813 
 2814         /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */
 2815         if (state)
 2816                 rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0,
 2817                                RFREG_MASK, 0x179c);
 2818         else
 2819                 rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0,
 2820                                RFREG_MASK, 0x208);
 2821 
 2822         rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
 2823 }
 2824 
 2825 static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
 2826                                          struct rtw89_rx_phy_ppdu *phy_ppdu,
 2827                                          struct ieee80211_rx_status *status)
 2828 {
 2829         u8 chan_idx = phy_ppdu->chan_idx;
 2830         enum nl80211_band band;
 2831         u8 ch;
 2832 
 2833         if (chan_idx == 0)
 2834                 return;
 2835 
 2836         rtw8852c_decode_chan_idx(rtwdev, chan_idx, &ch, &band);
 2837         status->freq = ieee80211_channel_to_frequency(ch, band);
 2838         status->band = band;
 2839 }
 2840 
 2841 static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev,
 2842                                 struct rtw89_rx_phy_ppdu *phy_ppdu,
 2843                                 struct ieee80211_rx_status *status)
 2844 {
 2845         u8 path;
 2846         s8 *rx_power = phy_ppdu->rssi;
 2847 
 2848         status->signal = max_t(s8, rx_power[RF_PATH_A], rx_power[RF_PATH_B]);
 2849         for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
 2850                 status->chains |= BIT(path);
 2851                 status->chain_signal[path] = rx_power[path];
 2852         }
 2853         if (phy_ppdu->valid)
 2854                 rtw8852c_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
 2855 }
 2856 
 2857 static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
 2858 {
 2859         int ret;
 2860 
 2861         rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
 2862                          B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
 2863 
 2864         rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
 2865         rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
 2866         rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
 2867 
 2868         rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S0_LDO_VSEL_F_MASK, 0x1);
 2869         rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S1_LDO_VSEL_F_MASK, 0x1);
 2870 
 2871         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL0, 0x7, FULL_BIT_MASK);
 2872         if (ret)
 2873                 return ret;
 2874 
 2875         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x6c, FULL_BIT_MASK);
 2876         if (ret)
 2877                 return ret;
 2878 
 2879         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xc7, FULL_BIT_MASK);
 2880         if (ret)
 2881                 return ret;
 2882 
 2883         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xc7, FULL_BIT_MASK);
 2884         if (ret)
 2885                 return ret;
 2886 
 2887         ret = rtw89_mac_write_xtal_si(rtwdev, XTAL3, 0xd, FULL_BIT_MASK);
 2888         if (ret)
 2889                 return ret;
 2890 
 2891         return 0;
 2892 }
 2893 
 2894 static void rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
 2895 {
 2896         rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
 2897                          B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
 2898 }
 2899 
 2900 static const struct rtw89_chip_ops rtw8852c_chip_ops = {
 2901         .enable_bb_rf           = rtw8852c_mac_enable_bb_rf,
 2902         .disable_bb_rf          = rtw8852c_mac_disable_bb_rf,
 2903         .bb_reset               = rtw8852c_bb_reset,
 2904         .bb_sethw               = rtw8852c_bb_sethw,
 2905         .read_rf                = rtw89_phy_read_rf_v1,
 2906         .write_rf               = rtw89_phy_write_rf_v1,
 2907         .set_channel            = rtw8852c_set_channel,
 2908         .set_channel_help       = rtw8852c_set_channel_help,
 2909         .read_efuse             = rtw8852c_read_efuse,
 2910         .read_phycap            = rtw8852c_read_phycap,
 2911         .fem_setup              = NULL,
 2912         .rfk_init               = rtw8852c_rfk_init,
 2913         .rfk_channel            = rtw8852c_rfk_channel,
 2914         .rfk_band_changed       = rtw8852c_rfk_band_changed,
 2915         .rfk_scan               = rtw8852c_rfk_scan,
 2916         .rfk_track              = rtw8852c_rfk_track,
 2917         .power_trim             = rtw8852c_power_trim,
 2918         .set_txpwr              = rtw8852c_set_txpwr,
 2919         .set_txpwr_ctrl         = rtw8852c_set_txpwr_ctrl,
 2920         .init_txpwr_unit        = rtw8852c_init_txpwr_unit,
 2921         .get_thermal            = rtw8852c_get_thermal,
 2922         .ctrl_btg               = rtw8852c_ctrl_btg,
 2923         .query_ppdu             = rtw8852c_query_ppdu,
 2924         .bb_ctrl_btc_preagc     = rtw8852c_bb_ctrl_btc_preagc,
 2925         .cfg_txrx_path          = rtw8852c_bb_cfg_txrx_path,
 2926         .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset,
 2927         .pwr_on_func            = rtw8852c_pwr_on_func,
 2928         .pwr_off_func           = rtw8852c_pwr_off_func,
 2929         .fill_txdesc            = rtw89_core_fill_txdesc_v1,
 2930         .fill_txdesc_fwcmd      = rtw89_core_fill_txdesc_fwcmd_v1,
 2931         .cfg_ctrl_path          = rtw89_mac_cfg_ctrl_path_v1,
 2932         .mac_cfg_gnt            = rtw89_mac_cfg_gnt_v1,
 2933         .stop_sch_tx            = rtw89_mac_stop_sch_tx_v1,
 2934         .resume_sch_tx          = rtw89_mac_resume_sch_tx_v1,
 2935         .h2c_dctl_sec_cam       = rtw89_fw_h2c_dctl_sec_cam_v1,
 2936 
 2937         .btc_set_rfe            = rtw8852c_btc_set_rfe,
 2938         .btc_init_cfg           = rtw8852c_btc_init_cfg,
 2939         .btc_set_wl_pri         = rtw8852c_btc_set_wl_pri,
 2940         .btc_set_wl_txpwr_ctrl  = rtw8852c_btc_set_wl_txpwr_ctrl,
 2941         .btc_get_bt_rssi        = rtw8852c_btc_get_bt_rssi,
 2942         .btc_bt_aci_imp         = rtw8852c_btc_bt_aci_imp,
 2943         .btc_update_bt_cnt      = rtw8852c_btc_update_bt_cnt,
 2944         .btc_wl_s1_standby      = rtw8852c_btc_wl_s1_standby,
 2945         .btc_set_policy         = rtw89_btc_set_policy_v1,
 2946 };
 2947 
 2948 const struct rtw89_chip_info rtw8852c_chip_info = {
 2949         .chip_id                = RTL8852C,
 2950         .ops                    = &rtw8852c_chip_ops,
 2951         .fw_name                = "rtw89/rtw8852c_fw.bin",
 2952         .fifo_size              = 458752,
 2953         .max_amsdu_limit        = 8000,
 2954         .dis_2g_40m_ul_ofdma    = false,
 2955         .rsvd_ple_ofst          = 0x6f800,
 2956         .hfc_param_ini          = rtw8852c_hfc_param_ini_pcie,
 2957         .dle_mem                = rtw8852c_dle_mem_pcie,
 2958         .rf_base_addr           = {0xe000, 0xf000},
 2959         .pwr_on_seq             = NULL,
 2960         .pwr_off_seq            = NULL,
 2961         .bb_table               = &rtw89_8852c_phy_bb_table,
 2962         .bb_gain_table          = &rtw89_8852c_phy_bb_gain_table,
 2963         .rf_table               = {&rtw89_8852c_phy_radiob_table,
 2964                                    &rtw89_8852c_phy_radioa_table,},
 2965         .nctl_table             = &rtw89_8852c_phy_nctl_table,
 2966         .byr_table              = &rtw89_8852c_byr_table,
 2967         .txpwr_lmt_2g           = &rtw89_8852c_txpwr_lmt_2g,
 2968         .txpwr_lmt_5g           = &rtw89_8852c_txpwr_lmt_5g,
 2969         .txpwr_lmt_6g           = &rtw89_8852c_txpwr_lmt_6g,
 2970         .txpwr_lmt_ru_2g        = &rtw89_8852c_txpwr_lmt_ru_2g,
 2971         .txpwr_lmt_ru_5g        = &rtw89_8852c_txpwr_lmt_ru_5g,
 2972         .txpwr_lmt_ru_6g        = &rtw89_8852c_txpwr_lmt_ru_6g,
 2973         .txpwr_factor_rf        = 2,
 2974         .txpwr_factor_mac       = 1,
 2975         .dig_table              = NULL,
 2976         .tssi_dbw_table         = &rtw89_8852c_tssi_dbw_table,
 2977         .support_chanctx_num    = 1,
 2978         .support_bands          = BIT(NL80211_BAND_2GHZ) |
 2979                                   BIT(NL80211_BAND_5GHZ) |
 2980                                   BIT(NL80211_BAND_6GHZ),
 2981         .support_bw160          = true,
 2982         .hw_sec_hdr             = true,
 2983         .rf_path_num            = 2,
 2984         .tx_nss                 = 2,
 2985         .rx_nss                 = 2,
 2986         .acam_num               = 128,
 2987         .bcam_num               = 20,
 2988         .scam_num               = 128,
 2989         .bacam_num              = 8,
 2990         .bacam_dynamic_num      = 8,
 2991         .bacam_v1               = true,
 2992         .sec_ctrl_efuse_size    = 4,
 2993         .physical_efuse_size    = 1216,
 2994         .logical_efuse_size     = 2048,
 2995         .limit_efuse_size       = 1280,
 2996         .dav_phy_efuse_size     = 96,
 2997         .dav_log_efuse_size     = 16,
 2998         .phycap_addr            = 0x590,
 2999         .phycap_size            = 0x60,
 3000         .para_ver               = 0x05050764,
 3001         .wlcx_desired           = 0x05050000,
 3002         .btcx_desired           = 0x5,
 3003         .scbd                   = 0x1,
 3004         .mailbox                = 0x1,
 3005 
 3006         .fcxbtcrpt_ver          = 4,
 3007         .fcxtdma_ver            = 3,
 3008         .fcxslots_ver           = 1,
 3009         .fcxcysta_ver           = 3,
 3010         .fcxstep_ver            = 3,
 3011         .fcxnullsta_ver         = 2,
 3012         .fcxmreg_ver            = 1,
 3013         .fcxgpiodbg_ver         = 1,
 3014         .fcxbtver_ver           = 1,
 3015         .fcxbtscan_ver          = 1,
 3016         .fcxbtafh_ver           = 1,
 3017         .fcxbtdevinfo_ver       = 1,
 3018 
 3019         .afh_guard_ch           = 6,
 3020         .wl_rssi_thres          = rtw89_btc_8852c_wl_rssi_thres,
 3021         .bt_rssi_thres          = rtw89_btc_8852c_bt_rssi_thres,
 3022         .rssi_tol               = 2,
 3023         .mon_reg_num            = ARRAY_SIZE(rtw89_btc_8852c_mon_reg),
 3024         .mon_reg                = rtw89_btc_8852c_mon_reg,
 3025         .rf_para_ulink_num      = ARRAY_SIZE(rtw89_btc_8852c_rf_ul),
 3026         .rf_para_ulink          = rtw89_btc_8852c_rf_ul,
 3027         .rf_para_dlink_num      = ARRAY_SIZE(rtw89_btc_8852c_rf_dl),
 3028         .rf_para_dlink          = rtw89_btc_8852c_rf_dl,
 3029         .ps_mode_supported      = 0,
 3030         .low_power_hci_modes    = BIT(RTW89_PS_MODE_CLK_GATED) |
 3031                                   BIT(RTW89_PS_MODE_PWR_GATED),
 3032         .h2c_cctl_func_id       = H2C_FUNC_MAC_CCTLINFO_UD_V1,
 3033         .hci_func_en_addr       = R_AX_HCI_FUNC_EN_V1,
 3034         .h2c_desc_size          = sizeof(struct rtw89_rxdesc_short),
 3035         .txwd_body_size         = sizeof(struct rtw89_txwd_body_v1),
 3036         .h2c_ctrl_reg           = R_AX_H2CREG_CTRL_V1,
 3037         .h2c_regs               = rtw8852c_h2c_regs,
 3038         .c2h_ctrl_reg           = R_AX_C2HREG_CTRL_V1,
 3039         .c2h_regs               = rtw8852c_c2h_regs,
 3040         .page_regs              = &rtw8852c_page_regs,
 3041         .dcfo_comp              = &rtw8852c_dcfo_comp,
 3042         .dcfo_comp_sft          = 5,
 3043         .imr_info               = &rtw8852c_imr_info
 3044 };
 3045 EXPORT_SYMBOL(rtw8852c_chip_info);
 3046 
 3047 MODULE_FIRMWARE("rtw89/rtw8852c_fw.bin");
 3048 MODULE_AUTHOR("Realtek Corporation");
 3049 MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
 3050 MODULE_LICENSE("Dual BSD/GPL");

Cache object: 28e74d2ab44f8a5d8cf4353e3bd3b61a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.