cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtw8852c.c (98580B)


      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
     16static 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
     32static 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
     39static 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
     47static 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
     60static 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
     65static 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
     70static 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
     85static const struct rtw89_reg_def rtw8852c_dcfo_comp = {
     86	R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK
     87};
     88
     89static 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
    134static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg);
    135
    136static 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
    251static 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
    313static 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
    321static 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
    355static 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
    365static 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
    390static 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
    415static 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
    460static 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
    480static 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
    508static 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
    528static 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
    554static 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
    563static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
    564{
    565	rtw8852c_thermal_trim(rtwdev);
    566	rtw8852c_pa_bias_trim(rtwdev);
    567}
    568
    569static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
    570				     struct rtw89_channel_params *param,
    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 (param->bandwidth) {
    582	case RTW89_CHANNEL_WIDTH_160:
    583		txsc80 = rtw89_phy_get_txsc(rtwdev, param,
    584					    RTW89_CHANNEL_WIDTH_80);
    585		fallthrough;
    586	case RTW89_CHANNEL_WIDTH_80:
    587		txsc40 = rtw89_phy_get_txsc(rtwdev, param,
    588					    RTW89_CHANNEL_WIDTH_40);
    589		fallthrough;
    590	case RTW89_CHANNEL_WIDTH_40:
    591		txsc20 = rtw89_phy_get_txsc(rtwdev, param,
    592					    RTW89_CHANNEL_WIDTH_20);
    593		break;
    594	default:
    595		break;
    596	}
    597
    598	switch (param->bandwidth) {
    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 (param->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", param->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
    640static 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
    645static 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
    650static 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
    674struct 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
    680static 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
    697static 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
    704struct 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
    711static
    712const 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
    729struct 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
    739static 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
    760static enum rtw89_phy_bb_gain_band
    761rtw8852c_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
    788static 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
    852static
    853const 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
    865static 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
    904static 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
    922static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
    923				     const struct rtw89_channel_params *param,
    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 (param->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 (param->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
    979static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
    980			     const struct rtw89_channel_params *param,
    981			     enum rtw89_phy_idx phy_idx)
    982{
    983	u8 sco;
    984	u16 central_freq = param->center_freq;
    985	u8 central_ch = param->center_chan;
    986	u8 band = param->band_type;
    987	u8 subband = param->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, param, 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, param, 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, param, 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, param->primary_chan, band);
   1099	rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx);
   1100}
   1101
   1102static 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
   1128static 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
   1140static void
   1141rtw8852c_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
   1248static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev,
   1249			      struct rtw89_channel_params *param)
   1250{
   1251	u8 center_chan = param->center_chan;
   1252	u8 bw = param->bandwidth;
   1253
   1254	switch (param->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
   1287static void rtw8852c_set_csi_tone_idx(struct rtw89_dev *rtwdev,
   1288				      struct rtw89_channel_params *param,
   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, param);
   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 - param->center_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
   1308static 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
   1327static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
   1328				      struct rtw89_channel_params *param,
   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, param);
   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 = param->center_freq;
   1346	if (param->bandwidth == RTW89_CHANNEL_WIDTH_160) {
   1347		fc = (spur_freq > fc) ? fc + 40 : fc - 40;
   1348		if ((fc > spur_freq && param->center_chan < param->primary_chan) ||
   1349		    (fc < spur_freq && param->center_chan > param->primary_chan))
   1350			notch2_chk = true;
   1351	}
   1352
   1353	freq_diff = (spur_freq - fc) * 1000000;
   1354	nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, &nbi_frac_idx);
   1355
   1356	if (param->bandwidth == RTW89_CHANNEL_WIDTH_20) {
   1357		s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx);
   1358	} else {
   1359		u16 tone_para = (param->bandwidth == RTW89_CHANNEL_WIDTH_40) ? 128 : 256;
   1360
   1361		s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx);
   1362	}
   1363	nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125);
   1364
   1365	if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
   1366		rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr,
   1367				       nbi->notch2_idx.mask, nbi_tone_idx);
   1368		rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr,
   1369				       nbi->notch2_frac_idx.mask, nbi_frac_tone_idx);
   1370		rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0);
   1371		rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 1);
   1372		rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
   1373	} else {
   1374		rtw89_phy_write32_mask(rtwdev, nbi->notch1_idx.addr,
   1375				       nbi->notch1_idx.mask, nbi_tone_idx);
   1376		rtw89_phy_write32_mask(rtwdev, nbi->notch1_frac_idx.addr,
   1377				       nbi->notch1_frac_idx.mask, nbi_frac_tone_idx);
   1378		rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
   1379		rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 1);
   1380		rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, nbi->notch2_en.mask, 0);
   1381	}
   1382}
   1383
   1384static void rtw8852c_spur_notch(struct rtw89_dev *rtwdev, u32 val,
   1385				enum rtw89_phy_idx phy_idx)
   1386{
   1387	u32 notch;
   1388	u32 notch2;
   1389
   1390	if (phy_idx == RTW89_PHY_0) {
   1391		notch = R_PATH0_NOTCH;
   1392		notch2 = R_PATH0_NOTCH2;
   1393	} else {
   1394		notch = R_PATH1_NOTCH;
   1395		notch2 = R_PATH1_NOTCH2;
   1396	}
   1397
   1398	rtw89_phy_write32_mask(rtwdev, notch,
   1399			       B_PATH0_NOTCH_VAL | B_PATH0_NOTCH_EN, val);
   1400	rtw89_phy_write32_set(rtwdev, notch, B_PATH0_NOTCH_EN);
   1401	rtw89_phy_write32_mask(rtwdev, notch2,
   1402			       B_PATH0_NOTCH2_VAL | B_PATH0_NOTCH2_EN, val);
   1403	rtw89_phy_write32_set(rtwdev, notch2, B_PATH0_NOTCH2_EN);
   1404}
   1405
   1406static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev,
   1407				      struct rtw89_channel_params *param,
   1408				      u8 pri_ch_idx,
   1409				      enum rtw89_phy_idx phy_idx)
   1410{
   1411	rtw8852c_set_csi_tone_idx(rtwdev, param, phy_idx);
   1412
   1413	if (phy_idx == RTW89_PHY_0) {
   1414		if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
   1415		    (pri_ch_idx == RTW89_SC_20_LOWER ||
   1416		     pri_ch_idx == RTW89_SC_20_UP3X)) {
   1417			rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_0);
   1418			if (!rtwdev->dbcc_en)
   1419				rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
   1420		} else if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
   1421			   (pri_ch_idx == RTW89_SC_20_UPPER ||
   1422			    pri_ch_idx == RTW89_SC_20_LOW3X)) {
   1423			rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_0);
   1424			if (!rtwdev->dbcc_en)
   1425				rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
   1426		} else {
   1427			rtw8852c_set_nbi_tone_idx(rtwdev, param, RF_PATH_A);
   1428			if (!rtwdev->dbcc_en)
   1429				rtw8852c_set_nbi_tone_idx(rtwdev, param,
   1430							  RF_PATH_B);
   1431		}
   1432	} else {
   1433		if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
   1434		    (pri_ch_idx == RTW89_SC_20_LOWER ||
   1435		     pri_ch_idx == RTW89_SC_20_UP3X)) {
   1436			rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
   1437		} else if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
   1438			   (pri_ch_idx == RTW89_SC_20_UPPER ||
   1439			    pri_ch_idx == RTW89_SC_20_LOW3X)) {
   1440			rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
   1441		} else {
   1442			rtw8852c_set_nbi_tone_idx(rtwdev, param, RF_PATH_B);
   1443		}
   1444	}
   1445
   1446	if (pri_ch_idx == RTW89_SC_20_UP3X || pri_ch_idx == RTW89_SC_20_LOW3X)
   1447		rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 0, phy_idx);
   1448	else
   1449		rtw89_phy_write32_idx(rtwdev, R_PD_BOOST_EN, B_PD_BOOST_EN, 1, phy_idx);
   1450}
   1451
   1452static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev,
   1453			     struct rtw89_channel_params *param,
   1454			     enum rtw89_phy_idx phy_idx)
   1455{
   1456	u8 pri_ch = param->primary_chan;
   1457	bool mask_5m_low;
   1458	bool mask_5m_en;
   1459
   1460	switch (param->bandwidth) {
   1461	case RTW89_CHANNEL_WIDTH_40:
   1462		mask_5m_en = true;
   1463		mask_5m_low = pri_ch == 2;
   1464		break;
   1465	case RTW89_CHANNEL_WIDTH_80:
   1466		mask_5m_en = ((pri_ch == 3) || (pri_ch == 4));
   1467		mask_5m_low = pri_ch == 4;
   1468		break;
   1469	default:
   1470		mask_5m_en = false;
   1471		mask_5m_low = false;
   1472		break;
   1473	}
   1474
   1475	if (!mask_5m_en) {
   1476		rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x0);
   1477		rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x0);
   1478		rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT,
   1479				      B_ASSIGN_SBD_OPT_EN, 0x0, phy_idx);
   1480	} else {
   1481		if (mask_5m_low) {
   1482			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4);
   1483			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1);
   1484			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x0);
   1485			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x1);
   1486			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4);
   1487			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1);
   1488			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x0);
   1489			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x1);
   1490		} else {
   1491			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_TH, 0x4);
   1492			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_EN, 0x1);
   1493			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB2, 0x1);
   1494			rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET, B_PATH0_5MDET_SB0, 0x0);
   1495			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_TH, 0x4);
   1496			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_EN, 0x1);
   1497			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB2, 0x1);
   1498			rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET, B_PATH1_5MDET_SB0, 0x0);
   1499		}
   1500		rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT, B_ASSIGN_SBD_OPT_EN, 0x1, phy_idx);
   1501	}
   1502}
   1503
   1504static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev,
   1505				  enum rtw89_phy_idx phy_idx)
   1506{
   1507	/*HW SI reset*/
   1508	rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
   1509			       0x7);
   1510	rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
   1511			       0x7);
   1512
   1513	udelay(1);
   1514
   1515	rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
   1516			      phy_idx);
   1517	rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0,
   1518			      phy_idx);
   1519	/*HW SI reset*/
   1520	rtw89_phy_write32_mask(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG,
   1521			       0x0);
   1522	rtw89_phy_write32_mask(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG,
   1523			       0x0);
   1524
   1525	rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
   1526			      phy_idx);
   1527}
   1528
   1529static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev,
   1530				 enum rtw89_phy_idx phy_idx, bool en)
   1531{
   1532	struct rtw89_hal *hal = &rtwdev->hal;
   1533
   1534	if (en) {
   1535		rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
   1536				      B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
   1537		rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
   1538				      B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
   1539		rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
   1540				      phy_idx);
   1541		if (hal->current_band_type == RTW89_BAND_2G)
   1542			rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x0);
   1543		rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
   1544	} else {
   1545		rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x1);
   1546		rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1);
   1547		rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
   1548				      B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
   1549		rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
   1550				      B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
   1551		fsleep(1);
   1552		rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0,
   1553				      phy_idx);
   1554	}
   1555}
   1556
   1557static void rtw8852c_bb_reset(struct rtw89_dev *rtwdev,
   1558			      enum rtw89_phy_idx phy_idx)
   1559{
   1560	rtw8852c_bb_reset_all(rtwdev, phy_idx);
   1561}
   1562
   1563static
   1564void rtw8852c_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
   1565			   u8 tx_path_en, u8 trsw_tx,
   1566			   u8 trsw_rx, u8 trsw, u8 trsw_b)
   1567{
   1568	static const u32 path_cr_bases[] = {0x5868, 0x7868};
   1569	u32 mask_ofst = 16;
   1570	u32 cr;
   1571	u32 val;
   1572
   1573	if (path >= ARRAY_SIZE(path_cr_bases))
   1574		return;
   1575
   1576	cr = path_cr_bases[path];
   1577
   1578	mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2;
   1579	val = FIELD_PREP(B_P0_TRSW_A, trsw) | FIELD_PREP(B_P0_TRSW_B, trsw_b);
   1580
   1581	rtw89_phy_write32_mask(rtwdev, cr, (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, val);
   1582}
   1583
   1584enum rtw8852c_rfe_src {
   1585	PAPE_RFM,
   1586	TRSW_RFM,
   1587	LNAON_RFM,
   1588};
   1589
   1590static
   1591void rtw8852c_bb_gpio_rfm(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
   1592			  enum rtw8852c_rfe_src src, u8 dis_tx_gnt_wl,
   1593			  u8 active_tx_opt, u8 act_bt_en, u8 rfm_output_val)
   1594{
   1595	static const u32 path_cr_bases[] = {0x5894, 0x7894};
   1596	static const u32 masks[] = {0, 8, 16};
   1597	u32 mask, mask_ofst;
   1598	u32 cr;
   1599	u32 val;
   1600
   1601	if (src >= ARRAY_SIZE(masks) || path >= ARRAY_SIZE(path_cr_bases))
   1602		return;
   1603
   1604	mask_ofst = masks[src];
   1605	cr = path_cr_bases[path];
   1606
   1607	val = FIELD_PREP(B_P0_RFM_DIS_WL, dis_tx_gnt_wl) |
   1608	      FIELD_PREP(B_P0_RFM_TX_OPT, active_tx_opt) |
   1609	      FIELD_PREP(B_P0_RFM_BT_EN, act_bt_en) |
   1610	      FIELD_PREP(B_P0_RFM_OUT, rfm_output_val);
   1611	mask = 0xff << mask_ofst;
   1612
   1613	rtw89_phy_write32_mask(rtwdev, cr, mask, val);
   1614}
   1615
   1616static void rtw8852c_bb_gpio_init(struct rtw89_dev *rtwdev)
   1617{
   1618	static const u32 cr_bases[] = {0x5800, 0x7800};
   1619	u32 addr;
   1620	u8 i;
   1621
   1622	for (i = 0; i < ARRAY_SIZE(cr_bases); i++) {
   1623		addr = cr_bases[i];
   1624		rtw89_phy_write32_set(rtwdev, (addr | 0x68), B_P0_TRSW_A);
   1625		rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_X);
   1626		rtw89_phy_write32_clr(rtwdev, (addr | 0x68), B_P0_TRSW_SO_A2);
   1627		rtw89_phy_write32(rtwdev, (addr | 0x80), 0x77777777);
   1628		rtw89_phy_write32(rtwdev, (addr | 0x84), 0x77777777);
   1629	}
   1630
   1631	rtw89_phy_write32(rtwdev, R_RFE_E_A2, 0xffffffff);
   1632	rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, 0);
   1633	rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, 0);
   1634	rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, 0);
   1635
   1636	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 0, 0, 1);
   1637	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 1, 1, 0);
   1638	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 0, 1, 0);
   1639	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 1, 1, 0);
   1640	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 0, 0, 1);
   1641	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 1, 1, 0);
   1642	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 0, 1, 0);
   1643	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 1, 1, 0);
   1644
   1645	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 0, 0, 1);
   1646	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 0, 1, 1, 0);
   1647	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 0, 1, 0);
   1648	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 0, 1, 1, 1, 0);
   1649	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 0, 0, 1);
   1650	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 0, 1, 1, 0);
   1651	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 0, 1, 0);
   1652	rtw8852c_bb_gpio_trsw(rtwdev, RF_PATH_B, 1, 1, 1, 1, 0);
   1653
   1654	rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, PAPE_RFM, 0, 0, 0, 0x0);
   1655	rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, TRSW_RFM, 0, 0, 0, 0x4);
   1656	rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_A, LNAON_RFM, 0, 0, 0, 0x8);
   1657
   1658	rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, PAPE_RFM, 0, 0, 0, 0x0);
   1659	rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, TRSW_RFM, 0, 0, 0, 0x4);
   1660	rtw8852c_bb_gpio_rfm(rtwdev, RF_PATH_B, LNAON_RFM, 0, 0, 0, 0x8);
   1661}
   1662
   1663static void rtw8852c_bb_macid_ctrl_init(struct rtw89_dev *rtwdev,
   1664					enum rtw89_phy_idx phy_idx)
   1665{
   1666	u32 addr;
   1667
   1668	for (addr = R_AX_PWR_MACID_LMT_TABLE0;
   1669	     addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4)
   1670		rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
   1671}
   1672
   1673static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev)
   1674{
   1675	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
   1676
   1677	rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT,
   1678			      B_DBCC_80P80_SEL_EVM_RPT_EN);
   1679	rtw89_phy_write32_set(rtwdev, R_DBCC_80P80_SEL_EVM_RPT2,
   1680			      B_DBCC_80P80_SEL_EVM_RPT2_EN);
   1681
   1682	rtw8852c_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0);
   1683	rtw8852c_bb_gpio_init(rtwdev);
   1684
   1685	/* read these registers after loading BB parameters */
   1686	gain->offset_base[RTW89_PHY_0] =
   1687		rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP, B_RPL_BIAS_COMP_MASK);
   1688	gain->offset_base[RTW89_PHY_1] =
   1689		rtw89_phy_read32_mask(rtwdev, R_RPL_BIAS_COMP1, B_RPL_BIAS_COMP1_MASK);
   1690}
   1691
   1692static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
   1693				    struct rtw89_channel_params *param,
   1694				    enum rtw89_phy_idx phy_idx)
   1695{
   1696	bool cck_en = param->band_type == RTW89_BAND_2G;
   1697	u8 pri_ch_idx = param->pri_ch_idx;
   1698	u32 mask, reg;
   1699	u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0,
   1700			       B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1};
   1701
   1702	if (param->band_type == RTW89_BAND_2G)
   1703		rtw8852c_ctrl_sco_cck(rtwdev, param->center_chan,
   1704				      param->primary_chan, param->bandwidth);
   1705
   1706	rtw8852c_ctrl_ch(rtwdev, param, phy_idx);
   1707	rtw8852c_ctrl_bw(rtwdev, pri_ch_idx, param->bandwidth, phy_idx);
   1708	if (cck_en) {
   1709		rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1);
   1710		rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0);
   1711		rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
   1712				      B_PD_ARBITER_OFF, 0x0, phy_idx);
   1713	} else {
   1714		rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0);
   1715		rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 1);
   1716		rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF,
   1717				      B_PD_ARBITER_OFF, 0x1, phy_idx);
   1718	}
   1719
   1720	rtw8852c_spur_elimination(rtwdev, param, pri_ch_idx, phy_idx);
   1721	rtw8852c_ctrl_btg(rtwdev, param->band_type == RTW89_BAND_2G);
   1722	rtw8852c_5m_mask(rtwdev, param, phy_idx);
   1723
   1724	if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
   1725	    rtwdev->hal.cv != CHIP_CAV) {
   1726		rtw89_phy_write32_idx(rtwdev, R_P80_AT_HIGH_FREQ,
   1727				      B_P80_AT_HIGH_FREQ, 0x0, phy_idx);
   1728		reg = rtw89_mac_reg_by_idx(R_P80_AT_HIGH_FREQ_BB_WRP,
   1729					   phy_idx);
   1730		if (param->primary_chan > param->center_chan) {
   1731			rtw89_phy_write32_mask(rtwdev,
   1732					       R_P80_AT_HIGH_FREQ_RU_ALLOC,
   1733					       ru_alloc_msk[phy_idx], 1);
   1734			rtw89_write32_mask(rtwdev, reg,
   1735					   B_P80_AT_HIGH_FREQ_BB_WRP, 1);
   1736		} else {
   1737			rtw89_phy_write32_mask(rtwdev,
   1738					       R_P80_AT_HIGH_FREQ_RU_ALLOC,
   1739					       ru_alloc_msk[phy_idx], 0);
   1740			rtw89_write32_mask(rtwdev, reg,
   1741					   B_P80_AT_HIGH_FREQ_BB_WRP, 0);
   1742		}
   1743	}
   1744
   1745	if (param->band_type == RTW89_BAND_6G &&
   1746	    param->bandwidth == RTW89_CHANNEL_WIDTH_160)
   1747		rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
   1748				      B_CDD_EVM_CHK_EN, 0, phy_idx);
   1749	else
   1750		rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
   1751				      B_CDD_EVM_CHK_EN, 1, phy_idx);
   1752
   1753	if (!rtwdev->dbcc_en) {
   1754		mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
   1755		rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1);
   1756		rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3);
   1757		mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
   1758		rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1);
   1759		rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3);
   1760	} else {
   1761		if (phy_idx == RTW89_PHY_0) {
   1762			mask = B_P0_TXPW_RSTB_TSSI | B_P0_TXPW_RSTB_MANON;
   1763			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x1);
   1764			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, mask, 0x3);
   1765		} else {
   1766			mask = B_P1_TXPW_RSTB_TSSI | B_P1_TXPW_RSTB_MANON;
   1767			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x1);
   1768			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, mask, 0x3);
   1769		}
   1770	}
   1771
   1772	rtw8852c_bb_reset_all(rtwdev, phy_idx);
   1773}
   1774
   1775static void rtw8852c_set_channel(struct rtw89_dev *rtwdev,
   1776				 struct rtw89_channel_params *params)
   1777{
   1778	rtw8852c_set_channel_mac(rtwdev, params, RTW89_MAC_0);
   1779	rtw8852c_set_channel_bb(rtwdev, params, RTW89_PHY_0);
   1780	rtw8852c_set_channel_rf(rtwdev, params, RTW89_PHY_0);
   1781}
   1782
   1783static void rtw8852c_dfs_en(struct rtw89_dev *rtwdev, bool en)
   1784{
   1785	if (en)
   1786		rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1);
   1787	else
   1788		rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0);
   1789}
   1790
   1791static void rtw8852c_adc_en(struct rtw89_dev *rtwdev, bool en)
   1792{
   1793	if (en)
   1794		rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
   1795				       0x0);
   1796	else
   1797		rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST,
   1798				       0xf);
   1799}
   1800
   1801static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
   1802				      struct rtw89_channel_help_params *p)
   1803{
   1804	u8 phy_idx = RTW89_PHY_0;
   1805
   1806	if (enter) {
   1807		rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL);
   1808		rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
   1809		rtw8852c_dfs_en(rtwdev, false);
   1810		rtw8852c_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0);
   1811		rtw8852c_adc_en(rtwdev, false);
   1812		fsleep(40);
   1813		rtw8852c_bb_reset_en(rtwdev, phy_idx, false);
   1814	} else {
   1815		rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
   1816		rtw8852c_adc_en(rtwdev, true);
   1817		rtw8852c_dfs_en(rtwdev, true);
   1818		rtw8852c_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0);
   1819		rtw8852c_bb_reset_en(rtwdev, phy_idx, true);
   1820		rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en);
   1821	}
   1822}
   1823
   1824static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
   1825{
   1826	struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
   1827
   1828	rtwdev->is_tssi_mode[RF_PATH_A] = false;
   1829	rtwdev->is_tssi_mode[RF_PATH_B] = false;
   1830	memset(mcc_info, 0, sizeof(*mcc_info));
   1831	rtw8852c_lck_init(rtwdev);
   1832
   1833	rtw8852c_rck(rtwdev);
   1834	rtw8852c_dack(rtwdev);
   1835	rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
   1836}
   1837
   1838static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev)
   1839{
   1840	enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
   1841
   1842	rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
   1843	rtw8852c_rx_dck(rtwdev, phy_idx, false);
   1844	rtw8852c_iqk(rtwdev, phy_idx);
   1845	rtw8852c_tssi(rtwdev, phy_idx);
   1846	rtw8852c_dpk(rtwdev, phy_idx);
   1847	rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
   1848}
   1849
   1850static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev)
   1851{
   1852	rtw8852c_tssi_scan(rtwdev, RTW89_PHY_0);
   1853}
   1854
   1855static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, bool start)
   1856{
   1857	rtw8852c_wifi_scan_notify(rtwdev, start, RTW89_PHY_0);
   1858}
   1859
   1860static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
   1861{
   1862	rtw8852c_dpk_track(rtwdev);
   1863	rtw8852c_lck_track(rtwdev);
   1864}
   1865
   1866static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
   1867				     enum rtw89_phy_idx phy_idx, s16 ref)
   1868{
   1869	s8 ofst_int = 0;
   1870	u8 base_cw_0db = 0x27;
   1871	u16 tssi_16dbm_cw = 0x12c;
   1872	s16 pwr_s10_3 = 0;
   1873	s16 rf_pwr_cw = 0;
   1874	u16 bb_pwr_cw = 0;
   1875	u32 pwr_cw = 0;
   1876	u32 tssi_ofst_cw = 0;
   1877
   1878	pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3);
   1879	bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3);
   1880	rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3);
   1881	rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
   1882	pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
   1883
   1884	tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3));
   1885	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
   1886		    "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
   1887		    tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
   1888
   1889	return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0));
   1890}
   1891
   1892static
   1893void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
   1894				     s8 pw_ofst, enum rtw89_mac_idx mac_idx)
   1895{
   1896	s8 pw_ofst_2tx;
   1897	s8 val_1t;
   1898	s8 val_2t;
   1899	u32 reg;
   1900	u8 i;
   1901
   1902	if (pw_ofst < -32 || pw_ofst > 31) {
   1903		rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
   1904		return;
   1905	}
   1906	val_1t = pw_ofst << 2;
   1907	pw_ofst_2tx = max(pw_ofst - 3, -32);
   1908	val_2t = pw_ofst_2tx << 2;
   1909
   1910	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_1tx=0x%x\n", val_1t);
   1911	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_2tx=0x%x\n", val_2t);
   1912
   1913	for (i = 0; i < 4; i++) {
   1914		/* 1TX */
   1915		reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
   1916		rtw89_write32_mask(rtwdev, reg,
   1917				   B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i),
   1918				   val_1t);
   1919		/* 2TX */
   1920		reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
   1921		rtw89_write32_mask(rtwdev, reg,
   1922				   B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i),
   1923				   val_2t);
   1924	}
   1925}
   1926
   1927static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
   1928				   enum rtw89_phy_idx phy_idx)
   1929{
   1930	static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800};
   1931	const u32 mask = 0x7FFFFFF;
   1932	const u8 ofst_ofdm = 0x4;
   1933	const u8 ofst_cck = 0x8;
   1934	s16 ref_ofdm = 0;
   1935	s16 ref_cck = 0;
   1936	u32 val;
   1937	u8 i;
   1938
   1939	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n");
   1940
   1941	rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
   1942				     GENMASK(27, 10), 0x0);
   1943
   1944	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
   1945	val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm);
   1946
   1947	for (i = 0; i < RF_PATH_NUM_8852C; i++)
   1948		rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val,
   1949				      phy_idx);
   1950
   1951	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
   1952	val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck);
   1953
   1954	for (i = 0; i < RF_PATH_NUM_8852C; i++)
   1955		rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val,
   1956				      phy_idx);
   1957}
   1958
   1959static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
   1960				      enum rtw89_phy_idx phy_idx)
   1961{
   1962	u8 ch = rtwdev->hal.current_channel;
   1963	static const u8 rs[] = {
   1964		RTW89_RS_CCK,
   1965		RTW89_RS_OFDM,
   1966		RTW89_RS_MCS,
   1967		RTW89_RS_HEDCM,
   1968	};
   1969	s8 tmp;
   1970	u8 i, j;
   1971	u32 val, shf, addr = R_AX_PWR_BY_RATE;
   1972	struct rtw89_rate_desc cur;
   1973
   1974	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
   1975		    "[TXPWR] set txpwr byrate with ch=%d\n", ch);
   1976
   1977	for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) {
   1978		for (i = 0; i < ARRAY_SIZE(rs); i++) {
   1979			if (cur.nss >= rtw89_rs_nss_max[rs[i]])
   1980				continue;
   1981
   1982			val = 0;
   1983			cur.rs = rs[i];
   1984
   1985			for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) {
   1986				cur.idx = j;
   1987				shf = (j % 4) * 8;
   1988				tmp = rtw89_phy_read_txpwr_byrate(rtwdev, &cur);
   1989				val |= (tmp << shf);
   1990
   1991				if ((j + 1) % 4)
   1992					continue;
   1993
   1994				rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
   1995				val = 0;
   1996				addr += 4;
   1997			}
   1998		}
   1999	}
   2000}
   2001
   2002static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev,
   2003				      enum rtw89_phy_idx phy_idx)
   2004{
   2005	struct rtw89_rate_desc desc = {
   2006		.nss = RTW89_NSS_1,
   2007		.rs = RTW89_RS_OFFSET,
   2008	};
   2009	u32 val = 0;
   2010	s8 v;
   2011
   2012	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n");
   2013
   2014	for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) {
   2015		v = rtw89_phy_read_txpwr_byrate(rtwdev, &desc);
   2016		val |= ((v & 0xf) << (4 * desc.idx));
   2017	}
   2018
   2019	rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL,
   2020				     GENMASK(19, 0), val);
   2021}
   2022
   2023static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
   2024					  u8 tx_shape_idx,
   2025					  enum rtw89_phy_idx phy_idx)
   2026{
   2027#define __DFIR_CFG_MASK 0xffffff
   2028#define __DFIR_CFG_NR 8
   2029#define __DECL_DFIR_VAR(_prefix, _name, _val...) \
   2030	static const u32 _prefix ## _ ## _name[] = {_val}; \
   2031	static_assert(ARRAY_SIZE(_prefix ## _ ## _name) == __DFIR_CFG_NR)
   2032#define __DECL_DFIR_PARAM(_name, _val...) __DECL_DFIR_VAR(param, _name, _val)
   2033#define __DECL_DFIR_ADDR(_name, _val...) __DECL_DFIR_VAR(addr, _name, _val)
   2034
   2035	__DECL_DFIR_PARAM(flat,
   2036			  0x003D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053,
   2037			  0x00F86F9A, 0x00FAEF92, 0x00FE5FCC, 0x00FFDFF5);
   2038	__DECL_DFIR_PARAM(sharp,
   2039			  0x003D83FF, 0x002C636A, 0x0013F204, 0x00008090,
   2040			  0x00F87FB0, 0x00F99F83, 0x00FDBFBA, 0x00003FF5);
   2041	__DECL_DFIR_PARAM(sharp_14,
   2042			  0x003B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E,
   2043			  0x00FD8F92, 0x0002D011, 0x0001C02C, 0x00FFF00A);
   2044	__DECL_DFIR_ADDR(filter,
   2045			 0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0,
   2046			 0x45C4, 0x45C8);
   2047	u8 ch = rtwdev->hal.current_channel;
   2048	const u32 *param;
   2049	int i;
   2050
   2051	if (ch > 14) {
   2052		rtw89_warn(rtwdev,
   2053			   "set tx shape dfir by unknown ch: %d on 2G\n", ch);
   2054		return;
   2055	}
   2056
   2057	if (ch == 14)
   2058		param = param_sharp_14;
   2059	else
   2060		param = tx_shape_idx == 0 ? param_flat : param_sharp;
   2061
   2062	for (i = 0; i < __DFIR_CFG_NR; i++) {
   2063		rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
   2064			    "set tx shape dfir: 0x%x: 0x%x\n", addr_filter[i],
   2065			    param[i]);
   2066		rtw89_phy_write32_idx(rtwdev, addr_filter[i], __DFIR_CFG_MASK,
   2067				      param[i], phy_idx);
   2068	}
   2069
   2070#undef __DECL_DFIR_ADDR
   2071#undef __DECL_DFIR_PARAM
   2072#undef __DECL_DFIR_VAR
   2073#undef __DFIR_CFG_NR
   2074#undef __DFIR_CFG_MASK
   2075}
   2076
   2077static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
   2078				  enum rtw89_phy_idx phy_idx)
   2079{
   2080	u8 band = rtwdev->hal.current_band_type;
   2081	u8 regd = rtw89_regd_get(rtwdev, band);
   2082	u8 tx_shape_cck = rtw89_8852c_tx_shape[band][RTW89_RS_CCK][regd];
   2083	u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd];
   2084
   2085	if (band == RTW89_BAND_2G)
   2086		rtw8852c_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx);
   2087
   2088	rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
   2089					     (enum rtw89_mac_idx)phy_idx,
   2090					     tx_shape_ofdm);
   2091}
   2092
   2093static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev,
   2094				     enum rtw89_phy_idx phy_idx)
   2095{
   2096#define __MAC_TXPWR_LMT_PAGE_SIZE 40
   2097	u8 ch = rtwdev->hal.current_channel;
   2098	u8 bw = rtwdev->hal.current_band_width;
   2099	struct rtw89_txpwr_limit lmt[NTX_NUM_8852C];
   2100	u32 addr, val;
   2101	const s8 *ptr;
   2102	u8 i, j, k;
   2103
   2104	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
   2105		    "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw);
   2106
   2107	for (i = 0; i < NTX_NUM_8852C; i++) {
   2108		rtw89_phy_fill_txpwr_limit(rtwdev, &lmt[i], i);
   2109
   2110		for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) {
   2111			addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i;
   2112			ptr = (s8 *)&lmt[i] + j;
   2113			val = 0;
   2114
   2115			for (k = 0; k < 4; k++)
   2116				val |= (ptr[k] << (8 * k));
   2117
   2118			rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
   2119		}
   2120	}
   2121#undef __MAC_TXPWR_LMT_PAGE_SIZE
   2122}
   2123
   2124static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
   2125					enum rtw89_phy_idx phy_idx)
   2126{
   2127#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
   2128	u8 ch = rtwdev->hal.current_channel;
   2129	u8 bw = rtwdev->hal.current_band_width;
   2130	struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C];
   2131	u32 addr, val;
   2132	const s8 *ptr;
   2133	u8 i, j, k;
   2134
   2135	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
   2136		    "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw);
   2137
   2138	for (i = 0; i < NTX_NUM_8852C; i++) {
   2139		rtw89_phy_fill_txpwr_limit_ru(rtwdev, &lmt_ru[i], i);
   2140
   2141		for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) {
   2142			addr = R_AX_PWR_RU_LMT + j +
   2143			       __MAC_TXPWR_LMT_RU_PAGE_SIZE * i;
   2144			ptr = (s8 *)&lmt_ru[i] + j;
   2145			val = 0;
   2146
   2147			for (k = 0; k < 4; k++)
   2148				val |= (ptr[k] << (8 * k));
   2149
   2150			rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
   2151		}
   2152	}
   2153
   2154#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE
   2155}
   2156
   2157static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev)
   2158{
   2159	rtw8852c_set_txpwr_byrate(rtwdev, RTW89_PHY_0);
   2160	rtw8852c_set_txpwr_offset(rtwdev, RTW89_PHY_0);
   2161	rtw8852c_set_tx_shape(rtwdev, RTW89_PHY_0);
   2162	rtw8852c_set_txpwr_limit(rtwdev, RTW89_PHY_0);
   2163	rtw8852c_set_txpwr_limit_ru(rtwdev, RTW89_PHY_0);
   2164}
   2165
   2166static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev)
   2167{
   2168	rtw8852c_set_txpwr_ref(rtwdev, RTW89_PHY_0);
   2169}
   2170
   2171static void
   2172rtw8852c_init_tssi_ctrl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
   2173{
   2174	static const struct rtw89_reg2_def ctrl_ini[] = {
   2175		{0xD938, 0x00010100},
   2176		{0xD93C, 0x0500D500},
   2177		{0xD940, 0x00000500},
   2178		{0xD944, 0x00000005},
   2179		{0xD94C, 0x00220000},
   2180		{0xD950, 0x00030000},
   2181	};
   2182	u32 addr;
   2183	int i;
   2184
   2185	for (addr = R_AX_TSSI_CTRL_HEAD; addr <= R_AX_TSSI_CTRL_TAIL; addr += 4)
   2186		rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
   2187
   2188	for (i = 0; i < ARRAY_SIZE(ctrl_ini); i++)
   2189		rtw89_mac_txpwr_write32(rtwdev, phy_idx, ctrl_ini[i].addr,
   2190					ctrl_ini[i].data);
   2191
   2192	rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev,
   2193					     (enum rtw89_mac_idx)phy_idx,
   2194					     RTW89_TSSI_BANDEDGE_FLAT);
   2195}
   2196
   2197static int
   2198rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
   2199{
   2200	int ret;
   2201
   2202	ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333);
   2203	if (ret)
   2204		return ret;
   2205
   2206	ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000);
   2207	if (ret)
   2208		return ret;
   2209
   2210	ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff);
   2211	if (ret)
   2212		return ret;
   2213
   2214	rtw8852c_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ?
   2215							      RTW89_MAC_1 :
   2216							      RTW89_MAC_0);
   2217	rtw8852c_init_tssi_ctrl(rtwdev, phy_idx);
   2218
   2219	return 0;
   2220}
   2221
   2222static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
   2223{
   2224	struct rtw89_hal *hal = &rtwdev->hal;
   2225	u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
   2226	u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
   2227
   2228	if (rtwdev->dbcc_en) {
   2229		rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 1);
   2230		rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 2,
   2231				      RTW89_PHY_1);
   2232
   2233		rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0,
   2234				       1);
   2235		rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1,
   2236				       1);
   2237		rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, 2,
   2238				      RTW89_PHY_1);
   2239		rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, 2,
   2240				      RTW89_PHY_1);
   2241
   2242		rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
   2243				       B_RXHT_MCS_LIMIT, 0);
   2244		rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
   2245				       B_RXVHT_MCS_LIMIT, 0);
   2246		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
   2247		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
   2248		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
   2249
   2250		rtw89_phy_write32_idx(rtwdev, R_RXHT_MCS_LIMIT,
   2251				      B_RXHT_MCS_LIMIT, 0, RTW89_PHY_1);
   2252		rtw89_phy_write32_idx(rtwdev, R_RXVHT_MCS_LIMIT,
   2253				      B_RXVHT_MCS_LIMIT, 0, RTW89_PHY_1);
   2254		rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_USER_MAX, 1,
   2255				      RTW89_PHY_1);
   2256		rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0,
   2257				      RTW89_PHY_1);
   2258		rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0,
   2259				      RTW89_PHY_1);
   2260		rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1);
   2261		rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3);
   2262		rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1);
   2263		rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3);
   2264	} else {
   2265		if (rx_path == RF_PATH_A) {
   2266			rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
   2267					       B_ANT_RX_SEG0, 1);
   2268			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
   2269					       B_ANT_RX_1RCCA_SEG0, 1);
   2270			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
   2271					       B_ANT_RX_1RCCA_SEG1, 1);
   2272			rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
   2273					       B_RXHT_MCS_LIMIT, 0);
   2274			rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
   2275					       B_RXVHT_MCS_LIMIT, 0);
   2276			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
   2277					       0);
   2278			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
   2279					       0);
   2280			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
   2281					       rst_mask0, 1);
   2282			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
   2283					       rst_mask0, 3);
   2284		} else if (rx_path == RF_PATH_B) {
   2285			rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
   2286					       B_ANT_RX_SEG0, 2);
   2287			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
   2288					       B_ANT_RX_1RCCA_SEG0, 2);
   2289			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
   2290					       B_ANT_RX_1RCCA_SEG1, 2);
   2291			rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
   2292					       B_RXHT_MCS_LIMIT, 0);
   2293			rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
   2294					       B_RXVHT_MCS_LIMIT, 0);
   2295			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
   2296					       0);
   2297			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
   2298					       0);
   2299			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
   2300					       rst_mask1, 1);
   2301			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
   2302					       rst_mask1, 3);
   2303		} else {
   2304			rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
   2305					       B_ANT_RX_SEG0, 3);
   2306			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
   2307					       B_ANT_RX_1RCCA_SEG0, 3);
   2308			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
   2309					       B_ANT_RX_1RCCA_SEG1, 3);
   2310			rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
   2311					       B_RXHT_MCS_LIMIT, 1);
   2312			rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
   2313					       B_RXVHT_MCS_LIMIT, 1);
   2314			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
   2315					       1);
   2316			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
   2317					       1);
   2318			rtw8852c_ctrl_btg(rtwdev, hal->current_band_type == RTW89_BAND_2G);
   2319			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
   2320					       rst_mask0, 1);
   2321			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
   2322					       rst_mask0, 3);
   2323			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
   2324					       rst_mask1, 1);
   2325			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
   2326					       rst_mask1, 3);
   2327		}
   2328		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
   2329	}
   2330}
   2331
   2332static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
   2333				       enum rtw89_mac_idx mac_idx)
   2334{
   2335	struct rtw89_reg2_def path_com[] = {
   2336		{R_AX_PATH_COM0, AX_PATH_COM0_DFVAL},
   2337		{R_AX_PATH_COM1, AX_PATH_COM1_DFVAL},
   2338		{R_AX_PATH_COM2, AX_PATH_COM2_DFVAL},
   2339		{R_AX_PATH_COM3, AX_PATH_COM3_DFVAL},
   2340		{R_AX_PATH_COM4, AX_PATH_COM4_DFVAL},
   2341		{R_AX_PATH_COM5, AX_PATH_COM5_DFVAL},
   2342		{R_AX_PATH_COM6, AX_PATH_COM6_DFVAL},
   2343		{R_AX_PATH_COM7, AX_PATH_COM7_DFVAL},
   2344		{R_AX_PATH_COM8, AX_PATH_COM8_DFVAL},
   2345		{R_AX_PATH_COM9, AX_PATH_COM9_DFVAL},
   2346		{R_AX_PATH_COM10, AX_PATH_COM10_DFVAL},
   2347		{R_AX_PATH_COM11, AX_PATH_COM11_DFVAL},
   2348	};
   2349	u32 addr;
   2350	u32 reg;
   2351	u8 cr_size = ARRAY_SIZE(path_com);
   2352	u8 i = 0;
   2353
   2354	rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_0);
   2355	rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_1);
   2356
   2357	for (addr = R_AX_MACID_ANT_TABLE;
   2358	     addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) {
   2359		reg = rtw89_mac_reg_by_idx(addr, mac_idx);
   2360		rtw89_write32(rtwdev, reg, 0);
   2361	}
   2362
   2363	if (tx_path == RF_A) {
   2364		path_com[0].data = AX_PATH_COM0_PATHA;
   2365		path_com[1].data = AX_PATH_COM1_PATHA;
   2366		path_com[2].data = AX_PATH_COM2_PATHA;
   2367		path_com[7].data = AX_PATH_COM7_PATHA;
   2368		path_com[8].data = AX_PATH_COM8_PATHA;
   2369	} else if (tx_path == RF_B) {
   2370		path_com[0].data = AX_PATH_COM0_PATHB;
   2371		path_com[1].data = AX_PATH_COM1_PATHB;
   2372		path_com[2].data = AX_PATH_COM2_PATHB;
   2373		path_com[7].data = AX_PATH_COM7_PATHB;
   2374		path_com[8].data = AX_PATH_COM8_PATHB;
   2375	} else if (tx_path == RF_AB) {
   2376		path_com[0].data = AX_PATH_COM0_PATHAB;
   2377		path_com[1].data = AX_PATH_COM1_PATHAB;
   2378		path_com[2].data = AX_PATH_COM2_PATHAB;
   2379		path_com[7].data = AX_PATH_COM7_PATHAB;
   2380		path_com[8].data = AX_PATH_COM8_PATHAB;
   2381	} else {
   2382		rtw89_warn(rtwdev, "[Invalid Tx Path]Tx Path: %d\n", tx_path);
   2383		return;
   2384	}
   2385
   2386	for (i = 0; i < cr_size; i++) {
   2387		rtw89_debug(rtwdev, RTW89_DBG_TSSI, "0x%x = 0x%x\n",
   2388			    path_com[i].addr, path_com[i].data);
   2389		reg = rtw89_mac_reg_by_idx(path_com[i].addr, mac_idx);
   2390		rtw89_write32(rtwdev, reg, path_com[i].data);
   2391	}
   2392}
   2393
   2394static void rtw8852c_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en)
   2395{
   2396	if (bt_en) {
   2397		rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
   2398				       B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x3);
   2399		rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
   2400				       B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x3);
   2401		rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
   2402				       B_PATH0_RXBB_MSK_V1, 0xf);
   2403		rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
   2404				       B_PATH1_RXBB_MSK_V1, 0xf);
   2405		rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
   2406				       B_PATH0_G_LNA6_OP1DB_V1, 0x80);
   2407		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
   2408				       B_PATH1_G_LNA6_OP1DB_V1, 0x80);
   2409		rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
   2410				       B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x80);
   2411		rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
   2412				       B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x80);
   2413		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
   2414				       B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x80);
   2415		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
   2416				       B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x80);
   2417		rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
   2418				       B_PATH0_BT_BACKOFF_V1, 0x780D1E);
   2419		rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
   2420				       B_PATH1_BT_BACKOFF_V1, 0x780D1E);
   2421		rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
   2422				       B_P0_BACKOFF_IBADC_V1, 0x34);
   2423		rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
   2424				       B_P1_BACKOFF_IBADC_V1, 0x34);
   2425	} else {
   2426		rtw89_phy_write32_mask(rtwdev, R_PATH0_FRC_FIR_TYPE_V1,
   2427				       B_PATH0_FRC_FIR_TYPE_MSK_V1, 0x0);
   2428		rtw89_phy_write32_mask(rtwdev, R_PATH1_FRC_FIR_TYPE_V1,
   2429				       B_PATH1_FRC_FIR_TYPE_MSK_V1, 0x0);
   2430		rtw89_phy_write32_mask(rtwdev, R_PATH0_RXBB_V1,
   2431				       B_PATH0_RXBB_MSK_V1, 0x60);
   2432		rtw89_phy_write32_mask(rtwdev, R_PATH1_RXBB_V1,
   2433				       B_PATH1_RXBB_MSK_V1, 0x60);
   2434		rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1,
   2435				       B_PATH0_G_LNA6_OP1DB_V1, 0x1a);
   2436		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
   2437				       B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
   2438		rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1,
   2439				       B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a);
   2440		rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA1_LNA6_OP1DB_V1,
   2441				       B_PATH0_G_TIA1_LNA6_OP1DB_V1, 0x2a);
   2442		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
   2443				       B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
   2444		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA1_LNA6_OP1DB_V1,
   2445				       B_PATH1_G_TIA1_LNA6_OP1DB_V1, 0x2a);
   2446		rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_BACKOFF_V1,
   2447				       B_PATH0_BT_BACKOFF_V1, 0x79E99E);
   2448		rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_BACKOFF_V1,
   2449				       B_PATH1_BT_BACKOFF_V1, 0x79E99E);
   2450		rtw89_phy_write32_mask(rtwdev, R_P0_BACKOFF_IBADC_V1,
   2451				       B_P0_BACKOFF_IBADC_V1, 0x26);
   2452		rtw89_phy_write32_mask(rtwdev, R_P1_BACKOFF_IBADC_V1,
   2453				       B_P1_BACKOFF_IBADC_V1, 0x26);
   2454	}
   2455}
   2456
   2457static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
   2458{
   2459	struct rtw89_hal *hal = &rtwdev->hal;
   2460	u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB;
   2461
   2462	rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB);
   2463
   2464	if (hal->rx_nss == 1) {
   2465		rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
   2466		rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
   2467		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
   2468		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
   2469	} else {
   2470		rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
   2471		rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
   2472		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
   2473		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
   2474	}
   2475
   2476	rtw8852c_ctrl_tx_path_tmac(rtwdev, ntx_path, RTW89_MAC_0);
   2477}
   2478
   2479static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
   2480{
   2481	rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
   2482	rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0);
   2483	rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
   2484
   2485	fsleep(200);
   2486
   2487	return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
   2488}
   2489
   2490static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev)
   2491{
   2492	struct rtw89_btc *btc = &rtwdev->btc;
   2493	struct rtw89_btc_module *module = &btc->mdinfo;
   2494
   2495	module->rfe_type = rtwdev->efuse.rfe_type;
   2496	module->cv = rtwdev->hal.cv;
   2497	module->bt_solo = 0;
   2498	module->switch_type = BTC_SWITCH_INTERNAL;
   2499
   2500	if (module->rfe_type > 0)
   2501		module->ant.num = (module->rfe_type % 2 ? 2 : 3);
   2502	else
   2503		module->ant.num = 2;
   2504
   2505	module->ant.diversity = 0;
   2506	module->ant.isolation = 10;
   2507
   2508	if (module->ant.num == 3) {
   2509		module->ant.type = BTC_ANT_DEDICATED;
   2510		module->bt_pos = BTC_BT_ALONE;
   2511	} else {
   2512		module->ant.type = BTC_ANT_SHARED;
   2513		module->bt_pos = BTC_BT_BTG;
   2514	}
   2515}
   2516
   2517static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg)
   2518{
   2519	if (btg) {
   2520		rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
   2521				       B_PATH0_BT_SHARE_V1, 0x1);
   2522		rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
   2523				       B_PATH0_BTG_PATH_V1, 0x0);
   2524		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
   2525				       B_PATH1_G_LNA6_OP1DB_V1, 0x20);
   2526		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
   2527				       B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30);
   2528		rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
   2529				       B_PATH1_BT_SHARE_V1, 0x1);
   2530		rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
   2531				       B_PATH1_BTG_PATH_V1, 0x1);
   2532		rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0);
   2533		rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x1);
   2534		rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x2);
   2535		rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
   2536				       B_BT_DYN_DC_EST_EN_MSK, 0x1);
   2537		rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
   2538				       0x1);
   2539	} else {
   2540		rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
   2541				       B_PATH0_BT_SHARE_V1, 0x0);
   2542		rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
   2543				       B_PATH0_BTG_PATH_V1, 0x0);
   2544		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
   2545				       B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
   2546		rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
   2547				       B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
   2548		rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
   2549				       B_PATH1_BT_SHARE_V1, 0x0);
   2550		rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
   2551				       B_PATH1_BTG_PATH_V1, 0x0);
   2552		rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf);
   2553		rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4);
   2554		rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_BT_SHARE, 0x0);
   2555		rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_BT_SEG0, 0x0);
   2556		rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN,
   2557				       B_BT_DYN_DC_EST_EN_MSK, 0x0);
   2558		rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
   2559				       0x0);
   2560	}
   2561}
   2562
   2563static
   2564void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
   2565{
   2566	rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000);
   2567	rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group);
   2568	rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val);
   2569	rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0);
   2570}
   2571
   2572static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev)
   2573{
   2574	struct rtw89_btc *btc = &rtwdev->btc;
   2575	struct rtw89_btc_module *module = &btc->mdinfo;
   2576	const struct rtw89_chip_info *chip = rtwdev->chip;
   2577	const struct rtw89_mac_ax_coex coex_params = {
   2578		.pta_mode = RTW89_MAC_AX_COEX_RTK_MODE,
   2579		.direction = RTW89_MAC_AX_COEX_INNER,
   2580	};
   2581
   2582	/* PTA init  */
   2583	rtw89_mac_coex_init_v1(rtwdev, &coex_params);
   2584
   2585	/* set WL Tx response = Hi-Pri */
   2586	chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true);
   2587	chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true);
   2588
   2589	/* set rf gnt debug off */
   2590	rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0);
   2591	rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0);
   2592
   2593	/* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */
   2594	if (module->ant.type == BTC_ANT_SHARED) {
   2595		rtw8852c_set_trx_mask(rtwdev,
   2596				      RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff);
   2597		rtw8852c_set_trx_mask(rtwdev,
   2598				      RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff);
   2599		/* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
   2600		rtw8852c_set_trx_mask(rtwdev,
   2601				      RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
   2602	} else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
   2603		rtw8852c_set_trx_mask(rtwdev,
   2604				      RF_PATH_A, BTC_BT_SS_GROUP, 0x5df);
   2605		rtw8852c_set_trx_mask(rtwdev,
   2606				      RF_PATH_B, BTC_BT_SS_GROUP, 0x5df);
   2607	}
   2608
   2609	/* set PTA break table */
   2610	rtw89_write32(rtwdev, R_AX_BT_BREAK_TABLE, BTC_BREAK_PARAM);
   2611
   2612	 /* enable BT counter 0xda10[1:0] = 2b'11 */
   2613	rtw89_write32_set(rtwdev,
   2614			  R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN |
   2615			  B_AX_BT_CNT_RST_V1);
   2616	btc->cx.wl.status.map.init_ok = true;
   2617}
   2618
   2619static
   2620void rtw8852c_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state)
   2621{
   2622	u32 bitmap = 0;
   2623	u32 reg = 0;
   2624
   2625	switch (map) {
   2626	case BTC_PRI_MASK_TX_RESP:
   2627		reg = R_BTC_COEX_WL_REQ;
   2628		bitmap = B_BTC_RSP_ACK_HI;
   2629		break;
   2630	case BTC_PRI_MASK_BEACON:
   2631		reg = R_BTC_COEX_WL_REQ;
   2632		bitmap = B_BTC_TX_BCN_HI;
   2633		break;
   2634	default:
   2635		return;
   2636	}
   2637
   2638	if (state)
   2639		rtw89_write32_set(rtwdev, reg, bitmap);
   2640	else
   2641		rtw89_write32_clr(rtwdev, reg, bitmap);
   2642}
   2643
   2644union rtw8852c_btc_wl_txpwr_ctrl {
   2645	u32 txpwr_val;
   2646	struct {
   2647		union {
   2648			u16 ctrl_all_time;
   2649			struct {
   2650				s16 data:9;
   2651				u16 rsvd:6;
   2652				u16 flag:1;
   2653			} all_time;
   2654		};
   2655		union {
   2656			u16 ctrl_gnt_bt;
   2657			struct {
   2658				s16 data:9;
   2659				u16 rsvd:7;
   2660			} gnt_bt;
   2661		};
   2662	};
   2663} __packed;
   2664
   2665static void
   2666rtw8852c_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
   2667{
   2668	union rtw8852c_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val };
   2669	s32 val;
   2670
   2671#define __write_ctrl(_reg, _msk, _val, _en, _cond)		\
   2672do {								\
   2673	u32 _wrt = FIELD_PREP(_msk, _val);			\
   2674	BUILD_BUG_ON((_msk & _en) != 0);			\
   2675	if (_cond)						\
   2676		_wrt |= _en;					\
   2677	else							\
   2678		_wrt &= ~_en;					\
   2679	rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg,	\
   2680				     _msk | _en, _wrt);		\
   2681} while (0)
   2682
   2683	switch (arg.ctrl_all_time) {
   2684	case 0xffff:
   2685		val = 0;
   2686		break;
   2687	default:
   2688		val = arg.all_time.data;
   2689		break;
   2690	}
   2691
   2692	__write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
   2693		     val, B_AX_FORCE_PWR_BY_RATE_EN,
   2694		     arg.ctrl_all_time != 0xffff);
   2695
   2696	switch (arg.ctrl_gnt_bt) {
   2697	case 0xffff:
   2698		val = 0;
   2699		break;
   2700	default:
   2701		val = arg.gnt_bt.data;
   2702		break;
   2703	}
   2704
   2705	__write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val,
   2706		     B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff);
   2707
   2708#undef __write_ctrl
   2709}
   2710
   2711static
   2712s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
   2713{
   2714	return clamp_t(s8, val, -100, 0) + 100;
   2715}
   2716
   2717static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = {
   2718	{255, 0, 0, 7}, /* 0 -> original */
   2719	{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
   2720	{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
   2721	{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
   2722	{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
   2723	{255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */
   2724	{6, 1, 0, 7},
   2725	{13, 1, 0, 7},
   2726	{13, 1, 0, 7}
   2727};
   2728
   2729static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_dl[] = {
   2730	{255, 0, 0, 7}, /* 0 -> original */
   2731	{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
   2732	{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
   2733	{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
   2734	{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
   2735	{255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */
   2736	{255, 1, 0, 7},
   2737	{255, 1, 0, 7},
   2738	{255, 1, 0, 7}
   2739};
   2740
   2741static const u8 rtw89_btc_8852c_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30};
   2742static const u8 rtw89_btc_8852c_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28};
   2743
   2744static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852c_mon_reg[] = {
   2745	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda00),
   2746	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda04),
   2747	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24),
   2748	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30),
   2749	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34),
   2750	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda38),
   2751	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda44),
   2752	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda48),
   2753	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c),
   2754	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200),
   2755	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220),
   2756	RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
   2757};
   2758
   2759static
   2760void rtw8852c_btc_bt_aci_imp(struct rtw89_dev *rtwdev)
   2761{
   2762	struct rtw89_btc *btc = &rtwdev->btc;
   2763	struct rtw89_btc_dm *dm = &btc->dm;
   2764	struct rtw89_btc_bt_info *bt = &btc->cx.bt;
   2765	struct rtw89_btc_bt_link_info *b = &bt->link_info;
   2766
   2767	/* fix LNA2 = level-5 for BT ACI issue at BTG */
   2768	if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0)
   2769		dm->trx_para_level = 1;
   2770}
   2771
   2772static
   2773void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
   2774{
   2775	struct rtw89_btc *btc = &rtwdev->btc;
   2776	struct rtw89_btc_cx *cx = &btc->cx;
   2777	u32 val;
   2778
   2779	val = rtw89_read32(rtwdev, R_BTC_BT_CNT_HIGH);
   2780	cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val);
   2781	cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val);
   2782
   2783	val = rtw89_read32(rtwdev, R_BTC_BT_CNT_LOW);
   2784	cx->cnt_bt[BTC_BCNT_LOPRI_TX] = FIELD_GET(B_AX_STATIS_BT_LO_TX_1_MASK, val);
   2785	cx->cnt_bt[BTC_BCNT_LOPRI_RX] = FIELD_GET(B_AX_STATIS_BT_LO_RX_1_MASK, val);
   2786
   2787	/* clock-gate off before reset counter*/
   2788	rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G);
   2789	rtw89_write32_clr(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_RST);
   2790	rtw89_write32_set(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_RST);
   2791	rtw89_write32_clr(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G);
   2792}
   2793
   2794static
   2795void rtw8852c_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
   2796{
   2797	rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
   2798	rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
   2799	rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x620);
   2800
   2801	/* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */
   2802	if (state)
   2803		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0,
   2804			       RFREG_MASK, 0x179c);
   2805	else
   2806		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0,
   2807			       RFREG_MASK, 0x208);
   2808
   2809	rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
   2810}
   2811
   2812static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
   2813					 struct rtw89_rx_phy_ppdu *phy_ppdu,
   2814					 struct ieee80211_rx_status *status)
   2815{
   2816	u8 chan_idx = phy_ppdu->chan_idx;
   2817	enum nl80211_band band;
   2818	u8 ch;
   2819
   2820	if (chan_idx == 0)
   2821		return;
   2822
   2823	rtw8852c_decode_chan_idx(rtwdev, chan_idx, &ch, &band);
   2824	status->freq = ieee80211_channel_to_frequency(ch, band);
   2825	status->band = band;
   2826}
   2827
   2828static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev,
   2829				struct rtw89_rx_phy_ppdu *phy_ppdu,
   2830				struct ieee80211_rx_status *status)
   2831{
   2832	u8 path;
   2833	s8 *rx_power = phy_ppdu->rssi;
   2834
   2835	status->signal = max_t(s8, rx_power[RF_PATH_A], rx_power[RF_PATH_B]);
   2836	for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
   2837		status->chains |= BIT(path);
   2838		status->chain_signal[path] = rx_power[path];
   2839	}
   2840	if (phy_ppdu->valid)
   2841		rtw8852c_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
   2842}
   2843
   2844static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
   2845{
   2846	int ret;
   2847
   2848	rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
   2849			 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
   2850
   2851	rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
   2852	rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
   2853	rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
   2854
   2855	rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S0_LDO_VSEL_F_MASK, 0x1);
   2856	rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S1_LDO_VSEL_F_MASK, 0x1);
   2857
   2858	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL0, 0x7, FULL_BIT_MASK);
   2859	if (ret)
   2860		return ret;
   2861
   2862	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x6c, FULL_BIT_MASK);
   2863	if (ret)
   2864		return ret;
   2865
   2866	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xc7, FULL_BIT_MASK);
   2867	if (ret)
   2868		return ret;
   2869
   2870	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xc7, FULL_BIT_MASK);
   2871	if (ret)
   2872		return ret;
   2873
   2874	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL3, 0xd, FULL_BIT_MASK);
   2875	if (ret)
   2876		return ret;
   2877
   2878	return 0;
   2879}
   2880
   2881static void rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
   2882{
   2883	rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
   2884			 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
   2885}
   2886
   2887static const struct rtw89_chip_ops rtw8852c_chip_ops = {
   2888	.enable_bb_rf		= rtw8852c_mac_enable_bb_rf,
   2889	.disable_bb_rf		= rtw8852c_mac_disable_bb_rf,
   2890	.bb_reset		= rtw8852c_bb_reset,
   2891	.bb_sethw		= rtw8852c_bb_sethw,
   2892	.read_rf		= rtw89_phy_read_rf_v1,
   2893	.write_rf		= rtw89_phy_write_rf_v1,
   2894	.set_channel		= rtw8852c_set_channel,
   2895	.set_channel_help	= rtw8852c_set_channel_help,
   2896	.read_efuse		= rtw8852c_read_efuse,
   2897	.read_phycap		= rtw8852c_read_phycap,
   2898	.fem_setup		= NULL,
   2899	.rfk_init		= rtw8852c_rfk_init,
   2900	.rfk_channel		= rtw8852c_rfk_channel,
   2901	.rfk_band_changed	= rtw8852c_rfk_band_changed,
   2902	.rfk_scan		= rtw8852c_rfk_scan,
   2903	.rfk_track		= rtw8852c_rfk_track,
   2904	.power_trim		= rtw8852c_power_trim,
   2905	.set_txpwr		= rtw8852c_set_txpwr,
   2906	.set_txpwr_ctrl		= rtw8852c_set_txpwr_ctrl,
   2907	.init_txpwr_unit	= rtw8852c_init_txpwr_unit,
   2908	.get_thermal		= rtw8852c_get_thermal,
   2909	.ctrl_btg		= rtw8852c_ctrl_btg,
   2910	.query_ppdu		= rtw8852c_query_ppdu,
   2911	.bb_ctrl_btc_preagc	= rtw8852c_bb_ctrl_btc_preagc,
   2912	.cfg_txrx_path		= rtw8852c_bb_cfg_txrx_path,
   2913	.set_txpwr_ul_tb_offset	= rtw8852c_set_txpwr_ul_tb_offset,
   2914	.pwr_on_func		= rtw8852c_pwr_on_func,
   2915	.pwr_off_func		= rtw8852c_pwr_off_func,
   2916	.fill_txdesc		= rtw89_core_fill_txdesc_v1,
   2917	.fill_txdesc_fwcmd	= rtw89_core_fill_txdesc_fwcmd_v1,
   2918	.cfg_ctrl_path		= rtw89_mac_cfg_ctrl_path_v1,
   2919	.mac_cfg_gnt		= rtw89_mac_cfg_gnt_v1,
   2920	.stop_sch_tx		= rtw89_mac_stop_sch_tx_v1,
   2921	.resume_sch_tx		= rtw89_mac_resume_sch_tx_v1,
   2922	.h2c_dctl_sec_cam	= rtw89_fw_h2c_dctl_sec_cam_v1,
   2923
   2924	.btc_set_rfe		= rtw8852c_btc_set_rfe,
   2925	.btc_init_cfg		= rtw8852c_btc_init_cfg,
   2926	.btc_set_wl_pri		= rtw8852c_btc_set_wl_pri,
   2927	.btc_set_wl_txpwr_ctrl	= rtw8852c_btc_set_wl_txpwr_ctrl,
   2928	.btc_get_bt_rssi	= rtw8852c_btc_get_bt_rssi,
   2929	.btc_bt_aci_imp		= rtw8852c_btc_bt_aci_imp,
   2930	.btc_update_bt_cnt	= rtw8852c_btc_update_bt_cnt,
   2931	.btc_wl_s1_standby	= rtw8852c_btc_wl_s1_standby,
   2932};
   2933
   2934const struct rtw89_chip_info rtw8852c_chip_info = {
   2935	.chip_id		= RTL8852C,
   2936	.ops			= &rtw8852c_chip_ops,
   2937	.fw_name		= "rtw89/rtw8852c_fw.bin",
   2938	.fifo_size		= 458752,
   2939	.max_amsdu_limit	= 8000,
   2940	.dis_2g_40m_ul_ofdma	= false,
   2941	.rsvd_ple_ofst		= 0x6f800,
   2942	.hfc_param_ini		= rtw8852c_hfc_param_ini_pcie,
   2943	.dle_mem		= rtw8852c_dle_mem_pcie,
   2944	.rf_base_addr		= {0xe000, 0xf000},
   2945	.pwr_on_seq		= NULL,
   2946	.pwr_off_seq		= NULL,
   2947	.bb_table		= &rtw89_8852c_phy_bb_table,
   2948	.bb_gain_table		= &rtw89_8852c_phy_bb_gain_table,
   2949	.rf_table		= {&rtw89_8852c_phy_radiob_table,
   2950				   &rtw89_8852c_phy_radioa_table,},
   2951	.nctl_table		= &rtw89_8852c_phy_nctl_table,
   2952	.byr_table		= &rtw89_8852c_byr_table,
   2953	.txpwr_lmt_2g		= &rtw89_8852c_txpwr_lmt_2g,
   2954	.txpwr_lmt_5g		= &rtw89_8852c_txpwr_lmt_5g,
   2955	.txpwr_lmt_6g		= &rtw89_8852c_txpwr_lmt_6g,
   2956	.txpwr_lmt_ru_2g	= &rtw89_8852c_txpwr_lmt_ru_2g,
   2957	.txpwr_lmt_ru_5g	= &rtw89_8852c_txpwr_lmt_ru_5g,
   2958	.txpwr_lmt_ru_6g	= &rtw89_8852c_txpwr_lmt_ru_6g,
   2959	.txpwr_factor_rf	= 2,
   2960	.txpwr_factor_mac	= 1,
   2961	.dig_table		= NULL,
   2962	.tssi_dbw_table		= &rtw89_8852c_tssi_dbw_table,
   2963	.support_bands		= BIT(NL80211_BAND_2GHZ) |
   2964				  BIT(NL80211_BAND_5GHZ) |
   2965				  BIT(NL80211_BAND_6GHZ),
   2966	.support_bw160		= true,
   2967	.hw_sec_hdr		= true,
   2968	.rf_path_num		= 2,
   2969	.tx_nss			= 2,
   2970	.rx_nss			= 2,
   2971	.acam_num		= 128,
   2972	.bcam_num		= 20,
   2973	.scam_num		= 128,
   2974	.sec_ctrl_efuse_size	= 4,
   2975	.physical_efuse_size	= 1216,
   2976	.logical_efuse_size	= 2048,
   2977	.limit_efuse_size	= 1280,
   2978	.dav_phy_efuse_size	= 96,
   2979	.dav_log_efuse_size	= 16,
   2980	.phycap_addr		= 0x590,
   2981	.phycap_size		= 0x60,
   2982	.para_ver		= 0x05050764,
   2983	.wlcx_desired		= 0x05050000,
   2984	.btcx_desired		= 0x5,
   2985	.scbd			= 0x1,
   2986	.mailbox		= 0x1,
   2987	.afh_guard_ch		= 6,
   2988	.wl_rssi_thres		= rtw89_btc_8852c_wl_rssi_thres,
   2989	.bt_rssi_thres		= rtw89_btc_8852c_bt_rssi_thres,
   2990	.rssi_tol		= 2,
   2991	.mon_reg_num		= ARRAY_SIZE(rtw89_btc_8852c_mon_reg),
   2992	.mon_reg		= rtw89_btc_8852c_mon_reg,
   2993	.rf_para_ulink_num	= ARRAY_SIZE(rtw89_btc_8852c_rf_ul),
   2994	.rf_para_ulink		= rtw89_btc_8852c_rf_ul,
   2995	.rf_para_dlink_num	= ARRAY_SIZE(rtw89_btc_8852c_rf_dl),
   2996	.rf_para_dlink		= rtw89_btc_8852c_rf_dl,
   2997	.ps_mode_supported	= 0,
   2998	.low_power_hci_modes	= BIT(RTW89_PS_MODE_CLK_GATED) |
   2999				  BIT(RTW89_PS_MODE_PWR_GATED),
   3000	.h2c_cctl_func_id	= H2C_FUNC_MAC_CCTLINFO_UD_V1,
   3001	.hci_func_en_addr	= R_AX_HCI_FUNC_EN_V1,
   3002	.h2c_desc_size		= sizeof(struct rtw89_rxdesc_short),
   3003	.txwd_body_size		= sizeof(struct rtw89_txwd_body_v1),
   3004	.h2c_ctrl_reg		= R_AX_H2CREG_CTRL_V1,
   3005	.h2c_regs		= rtw8852c_h2c_regs,
   3006	.c2h_ctrl_reg		= R_AX_C2HREG_CTRL_V1,
   3007	.c2h_regs		= rtw8852c_c2h_regs,
   3008	.page_regs		= &rtw8852c_page_regs,
   3009	.dcfo_comp		= &rtw8852c_dcfo_comp,
   3010	.dcfo_comp_sft		= 5,
   3011	.imr_info		= &rtw8852c_imr_info
   3012};
   3013EXPORT_SYMBOL(rtw8852c_chip_info);
   3014
   3015MODULE_FIRMWARE("rtw89/rtw8852c_fw.bin");
   3016MODULE_AUTHOR("Realtek Corporation");
   3017MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
   3018MODULE_LICENSE("Dual BSD/GPL");