File Index
Files and directories
Sign in
FILE

rtw8852c.c

File preview with syntax highlighting.

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