File Index
Files and directories
Sign in
FILE

rtw8922a.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/realtek/rtw89/rtw8922a.c C
   1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
   2/* Copyright(c) 2023  Realtek Corporation
   3 */
   4
   5#include "chan.h"
   6#include "coex.h"
   7#include "debug.h"
   8#include "efuse.h"
   9#include "fw.h"
  10#include "mac.h"
  11#include "phy.h"
  12#include "reg.h"
  13#include "rtw8922a.h"
  14#include "rtw8922a_rfk.h"
  15#include "sar.h"
  16#include "util.h"
  17
  18#define RTW8922A_FW_FORMAT_MAX 4
  19#define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw"
  20#define RTW8922A_MODULE_FIRMWARE \
  21	RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin"
  22
  23#define HE_N_USER_MAX_8922A 4
  24
  25static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_pcie[] = {
  26	{2, 1641, grp_0}, /* ACH 0 */
  27	{2, 1641, grp_0}, /* ACH 1 */
  28	{2, 1641, grp_0}, /* ACH 2 */
  29	{2, 1641, grp_0}, /* ACH 3 */
  30	{2, 1641, grp_1}, /* ACH 4 */
  31	{2, 1641, grp_1}, /* ACH 5 */
  32	{2, 1641, grp_1}, /* ACH 6 */
  33	{2, 1641, grp_1}, /* ACH 7 */
  34	{2, 1641, grp_0}, /* B0MGQ */
  35	{2, 1641, grp_0}, /* B0HIQ */
  36	{2, 1641, grp_1}, /* B1MGQ */
  37	{2, 1641, grp_1}, /* B1HIQ */
  38	{0, 0, 0}, /* FWCMDQ */
  39	{0, 0, 0}, /* BMC */
  40	{0, 0, 0}, /* H2D */
  41};
  42
  43static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_pcie = {
  44	1651, /* Group 0 */
  45	1651, /* Group 1 */
  46	3302, /* Public Max */
  47	0, /* WP threshold */
  48};
  49
  50static const struct rtw89_hfc_param_ini rtw8922a_hfc_param_ini_pcie[] = {
  51	[RTW89_QTA_SCC] = {rtw8922a_hfc_chcfg_pcie, &rtw8922a_hfc_pubcfg_pcie,
  52			   &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH},
  53	[RTW89_QTA_DBCC] = {rtw8922a_hfc_chcfg_pcie, &rtw8922a_hfc_pubcfg_pcie,
  54			   &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH},
  55	[RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2,
  56			    RTW89_HCIFC_POH},
  57	[RTW89_QTA_INVALID] = {NULL},
  58};
  59
  60static const struct rtw89_dle_mem rtw8922a_dle_mem_pcie[] = {
  61	[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0_v1,
  62			   &rtw89_mac_size.ple_size0_v1, &rtw89_mac_size.wde_qt0_v1,
  63			   &rtw89_mac_size.wde_qt0_v1, &rtw89_mac_size.ple_qt0,
  64			   &rtw89_mac_size.ple_qt1, &rtw89_mac_size.ple_rsvd_qt0,
  65			   &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0},
  66	[RTW89_QTA_DBCC] = {RTW89_QTA_DBCC, &rtw89_mac_size.wde_size0_v1,
  67			   &rtw89_mac_size.ple_size0_v1, &rtw89_mac_size.wde_qt0_v1,
  68			   &rtw89_mac_size.wde_qt0_v1, &rtw89_mac_size.ple_qt0,
  69			   &rtw89_mac_size.ple_qt1, &rtw89_mac_size.ple_rsvd_qt0,
  70			   &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0},
  71	[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4_v1,
  72			    &rtw89_mac_size.ple_size3_v1, &rtw89_mac_size.wde_qt4,
  73			    &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt9,
  74			    &rtw89_mac_size.ple_qt9, &rtw89_mac_size.ple_rsvd_qt1,
  75			    &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0},
  76	[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
  77			       NULL},
  78};
  79
  80static const u32 rtw8922a_h2c_regs[RTW89_H2CREG_MAX] = {
  81	R_BE_H2CREG_DATA0, R_BE_H2CREG_DATA1, R_BE_H2CREG_DATA2,
  82	R_BE_H2CREG_DATA3
  83};
  84
  85static const u32 rtw8922a_c2h_regs[RTW89_H2CREG_MAX] = {
  86	R_BE_C2HREG_DATA0, R_BE_C2HREG_DATA1, R_BE_C2HREG_DATA2,
  87	R_BE_C2HREG_DATA3
  88};
  89
  90static const u32 rtw8922a_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
  91	R_AX_C2HREG_DATA3_V1 + 3, R_BE_DBG_WOW,
  92};
  93
  94static const struct rtw89_page_regs rtw8922a_page_regs = {
  95	.hci_fc_ctrl	= R_BE_HCI_FC_CTRL,
  96	.ch_page_ctrl	= R_BE_CH_PAGE_CTRL,
  97	.ach_page_ctrl	= R_BE_CH0_PAGE_CTRL,
  98	.ach_page_info	= R_BE_CH0_PAGE_INFO,
  99	.pub_page_info3	= R_BE_PUB_PAGE_INFO3,
 100	.pub_page_ctrl1	= R_BE_PUB_PAGE_CTRL1,
 101	.pub_page_ctrl2	= R_BE_PUB_PAGE_CTRL2,
 102	.pub_page_info1	= R_BE_PUB_PAGE_INFO1,
 103	.pub_page_info2 = R_BE_PUB_PAGE_INFO2,
 104	.wp_page_ctrl1	= R_BE_WP_PAGE_CTRL1,
 105	.wp_page_ctrl2	= R_BE_WP_PAGE_CTRL2,
 106	.wp_page_info1	= R_BE_WP_PAGE_INFO1,
 107};
 108
 109static const struct rtw89_reg_imr rtw8922a_imr_dmac_regs[] = {
 110	{R_BE_DISP_HOST_IMR, B_BE_DISP_HOST_IMR_CLR, B_BE_DISP_HOST_IMR_SET},
 111	{R_BE_DISP_CPU_IMR, B_BE_DISP_CPU_IMR_CLR, B_BE_DISP_CPU_IMR_SET},
 112	{R_BE_DISP_OTHER_IMR, B_BE_DISP_OTHER_IMR_CLR, B_BE_DISP_OTHER_IMR_SET},
 113	{R_BE_PKTIN_ERR_IMR, B_BE_PKTIN_ERR_IMR_CLR, B_BE_PKTIN_ERR_IMR_SET},
 114	{R_BE_INTERRUPT_MASK_REG, B_BE_INTERRUPT_MASK_REG_CLR, B_BE_INTERRUPT_MASK_REG_SET},
 115	{R_BE_MLO_ERR_IDCT_IMR, B_BE_MLO_ERR_IDCT_IMR_CLR, B_BE_MLO_ERR_IDCT_IMR_SET},
 116	{R_BE_MPDU_TX_ERR_IMR, B_BE_MPDU_TX_ERR_IMR_CLR, B_BE_MPDU_TX_ERR_IMR_SET},
 117	{R_BE_MPDU_RX_ERR_IMR, B_BE_MPDU_RX_ERR_IMR_CLR, B_BE_MPDU_RX_ERR_IMR_SET},
 118	{R_BE_SEC_ERROR_IMR, B_BE_SEC_ERROR_IMR_CLR, B_BE_SEC_ERROR_IMR_SET},
 119	{R_BE_CPUIO_ERR_IMR, B_BE_CPUIO_ERR_IMR_CLR, B_BE_CPUIO_ERR_IMR_SET},
 120	{R_BE_WDE_ERR_IMR, B_BE_WDE_ERR_IMR_CLR, B_BE_WDE_ERR_IMR_SET},
 121	{R_BE_WDE_ERR1_IMR, B_BE_WDE_ERR1_IMR_CLR, B_BE_WDE_ERR1_IMR_SET},
 122	{R_BE_PLE_ERR_IMR, B_BE_PLE_ERR_IMR_CLR, B_BE_PLE_ERR_IMR_SET},
 123	{R_BE_PLE_ERRFLAG1_IMR, B_BE_PLE_ERRFLAG1_IMR_CLR, B_BE_PLE_ERRFLAG1_IMR_SET},
 124	{R_BE_WDRLS_ERR_IMR, B_BE_WDRLS_ERR_IMR_CLR, B_BE_WDRLS_ERR_IMR_SET},
 125	{R_BE_TXPKTCTL_B0_ERRFLAG_IMR, B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR,
 126	 B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET},
 127	{R_BE_TXPKTCTL_B1_ERRFLAG_IMR, B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR,
 128	 B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET},
 129	{R_BE_BBRPT_COM_ERR_IMR, B_BE_BBRPT_COM_ERR_IMR_CLR, B_BE_BBRPT_COM_ERR_IMR_SET},
 130	{R_BE_BBRPT_CHINFO_ERR_IMR, B_BE_BBRPT_CHINFO_ERR_IMR_CLR,
 131	 B_BE_BBRPT_CHINFO_ERR_IMR_SET},
 132	{R_BE_BBRPT_DFS_ERR_IMR, B_BE_BBRPT_DFS_ERR_IMR_CLR, B_BE_BBRPT_DFS_ERR_IMR_SET},
 133	{R_BE_LA_ERRFLAG_IMR, B_BE_LA_ERRFLAG_IMR_CLR, B_BE_LA_ERRFLAG_IMR_SET},
 134	{R_BE_CH_INFO_DBGFLAG_IMR, B_BE_CH_INFO_DBGFLAG_IMR_CLR, B_BE_CH_INFO_DBGFLAG_IMR_SET},
 135	{R_BE_PLRLS_ERR_IMR, B_BE_PLRLS_ERR_IMR_CLR, B_BE_PLRLS_ERR_IMR_SET},
 136	{R_BE_HAXI_IDCT_MSK, B_BE_HAXI_IDCT_MSK_CLR, B_BE_HAXI_IDCT_MSK_SET},
 137};
 138
 139static const struct rtw89_imr_table rtw8922a_imr_dmac_table = {
 140	.regs = rtw8922a_imr_dmac_regs,
 141	.n_regs = ARRAY_SIZE(rtw8922a_imr_dmac_regs),
 142};
 143
 144static const struct rtw89_reg_imr rtw8922a_imr_cmac_regs[] = {
 145	{R_BE_RESP_IMR, B_BE_RESP_IMR_CLR, B_BE_RESP_IMR_SET},
 146	{R_BE_RX_ERROR_FLAG_IMR, B_BE_RX_ERROR_FLAG_IMR_CLR, B_BE_RX_ERROR_FLAG_IMR_SET},
 147	{R_BE_TX_ERROR_FLAG_IMR, B_BE_TX_ERROR_FLAG_IMR_CLR, B_BE_TX_ERROR_FLAG_IMR_SET},
 148	{R_BE_RX_ERROR_FLAG_IMR_1, B_BE_TX_ERROR_FLAG_IMR_1_CLR, B_BE_TX_ERROR_FLAG_IMR_1_SET},
 149	{R_BE_PTCL_IMR1, B_BE_PTCL_IMR1_CLR, B_BE_PTCL_IMR1_SET},
 150	{R_BE_PTCL_IMR0, B_BE_PTCL_IMR0_CLR, B_BE_PTCL_IMR0_SET},
 151	{R_BE_PTCL_IMR_2, B_BE_PTCL_IMR_2_CLR, B_BE_PTCL_IMR_2_SET},
 152	{R_BE_SCHEDULE_ERR_IMR, B_BE_SCHEDULE_ERR_IMR_CLR, B_BE_SCHEDULE_ERR_IMR_SET},
 153	{R_BE_C0_TXPWR_IMR, B_BE_C0_TXPWR_IMR_CLR, B_BE_C0_TXPWR_IMR_SET},
 154	{R_BE_TRXPTCL_ERROR_INDICA_MASK, B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR,
 155	 B_BE_TRXPTCL_ERROR_INDICA_MASK_SET},
 156	{R_BE_RX_ERR_IMR, B_BE_RX_ERR_IMR_CLR, B_BE_RX_ERR_IMR_SET},
 157	{R_BE_PHYINFO_ERR_IMR_V1, B_BE_PHYINFO_ERR_IMR_V1_CLR, B_BE_PHYINFO_ERR_IMR_V1_SET},
 158};
 159
 160static const struct rtw89_imr_table rtw8922a_imr_cmac_table = {
 161	.regs = rtw8922a_imr_cmac_regs,
 162	.n_regs = ARRAY_SIZE(rtw8922a_imr_cmac_regs),
 163};
 164
 165static const struct rtw89_rrsr_cfgs rtw8922a_rrsr_cfgs = {
 166	.ref_rate = {R_BE_TRXPTCL_RESP_1, B_BE_WMAC_RESP_REF_RATE_SEL, 0},
 167	.rsc = {R_BE_PTCL_RRSR1, B_BE_RSC_MASK, 2},
 168};
 169
 170static const struct rtw89_rfkill_regs rtw8922a_rfkill_regs = {
 171	.pinmux = {R_BE_GPIO8_15_FUNC_SEL,
 172		   B_BE_PINMUX_GPIO9_FUNC_SEL_MASK,
 173		   0xf},
 174	.mode = {R_BE_GPIO_EXT_CTRL + 2,
 175		 (B_BE_GPIO_MOD_9 | B_BE_GPIO_IO_SEL_9) >> 16,
 176		 0x0},
 177};
 178
 179static const struct rtw89_dig_regs rtw8922a_dig_regs = {
 180	.seg0_pd_reg = R_SEG0R_PD_V2,
 181	.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
 182	.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1,
 183	.bmode_pd_reg = R_BMODE_PDTH_EN_V2,
 184	.bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
 185	.bmode_pd_lower_bound_reg = R_BMODE_PDTH_V2,
 186	.bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
 187	.p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
 188	.p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
 189	.p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
 190	.p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1},
 191	.p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1},
 192	.p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1},
 193	.p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V3,
 194			      B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
 195	.p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V3,
 196			      B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
 197	.p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V3,
 198			      B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
 199	.p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V3,
 200			      B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
 201};
 202
 203static const struct rtw89_edcca_regs rtw8922a_edcca_regs = {
 204	.edcca_level			= R_SEG0R_EDCCA_LVL_BE,
 205	.edcca_mask			= B_EDCCA_LVL_MSK0,
 206	.edcca_p_mask			= B_EDCCA_LVL_MSK1,
 207	.ppdu_level			= R_SEG0R_PPDU_LVL_BE,
 208	.ppdu_mask			= B_EDCCA_LVL_MSK1,
 209	.p = {{
 210		.rpt_a			= R_EDCCA_RPT_A_BE,
 211		.rpt_b			= R_EDCCA_RPT_B_BE,
 212		.rpt_sel		= R_EDCCA_RPT_SEL_BE,
 213		.rpt_sel_mask		= B_EDCCA_RPT_SEL_MSK,
 214	}, {
 215		.rpt_a			= R_EDCCA_RPT_P1_A_BE,
 216		.rpt_b			= R_EDCCA_RPT_P1_B_BE,
 217		.rpt_sel		= R_EDCCA_RPT_SEL_BE,
 218		.rpt_sel_mask		= B_EDCCA_RPT_SEL_P1_MSK,
 219	}},
 220	.rpt_sel_be			= R_EDCCA_RPTREG_SEL_BE,
 221	.rpt_sel_be_mask		= B_EDCCA_RPTREG_SEL_BE_MSK,
 222	.tx_collision_t2r_st		= R_TX_COLLISION_T2R_ST_BE,
 223	.tx_collision_t2r_st_mask	= B_TX_COLLISION_T2R_ST_BE_M,
 224};
 225
 226static const struct rtw89_efuse_block_cfg rtw8922a_efuse_blocks[] = {
 227	[RTW89_EFUSE_BLOCK_SYS]			= {.offset = 0x00000, .size = 0x310},
 228	[RTW89_EFUSE_BLOCK_RF]			= {.offset = 0x10000, .size = 0x240},
 229	[RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO]	= {.offset = 0x20000, .size = 0x4800},
 230	[RTW89_EFUSE_BLOCK_HCI_DIG_USB]		= {.offset = 0x30000, .size = 0x890},
 231	[RTW89_EFUSE_BLOCK_HCI_PHY_PCIE]	= {.offset = 0x40000, .size = 0x200},
 232	[RTW89_EFUSE_BLOCK_HCI_PHY_USB3]	= {.offset = 0x50000, .size = 0x80},
 233	[RTW89_EFUSE_BLOCK_HCI_PHY_USB2]	= {.offset = 0x60000, .size = 0x0},
 234	[RTW89_EFUSE_BLOCK_ADIE]		= {.offset = 0x70000, .size = 0x10},
 235};
 236
 237static void rtw8922a_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
 238				    enum rtw89_phy_idx phy_idx)
 239{
 240	if (en) {
 241		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_SHARE_A, 0x1, phy_idx);
 242		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BTG_PATH_A, 0x0, phy_idx);
 243		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_SHARE_B, 0x1, phy_idx);
 244		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BTG_PATH_B, 0x1, phy_idx);
 245		rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x20, phy_idx);
 246		rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA0_B, 0x30, phy_idx);
 247		rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0, phy_idx);
 248		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_BT_SHARE, 0x1, phy_idx);
 249		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_BT_SG0, 0x2, phy_idx);
 250		rtw89_phy_write32_idx(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
 251				      0x1, phy_idx);
 252	} else {
 253		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_SHARE_A, 0x0, phy_idx);
 254		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BTG_PATH_A, 0x0, phy_idx);
 255		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_SHARE_B, 0x0, phy_idx);
 256		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BTG_PATH_B, 0x0, phy_idx);
 257		rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x1a, phy_idx);
 258		rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA0_B, 0x2a, phy_idx);
 259		rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc, phy_idx);
 260		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_BT_SHARE, 0x0, phy_idx);
 261		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_BT_SG0, 0x0, phy_idx);
 262		rtw89_phy_write32_idx(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN,
 263				      0x0, phy_idx);
 264	}
 265}
 266
 267static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev)
 268{
 269	struct rtw89_hal *hal = &rtwdev->hal;
 270	u32 val32;
 271	int ret;
 272
 273	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_AFSM_WLSUS_EN |
 274						    B_BE_AFSM_PCIE_SUS_EN);
 275	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_DIS_WLBT_PDNSUSEN_SOPC);
 276	rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_DIS_WLBT_LPSEN_LOPC);
 277	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APDM_HPDN);
 278	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
 279
 280	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_RDY_SYSPWR,
 281				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
 282	if (ret)
 283		return ret;
 284
 285	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
 286	rtw89_write32_set(rtwdev, R_BE_WLRESUME_CTRL, B_BE_LPSROP_CMAC0 |
 287						      B_BE_LPSROP_CMAC1);
 288	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFN_ONMAC);
 289
 290	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFN_ONMAC),
 291				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
 292	if (ret)
 293		return ret;
 294
 295	rtw89_write32_clr(rtwdev, R_BE_AFE_ON_CTRL1, B_BE_REG_CK_MON_CK960M_EN);
 296	rtw89_write8_set(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 |
 297						      B_BE_POW_PC_LDO_PORT1);
 298	rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP |
 299						       B_BE_R_SYM_ISO_ADDA_P12PP);
 300	rtw89_write8_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_PLATFORM_EN);
 301	rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
 302
 303	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HAXIDMA_IO_ST,
 304				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
 305	if (ret)
 306		return ret;
 307
 308	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
 309				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
 310	if (ret)
 311		return ret;
 312
 313	rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
 314
 315	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HCI_WLAN_IO_ST,
 316				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
 317	if (ret)
 318		return ret;
 319
 320	rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN);
 321
 322	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0x02);
 323	if (ret)
 324		return ret;
 325	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x01, 0x01);
 326	if (ret)
 327		return ret;
 328
 329	rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3);
 330
 331	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x40, 0x40);
 332	if (ret)
 333		return ret;
 334
 335	rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3);
 336
 337	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x20, 0x20);
 338	if (ret)
 339		return ret;
 340	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x04, 0x04);
 341	if (ret)
 342		return ret;
 343	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x08, 0x08);
 344	if (ret)
 345		return ret;
 346	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x10);
 347	if (ret)
 348		return ret;
 349	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xEB, 0xFF);
 350	if (ret)
 351		return ret;
 352	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xEB, 0xFF);
 353	if (ret)
 354		return ret;
 355	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x01, 0x01);
 356	if (ret)
 357		return ret;
 358	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x02, 0x02);
 359	if (ret)
 360		return ret;
 361	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x80);
 362	if (ret)
 363		return ret;
 364	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF1, 0, 0x40);
 365	if (ret)
 366		return ret;
 367	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF2, 0, 0x40);
 368	if (ret)
 369		return ret;
 370	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, 0x40, 0x60);
 371	if (ret)
 372		return ret;
 373
 374	if (hal->cv != CHIP_CAV) {
 375		rtw89_write32_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
 376		rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE);
 377		rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B);
 378
 379		mdelay(1);
 380
 381		rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S);
 382		rtw89_write32_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
 383	}
 384
 385	rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN,
 386			  B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN | B_BE_MPDU_PROC_EN |
 387			  B_BE_WD_RLS_EN | B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN |
 388			  B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN | B_BE_PKT_BUF_EN |
 389			  B_BE_DMAC_TBL_EN | B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN |
 390			  B_BE_DISPATCHER_EN | B_BE_BBRPT_EN | B_BE_MAC_SEC_EN |
 391			  B_BE_H_AXIDMA_EN | B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN |
 392			  B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN | B_BE_LTR_CTL_EN);
 393
 394	set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
 395
 396	rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN,
 397			  B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN | B_BE_ADDRSRCH_EN |
 398			  B_BE_BTCOEX_EN);
 399	rtw89_write32_set(rtwdev, R_BE_CMAC_FUNC_EN,
 400			  B_BE_CMAC_EN | B_BE_CMAC_TXEN |  B_BE_CMAC_RXEN |
 401			  B_BE_SIGB_EN | B_BE_PHYINTF_EN | B_BE_CMAC_DMA_EN |
 402			  B_BE_PTCLTOP_EN | B_BE_SCHEDULER_EN | B_BE_TMAC_EN |
 403			  B_BE_RMAC_EN | B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN);
 404
 405	set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
 406
 407	rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
 408						       B_BE_FEN_BBPLAT_RSTB);
 409
 410	return 0;
 411}
 412
 413static int rtw8922a_pwr_off_func(struct rtw89_dev *rtwdev)
 414{
 415	u32 val32;
 416	int ret;
 417
 418	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x10, 0x10);
 419	if (ret)
 420		return ret;
 421	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x08);
 422	if (ret)
 423		return ret;
 424	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x04);
 425	if (ret)
 426		return ret;
 427	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC6, 0xFF);
 428	if (ret)
 429		return ret;
 430	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC6, 0xFF);
 431	if (ret)
 432		return ret;
 433	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x80, 0x80);
 434	if (ret)
 435		return ret;
 436	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x02);
 437	if (ret)
 438		return ret;
 439	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x01);
 440	if (ret)
 441		return ret;
 442	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0xFF);
 443	if (ret)
 444		return ret;
 445	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x00, 0xFF);
 446	if (ret)
 447		return ret;
 448
 449	rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP |
 450						       B_BE_R_SYM_ISO_ADDA_P12PP);
 451	rtw89_write8_clr(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 |
 452						      B_BE_POW_PC_LDO_PORT1);
 453	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
 454	rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
 455						      B_BE_FEN_BBPLAT_RSTB);
 456	rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3);
 457
 458	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x20);
 459	if (ret)
 460		return ret;
 461
 462	rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3);
 463
 464	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x40);
 465	if (ret)
 466		return ret;
 467
 468	rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
 469
 470	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_IO_ST),
 471				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
 472	if (ret)
 473		return ret;
 474
 475	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
 476				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
 477	if (ret)
 478		return ret;
 479
 480	rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
 481
 482	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HCI_WLAN_IO_ST),
 483				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
 484	if (ret)
 485		return ret;
 486
 487	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC);
 488
 489	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFM_OFFMAC),
 490				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
 491	if (ret)
 492		return ret;
 493
 494	rtw89_write32(rtwdev, R_BE_WLLPS_CTRL, 0x0000A1B2);
 495	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_XTAL_OFF_A_DIE);
 496	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
 497	rtw89_write32(rtwdev, R_BE_UDM1, 0);
 498
 499	return 0;
 500}
 501
 502static void rtw8922a_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
 503					struct rtw8922a_efuse *map)
 504{
 505	struct rtw8922a_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
 506	u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b};
 507	struct rtw89_tssi_info *tssi = &rtwdev->tssi;
 508	u8 i, j;
 509
 510	tssi->thermal[RF_PATH_A] = map->path_a_therm;
 511	tssi->thermal[RF_PATH_B] = map->path_b_therm;
 512
 513	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
 514		memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
 515		       sizeof(ofst[i]->cck_tssi));
 516
 517		for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
 518			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
 519				    "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
 520				    i, j, tssi->tssi_cck[i][j]);
 521
 522		memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
 523		       sizeof(ofst[i]->bw40_tssi));
 524		memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
 525		       ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
 526		memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i],
 527		       sizeof(tssi->tssi_6g_mcs[i]));
 528
 529		for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
 530			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
 531				    "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
 532				    i, j, tssi->tssi_mcs[i][j]);
 533	}
 534}
 535
 536static void rtw8922a_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
 537					       struct rtw8922a_efuse *map)
 538{
 539	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
 540	bool all_0xff = true, all_0x00 = true;
 541	int i, j;
 542	u8 t;
 543
 544	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK] = map->rx_gain_a._2g_cck;
 545	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK] = map->rx_gain_b._2g_cck;
 546	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM] = map->rx_gain_a._2g_ofdm;
 547	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM] = map->rx_gain_b._2g_ofdm;
 548	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW] = map->rx_gain_a._5g_low;
 549	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW] = map->rx_gain_b._5g_low;
 550	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID] = map->rx_gain_a._5g_mid;
 551	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID] = map->rx_gain_b._5g_mid;
 552	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH] = map->rx_gain_a._5g_high;
 553	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH] = map->rx_gain_b._5g_high;
 554	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L0] = map->rx_gain_6g_a._6g_l0;
 555	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L0] = map->rx_gain_6g_b._6g_l0;
 556	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L1] = map->rx_gain_6g_a._6g_l1;
 557	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L1] = map->rx_gain_6g_b._6g_l1;
 558	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M0] = map->rx_gain_6g_a._6g_m0;
 559	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M0] = map->rx_gain_6g_b._6g_m0;
 560	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M1] = map->rx_gain_6g_a._6g_m1;
 561	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M1] = map->rx_gain_6g_b._6g_m1;
 562	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H0] = map->rx_gain_6g_a._6g_h0;
 563	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H0] = map->rx_gain_6g_b._6g_h0;
 564	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H1] = map->rx_gain_6g_a._6g_h1;
 565	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H1] = map->rx_gain_6g_b._6g_h1;
 566	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH0] = map->rx_gain_6g_a._6g_uh0;
 567	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH0] = map->rx_gain_6g_b._6g_uh0;
 568	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH1] = map->rx_gain_6g_a._6g_uh1;
 569	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH1] = map->rx_gain_6g_b._6g_uh1;
 570
 571	for (i = RF_PATH_A; i <= RF_PATH_B; i++)
 572		for (j = 0; j < RTW89_GAIN_OFFSET_NR; j++) {
 573			t = gain->offset[i][j];
 574			if (t != 0xff)
 575				all_0xff = false;
 576			if (t != 0x0)
 577				all_0x00 = false;
 578
 579			/* transform: sign-bit + U(7,2) to S(8,2) */
 580			if (t & 0x80)
 581				gain->offset[i][j] = (t ^ 0x7f) + 1;
 582		}
 583
 584	gain->offset_valid = !all_0xff && !all_0x00;
 585}
 586
 587static void rtw8922a_read_efuse_mac_addr(struct rtw89_dev *rtwdev, u32 addr)
 588{
 589	struct rtw89_efuse *efuse = &rtwdev->efuse;
 590	u16 val;
 591	int i;
 592
 593	for (i = 0; i < ETH_ALEN; i += 2, addr += 2) {
 594		val = rtw89_read16(rtwdev, addr);
 595		efuse->addr[i] = val & 0xff;
 596		efuse->addr[i + 1] = val >> 8;
 597	}
 598}
 599
 600static int rtw8922a_read_efuse_pci_sdio(struct rtw89_dev *rtwdev, u8 *log_map)
 601{
 602	struct rtw89_efuse *efuse = &rtwdev->efuse;
 603
 604	if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
 605		rtw8922a_read_efuse_mac_addr(rtwdev, 0x3104);
 606	else
 607		ether_addr_copy(efuse->addr, log_map + 0x001A);
 608
 609	return 0;
 610}
 611
 612static int rtw8922a_read_efuse_usb(struct rtw89_dev *rtwdev, u8 *log_map)
 613{
 614	rtw8922a_read_efuse_mac_addr(rtwdev, 0x4078);
 615
 616	return 0;
 617}
 618
 619static int rtw8922a_read_efuse_rf(struct rtw89_dev *rtwdev, u8 *log_map)
 620{
 621	struct rtw8922a_efuse *map = (struct rtw8922a_efuse *)log_map;
 622	struct rtw89_efuse *efuse = &rtwdev->efuse;
 623
 624	efuse->rfe_type = map->rfe_type;
 625	efuse->xtal_cap = map->xtal_k;
 626	efuse->country_code[0] = map->country_code[0];
 627	efuse->country_code[1] = map->country_code[1];
 628	rtw8922a_efuse_parsing_tssi(rtwdev, map);
 629	rtw8922a_efuse_parsing_gain_offset(rtwdev, map);
 630
 631	rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
 632
 633	return 0;
 634}
 635
 636static int rtw8922a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
 637			       enum rtw89_efuse_block block)
 638{
 639	struct rtw89_efuse *efuse = &rtwdev->efuse;
 640	int ret;
 641
 642	switch (block) {
 643	case RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO:
 644		ret = rtw8922a_read_efuse_pci_sdio(rtwdev, log_map);
 645		break;
 646	case RTW89_EFUSE_BLOCK_HCI_DIG_USB:
 647		ret = rtw8922a_read_efuse_usb(rtwdev, log_map);
 648		break;
 649	case RTW89_EFUSE_BLOCK_RF:
 650		ret = rtw8922a_read_efuse_rf(rtwdev, log_map);
 651		break;
 652	default:
 653		ret = 0;
 654		break;
 655	}
 656
 657	if (!ret && is_zero_ether_addr(efuse->addr)) {
 658		rtw89_info(rtwdev, "efuse mac address is zero, using random mac\n");
 659		eth_random_addr(efuse->addr);
 660	}
 661
 662	return ret;
 663}
 664
 665#define THM_TRIM_POSITIVE_MASK BIT(6)
 666#define THM_TRIM_MAGNITUDE_MASK GENMASK(5, 0)
 667
 668static void rtw8922a_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
 669						 u8 *phycap_map)
 670{
 671	static const u32 thm_trim_addr[RF_PATH_NUM_8922A] = {0x1706, 0x1733};
 672	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
 673	u32 addr = rtwdev->chip->phycap_addr;
 674	bool pg = true;
 675	u8 pg_th;
 676	s8 val;
 677	u8 i;
 678
 679	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
 680		pg_th = phycap_map[thm_trim_addr[i] - addr];
 681		if (pg_th == 0xff) {
 682			info->thermal_trim[i] = 0;
 683			pg = false;
 684			break;
 685		}
 686
 687		val = u8_get_bits(pg_th, THM_TRIM_MAGNITUDE_MASK);
 688
 689		if (!(pg_th & THM_TRIM_POSITIVE_MASK))
 690			val *= -1;
 691
 692		info->thermal_trim[i] = val;
 693
 694		rtw89_debug(rtwdev, RTW89_DBG_RFK,
 695			    "[THERMAL][TRIM] path=%d thermal_trim=0x%x (%d)\n",
 696			    i, pg_th, val);
 697	}
 698
 699	info->pg_thermal_trim = pg;
 700}
 701
 702static void rtw8922a_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
 703						 u8 *phycap_map)
 704{
 705	static const u32 pabias_trim_addr[RF_PATH_NUM_8922A] = {0x1707, 0x1734};
 706	static const u32 check_pa_pad_trim_addr = 0x1700;
 707	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
 708	u32 addr = rtwdev->chip->phycap_addr;
 709	u8 val;
 710	u8 i;
 711
 712	val = phycap_map[check_pa_pad_trim_addr - addr];
 713	if (val != 0xff)
 714		info->pg_pa_bias_trim = true;
 715
 716	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
 717		info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
 718
 719		rtw89_debug(rtwdev, RTW89_DBG_RFK,
 720			    "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
 721			    i, info->pa_bias_trim[i]);
 722	}
 723}
 724
 725static void rtw8922a_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_8922A; 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_V1, pabias_2g);
 747		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA_V1, pabias_5g);
 748	}
 749}
 750
 751static void rtw8922a_phycap_parsing_pad_bias_trim(struct rtw89_dev *rtwdev,
 752						  u8 *phycap_map)
 753{
 754	static const u32 pad_bias_trim_addr[RF_PATH_NUM_8922A] = {0x1708, 0x1735};
 755	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
 756	u32 addr = rtwdev->chip->phycap_addr;
 757	u8 i;
 758
 759	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
 760		info->pad_bias_trim[i] = phycap_map[pad_bias_trim_addr[i] - addr];
 761
 762		rtw89_debug(rtwdev, RTW89_DBG_RFK,
 763			    "[PAD_BIAS][TRIM] path=%d pad_bias_trim=0x%x\n",
 764			    i, info->pad_bias_trim[i]);
 765	}
 766}
 767
 768static void rtw8922a_pad_bias_trim(struct rtw89_dev *rtwdev)
 769{
 770	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
 771	u8 pad_bias_2g, pad_bias_5g;
 772	u8 i;
 773
 774	if (!info->pg_pa_bias_trim) {
 775		rtw89_debug(rtwdev, RTW89_DBG_RFK,
 776			    "[PAD_BIAS][TRIM] no PG, do nothing\n");
 777		return;
 778	}
 779
 780	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
 781		pad_bias_2g = u8_get_bits(info->pad_bias_trim[i], GENMASK(3, 0));
 782		pad_bias_5g = u8_get_bits(info->pad_bias_trim[i], GENMASK(7, 4));
 783
 784		rtw89_debug(rtwdev, RTW89_DBG_RFK,
 785			    "[PAD_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
 786			    i, pad_bias_2g, pad_bias_5g);
 787
 788		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXG_V1, pad_bias_2g);
 789		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXA_V1, pad_bias_5g);
 790	}
 791}
 792
 793static int rtw8922a_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
 794{
 795	rtw8922a_phycap_parsing_thermal_trim(rtwdev, phycap_map);
 796	rtw8922a_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
 797	rtw8922a_phycap_parsing_pad_bias_trim(rtwdev, phycap_map);
 798
 799	return 0;
 800}
 801
 802static void rtw8922a_power_trim(struct rtw89_dev *rtwdev)
 803{
 804	rtw8922a_pa_bias_trim(rtwdev);
 805	rtw8922a_pad_bias_trim(rtwdev);
 806}
 807
 808static void rtw8922a_set_channel_mac(struct rtw89_dev *rtwdev,
 809				     const struct rtw89_chan *chan,
 810				     u8 mac_idx)
 811{
 812	u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_BE_TX_SUB_BAND_VALUE, mac_idx);
 813	u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_BE_TXRATE_CHK, mac_idx);
 814	u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_RFMOD, mac_idx);
 815	u8 txsb20 = 0, txsb40 = 0, txsb80 = 0;
 816	u8 rf_mod_val, chk_rate_mask;
 817	u32 txsb;
 818	u32 reg;
 819
 820	switch (chan->band_width) {
 821	case RTW89_CHANNEL_WIDTH_160:
 822		txsb80 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_80);
 823		fallthrough;
 824	case RTW89_CHANNEL_WIDTH_80:
 825		txsb40 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_40);
 826		fallthrough;
 827	case RTW89_CHANNEL_WIDTH_40:
 828		txsb20 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_20);
 829		break;
 830	default:
 831		break;
 832	}
 833
 834	switch (chan->band_width) {
 835	case RTW89_CHANNEL_WIDTH_160:
 836		rf_mod_val = BE_WMAC_RFMOD_160M;
 837		txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) |
 838		       u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK) |
 839		       u32_encode_bits(txsb80, B_BE_TXSB_80M_MASK);
 840		break;
 841	case RTW89_CHANNEL_WIDTH_80:
 842		rf_mod_val = BE_WMAC_RFMOD_80M;
 843		txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) |
 844		       u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK);
 845		break;
 846	case RTW89_CHANNEL_WIDTH_40:
 847		rf_mod_val = BE_WMAC_RFMOD_40M;
 848		txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK);
 849		break;
 850	case RTW89_CHANNEL_WIDTH_20:
 851	default:
 852		rf_mod_val = BE_WMAC_RFMOD_20M;
 853		txsb = 0;
 854		break;
 855	}
 856
 857	if (txsb20 <= BE_PRI20_BITMAP_MAX)
 858		txsb |= u32_encode_bits(BIT(txsb20), B_BE_PRI20_BITMAP_MASK);
 859
 860	rtw89_write8_mask(rtwdev, rf_mod, B_BE_WMAC_RFMOD_MASK, rf_mod_val);
 861	rtw89_write32(rtwdev, sub_carr, txsb);
 862
 863	switch (chan->band_type) {
 864	case RTW89_BAND_2G:
 865		chk_rate_mask = B_BE_BAND_MODE;
 866		break;
 867	case RTW89_BAND_5G:
 868	case RTW89_BAND_6G:
 869		chk_rate_mask = B_BE_CHECK_CCK_EN | B_BE_RTS_LIMIT_IN_OFDM6;
 870		break;
 871	default:
 872		rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type);
 873		return;
 874	}
 875
 876	rtw89_write8_clr(rtwdev, chk_rate, B_BE_BAND_MODE | B_BE_CHECK_CCK_EN |
 877					   B_BE_RTS_LIMIT_IN_OFDM6);
 878	rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask);
 879
 880	switch (chan->band_width) {
 881	case RTW89_CHANNEL_WIDTH_320:
 882	case RTW89_CHANNEL_WIDTH_160:
 883	case RTW89_CHANNEL_WIDTH_80:
 884	case RTW89_CHANNEL_WIDTH_40:
 885		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PREBKF_CFG_1, mac_idx);
 886		rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_T1_MASK, 0x41);
 887		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx);
 888		rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_MASK, 0x41);
 889		break;
 890	default:
 891		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PREBKF_CFG_1, mac_idx);
 892		rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_T1_MASK, 0x3f);
 893		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx);
 894		rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_MASK, 0x3e);
 895		break;
 896	}
 897}
 898
 899static const u32 rtw8922a_sco_barker_threshold[14] = {
 900	0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6,
 901	0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a
 902};
 903
 904static const u32 rtw8922a_sco_cck_threshold[14] = {
 905	0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db,
 906	0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e
 907};
 908
 909static int rtw8922a_ctrl_sco_cck(struct rtw89_dev *rtwdev,
 910				 u8 primary_ch, enum rtw89_bandwidth bw,
 911				 enum rtw89_phy_idx phy_idx)
 912{
 913	u8 ch_element;
 914
 915	if (primary_ch >= 14)
 916		return -EINVAL;
 917
 918	ch_element = primary_ch - 1;
 919
 920	rtw89_phy_write32_idx(rtwdev, R_BK_FC0INV, B_BK_FC0INV,
 921			      rtw8922a_sco_barker_threshold[ch_element],
 922			      phy_idx);
 923	rtw89_phy_write32_idx(rtwdev, R_CCK_FC0INV, B_CCK_FC0INV,
 924			      rtw8922a_sco_cck_threshold[ch_element],
 925			      phy_idx);
 926
 927	return 0;
 928}
 929
 930struct rtw8922a_bb_gain {
 931	u32 gain_g[BB_PATH_NUM_8922A];
 932	u32 gain_a[BB_PATH_NUM_8922A];
 933	u32 gain_g_mask;
 934	u32 gain_a_mask;
 935};
 936
 937static const struct rtw89_reg_def rpl_comp_bw160[RTW89_BW20_SC_160M] = {
 938	{ .addr = 0x41E8, .mask = 0xFF00},
 939	{ .addr = 0x41E8, .mask = 0xFF0000},
 940	{ .addr = 0x41E8, .mask = 0xFF000000},
 941	{ .addr = 0x41EC, .mask = 0xFF},
 942	{ .addr = 0x41EC, .mask = 0xFF00},
 943	{ .addr = 0x41EC, .mask = 0xFF0000},
 944	{ .addr = 0x41EC, .mask = 0xFF000000},
 945	{ .addr = 0x41F0, .mask = 0xFF}
 946};
 947
 948static const struct rtw89_reg_def rpl_comp_bw80[RTW89_BW20_SC_80M] = {
 949	{ .addr = 0x41F4, .mask = 0xFF},
 950	{ .addr = 0x41F4, .mask = 0xFF00},
 951	{ .addr = 0x41F4, .mask = 0xFF0000},
 952	{ .addr = 0x41F4, .mask = 0xFF000000}
 953};
 954
 955static const struct rtw89_reg_def rpl_comp_bw40[RTW89_BW20_SC_40M] = {
 956	{ .addr = 0x41F0, .mask = 0xFF0000},
 957	{ .addr = 0x41F0, .mask = 0xFF000000}
 958};
 959
 960static const struct rtw89_reg_def rpl_comp_bw20[RTW89_BW20_SC_20M] = {
 961	{ .addr = 0x41F0, .mask = 0xFF00}
 962};
 963
 964static const struct rtw8922a_bb_gain bb_gain_lna[LNA_GAIN_NUM] = {
 965	{ .gain_g = {0x409c, 0x449c}, .gain_a = {0x406C, 0x446C},
 966	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
 967	{ .gain_g = {0x409c, 0x449c}, .gain_a = {0x406C, 0x446C},
 968	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000},
 969	{ .gain_g = {0x40a0, 0x44a0}, .gain_a = {0x4070, 0x4470},
 970	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
 971	{ .gain_g = {0x40a0, 0x44a0}, .gain_a = {0x4070, 0x4470},
 972	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000},
 973	{ .gain_g = {0x40a4, 0x44a4}, .gain_a = {0x4074, 0x4474},
 974	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
 975	{ .gain_g = {0x40a4, 0x44a4}, .gain_a = {0x4074, 0x4474},
 976	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000},
 977	{ .gain_g = {0x40a8, 0x44a8}, .gain_a = {0x4078, 0x4478},
 978	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
 979};
 980
 981static const struct rtw8922a_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
 982	{ .gain_g = {0x4054, 0x4454}, .gain_a = {0x4054, 0x4454},
 983	  .gain_g_mask = 0x7FC0000, .gain_a_mask = 0x1FF},
 984	{ .gain_g = {0x4058, 0x4458}, .gain_a = {0x4054, 0x4454},
 985	  .gain_g_mask = 0x1FF, .gain_a_mask = 0x3FE00 },
 986};
 987
 988static const struct rtw8922a_bb_gain bb_op1db_lna[LNA_GAIN_NUM] = {
 989	{ .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x4078, 0x4478},
 990	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
 991	{ .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
 992	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
 993	{ .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
 994	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
 995	{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
 996	  .gain_g_mask = 0xFF, .gain_a_mask = 0xFF0000},
 997	{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
 998	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
 999	{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
1000	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
1001	{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
1002	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
1003};
1004
1005static const struct rtw8922a_bb_gain bb_op1db_tia_lna[TIA_LNA_OP1DB_NUM] = {
1006	{ .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4080, 0x4480},
1007	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
1008	{ .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4084, 0x4484},
1009	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
1010	{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
1011	  .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
1012	{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
1013	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
1014	{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
1015	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
1016	{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4088, 0x4488},
1017	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
1018	{ .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
1019	  .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
1020	{ .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
1021	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
1022};
1023
1024struct rtw8922a_bb_gain_bypass {
1025	u32 gain_g[BB_PATH_NUM_8922A];
1026	u32 gain_a[BB_PATH_NUM_8922A];
1027	u32 gain_mask_g;
1028	u32 gain_mask_a;
1029};
1030
1031static void rtw8922a_set_rpl_gain(struct rtw89_dev *rtwdev,
1032				  const struct rtw89_chan *chan,
1033				  enum rtw89_rf_path path,
1034				  enum rtw89_phy_idx phy_idx)
1035{
1036	const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
1037	u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type);
1038	u32 reg_path_ofst = 0;
1039	u32 mask;
1040	s32 val;
1041	u32 reg;
1042	int i;
1043
1044	if (path == RF_PATH_B)
1045		reg_path_ofst = 0x400;
1046
1047	for (i = 0; i < RTW89_BW20_SC_160M; i++) {
1048		reg = rpl_comp_bw160[i].addr | reg_path_ofst;
1049		mask = rpl_comp_bw160[i].mask;
1050		val = gain->rpl_ofst_160[gain_band][path][i];
1051		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1052	}
1053
1054	for (i = 0; i < RTW89_BW20_SC_80M; i++) {
1055		reg = rpl_comp_bw80[i].addr | reg_path_ofst;
1056		mask = rpl_comp_bw80[i].mask;
1057		val = gain->rpl_ofst_80[gain_band][path][i];
1058		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1059	}
1060
1061	for (i = 0; i < RTW89_BW20_SC_40M; i++) {
1062		reg = rpl_comp_bw40[i].addr | reg_path_ofst;
1063		mask = rpl_comp_bw40[i].mask;
1064		val = gain->rpl_ofst_40[gain_band][path][i];
1065		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1066	}
1067
1068	for (i = 0; i < RTW89_BW20_SC_20M; i++) {
1069		reg = rpl_comp_bw20[i].addr | reg_path_ofst;
1070		mask = rpl_comp_bw20[i].mask;
1071		val = gain->rpl_ofst_20[gain_band][path][i];
1072		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1073	}
1074}
1075
1076static void rtw8922a_set_lna_tia_gain(struct rtw89_dev *rtwdev,
1077				      const struct rtw89_chan *chan,
1078				      enum rtw89_rf_path path,
1079				      enum rtw89_phy_idx phy_idx)
1080{
1081	const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
1082	u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type);
1083	enum rtw89_phy_bb_bw_be bw_type;
1084	s32 val;
1085	u32 reg;
1086	u32 mask;
1087	int i;
1088
1089	bw_type = chan->band_width <= RTW89_CHANNEL_WIDTH_40 ?
1090		  RTW89_BB_BW_20_40 : RTW89_BB_BW_80_160_320;
1091
1092	for (i = 0; i < LNA_GAIN_NUM; i++) {
1093		if (chan->band_type == RTW89_BAND_2G) {
1094			reg = bb_gain_lna[i].gain_g[path];
1095			mask = bb_gain_lna[i].gain_g_mask;
1096		} else {
1097			reg = bb_gain_lna[i].gain_a[path];
1098			mask = bb_gain_lna[i].gain_a_mask;
1099		}
1100		val = gain->lna_gain[gain_band][bw_type][path][i];
1101		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1102	}
1103
1104	for (i = 0; i < TIA_GAIN_NUM; i++) {
1105		if (chan->band_type == RTW89_BAND_2G) {
1106			reg = bb_gain_tia[i].gain_g[path];
1107			mask = bb_gain_tia[i].gain_g_mask;
1108		} else {
1109			reg = bb_gain_tia[i].gain_a[path];
1110			mask = bb_gain_tia[i].gain_a_mask;
1111		}
1112		val = gain->tia_gain[gain_band][bw_type][path][i];
1113		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1114	}
1115
1116	for (i = 0; i < LNA_GAIN_NUM; i++) {
1117		if (chan->band_type == RTW89_BAND_2G) {
1118			reg = bb_op1db_lna[i].gain_g[path];
1119			mask = bb_op1db_lna[i].gain_g_mask;
1120		} else {
1121			reg = bb_op1db_lna[i].gain_a[path];
1122			mask = bb_op1db_lna[i].gain_a_mask;
1123		}
1124		val = gain->lna_op1db[gain_band][bw_type][path][i];
1125		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1126	}
1127
1128	for (i = 0; i < TIA_LNA_OP1DB_NUM; i++) {
1129		if (chan->band_type == RTW89_BAND_2G) {
1130			reg = bb_op1db_tia_lna[i].gain_g[path];
1131			mask = bb_op1db_tia_lna[i].gain_g_mask;
1132		} else {
1133			reg = bb_op1db_tia_lna[i].gain_a[path];
1134			mask = bb_op1db_tia_lna[i].gain_a_mask;
1135		}
1136		val = gain->tia_lna_op1db[gain_band][bw_type][path][i];
1137		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1138	}
1139}
1140
1141static void rtw8922a_set_gain(struct rtw89_dev *rtwdev,
1142			      const struct rtw89_chan *chan,
1143			      enum rtw89_rf_path path,
1144			      enum rtw89_phy_idx phy_idx)
1145{
1146	rtw8922a_set_lna_tia_gain(rtwdev, chan, path, phy_idx);
1147	rtw8922a_set_rpl_gain(rtwdev, chan, path, phy_idx);
1148}
1149
1150static void rtw8922a_set_rx_gain_normal_cck(struct rtw89_dev *rtwdev,
1151					    const struct rtw89_chan *chan,
1152					    enum rtw89_rf_path path)
1153{
1154	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1155	s8 value = -gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK]; /* S(8,2) */
1156	u8 fraction = value & 0x3;
1157
1158	if (fraction) {
1159		rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW20,
1160				       (0x4 - fraction) << 1);
1161		rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW40,
1162				       (0x4 - fraction) << 1);
1163
1164		value >>= 2;
1165		rtw89_phy_write32_mask(rtwdev, R_CCK_RPL_OFST, B_CCK_RPL_OFST,
1166				       value + 1 + 0xdc);
1167	} else {
1168		rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW20, 0);
1169		rtw89_phy_write32_mask(rtwdev, R_MGAIN_BIAS, B_MGAIN_BIAS_BW40, 0);
1170
1171		value >>= 2;
1172		rtw89_phy_write32_mask(rtwdev, R_CCK_RPL_OFST, B_CCK_RPL_OFST,
1173				       value + 0xdc);
1174	}
1175}
1176
1177static void rtw8922a_set_rx_gain_normal_ofdm(struct rtw89_dev *rtwdev,
1178					     const struct rtw89_chan *chan,
1179					     enum rtw89_rf_path path)
1180{
1181	static const u32 rssi_tb_bias_comp[2] = {0x41f8, 0x45f8};
1182	static const u32 rssi_tb_ext_comp[2] = {0x4208, 0x4608};
1183	static const u32 rssi_ofst_addr[2] = {0x40c8, 0x44c8};
1184	static const u32 rpl_bias_comp[2] = {0x41e8, 0x45e8};
1185	static const u32 rpl_ext_comp[2] = {0x41f8, 0x45f8};
1186	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1187	enum rtw89_gain_offset gain_band;
1188	s8 v1, v2, v3;
1189	s32 value;
1190
1191	gain_band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type);
1192	value = gain->offset[path][gain_band];
1193	rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[path], 0xff000000, value + 0xF8);
1194
1195	value *= -4;
1196	v1 = clamp_t(s32, value, S8_MIN, S8_MAX);
1197	value -= v1;
1198	v2 = clamp_t(s32, value, S8_MIN, S8_MAX);
1199	value -= v2;
1200	v3 = clamp_t(s32, value, S8_MIN, S8_MAX);
1201
1202	rtw89_phy_write32_mask(rtwdev, rpl_bias_comp[path], 0xff, v1);
1203	rtw89_phy_write32_mask(rtwdev, rpl_ext_comp[path], 0xff, v2);
1204	rtw89_phy_write32_mask(rtwdev, rpl_ext_comp[path], 0xff00, v3);
1205
1206	rtw89_phy_write32_mask(rtwdev, rssi_tb_bias_comp[path], 0xff0000, v1);
1207	rtw89_phy_write32_mask(rtwdev, rssi_tb_ext_comp[path], 0xff0000, v2);
1208	rtw89_phy_write32_mask(rtwdev, rssi_tb_ext_comp[path], 0xff000000, v3);
1209}
1210
1211static void rtw8922a_set_rx_gain_normal(struct rtw89_dev *rtwdev,
1212					const struct rtw89_chan *chan,
1213					enum rtw89_rf_path path)
1214{
1215	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1216
1217	if (!gain->offset_valid)
1218		return;
1219
1220	if (chan->band_type == RTW89_BAND_2G)
1221		rtw8922a_set_rx_gain_normal_cck(rtwdev, chan, path);
1222
1223	rtw8922a_set_rx_gain_normal_ofdm(rtwdev, chan, path);
1224}
1225
1226static void rtw8922a_set_cck_parameters(struct rtw89_dev *rtwdev, u8 central_ch,
1227					enum rtw89_phy_idx phy_idx)
1228{
1229	if (central_ch == 14) {
1230		rtw89_phy_write32_idx(rtwdev, R_PCOEFF01, B_PCOEFF01, 0x3b13ff, phy_idx);
1231		rtw89_phy_write32_idx(rtwdev, R_PCOEFF23, B_PCOEFF23, 0x1c42de, phy_idx);
1232		rtw89_phy_write32_idx(rtwdev, R_PCOEFF45, B_PCOEFF45, 0xfdb0ad, phy_idx);
1233		rtw89_phy_write32_idx(rtwdev, R_PCOEFF67, B_PCOEFF67, 0xf60f6e, phy_idx);
1234		rtw89_phy_write32_idx(rtwdev, R_PCOEFF89, B_PCOEFF89, 0xfd8f92, phy_idx);
1235		rtw89_phy_write32_idx(rtwdev, R_PCOEFFAB, B_PCOEFFAB, 0x02d011, phy_idx);
1236		rtw89_phy_write32_idx(rtwdev, R_PCOEFFCD, B_PCOEFFCD, 0x01c02c, phy_idx);
1237		rtw89_phy_write32_idx(rtwdev, R_PCOEFFEF, B_PCOEFFEF, 0xfff00a, phy_idx);
1238	} else {
1239		rtw89_phy_write32_idx(rtwdev, R_PCOEFF01, B_PCOEFF01, 0x3a63ca, phy_idx);
1240		rtw89_phy_write32_idx(rtwdev, R_PCOEFF23, B_PCOEFF23, 0x2a833f, phy_idx);
1241		rtw89_phy_write32_idx(rtwdev, R_PCOEFF45, B_PCOEFF45, 0x1491f8, phy_idx);
1242		rtw89_phy_write32_idx(rtwdev, R_PCOEFF67, B_PCOEFF67, 0x03c0b0, phy_idx);
1243		rtw89_phy_write32_idx(rtwdev, R_PCOEFF89, B_PCOEFF89, 0xfccff1, phy_idx);
1244		rtw89_phy_write32_idx(rtwdev, R_PCOEFFAB, B_PCOEFFAB, 0xfccfc3, phy_idx);
1245		rtw89_phy_write32_idx(rtwdev, R_PCOEFFCD, B_PCOEFFCD, 0xfebfdc, phy_idx);
1246		rtw89_phy_write32_idx(rtwdev, R_PCOEFFEF, B_PCOEFFEF, 0xffdff7, phy_idx);
1247	}
1248}
1249
1250static void rtw8922a_ctrl_ch(struct rtw89_dev *rtwdev,
1251			     const struct rtw89_chan *chan,
1252			     enum rtw89_phy_idx phy_idx)
1253{
1254	static const u32 band_sel[2] = {0x4160, 0x4560};
1255	u16 central_freq = chan->freq;
1256	u8 central_ch = chan->channel;
1257	u8 band = chan->band_type;
1258	bool is_2g = band == RTW89_BAND_2G;
1259	u8 chan_idx;
1260	u8 path;
1261	u8 sco;
1262
1263	if (!central_freq) {
1264		rtw89_warn(rtwdev, "Invalid central_freq\n");
1265		return;
1266	}
1267
1268	rtw8922a_set_gain(rtwdev, chan, RF_PATH_A, phy_idx);
1269	rtw8922a_set_gain(rtwdev, chan, RF_PATH_B, phy_idx);
1270
1271	for (path = RF_PATH_A; path < BB_PATH_NUM_8922A; path++)
1272		rtw89_phy_write32_idx(rtwdev, band_sel[path], BIT((26)), is_2g, phy_idx);
1273
1274	rtw8922a_set_rx_gain_normal(rtwdev, chan, RF_PATH_A);
1275	rtw8922a_set_rx_gain_normal(rtwdev, chan, RF_PATH_B);
1276
1277	rtw89_phy_write32_idx(rtwdev, R_FC0, B_FC0, central_freq, phy_idx);
1278	sco = DIV_ROUND_CLOSEST(1 << 18, central_freq);
1279	rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_FC0_INV, sco, phy_idx);
1280
1281	if (band == RTW89_BAND_2G)
1282		rtw8922a_set_cck_parameters(rtwdev, central_ch, phy_idx);
1283
1284	chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band);
1285	rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx);
1286}
1287
1288static void
1289rtw8922a_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_sb, u8 bw,
1290		 enum rtw89_phy_idx phy_idx)
1291{
1292	switch (bw) {
1293	case RTW89_CHANNEL_WIDTH_5:
1294		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x0, phy_idx);
1295		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x1, phy_idx);
1296		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, 0x0, phy_idx);
1297		rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx);
1298		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx);
1299		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx);
1300		break;
1301	case RTW89_CHANNEL_WIDTH_10:
1302		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x0, phy_idx);
1303		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x2, phy_idx);
1304		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, 0x0, phy_idx);
1305		rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx);
1306		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx);
1307		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx);
1308		break;
1309	case RTW89_CHANNEL_WIDTH_20:
1310		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x0, phy_idx);
1311		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx);
1312		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, 0x0, phy_idx);
1313		rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx);
1314		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx);
1315		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx);
1316		break;
1317	case RTW89_CHANNEL_WIDTH_40:
1318		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x1, phy_idx);
1319		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx);
1320		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, pri_sb, phy_idx);
1321		rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx);
1322		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x0, phy_idx);
1323		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x0, phy_idx);
1324		break;
1325	case RTW89_CHANNEL_WIDTH_80:
1326		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x2, phy_idx);
1327		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx);
1328		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, pri_sb, phy_idx);
1329		rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx);
1330		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x1, phy_idx);
1331		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x1, phy_idx);
1332		break;
1333	case RTW89_CHANNEL_WIDTH_160:
1334		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_BW, 0x3, phy_idx);
1335		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_SMALLBW, 0x0, phy_idx);
1336		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_CHBW_PRICH, pri_sb, phy_idx);
1337		rtw89_phy_write32_idx(rtwdev, R_DAC_CLK, B_DAC_CLK, 0x1, phy_idx);
1338		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP0, B_GAIN_MAP0_EN, 0x1, phy_idx);
1339		rtw89_phy_write32_idx(rtwdev, R_GAIN_MAP1, B_GAIN_MAP1_EN, 0x1, phy_idx);
1340		break;
1341	default:
1342		rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri_sb:%d)\n", bw,
1343			   pri_sb);
1344		break;
1345	}
1346
1347	if (bw == RTW89_CHANNEL_WIDTH_40)
1348		rtw89_phy_write32_idx(rtwdev, R_FC0, B_BW40_2XFFT, 1, phy_idx);
1349	else
1350		rtw89_phy_write32_idx(rtwdev, R_FC0, B_BW40_2XFFT, 0, phy_idx);
1351}
1352
1353static u32 rtw8922a_spur_freq(struct rtw89_dev *rtwdev,
1354			      const struct rtw89_chan *chan)
1355{
1356	return 0;
1357}
1358
1359#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */
1360#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */
1361#define MAX_TONE_NUM 2048
1362
1363static void rtw8922a_set_csi_tone_idx(struct rtw89_dev *rtwdev,
1364				      const struct rtw89_chan *chan,
1365				      enum rtw89_phy_idx phy_idx)
1366{
1367	s32 freq_diff, csi_idx, csi_tone_idx;
1368	u32 spur_freq;
1369
1370	spur_freq = rtw8922a_spur_freq(rtwdev, chan);
1371	if (spur_freq == 0) {
1372		rtw89_phy_write32_idx(rtwdev, R_S0S1_CSI_WGT, B_S0S1_CSI_WGT_EN,
1373				      0, phy_idx);
1374		return;
1375	}
1376
1377	freq_diff = (spur_freq - chan->freq) * 1000000;
1378	csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125);
1379	s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx);
1380
1381	rtw89_phy_write32_idx(rtwdev, R_S0S1_CSI_WGT, B_S0S1_CSI_WGT_TONE_IDX,
1382			      csi_tone_idx, phy_idx);
1383	rtw89_phy_write32_idx(rtwdev, R_S0S1_CSI_WGT, B_S0S1_CSI_WGT_EN, 1, phy_idx);
1384}
1385
1386static const struct rtw89_nbi_reg_def rtw8922a_nbi_reg_def[] = {
1387	[RF_PATH_A] = {
1388		.notch1_idx = {0x41a0, 0xFF},
1389		.notch1_frac_idx = {0x41a0, 0xC00},
1390		.notch1_en = {0x41a0, 0x1000},
1391		.notch2_idx = {0x41ac, 0xFF},
1392		.notch2_frac_idx = {0x41ac, 0xC00},
1393		.notch2_en = {0x41ac, 0x1000},
1394	},
1395	[RF_PATH_B] = {
1396		.notch1_idx = {0x45a0, 0xFF},
1397		.notch1_frac_idx = {0x45a0, 0xC00},
1398		.notch1_en = {0x45a0, 0x1000},
1399		.notch2_idx = {0x45ac, 0xFF},
1400		.notch2_frac_idx = {0x45ac, 0xC00},
1401		.notch2_en = {0x45ac, 0x1000},
1402	},
1403};
1404
1405static void rtw8922a_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
1406				      const struct rtw89_chan *chan,
1407				      enum rtw89_rf_path path,
1408				      enum rtw89_phy_idx phy_idx)
1409{
1410	const struct rtw89_nbi_reg_def *nbi = &rtw8922a_nbi_reg_def[path];
1411	s32 nbi_frac_idx, nbi_frac_tone_idx;
1412	s32 nbi_idx, nbi_tone_idx;
1413	bool notch2_chk = false;
1414	u32 spur_freq, fc;
1415	s32 freq_diff;
1416
1417	spur_freq = rtw8922a_spur_freq(rtwdev, chan);
1418	if (spur_freq == 0) {
1419		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1420				      nbi->notch1_en.mask, 0, phy_idx);
1421		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1422				      nbi->notch2_en.mask, 0, phy_idx);
1423		return;
1424	}
1425
1426	fc = chan->freq;
1427	if (chan->band_width == RTW89_CHANNEL_WIDTH_160) {
1428		fc = (spur_freq > fc) ? fc + 40 : fc - 40;
1429		if ((fc > spur_freq &&
1430		     chan->channel < chan->primary_channel) ||
1431		    (fc < spur_freq &&
1432		     chan->channel > chan->primary_channel))
1433			notch2_chk = true;
1434	}
1435
1436	freq_diff = (spur_freq - fc) * 1000000;
1437	nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5,
1438					 &nbi_frac_idx);
1439
1440	if (chan->band_width == RTW89_CHANNEL_WIDTH_20) {
1441		s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx);
1442	} else {
1443		u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ?
1444				128 : 256;
1445
1446		s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx);
1447	}
1448	nbi_frac_tone_idx =
1449		s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125);
1450
1451	if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
1452		rtw89_phy_write32_idx(rtwdev, nbi->notch2_idx.addr,
1453				      nbi->notch2_idx.mask, nbi_tone_idx, phy_idx);
1454		rtw89_phy_write32_idx(rtwdev, nbi->notch2_frac_idx.addr,
1455				      nbi->notch2_frac_idx.mask, nbi_frac_tone_idx,
1456				      phy_idx);
1457		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1458				      nbi->notch2_en.mask, 0, phy_idx);
1459		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1460				      nbi->notch2_en.mask, 1, phy_idx);
1461		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1462				      nbi->notch1_en.mask, 0, phy_idx);
1463	} else {
1464		rtw89_phy_write32_idx(rtwdev, nbi->notch1_idx.addr,
1465				      nbi->notch1_idx.mask, nbi_tone_idx, phy_idx);
1466		rtw89_phy_write32_idx(rtwdev, nbi->notch1_frac_idx.addr,
1467				      nbi->notch1_frac_idx.mask, nbi_frac_tone_idx,
1468				      phy_idx);
1469		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1470				      nbi->notch1_en.mask, 0, phy_idx);
1471		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1472				      nbi->notch1_en.mask, 1, phy_idx);
1473		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1474				      nbi->notch2_en.mask, 0, phy_idx);
1475	}
1476}
1477
1478static void rtw8922a_spur_elimination(struct rtw89_dev *rtwdev,
1479				      const struct rtw89_chan *chan,
1480				      enum rtw89_phy_idx phy_idx)
1481{
1482	rtw8922a_set_csi_tone_idx(rtwdev, chan, phy_idx);
1483	rtw8922a_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A, phy_idx);
1484	rtw8922a_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B, phy_idx);
1485}
1486
1487static void rtw8922a_ctrl_afe_dac(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw,
1488				  enum rtw89_rf_path path)
1489{
1490	u32 cr_ofst = 0x0;
1491
1492	if (path == RF_PATH_B)
1493		cr_ofst = 0x100;
1494
1495	switch (bw) {
1496	case RTW89_CHANNEL_WIDTH_5:
1497	case RTW89_CHANNEL_WIDTH_10:
1498	case RTW89_CHANNEL_WIDTH_20:
1499	case RTW89_CHANNEL_WIDTH_40:
1500	case RTW89_CHANNEL_WIDTH_80:
1501		rtw89_phy_write32_mask(rtwdev, R_AFEDAC0 + cr_ofst, B_AFEDAC0, 0xE);
1502		rtw89_phy_write32_mask(rtwdev, R_AFEDAC1 + cr_ofst, B_AFEDAC1, 0x7);
1503		break;
1504	case RTW89_CHANNEL_WIDTH_160:
1505		rtw89_phy_write32_mask(rtwdev, R_AFEDAC0 + cr_ofst, B_AFEDAC0, 0xD);
1506		rtw89_phy_write32_mask(rtwdev, R_AFEDAC1 + cr_ofst, B_AFEDAC1, 0x6);
1507		break;
1508	default:
1509		break;
1510	}
1511}
1512
1513static const struct rtw89_reg2_def bb_mcu0_init_reg[] = {
1514	{0x6990, 0x00000000},
1515	{0x6994, 0x00000000},
1516	{0x6998, 0x00000000},
1517	{0x6820, 0xFFFFFFFE},
1518	{0x6800, 0xC0000FFE},
1519	{0x6808, 0x76543210},
1520	{0x6814, 0xBFBFB000},
1521	{0x6818, 0x0478C009},
1522	{0x6800, 0xC0000FFF},
1523	{0x6820, 0xFFFFFFFF},
1524};
1525
1526static const struct rtw89_reg2_def bb_mcu1_init_reg[] = {
1527	{0x6990, 0x00000000},
1528	{0x6994, 0x00000000},
1529	{0x6998, 0x00000000},
1530	{0x6820, 0xFFFFFFFE},
1531	{0x6800, 0xC0000FFE},
1532	{0x6808, 0x76543210},
1533	{0x6814, 0xBFBFB000},
1534	{0x6818, 0x0478C009},
1535	{0x6800, 0xC0000FFF},
1536	{0x6820, 0xFFFFFFFF},
1537};
1538
1539static void rtw8922a_bbmcu_cr_init(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
1540{
1541	const struct rtw89_reg2_def *reg;
1542	int size;
1543	int i;
1544
1545	if (phy_idx == RTW89_PHY_0) {
1546		reg = bb_mcu0_init_reg;
1547		size = ARRAY_SIZE(bb_mcu0_init_reg);
1548	} else {
1549		reg = bb_mcu1_init_reg;
1550		size = ARRAY_SIZE(bb_mcu1_init_reg);
1551	}
1552
1553	for (i = 0; i < size; i++, reg++)
1554		rtw89_bbmcu_write32(rtwdev, reg->addr, reg->data, phy_idx);
1555}
1556
1557static const u32 dmac_sys_mask[2] = {B_BE_DMAC_BB_PHY0_MASK, B_BE_DMAC_BB_PHY1_MASK};
1558static const u32 bbrst_mask[2] = {B_BE_FEN_BBPLAT_RSTB, B_BE_FEN_BB1PLAT_RSTB};
1559static const u32 glbrst_mask[2] = {B_BE_FEN_BB_IP_RSTN, B_BE_FEN_BB1_IP_RSTN};
1560static const u32 mcu_bootrdy_mask[2] = {B_BE_BOOT_RDY0, B_BE_BOOT_RDY1};
1561
1562static void rtw8922a_bb_preinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
1563{
1564	u32 rdy = 0;
1565
1566	if (phy_idx == RTW89_PHY_1)
1567		rdy = 1;
1568
1569	rtw89_write32_mask(rtwdev, R_BE_DMAC_SYS_CR32B, dmac_sys_mask[phy_idx], 0x7FF9);
1570	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x0);
1571	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx], 0x0);
1572	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x1);
1573	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, mcu_bootrdy_mask[phy_idx], rdy);
1574	rtw89_write32_mask(rtwdev, R_BE_MEM_PWR_CTRL, B_BE_MEM_BBMCU0_DS_V1, 0);
1575
1576	fsleep(1);
1577	rtw8922a_bbmcu_cr_init(rtwdev, phy_idx);
1578}
1579
1580static void rtw8922a_bb_postinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
1581{
1582	if (phy_idx == RTW89_PHY_0)
1583		rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, mcu_bootrdy_mask[phy_idx]);
1584	rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx]);
1585
1586	rtw89_phy_write32_set(rtwdev, R_BBCLK, B_CLK_640M);
1587	rtw89_phy_write32_clr(rtwdev, R_TXSCALE, B_TXFCTR_EN);
1588	rtw89_phy_set_phy_regs(rtwdev, R_TXFCTR, B_TXFCTR_THD, 0x200);
1589	rtw89_phy_set_phy_regs(rtwdev, R_SLOPE, B_EHT_RATE_TH, 0xA);
1590	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE, B_HE_RATE_TH, 0xA);
1591	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE2, B_HT_VHT_TH, 0xAAA);
1592	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE, B_EHT_MCS14, 0x1);
1593	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE2, B_EHT_MCS15, 0x1);
1594	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_EHTTB_EN, 0x0);
1595	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_HEERSU_EN, 0x0);
1596	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_HEMU_EN, 0x0);
1597	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE3, B_TB_EN, 0x0);
1598	rtw89_phy_set_phy_regs(rtwdev, R_SU_PUNC, B_SU_PUNC_EN, 0x1);
1599	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE5, B_HWGEN_EN, 0x1);
1600	rtw89_phy_set_phy_regs(rtwdev, R_BEDGE5, B_PWROFST_COMP, 0x1);
1601	rtw89_phy_set_phy_regs(rtwdev, R_MAG_AB, B_BY_SLOPE, 0x1);
1602	rtw89_phy_set_phy_regs(rtwdev, R_MAG_A, B_MGA_AEND, 0xe0);
1603	rtw89_phy_set_phy_regs(rtwdev, R_MAG_AB, B_MAG_AB, 0xe0c000);
1604	rtw89_phy_set_phy_regs(rtwdev, R_SLOPE, B_SLOPE_A, 0x3FE0);
1605	rtw89_phy_set_phy_regs(rtwdev, R_SLOPE, B_SLOPE_B, 0x3FE0);
1606	rtw89_phy_set_phy_regs(rtwdev, R_SC_CORNER, B_SC_CORNER, 0x200);
1607	rtw89_phy_write32_idx(rtwdev, R_UDP_COEEF, B_UDP_COEEF, 0x0, phy_idx);
1608	rtw89_phy_write32_idx(rtwdev, R_UDP_COEEF, B_UDP_COEEF, 0x1, phy_idx);
1609}
1610
1611static void rtw8922a_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band,
1612				 bool en, enum rtw89_phy_idx phy_idx)
1613{
1614	if (en) {
1615		rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx);
1616		if (band == RTW89_BAND_2G)
1617			rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1,
1618					      B_RXCCA_BE1_DIS, 0x0, phy_idx);
1619		rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0, phy_idx);
1620	} else {
1621		rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1, B_RXCCA_BE1_DIS, 0x1, phy_idx);
1622		rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1, phy_idx);
1623		fsleep(1);
1624		rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx);
1625	}
1626}
1627
1628static int rtw8922a_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev,
1629				      enum rtw89_rf_path tx_path,
1630				      enum rtw89_phy_idx phy_idx)
1631{
1632	struct rtw89_reg2_def path_com_cr[] = {
1633		{0x11A00, 0x21C86900},
1634		{0x11A04, 0x00E4E433},
1635		{0x11A08, 0x39390CC9},
1636		{0x11A0C, 0x4E433240},
1637		{0x11A10, 0x90CC900E},
1638		{0x11A14, 0x00240393},
1639		{0x11A18, 0x201C8600},
1640	};
1641	int ret = 0;
1642	u32 reg;
1643	int i;
1644
1645	rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL, 0x0, phy_idx);
1646
1647	if (phy_idx == RTW89_PHY_1 && !rtwdev->dbcc_en)
1648		return 0;
1649
1650	if (tx_path == RF_PATH_A) {
1651		path_com_cr[0].data = 0x21C82900;
1652		path_com_cr[1].data = 0x00E4E431;
1653		path_com_cr[2].data = 0x39390C49;
1654		path_com_cr[3].data = 0x4E431240;
1655		path_com_cr[4].data = 0x90C4900E;
1656		path_com_cr[6].data = 0x201C8200;
1657	} else if (tx_path == RF_PATH_B) {
1658		path_com_cr[0].data = 0x21C04900;
1659		path_com_cr[1].data = 0x00E4E032;
1660		path_com_cr[2].data = 0x39380C89;
1661		path_com_cr[3].data = 0x4E032240;
1662		path_com_cr[4].data = 0x80C8900E;
1663		path_com_cr[6].data = 0x201C0400;
1664	} else if (tx_path == RF_PATH_AB) {
1665		path_com_cr[0].data = 0x21C86900;
1666		path_com_cr[1].data = 0x00E4E433;
1667		path_com_cr[2].data = 0x39390CC9;
1668		path_com_cr[3].data = 0x4E433240;
1669		path_com_cr[4].data = 0x90CC900E;
1670		path_com_cr[6].data = 0x201C8600;
1671	} else {
1672		ret = -EINVAL;
1673	}
1674
1675	for (i = 0; i < ARRAY_SIZE(path_com_cr); i++) {
1676		reg = rtw89_mac_reg_by_idx(rtwdev, path_com_cr[i].addr, phy_idx);
1677		rtw89_write32(rtwdev, reg, path_com_cr[i].data);
1678	}
1679
1680	return ret;
1681}
1682
1683static void rtw8922a_bb_reset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
1684{
1685}
1686
1687static int rtw8922a_cfg_rx_nss_limit(struct rtw89_dev *rtwdev, u8 rx_nss,
1688				     enum rtw89_phy_idx phy_idx)
1689{
1690	if (rx_nss == 1) {
1691		rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_HTMCS_LMT, 0, phy_idx);
1692		rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_VHTMCS_LMT, 0, phy_idx);
1693		rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_N_USR_MAX,
1694				      HE_N_USER_MAX_8922A, phy_idx);
1695		rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_NSS_MAX, 0, phy_idx);
1696		rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_TB_NSS_MAX, 0, phy_idx);
1697		rtw89_phy_write32_idx(rtwdev, R_BRK_EHT, B_RXEHT_NSS_MAX, 0, phy_idx);
1698		rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHTTB_NSS_MAX, 0,
1699				      phy_idx);
1700		rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHT_N_USER_MAX,
1701				      HE_N_USER_MAX_8922A, phy_idx);
1702	} else if (rx_nss == 2) {
1703		rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_HTMCS_LMT, 1, phy_idx);
1704		rtw89_phy_write32_idx(rtwdev, R_BRK_R, B_VHTMCS_LMT, 1, phy_idx);
1705		rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_N_USR_MAX,
1706				      HE_N_USER_MAX_8922A, phy_idx);
1707		rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_NSS_MAX, 1, phy_idx);
1708		rtw89_phy_write32_idx(rtwdev, R_BRK_HE, B_TB_NSS_MAX, 1, phy_idx);
1709		rtw89_phy_write32_idx(rtwdev, R_BRK_EHT, B_RXEHT_NSS_MAX, 1, phy_idx);
1710		rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHTTB_NSS_MAX, 1,
1711				      phy_idx);
1712		rtw89_phy_write32_idx(rtwdev, R_BRK_RXEHT, B_RXEHT_N_USER_MAX,
1713				      HE_N_USER_MAX_8922A, phy_idx);
1714	} else {
1715		return -EINVAL;
1716	}
1717
1718	return 0;
1719}
1720
1721static void rtw8922a_tssi_reset(struct rtw89_dev *rtwdev,
1722				enum rtw89_rf_path path,
1723				enum rtw89_phy_idx phy_idx)
1724{
1725	if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
1726		if (phy_idx == RTW89_PHY_0) {
1727			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x0);
1728			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x1);
1729		} else {
1730			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x0);
1731			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x1);
1732		}
1733	} else {
1734		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x0);
1735		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTA, B_TXPWR_RSTA, 0x1);
1736		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x0);
1737		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB, B_TXPWR_RSTB, 0x1);
1738	}
1739}
1740
1741static int rtw8922a_ctrl_rx_path_tmac(struct rtw89_dev *rtwdev,
1742				      enum rtw89_rf_path rx_path,
1743				      enum rtw89_phy_idx phy_idx)
1744{
1745	u8 rx_nss = (rx_path == RF_PATH_AB) ? 2 : 1;
1746
1747	/* Set to 0 first to avoid abnormal EDCCA report */
1748	rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x0, phy_idx);
1749
1750	if (rx_path == RF_PATH_A) {
1751		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x1, phy_idx);
1752		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_1RCCA, 1, phy_idx);
1753		rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx);
1754		rtw8922a_tssi_reset(rtwdev, rx_path, phy_idx);
1755	} else if (rx_path == RF_PATH_B) {
1756		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x2, phy_idx);
1757		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_1RCCA, 2, phy_idx);
1758		rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx);
1759		rtw8922a_tssi_reset(rtwdev, rx_path, phy_idx);
1760	} else if (rx_path == RF_PATH_AB) {
1761		rtw89_phy_write32_idx(rtwdev, R_ANT_CHBW, B_ANT_RX_SG0, 0x3, phy_idx);
1762		rtw89_phy_write32_idx(rtwdev, R_FC0INV_SBW, B_RX_1RCCA, 3, phy_idx);
1763		rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx);
1764		rtw8922a_tssi_reset(rtwdev, rx_path, phy_idx);
1765	} else {
1766		return -EINVAL;
1767	}
1768
1769	return 0;
1770}
1771
1772#define DIGITAL_PWR_COMP_REG_NUM 22
1773static const u32 rtw8922a_digital_pwr_comp_2g_s0_val[][DIGITAL_PWR_COMP_REG_NUM] = {
1774	{0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320,
1775	 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010000, 0x00000101,
1776	 0x01010101, 0x02020201, 0x02010000, 0x03030202, 0x00000303,
1777	 0x03020101, 0x06060504, 0x01010000, 0x06050403, 0x01000606,
1778	 0x05040202, 0x07070706},
1779	{0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320,
1780	 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010100, 0x00000101,
1781	 0x01000000, 0x01010101, 0x01010000, 0x02020202, 0x00000404,
1782	 0x03020101, 0x04040303, 0x02010000, 0x03030303, 0x00000505,
1783	 0x03030201, 0x05050303},
1784};
1785
1786static const u32 rtw8922a_digital_pwr_comp_2g_s1_val[][DIGITAL_PWR_COMP_REG_NUM] = {
1787	{0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320,
1788	 0x0D05091D, 0x14D50FA0, 0x01010000, 0x01010101, 0x00000101,
1789	 0x01010100, 0x01010101, 0x01010000, 0x02020202, 0x01000202,
1790	 0x02020101, 0x03030202, 0x02010000, 0x05040403, 0x01000606,
1791	 0x05040302, 0x07070605},
1792	{0x012C0064, 0x04B00258, 0x00432710, 0x019000A7, 0x06400320,
1793	 0x0D05091D, 0x14D50FA0, 0x00000000, 0x01010100, 0x00000101,
1794	 0x01010000, 0x02020201, 0x02010100, 0x03030202, 0x01000404,
1795	 0x04030201, 0x05050404, 0x01010100, 0x04030303, 0x01000505,
1796	 0x03030101, 0x05050404},
1797};
1798
1799static const u32 rtw8922a_digital_pwr_comp_val[][DIGITAL_PWR_COMP_REG_NUM] = {
1800	{0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A,
1801	 0x0BB80708, 0x17701194, 0x02020100, 0x03030303, 0x01000303,
1802	 0x05030302, 0x06060605, 0x06050300, 0x0A090807, 0x02000B0B,
1803	 0x09080604, 0x0D0D0C0B, 0x08060400, 0x110F0C0B, 0x05001111,
1804	 0x0D0C0907, 0x12121210},
1805	{0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A,
1806	 0x0BB80708, 0x17701194, 0x04030201, 0x05050505, 0x01000505,
1807	 0x07060504, 0x09090908, 0x09070400, 0x0E0D0C0B, 0x03000E0E,
1808	 0x0D0B0907, 0x1010100F, 0x0B080500, 0x1512100D, 0x05001515,
1809	 0x100D0B08, 0x15151512},
1810};
1811
1812static void rtw8922a_set_digital_pwr_comp(struct rtw89_dev *rtwdev,
1813					  u8 band, u8 nss,
1814					  enum rtw89_rf_path path)
1815{
1816	static const u32 ltpc_t0[2] = {R_BE_LTPC_T0_PATH0, R_BE_LTPC_T0_PATH1};
1817	const u32 *digital_pwr_comp;
1818	u32 addr, val;
1819	u32 i;
1820
1821	if (nss == 1) {
1822		if (band == RTW89_BAND_2G)
1823			digital_pwr_comp = path == RF_PATH_A ?
1824				rtw8922a_digital_pwr_comp_2g_s0_val[0] :
1825				rtw8922a_digital_pwr_comp_2g_s1_val[0];
1826		else
1827			digital_pwr_comp = rtw8922a_digital_pwr_comp_val[0];
1828	} else {
1829		if (band == RTW89_BAND_2G)
1830			digital_pwr_comp = path == RF_PATH_A ?
1831				rtw8922a_digital_pwr_comp_2g_s0_val[1] :
1832				rtw8922a_digital_pwr_comp_2g_s1_val[1];
1833		else
1834			digital_pwr_comp = rtw8922a_digital_pwr_comp_val[1];
1835	}
1836
1837	addr = ltpc_t0[path];
1838	for (i = 0; i < DIGITAL_PWR_COMP_REG_NUM; i++, addr += 4) {
1839		val = digital_pwr_comp[i];
1840		rtw89_phy_write32(rtwdev, addr, val);
1841	}
1842}
1843
1844static void rtw8922a_digital_pwr_comp(struct rtw89_dev *rtwdev,
1845				      enum rtw89_phy_idx phy_idx)
1846{
1847	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
1848	u8 band = chan->band_type;
1849	u8 path;
1850
1851	if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
1852		if (phy_idx == RTW89_PHY_0)
1853			path = RF_PATH_A;
1854		else
1855			path = RF_PATH_B;
1856		rtw8922a_set_digital_pwr_comp(rtwdev, band, 1, path);
1857	} else {
1858		rtw8922a_set_digital_pwr_comp(rtwdev, band, 2, RF_PATH_A);
1859		rtw8922a_set_digital_pwr_comp(rtwdev, band, 2, RF_PATH_B);
1860	}
1861}
1862
1863static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode)
1864{
1865	const struct rtw89_chan *chan0, *chan1;
1866
1867	if (mode == MLO_1_PLUS_1_1RF || mode == DBCC_LEGACY) {
1868		rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x1);
1869		rtw89_phy_write32_mask(rtwdev, R_DBCC_FA, B_DBCC_FA, 0x0);
1870	} else if (mode == MLO_2_PLUS_0_1RF || mode == MLO_0_PLUS_2_1RF ||
1871		   mode == MLO_DBCC_NOT_SUPPORT) {
1872		rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x0);
1873		rtw89_phy_write32_mask(rtwdev, R_DBCC_FA, B_DBCC_FA, 0x1);
1874	} else {
1875		return -EOPNOTSUPP;
1876	}
1877
1878	if (mode == MLO_1_PLUS_1_1RF) {
1879		chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
1880		chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
1881	} else if (mode == MLO_0_PLUS_2_1RF) {
1882		chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
1883		chan0 = chan1;
1884	} else {
1885		chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
1886		chan1 = chan0;
1887	}
1888
1889	rtw8922a_ctrl_afe_dac(rtwdev, chan0->band_width, RF_PATH_A);
1890	rtw8922a_ctrl_afe_dac(rtwdev, chan1->band_width, RF_PATH_B);
1891
1892	rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180);
1893
1894	if (mode == MLO_2_PLUS_0_1RF) {
1895		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB);
1896		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xABA9);
1897		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEBA9);
1898		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEAA9);
1899	} else if (mode == MLO_0_PLUS_2_1RF) {
1900		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB);
1901		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xAFFF);
1902		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEFFF);
1903		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEEFF);
1904	} else if ((mode == MLO_1_PLUS_1_1RF) || (mode == DBCC_LEGACY)) {
1905		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x7BAB);
1906		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x3BAB);
1907		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x3AAB);
1908	} else {
1909		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x180);
1910		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x0);
1911	}
1912
1913	return 0;
1914}
1915
1916static void rtw8922a_bb_sethw(struct rtw89_dev *rtwdev)
1917{
1918	u32 reg;
1919
1920	rtw89_phy_write32_clr(rtwdev, R_EN_SND_WO_NDP, B_EN_SND_WO_NDP);
1921	rtw89_phy_write32_clr(rtwdev, R_EN_SND_WO_NDP_C1, B_EN_SND_WO_NDP);
1922
1923	rtw89_write32_mask(rtwdev, R_BE_PWR_BOOST, B_BE_PWR_CTRL_SEL, 0);
1924	if (rtwdev->dbcc_en) {
1925		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_BOOST, RTW89_MAC_1);
1926		rtw89_write32_mask(rtwdev, reg, B_BE_PWR_CTRL_SEL, 0);
1927	}
1928
1929	rtw8922a_ctrl_mlo(rtwdev, rtwdev->mlo_dbcc_mode);
1930}
1931
1932static void rtw8922a_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en,
1933				 enum rtw89_phy_idx phy_idx)
1934{
1935	if (cck_en) {
1936		rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1, B_RXCCA_BE1_DIS, 0, phy_idx);
1937		rtw89_phy_write32_idx(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1, phy_idx);
1938		rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, B_PD_ARBITER_OFF,
1939				      0, phy_idx);
1940	} else {
1941		rtw89_phy_write32_idx(rtwdev, R_RXCCA_BE1, B_RXCCA_BE1_DIS, 1, phy_idx);
1942		rtw89_phy_write32_idx(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0, phy_idx);
1943		rtw89_phy_write32_idx(rtwdev, R_PD_ARBITER_OFF, B_PD_ARBITER_OFF,
1944				      1, phy_idx);
1945	}
1946}
1947
1948static void rtw8922a_set_channel_bb(struct rtw89_dev *rtwdev,
1949				    const struct rtw89_chan *chan,
1950				    enum rtw89_phy_idx phy_idx)
1951{
1952	bool cck_en = chan->band_type == RTW89_BAND_2G;
1953	u8 pri_sb = chan->pri_sb_idx;
1954
1955	if (cck_en)
1956		rtw8922a_ctrl_sco_cck(rtwdev, chan->primary_channel,
1957				      chan->band_width, phy_idx);
1958
1959	rtw8922a_ctrl_ch(rtwdev, chan, phy_idx);
1960	rtw8922a_ctrl_bw(rtwdev, pri_sb, chan->band_width, phy_idx);
1961	rtw8922a_ctrl_cck_en(rtwdev, cck_en, phy_idx);
1962	rtw8922a_spur_elimination(rtwdev, chan, phy_idx);
1963
1964	rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx);
1965	rtw8922a_tssi_reset(rtwdev, RF_PATH_AB, phy_idx);
1966}
1967
1968static void rtw8922a_pre_set_channel_bb(struct rtw89_dev *rtwdev,
1969					enum rtw89_phy_idx phy_idx)
1970{
1971	if (!rtwdev->dbcc_en)
1972		return;
1973
1974	if (phy_idx == RTW89_PHY_0) {
1975		rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x0);
1976		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180);
1977		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB);
1978		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xABA9);
1979		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEBA9);
1980		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEAA9);
1981	} else {
1982		rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x0);
1983		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xBBAB);
1984		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xAFFF);
1985		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEFFF);
1986		rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0xEEFF);
1987	}
1988}
1989
1990static void rtw8922a_post_set_channel_bb(struct rtw89_dev *rtwdev,
1991					 enum rtw89_mlo_dbcc_mode mode,
1992					 enum rtw89_phy_idx phy_idx)
1993{
1994	if (!rtwdev->dbcc_en)
1995		return;
1996
1997	rtw8922a_digital_pwr_comp(rtwdev, phy_idx);
1998	rtw8922a_ctrl_mlo(rtwdev, mode);
1999}
2000
2001static void rtw8922a_set_channel(struct rtw89_dev *rtwdev,
2002				 const struct rtw89_chan *chan,
2003				 enum rtw89_mac_idx mac_idx,
2004				 enum rtw89_phy_idx phy_idx)
2005{
2006	rtw8922a_set_channel_mac(rtwdev, chan, mac_idx);
2007	rtw8922a_set_channel_bb(rtwdev, chan, phy_idx);
2008	rtw8922a_set_channel_rf(rtwdev, chan, phy_idx);
2009}
2010
2011static void rtw8922a_dfs_en_idx(struct rtw89_dev *rtwdev,
2012				enum rtw89_phy_idx phy_idx, enum rtw89_rf_path path,
2013				bool en)
2014{
2015	u32 path_ofst = (path == RF_PATH_B) ? 0x100 : 0x0;
2016
2017	if (en)
2018		rtw89_phy_write32_idx(rtwdev, 0x2800 + path_ofst, BIT(1), 1,
2019				      phy_idx);
2020	else
2021		rtw89_phy_write32_idx(rtwdev, 0x2800 + path_ofst, BIT(1), 0,
2022				      phy_idx);
2023}
2024
2025static void rtw8922a_dfs_en(struct rtw89_dev *rtwdev, bool en,
2026			    enum rtw89_phy_idx phy_idx)
2027{
2028	rtw8922a_dfs_en_idx(rtwdev, phy_idx, RF_PATH_A, en);
2029	rtw8922a_dfs_en_idx(rtwdev, phy_idx, RF_PATH_B, en);
2030}
2031
2032static void rtw8922a_adc_en_path(struct rtw89_dev *rtwdev,
2033				 enum rtw89_rf_path path, bool en)
2034{
2035	u32 val;
2036
2037	val = rtw89_phy_read32_mask(rtwdev, R_ADC_FIFO_V1, B_ADC_FIFO_EN_V1);
2038
2039	if (en) {
2040		if (path == RF_PATH_A)
2041			val &= ~0x1;
2042		else
2043			val &= ~0x2;
2044	} else {
2045		if (path == RF_PATH_A)
2046			val |= 0x1;
2047		else
2048			val |= 0x2;
2049	}
2050
2051	rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO_V1, B_ADC_FIFO_EN_V1, val);
2052}
2053
2054static void rtw8922a_adc_en(struct rtw89_dev *rtwdev, bool en, u8 phy_idx)
2055{
2056	if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
2057		if (phy_idx == RTW89_PHY_0)
2058			rtw8922a_adc_en_path(rtwdev, RF_PATH_A, en);
2059		else
2060			rtw8922a_adc_en_path(rtwdev, RF_PATH_B, en);
2061	} else {
2062		rtw8922a_adc_en_path(rtwdev, RF_PATH_A, en);
2063		rtw8922a_adc_en_path(rtwdev, RF_PATH_B, en);
2064	}
2065}
2066
2067static
2068void rtw8922a_hal_reset(struct rtw89_dev *rtwdev,
2069			enum rtw89_phy_idx phy_idx, enum rtw89_mac_idx mac_idx,
2070			enum rtw89_band band, u32 *tx_en, bool enter)
2071{
2072	if (enter) {
2073		rtw89_chip_stop_sch_tx(rtwdev, mac_idx, tx_en, RTW89_SCH_TX_SEL_ALL);
2074		rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false);
2075		rtw8922a_dfs_en(rtwdev, false, phy_idx);
2076		rtw8922a_tssi_cont_en_phyidx(rtwdev, false, phy_idx);
2077		rtw8922a_adc_en(rtwdev, false, phy_idx);
2078		fsleep(40);
2079		rtw8922a_bb_reset_en(rtwdev, band, false, phy_idx);
2080	} else {
2081		rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true);
2082		rtw8922a_adc_en(rtwdev, true, phy_idx);
2083		rtw8922a_dfs_en(rtwdev, true, phy_idx);
2084		rtw8922a_tssi_cont_en_phyidx(rtwdev, true, phy_idx);
2085		rtw8922a_bb_reset_en(rtwdev, band, true, phy_idx);
2086		rtw89_chip_resume_sch_tx(rtwdev, mac_idx, *tx_en);
2087	}
2088}
2089
2090static void rtw8922a_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
2091				      struct rtw89_channel_help_params *p,
2092				      const struct rtw89_chan *chan,
2093				      enum rtw89_mac_idx mac_idx,
2094				      enum rtw89_phy_idx phy_idx)
2095{
2096	if (enter) {
2097		rtw8922a_pre_set_channel_bb(rtwdev, phy_idx);
2098		rtw8922a_pre_set_channel_rf(rtwdev, phy_idx);
2099	}
2100
2101	rtw8922a_hal_reset(rtwdev, phy_idx, mac_idx, chan->band_type, &p->tx_en, enter);
2102
2103	if (!enter) {
2104		rtw8922a_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode, phy_idx);
2105		rtw8922a_post_set_channel_rf(rtwdev, phy_idx);
2106	}
2107}
2108
2109static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev)
2110{
2111	struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
2112
2113	rtwdev->is_tssi_mode[RF_PATH_A] = false;
2114	rtwdev->is_tssi_mode[RF_PATH_B] = false;
2115	memset(rfk_mcc, 0, sizeof(*rfk_mcc));
2116}
2117
2118static void __rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev,
2119				     enum rtw89_phy_idx phy_idx,
2120				     const struct rtw89_chan *chan)
2121{
2122	rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
2123
2124	rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58);
2125	if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
2126		rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 128);
2127}
2128
2129static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev)
2130{
2131	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
2132
2133	__rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_0, chan);
2134	if (rtwdev->dbcc_en)
2135		__rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_1, chan);
2136}
2137
2138static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
2139{
2140	u32 rf_mode;
2141	u8 path;
2142	int ret;
2143
2144	for (path = 0; path < RF_PATH_NUM_8922A; path++) {
2145		if (!(kpath & BIT(path)))
2146			continue;
2147
2148		ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2,
2149					       2, 5000, false, rtwdev, path, 0x00,
2150					       RR_MOD_MASK);
2151		rtw89_debug(rtwdev, RTW89_DBG_RFK,
2152			    "[RFK] Wait S%d to Rx mode!! (ret = %d)\n",
2153			    path, ret);
2154	}
2155}
2156
2157static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev,
2158				 struct rtw89_vif_link *rtwvif_link)
2159{
2160	enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
2161	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
2162	enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
2163	u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
2164	u32 tx_en;
2165
2166	rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_START);
2167	rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
2168	_wait_rx_mode(rtwdev, RF_AB);
2169
2170	rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
2171	rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54);
2172	rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84);
2173	rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20);
2174	rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 34);
2175	rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32);
2176
2177	rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
2178	rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP);
2179}
2180
2181static void rtw8922a_rfk_band_changed(struct rtw89_dev *rtwdev,
2182				      enum rtw89_phy_idx phy_idx,
2183				      const struct rtw89_chan *chan)
2184{
2185	rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_SCAN, 6);
2186}
2187
2188static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev,
2189			      struct rtw89_vif_link *rtwvif_link,
2190			      bool start)
2191{
2192}
2193
2194static void rtw8922a_rfk_track(struct rtw89_dev *rtwdev)
2195{
2196}
2197
2198static void rtw8922a_set_txpwr_ref(struct rtw89_dev *rtwdev,
2199				   enum rtw89_phy_idx phy_idx)
2200{
2201	s16 ref_ofdm = 0;
2202	s16 ref_cck = 0;
2203
2204	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n");
2205
2206	rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL,
2207				     B_BE_PWR_REF_CTRL_OFDM, ref_ofdm);
2208	rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL,
2209				     B_BE_PWR_REF_CTRL_CCK, ref_cck);
2210}
2211
2212static const struct rtw89_reg_def rtw8922a_txpwr_ref[][3] = {
2213	{{ .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_OFDM_REF_DBM_P0},
2214	 { .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_CCK_REF_DBM_P0},
2215	 { .addr = R_TSSI_K_P0, .mask = B_TSSI_K_OFDM_P0}
2216	},
2217	{{ .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_OFDM_REF_DBM_RF1_P0},
2218	 { .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_CCK_REF_DBM_RF1_P0},
2219	 { .addr = R_TSSI_K_RF1_P0, .mask = B_TSSI_K_OFDM_RF1_P0}
2220	},
2221};
2222
2223static void rtw8922a_set_txpwr_diff(struct rtw89_dev *rtwdev,
2224				    const struct rtw89_chan *chan,
2225				    enum rtw89_phy_idx phy_idx)
2226{
2227	s16 pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
2228	const struct rtw89_chip_info *chip = rtwdev->chip;
2229	static const u32 path_ofst[] = {0x0, 0x100};
2230	const struct rtw89_reg_def *txpwr_ref;
2231	static const s16 tssi_k_base = 0x12;
2232	s16 tssi_k_ofst = abs(pwr_ofst) + tssi_k_base;
2233	s16 ofst_dec[RF_PATH_NUM_8922A];
2234	s16 tssi_k[RF_PATH_NUM_8922A];
2235	s16 pwr_ref_ofst;
2236	s16 pwr_ref = 0;
2237	u8 i;
2238
2239	if (rtwdev->hal.cv == CHIP_CAV)
2240		pwr_ref = 16;
2241
2242	pwr_ref <<= chip->txpwr_factor_rf;
2243	pwr_ref_ofst = pwr_ref - rtw89_phy_txpwr_bb_to_rf(rtwdev, abs(pwr_ofst));
2244
2245	ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? pwr_ref : pwr_ref_ofst;
2246	ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ref_ofst : pwr_ref;
2247	tssi_k[RF_PATH_A] = pwr_ofst > 0 ? tssi_k_base : tssi_k_ofst;
2248	tssi_k[RF_PATH_B] = pwr_ofst > 0 ? tssi_k_ofst : tssi_k_base;
2249
2250	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
2251		txpwr_ref = rtw8922a_txpwr_ref[phy_idx];
2252
2253		rtw89_phy_write32_mask(rtwdev, txpwr_ref[0].addr + path_ofst[i],
2254				       txpwr_ref[0].mask, ofst_dec[i]);
2255		rtw89_phy_write32_mask(rtwdev, txpwr_ref[1].addr + path_ofst[i],
2256				       txpwr_ref[1].mask, ofst_dec[i]);
2257		rtw89_phy_write32_mask(rtwdev, txpwr_ref[2].addr + path_ofst[i],
2258				       txpwr_ref[2].mask, tssi_k[i]);
2259	}
2260}
2261
2262static void rtw8922a_bb_tx_triangular(struct rtw89_dev *rtwdev, bool en,
2263				      enum rtw89_phy_idx phy_idx)
2264{
2265	u8 ctrl = en ? 0x1 : 0x0;
2266
2267	rtw89_phy_write32_idx(rtwdev, R_BEDGE3, B_BEDGE_CFG, ctrl, phy_idx);
2268}
2269
2270static void rtw8922a_set_tx_shape(struct rtw89_dev *rtwdev,
2271				  const struct rtw89_chan *chan,
2272				  enum rtw89_phy_idx phy_idx)
2273{
2274	const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
2275	const struct rtw89_tx_shape *tx_shape = &rfe_parms->tx_shape;
2276	u8 tx_shape_idx;
2277	u8 band, regd;
2278
2279	band = chan->band_type;
2280	regd = rtw89_regd_get(rtwdev, band);
2281	tx_shape_idx = (*tx_shape->lmt)[band][RTW89_RS_OFDM][regd];
2282
2283	if (tx_shape_idx == 0)
2284		rtw8922a_bb_tx_triangular(rtwdev, false, phy_idx);
2285	else
2286		rtw8922a_bb_tx_triangular(rtwdev, true, phy_idx);
2287}
2288
2289static void rtw8922a_set_txpwr_sar_diff(struct rtw89_dev *rtwdev,
2290					const struct rtw89_chan *chan,
2291					enum rtw89_phy_idx phy_idx)
2292{
2293	struct rtw89_sar_parm sar_parm = {
2294		.center_freq = chan->freq,
2295		.force_path = true,
2296	};
2297	s16 sar_rf;
2298	s8 sar_mac;
2299
2300	if (phy_idx != RTW89_PHY_0)
2301		return;
2302
2303	sar_parm.path = RF_PATH_A;
2304	sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
2305	sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
2306	rtw89_phy_write32_mask(rtwdev, R_P0_TXPWRB_BE, B_TXPWRB_MAX_BE, sar_rf);
2307
2308	sar_parm.path = RF_PATH_B;
2309	sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
2310	sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
2311	rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB_BE, B_TXPWRB_MAX_BE, sar_rf);
2312}
2313
2314static void rtw8922a_set_txpwr(struct rtw89_dev *rtwdev,
2315			       const struct rtw89_chan *chan,
2316			       enum rtw89_phy_idx phy_idx)
2317{
2318	rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
2319	rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
2320	rtw8922a_set_tx_shape(rtwdev, chan, phy_idx);
2321	rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
2322	rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
2323	rtw8922a_set_txpwr_diff(rtwdev, chan, phy_idx);
2324	rtw8922a_set_txpwr_ref(rtwdev, phy_idx);
2325	rtw8922a_set_txpwr_sar_diff(rtwdev, chan, phy_idx);
2326}
2327
2328static void rtw8922a_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
2329				    enum rtw89_phy_idx phy_idx)
2330{
2331	rtw8922a_set_txpwr_ref(rtwdev, phy_idx);
2332}
2333
2334static void rtw8922a_ctrl_trx_path(struct rtw89_dev *rtwdev,
2335				   enum rtw89_rf_path tx_path, u8 tx_nss,
2336				   enum rtw89_rf_path rx_path, u8 rx_nss)
2337{
2338	enum rtw89_phy_idx phy_idx;
2339
2340	for (phy_idx = RTW89_PHY_0; phy_idx <= RTW89_PHY_1; phy_idx++) {
2341		rtw8922a_ctrl_tx_path_tmac(rtwdev, tx_path, phy_idx);
2342		rtw8922a_ctrl_rx_path_tmac(rtwdev, rx_path, phy_idx);
2343		rtw8922a_cfg_rx_nss_limit(rtwdev, rx_nss, phy_idx);
2344	}
2345}
2346
2347static void rtw8922a_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
2348				     enum rtw89_phy_idx phy_idx)
2349{
2350	if (en) {
2351		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x3, phy_idx);
2352		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A,
2353				      0xf, phy_idx);
2354		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A,
2355				      0x0, phy_idx);
2356		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x0, phy_idx);
2357		rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x80, phy_idx);
2358		rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x8080, phy_idx);
2359		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x34, phy_idx);
2360		rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x34, phy_idx);
2361		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x3, phy_idx);
2362		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B,
2363				      0xf, phy_idx);
2364		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B,
2365				      0x0, phy_idx);
2366		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x0, phy_idx);
2367		rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x80, phy_idx);
2368		rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA10_B, 0x8080, phy_idx);
2369		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x34, phy_idx);
2370		rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x34, phy_idx);
2371	} else {
2372		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x0, phy_idx);
2373		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A,
2374				      0x0, phy_idx);
2375		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A,
2376				      0x1, phy_idx);
2377		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x1, phy_idx);
2378		rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x1a, phy_idx);
2379		rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x2a2a, phy_idx);
2380		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x7a6, phy_idx);
2381		rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x26, phy_idx);
2382		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x0, phy_idx);
2383		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B,
2384				      0x0, phy_idx);
2385		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B,
2386				      0x1, phy_idx);
2387		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x1, phy_idx);
2388		rtw89_phy_write32_idx(rtwdev, R_LNA_OP, B_LNA6, 0x20, phy_idx);
2389		rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA10_B, 0x2a30, phy_idx);
2390		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x7a6, phy_idx);
2391		rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x26, phy_idx);
2392	}
2393}
2394
2395static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
2396{
2397	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
2398	enum rtw89_band band = chan->band_type;
2399	struct rtw89_hal *hal = &rtwdev->hal;
2400	u8 ntx_path = RF_PATH_AB;
2401	u8 nrx_path = RF_PATH_AB;
2402	u32 tx_en0, tx_en1;
2403	u8 rx_nss = 2;
2404
2405	if (hal->antenna_tx == RF_A)
2406		ntx_path = RF_PATH_A;
2407	else if (hal->antenna_tx == RF_B)
2408		ntx_path = RF_PATH_B;
2409
2410	if (hal->antenna_rx == RF_A)
2411		nrx_path = RF_PATH_A;
2412	else if (hal->antenna_rx == RF_B)
2413		nrx_path = RF_PATH_B;
2414
2415	if (nrx_path != RF_PATH_AB)
2416		rx_nss = 1;
2417
2418	rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, true);
2419	if (rtwdev->dbcc_en)
2420		rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band,
2421				   &tx_en1, true);
2422
2423	rtw8922a_ctrl_trx_path(rtwdev, ntx_path, 2, nrx_path, rx_nss);
2424
2425	rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false);
2426	if (rtwdev->dbcc_en)
2427		rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band,
2428				   &tx_en1, false);
2429}
2430
2431static u8 rtw8922a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
2432{
2433	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
2434	struct rtw89_hal *hal = &rtwdev->hal;
2435	int th;
2436
2437	/* read thermal only if debugging or thermal protection enabled */
2438	if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK) &&
2439	    !hal->thermal_prot_th)
2440		return 80;
2441
2442	rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
2443	rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0);
2444	rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
2445
2446	fsleep(200);
2447
2448	th = rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL_V1);
2449	th += (s8)info->thermal_trim[rf_path];
2450
2451	return clamp_t(int, th, 0, U8_MAX);
2452}
2453
2454static u32 rtw8922a_chan_to_rf18_val(struct rtw89_dev *rtwdev,
2455				     const struct rtw89_chan *chan)
2456{
2457	u32 val = u32_encode_bits(chan->channel, RR_CFGCH_CH);
2458
2459	switch (chan->band_type) {
2460	case RTW89_BAND_2G:
2461	default:
2462		break;
2463	case RTW89_BAND_5G:
2464		val |= u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) |
2465		       u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0);
2466		break;
2467	case RTW89_BAND_6G:
2468		val |= u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) |
2469		       u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0);
2470		break;
2471	}
2472
2473	switch (chan->band_width) {
2474	case RTW89_CHANNEL_WIDTH_5:
2475	case RTW89_CHANNEL_WIDTH_10:
2476	case RTW89_CHANNEL_WIDTH_20:
2477	default:
2478		break;
2479	case RTW89_CHANNEL_WIDTH_40:
2480		val |= u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2);
2481		break;
2482	case RTW89_CHANNEL_WIDTH_80:
2483		val |= u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2);
2484		break;
2485	case RTW89_CHANNEL_WIDTH_160:
2486		val |= u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2);
2487		break;
2488	case RTW89_CHANNEL_WIDTH_320:
2489		val |= u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2);
2490		break;
2491	}
2492
2493	return val;
2494}
2495
2496static void rtw8922a_btc_set_rfe(struct rtw89_dev *rtwdev)
2497{
2498	union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
2499	struct rtw89_btc_module_v7 *module = &md->md_v7;
2500
2501	module->rfe_type = rtwdev->efuse.rfe_type;
2502	module->kt_ver = rtwdev->hal.cv;
2503	module->bt_solo = 0;
2504	module->switch_type = BTC_SWITCH_INTERNAL;
2505	module->wa_type = 0;
2506
2507	module->ant.type = BTC_ANT_SHARED;
2508	module->ant.num = 2;
2509	module->ant.isolation = 10;
2510	module->ant.diversity = 0;
2511	module->ant.single_pos = RF_PATH_A;
2512	module->ant.btg_pos = RF_PATH_B;
2513
2514	if (module->kt_ver <= 1)
2515		module->wa_type |= BTC_WA_HFP_ZB;
2516
2517	rtwdev->btc.cx.other.type = BTC_3CX_NONE;
2518
2519	if (module->rfe_type == 0) {
2520		rtwdev->btc.dm.error.map.rfe_type0 = true;
2521		return;
2522	}
2523
2524	module->ant.num = (module->rfe_type % 2) ?  2 : 3;
2525
2526	if (module->kt_ver == 0)
2527		module->ant.num = 2;
2528
2529	if (module->ant.num == 3) {
2530		module->ant.type = BTC_ANT_DEDICATED;
2531		module->bt_pos = BTC_BT_ALONE;
2532	} else {
2533		module->ant.type = BTC_ANT_SHARED;
2534		module->bt_pos = BTC_BT_BTG;
2535	}
2536	rtwdev->btc.btg_pos = module->ant.btg_pos;
2537	rtwdev->btc.ant_type = module->ant.type;
2538}
2539
2540static
2541void rtw8922a_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
2542{
2543	rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group);
2544	rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val);
2545}
2546
2547static void rtw8922a_btc_init_cfg(struct rtw89_dev *rtwdev)
2548{
2549	struct rtw89_btc *btc = &rtwdev->btc;
2550	struct rtw89_btc_ant_info_v7 *ant = &btc->mdinfo.md_v7.ant;
2551	u32 wl_pri, path_min, path_max;
2552	u8 path;
2553
2554	/* for 1-Ant && 1-ss case: only 1-path */
2555	if (ant->num == 1) {
2556		path_min = ant->single_pos;
2557		path_max = path_min;
2558	} else {
2559		path_min = RF_PATH_A;
2560		path_max = RF_PATH_B;
2561	}
2562
2563	path = path_min;
2564
2565	for (path = path_min; path <= path_max; path++) {
2566		/* set DEBUG_LUT_RFMODE_MASK = 1 to start trx-mask-setup */
2567		rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, BIT(17));
2568
2569		/* if GNT_WL=0 && BT=SS_group --> WL Tx/Rx = THRU  */
2570		rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_SS_GROUP, 0x5ff);
2571
2572		/* if GNT_WL=0 && BT=Rx_group --> WL-Rx = THRU + WL-Tx = MASK */
2573		rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_RX_GROUP, 0x5df);
2574
2575		/* if GNT_WL = 0 && BT = Tx_group -->
2576		 * Shared-Ant && BTG-path:WL mask(0x55f), others:WL THRU(0x5ff)
2577		 */
2578		if (btc->ant_type == BTC_ANT_SHARED && btc->btg_pos == path)
2579			rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x55f);
2580		else
2581			rtw8922a_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x5ff);
2582
2583		rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0);
2584	}
2585
2586	/* set WL PTA Hi-Pri: Ack-Tx, beacon-tx, Trig-frame-Tx, Null-Tx*/
2587	wl_pri = B_BTC_RSP_ACK_HI | B_BTC_TX_BCN_HI | B_BTC_TX_TRI_HI |
2588		 B_BTC_TX_NULL_HI;
2589	rtw89_write32(rtwdev, R_BTC_COEX_WL_REQ_BE, wl_pri);
2590
2591	/* set PTA break table */
2592	rtw89_write32(rtwdev, R_BE_BT_BREAK_TABLE, BTC_BREAK_PARAM);
2593
2594	/* ZB coex table init for HFP PTA req-cmd bit-4 define issue COEX-900*/
2595	rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, 0xda5a5a5a);
2596
2597	rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, 0xda5a5a5a);
2598
2599	rtw89_write32(rtwdev, R_BTC_ZB_BREAK_TBL, 0xf0ffffff);
2600	btc->cx.wl.status.map.init_ok = true;
2601}
2602
2603static void
2604rtw8922a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
2605{
2606	u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0));
2607	u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16));
2608
2609	switch (ctrl_all_time) {
2610	case 0xffff:
2611		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2612					     B_BE_FORCE_PWR_BY_RATE_EN, 0x0);
2613		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2614					     B_BE_FORCE_PWR_BY_RATE_VAL, 0x0);
2615		break;
2616	default:
2617		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2618					     B_BE_FORCE_PWR_BY_RATE_VAL, ctrl_all_time);
2619		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2620					     B_BE_FORCE_PWR_BY_RATE_EN, 0x1);
2621		break;
2622	}
2623
2624	switch (ctrl_gnt_bt) {
2625	case 0xffff:
2626		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL,
2627					     B_BE_PWR_BT_EN, 0x0);
2628		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL,
2629					     B_BE_PWR_BT_VAL, 0x0);
2630		break;
2631	default:
2632		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL,
2633					     B_BE_PWR_BT_VAL, ctrl_gnt_bt);
2634		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL,
2635					     B_BE_PWR_BT_EN, 0x1);
2636		break;
2637	}
2638}
2639
2640static
2641s8 rtw8922a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
2642{
2643	return clamp_t(s8, val, -100, 0) + 100;
2644}
2645
2646static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_ul[] = {
2647	{255, 0, 0, 7}, /* 0 -> original */
2648	{255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
2649	{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
2650	{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
2651	{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
2652	{255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
2653	{6, 1, 0, 7},
2654	{13, 1, 0, 7},
2655	{13, 1, 0, 7}
2656};
2657
2658static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_dl[] = {
2659	{255, 0, 0, 7}, /* 0 -> original */
2660	{255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
2661	{255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
2662	{255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
2663	{255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
2664	{255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
2665	{255, 1, 0, 7},
2666	{255, 1, 0, 7},
2667	{255, 1, 0, 7}
2668};
2669
2670static const u8 rtw89_btc_8922a_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30};
2671static const u8 rtw89_btc_8922a_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20};
2672
2673static const struct rtw89_btc_fbtc_mreg rtw89_btc_8922a_mon_reg[] = {
2674	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe300),
2675	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe320),
2676	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe324),
2677	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe328),
2678	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe32c),
2679	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe330),
2680	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe334),
2681	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe338),
2682	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe344),
2683	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe348),
2684	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe34c),
2685	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe350),
2686	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a2c),
2687	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a50),
2688	RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
2689	RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x660),
2690	RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x1660),
2691	RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x418c),
2692	RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x518c),
2693};
2694
2695static
2696void rtw8922a_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
2697{
2698	/* Feature move to firmware */
2699}
2700
2701static
2702void rtw8922a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
2703{
2704	if (!state) {
2705		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
2706		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
2707		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110);
2708		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x01018);
2709		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000);
2710
2711		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
2712		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1);
2713		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110);
2714		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x01018);
2715		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
2716	} else {
2717		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
2718		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
2719		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110);
2720		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x09018);
2721		rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000);
2722
2723		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
2724		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1);
2725		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110);
2726		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x09018);
2727		rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
2728	}
2729}
2730
2731static void rtw8922a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
2732{
2733}
2734
2735static void rtw8922a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
2736					 struct rtw89_rx_phy_ppdu *phy_ppdu,
2737					 struct ieee80211_rx_status *status)
2738{
2739	u8 chan_idx = phy_ppdu->chan_idx;
2740	enum nl80211_band band;
2741	u8 ch;
2742
2743	if (chan_idx == 0)
2744		return;
2745
2746	rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band);
2747	status->freq = ieee80211_channel_to_frequency(ch, band);
2748	status->band = band;
2749}
2750
2751static void rtw8922a_query_ppdu(struct rtw89_dev *rtwdev,
2752				struct rtw89_rx_phy_ppdu *phy_ppdu,
2753				struct ieee80211_rx_status *status)
2754{
2755	u8 path;
2756	u8 *rx_power = phy_ppdu->rssi;
2757
2758	if (!status->signal)
2759		status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A],
2760							   rx_power[RF_PATH_B]));
2761
2762	for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
2763		status->chains |= BIT(path);
2764		status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
2765	}
2766	if (phy_ppdu->valid)
2767		rtw8922a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
2768}
2769
2770static void rtw8922a_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
2771					 struct rtw89_rx_phy_ppdu *phy_ppdu)
2772{
2773	/* Mapping to BW: 5, 10, 20, 40, 80, 160, 80_80 */
2774	static const u8 bw_compensate[] = {0, 0, 0, 6, 12, 18, 0};
2775	u8 *rssi = phy_ppdu->rssi;
2776	u8 compensate = 0;
2777	u16 rpl_tmp;
2778	u8 i;
2779
2780	if (phy_ppdu->bw_idx < ARRAY_SIZE(bw_compensate))
2781		compensate = bw_compensate[phy_ppdu->bw_idx];
2782
2783	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
2784		if (!(phy_ppdu->rx_path_en & BIT(i))) {
2785			rssi[i] = 0;
2786			phy_ppdu->rpl_path[i] = 0;
2787			phy_ppdu->rpl_fd[i] = 0;
2788		}
2789		if (phy_ppdu->rate >= RTW89_HW_RATE_OFDM6) {
2790			rpl_tmp = phy_ppdu->rpl_fd[i];
2791			if (rpl_tmp)
2792				rpl_tmp += compensate;
2793
2794			phy_ppdu->rpl_path[i] = rpl_tmp;
2795		}
2796		rssi[i] = phy_ppdu->rpl_path[i];
2797	}
2798
2799	phy_ppdu->rssi_avg = phy_ppdu->rpl_avg;
2800}
2801
2802static void rtw8922a_phy_rpt_to_rssi(struct rtw89_dev *rtwdev,
2803				     struct rtw89_rx_desc_info *desc_info,
2804				     struct ieee80211_rx_status *rx_status)
2805{
2806	if (desc_info->rssi <= 0x1 || (desc_info->rssi >> 2) > MAX_RSSI)
2807		return;
2808
2809	rx_status->signal = (desc_info->rssi >> 2) - MAX_RSSI;
2810}
2811
2812static int rtw8922a_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
2813{
2814	rtw89_write8_set(rtwdev, R_BE_FEN_RST_ENABLE,
2815			 B_BE_FEN_BBPLAT_RSTB | B_BE_FEN_BB_IP_RSTN);
2816	rtw89_write32(rtwdev, R_BE_DMAC_SYS_CR32B, 0x7FF97FF9);
2817
2818	return 0;
2819}
2820
2821static int rtw8922a_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
2822{
2823	rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE,
2824			 B_BE_FEN_BBPLAT_RSTB | B_BE_FEN_BB_IP_RSTN);
2825
2826	return 0;
2827}
2828
2829static const struct rtw89_chanctx_listener rtw8922a_chanctx_listener = {
2830	.callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb,
2831};
2832
2833#ifdef CONFIG_PM
2834static const struct wiphy_wowlan_support rtw_wowlan_stub_8922a = {
2835	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
2836		 WIPHY_WOWLAN_NET_DETECT,
2837	.n_patterns = RTW89_MAX_PATTERN_NUM,
2838	.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
2839	.pattern_min_len = 1,
2840	.max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID,
2841};
2842#endif
2843
2844static const struct rtw89_chip_ops rtw8922a_chip_ops = {
2845	.enable_bb_rf		= rtw8922a_mac_enable_bb_rf,
2846	.disable_bb_rf		= rtw8922a_mac_disable_bb_rf,
2847	.bb_preinit		= rtw8922a_bb_preinit,
2848	.bb_postinit		= rtw8922a_bb_postinit,
2849	.bb_reset		= rtw8922a_bb_reset,
2850	.bb_sethw		= rtw8922a_bb_sethw,
2851	.read_rf		= rtw89_phy_read_rf_v2,
2852	.write_rf		= rtw89_phy_write_rf_v2,
2853	.set_channel		= rtw8922a_set_channel,
2854	.set_channel_help	= rtw8922a_set_channel_help,
2855	.read_efuse		= rtw8922a_read_efuse,
2856	.read_phycap		= rtw8922a_read_phycap,
2857	.fem_setup		= NULL,
2858	.rfe_gpio		= NULL,
2859	.rfk_hw_init		= rtw8922a_rfk_hw_init,
2860	.rfk_init		= rtw8922a_rfk_init,
2861	.rfk_init_late		= rtw8922a_rfk_init_late,
2862	.rfk_channel		= rtw8922a_rfk_channel,
2863	.rfk_band_changed	= rtw8922a_rfk_band_changed,
2864	.rfk_scan		= rtw8922a_rfk_scan,
2865	.rfk_track		= rtw8922a_rfk_track,
2866	.power_trim		= rtw8922a_power_trim,
2867	.set_txpwr		= rtw8922a_set_txpwr,
2868	.set_txpwr_ctrl		= rtw8922a_set_txpwr_ctrl,
2869	.init_txpwr_unit	= NULL,
2870	.get_thermal		= rtw8922a_get_thermal,
2871	.chan_to_rf18_val	= rtw8922a_chan_to_rf18_val,
2872	.ctrl_btg_bt_rx		= rtw8922a_ctrl_btg_bt_rx,
2873	.query_ppdu		= rtw8922a_query_ppdu,
2874	.convert_rpl_to_rssi	= rtw8922a_convert_rpl_to_rssi,
2875	.phy_rpt_to_rssi	= rtw8922a_phy_rpt_to_rssi,
2876	.ctrl_nbtg_bt_tx	= rtw8922a_ctrl_nbtg_bt_tx,
2877	.cfg_txrx_path		= rtw8922a_bb_cfg_txrx_path,
2878	.set_txpwr_ul_tb_offset	= NULL,
2879	.digital_pwr_comp	= rtw8922a_digital_pwr_comp,
2880	.pwr_on_func		= rtw8922a_pwr_on_func,
2881	.pwr_off_func		= rtw8922a_pwr_off_func,
2882	.query_rxdesc		= rtw89_core_query_rxdesc_v2,
2883	.fill_txdesc		= rtw89_core_fill_txdesc_v2,
2884	.fill_txdesc_fwcmd	= rtw89_core_fill_txdesc_fwcmd_v2,
2885	.get_ch_dma		= {rtw89_core_get_ch_dma,
2886				   rtw89_core_get_ch_dma_v2,
2887				   NULL,},
2888	.cfg_ctrl_path		= rtw89_mac_cfg_ctrl_path_v2,
2889	.mac_cfg_gnt		= rtw89_mac_cfg_gnt_v2,
2890	.stop_sch_tx		= rtw89_mac_stop_sch_tx_v2,
2891	.resume_sch_tx		= rtw89_mac_resume_sch_tx_v2,
2892	.h2c_dctl_sec_cam	= rtw89_fw_h2c_dctl_sec_cam_v2,
2893	.h2c_default_cmac_tbl	= rtw89_fw_h2c_default_cmac_tbl_g7,
2894	.h2c_assoc_cmac_tbl	= rtw89_fw_h2c_assoc_cmac_tbl_g7,
2895	.h2c_ampdu_cmac_tbl	= rtw89_fw_h2c_ampdu_cmac_tbl_g7,
2896	.h2c_txtime_cmac_tbl	= rtw89_fw_h2c_txtime_cmac_tbl_g7,
2897	.h2c_punctured_cmac_tbl	= rtw89_fw_h2c_punctured_cmac_tbl_g7,
2898	.h2c_default_dmac_tbl	= rtw89_fw_h2c_default_dmac_tbl_v2,
2899	.h2c_update_beacon	= rtw89_fw_h2c_update_beacon_be,
2900	.h2c_ba_cam		= rtw89_fw_h2c_ba_cam_v1,
2901
2902	.btc_set_rfe		= rtw8922a_btc_set_rfe,
2903	.btc_init_cfg		= rtw8922a_btc_init_cfg,
2904	.btc_set_wl_pri		= NULL,
2905	.btc_set_wl_txpwr_ctrl	= rtw8922a_btc_set_wl_txpwr_ctrl,
2906	.btc_get_bt_rssi	= rtw8922a_btc_get_bt_rssi,
2907	.btc_update_bt_cnt	= rtw8922a_btc_update_bt_cnt,
2908	.btc_wl_s1_standby	= rtw8922a_btc_wl_s1_standby,
2909	.btc_set_wl_rx_gain	= rtw8922a_btc_set_wl_rx_gain,
2910	.btc_set_policy		= rtw89_btc_set_policy_v1,
2911};
2912
2913const struct rtw89_chip_info rtw8922a_chip_info = {
2914	.chip_id		= RTL8922A,
2915	.chip_gen		= RTW89_CHIP_BE,
2916	.ops			= &rtw8922a_chip_ops,
2917	.mac_def		= &rtw89_mac_gen_be,
2918	.phy_def		= &rtw89_phy_gen_be,
2919	.fw_basename		= RTW8922A_FW_BASENAME,
2920	.fw_format_max		= RTW8922A_FW_FORMAT_MAX,
2921	.try_ce_fw		= false,
2922	.bbmcu_nr		= 1,
2923	.needed_fw_elms		= RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS,
2924	.fw_blacklist		= &rtw89_fw_blacklist_default,
2925	.fifo_size		= 589824,
2926	.small_fifo_size	= false,
2927	.dle_scc_rsvd_size	= 0,
2928	.max_amsdu_limit	= 8000,
2929	.dis_2g_40m_ul_ofdma	= false,
2930	.rsvd_ple_ofst		= 0x8f800,
2931	.hfc_param_ini		= {rtw8922a_hfc_param_ini_pcie, NULL, NULL},
2932	.dle_mem		= {rtw8922a_dle_mem_pcie, NULL, NULL, NULL},
2933	.wde_qempty_acq_grpnum	= 4,
2934	.wde_qempty_mgq_grpsel	= 4,
2935	.rf_base_addr		= {0xe000, 0xf000},
2936	.thermal_th		= {0xad, 0xb4},
2937	.pwr_on_seq		= NULL,
2938	.pwr_off_seq		= NULL,
2939	.bb_table		= NULL,
2940	.bb_gain_table		= NULL,
2941	.rf_table		= {},
2942	.nctl_table		= NULL,
2943	.nctl_post_table	= NULL,
2944	.dflt_parms		= NULL, /* load parm from fw */
2945	.rfe_parms_conf		= NULL, /* load parm from fw */
2946	.chanctx_listener	= &rtw8922a_chanctx_listener,
2947	.txpwr_factor_bb	= 3,
2948	.txpwr_factor_rf	= 2,
2949	.txpwr_factor_mac	= 1,
2950	.dig_table		= NULL,
2951	.dig_regs		= &rtw8922a_dig_regs,
2952	.tssi_dbw_table		= NULL,
2953	.support_macid_num	= 32,
2954	.support_link_num	= 2,
2955	.support_chanctx_num	= 2,
2956	.support_rnr		= true,
2957	.support_bands		= BIT(NL80211_BAND_2GHZ) |
2958				  BIT(NL80211_BAND_5GHZ) |
2959				  BIT(NL80211_BAND_6GHZ),
2960	.support_bandwidths	= BIT(NL80211_CHAN_WIDTH_20) |
2961				  BIT(NL80211_CHAN_WIDTH_40) |
2962				  BIT(NL80211_CHAN_WIDTH_80) |
2963				  BIT(NL80211_CHAN_WIDTH_160),
2964	.support_unii4		= true,
2965	.support_ant_gain	= true,
2966	.support_tas		= true,
2967	.support_sar_by_ant	= true,
2968	.support_noise		= false,
2969	.ul_tb_waveform_ctrl	= false,
2970	.ul_tb_pwr_diff		= false,
2971	.rx_freq_frome_ie	= false,
2972	.hw_sec_hdr		= true,
2973	.hw_mgmt_tx_encrypt	= true,
2974	.hw_tkip_crypto		= true,
2975	.hw_mlo_bmc_crypto	= false,
2976	.rf_path_num		= 2,
2977	.tx_nss			= 2,
2978	.rx_nss			= 2,
2979	.acam_num		= 128,
2980	.bcam_num		= 20,
2981	.scam_num		= 32,
2982	.bacam_num		= 24,
2983	.bacam_dynamic_num	= 8,
2984	.bacam_ver		= RTW89_BACAM_V1,
2985	.addrcam_ver		= 0,
2986	.ppdu_max_usr		= 16,
2987	.sec_ctrl_efuse_size	= 4,
2988	.physical_efuse_size	= 0x1300,
2989	.logical_efuse_size	= 0x70000,
2990	.limit_efuse_size	= 0x40000,
2991	.dav_phy_efuse_size	= 0,
2992	.dav_log_efuse_size	= 0,
2993	.efuse_blocks		= rtw8922a_efuse_blocks,
2994	.phycap_addr		= 0x1700,
2995	.phycap_size		= 0x38,
2996	.para_ver		= 0xf,
2997	.wlcx_desired		= 0x07110000,
2998	.scbd			= 0x1,
2999	.mailbox		= 0x1,
3000
3001	.afh_guard_ch		= 6,
3002	.wl_rssi_thres		= rtw89_btc_8922a_wl_rssi_thres,
3003	.bt_rssi_thres		= rtw89_btc_8922a_bt_rssi_thres,
3004	.rssi_tol		= 2,
3005	.mon_reg_num		= ARRAY_SIZE(rtw89_btc_8922a_mon_reg),
3006	.mon_reg		= rtw89_btc_8922a_mon_reg,
3007	.rf_para_ulink_num	= ARRAY_SIZE(rtw89_btc_8922a_rf_ul),
3008	.rf_para_ulink		= rtw89_btc_8922a_rf_ul,
3009	.rf_para_dlink_num	= ARRAY_SIZE(rtw89_btc_8922a_rf_dl),
3010	.rf_para_dlink		= rtw89_btc_8922a_rf_dl,
3011	.ps_mode_supported	= BIT(RTW89_PS_MODE_RFOFF) |
3012				  BIT(RTW89_PS_MODE_CLK_GATED) |
3013				  BIT(RTW89_PS_MODE_PWR_GATED),
3014	.low_power_hci_modes	= 0,
3015	.h2c_cctl_func_id	= H2C_FUNC_MAC_CCTLINFO_UD_G7,
3016	.hci_func_en_addr	= R_BE_HCI_FUNC_EN,
3017	.h2c_desc_size		= sizeof(struct rtw89_rxdesc_short_v2),
3018	.txwd_body_size		= sizeof(struct rtw89_txwd_body_v2),
3019	.txwd_info_size		= sizeof(struct rtw89_txwd_info_v2),
3020	.h2c_ctrl_reg		= R_BE_H2CREG_CTRL,
3021	.h2c_counter_reg	= {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8},
3022	.h2c_regs		= rtw8922a_h2c_regs,
3023	.c2h_ctrl_reg		= R_BE_C2HREG_CTRL,
3024	.c2h_counter_reg	= {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
3025	.c2h_regs		= rtw8922a_c2h_regs,
3026	.page_regs		= &rtw8922a_page_regs,
3027	.wow_reason_reg		= rtw8922a_wow_wakeup_regs,
3028	.cfo_src_fd		= true,
3029	.cfo_hw_comp            = true,
3030	.dcfo_comp		= NULL,
3031	.dcfo_comp_sft		= 0,
3032	.nhm_report		= NULL,
3033	.nhm_th			= NULL,
3034	.imr_info		= NULL,
3035	.imr_dmac_table		= &rtw8922a_imr_dmac_table,
3036	.imr_cmac_table		= &rtw8922a_imr_cmac_table,
3037	.rrsr_cfgs		= &rtw8922a_rrsr_cfgs,
3038	.bss_clr_vld		= {R_BSS_CLR_VLD_V2, B_BSS_CLR_VLD0_V2},
3039	.bss_clr_map_reg	= R_BSS_CLR_MAP_V2,
3040	.rfkill_init		= &rtw8922a_rfkill_regs,
3041	.rfkill_get		= {R_BE_GPIO_EXT_CTRL, B_BE_GPIO_IN_9},
3042	.dma_ch_mask		= 0,
3043	.edcca_regs		= &rtw8922a_edcca_regs,
3044#ifdef CONFIG_PM
3045	.wowlan_stub		= &rtw_wowlan_stub_8922a,
3046#endif
3047	.xtal_info		= NULL,
3048};
3049EXPORT_SYMBOL(rtw8922a_chip_info);
3050
3051const struct rtw89_chip_variant rtw8922ae_vs_variant = {
3052	.no_mcs_12_13 = true,
3053	.fw_min_ver_code = RTW89_FW_VER_CODE(0, 35, 54, 0),
3054};
3055EXPORT_SYMBOL(rtw8922ae_vs_variant);
3056
3057MODULE_FIRMWARE(RTW8922A_MODULE_FIRMWARE);
3058MODULE_AUTHOR("Realtek Corporation");
3059MODULE_DESCRIPTION("Realtek 802.11be wireless 8922A driver");
3060MODULE_LICENSE("Dual BSD/GPL");
~/ Read-only file preview.