xref: /linux/drivers/net/wireless/realtek/rtw89/rtw8922d.c (revision 91a4855d6c03e770e42f17c798a36a3c46e63de2)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2026  Realtek Corporation
3  */
4 
5 #include "chan.h"
6 #include "coex.h"
7 #include "debug.h"
8 #include "efuse.h"
9 #include "mac.h"
10 #include "phy.h"
11 #include "reg.h"
12 #include "rtw8922d.h"
13 #include "rtw8922d_rfk.h"
14 #include "sar.h"
15 #include "util.h"
16 
17 #define RTW8922D_FW_FORMAT_MAX 0
18 #define RTW8922D_FW_BASENAME "rtw89/rtw8922d_fw"
19 #define RTW8922D_MODULE_FIRMWARE \
20 	RTW89_GEN_MODULE_FWNAME(RTW8922D_FW_BASENAME, RTW8922D_FW_FORMAT_MAX)
21 
22 #define RTW8922DS_FW_FORMAT_MAX 0
23 #define RTW8922DS_FW_BASENAME "rtw89/rtw8922ds_fw"
24 #define RTW8922DS_MODULE_FIRMWARE \
25 	RTW89_GEN_MODULE_FWNAME(RTW8922DS_FW_BASENAME, RTW8922DS_FW_FORMAT_MAX)
26 
27 static const struct rtw89_hfc_ch_cfg rtw8922d_hfc_chcfg_pcie[] = {
28 	{2, 603, 0}, /* ACH 0 */
29 	{0, 601, 0}, /* ACH 1 */
30 	{2, 603, 0}, /* ACH 2 */
31 	{0, 601, 0}, /* ACH 3 */
32 	{2, 603, 0}, /* ACH 4 */
33 	{0, 601, 0}, /* ACH 5 */
34 	{2, 603, 0}, /* ACH 6 */
35 	{0, 601, 0}, /* ACH 7 */
36 	{2, 603, 0}, /* B0MGQ */
37 	{0, 601, 0}, /* B0HIQ */
38 	{2, 603, 0}, /* B1MGQ */
39 	{0, 601, 0}, /* B1HIQ */
40 	{0, 0, 0}, /* FWCMDQ */
41 	{0, 0, 0}, /* BMC */
42 	{0, 0, 0}, /* H2D */
43 };
44 
45 static const struct rtw89_hfc_pub_cfg rtw8922d_hfc_pubcfg_pcie = {
46 	613, /* Group 0 */
47 	0, /* Group 1 */
48 	613, /* Public Max */
49 	0, /* WP threshold */
50 };
51 
52 static const struct rtw89_hfc_param_ini rtw8922d_hfc_param_ini_pcie[] = {
53 	[RTW89_QTA_SCC] = {rtw8922d_hfc_chcfg_pcie, &rtw8922d_hfc_pubcfg_pcie,
54 			   &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH},
55 	[RTW89_QTA_DBCC] = {rtw8922d_hfc_chcfg_pcie, &rtw8922d_hfc_pubcfg_pcie,
56 			   &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH},
57 	[RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2,
58 			    RTW89_HCIFC_POH},
59 	[RTW89_QTA_INVALID] = {NULL},
60 };
61 
62 static const struct rtw89_dle_mem rtw8922d_dle_mem_pcie[] = {
63 	[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size16_v1,
64 			   &rtw89_mac_size.ple_size20_v1, &rtw89_mac_size.wde_qt19_v1,
65 			   &rtw89_mac_size.wde_qt19_v1, &rtw89_mac_size.ple_qt42_v2,
66 			   &rtw89_mac_size.ple_qt43_v2, &rtw89_mac_size.ple_rsvd_qt9,
67 			   &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size2,
68 			   &rtw89_mac_size.dle_input18},
69 	[RTW89_QTA_DBCC] = {RTW89_QTA_DBCC, &rtw89_mac_size.wde_size16_v1,
70 			   &rtw89_mac_size.ple_size20_v1, &rtw89_mac_size.wde_qt19_v1,
71 			   &rtw89_mac_size.wde_qt19_v1, &rtw89_mac_size.ple_qt42_v2,
72 			   &rtw89_mac_size.ple_qt43_v2, &rtw89_mac_size.ple_rsvd_qt9,
73 			   &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size2,
74 			   &rtw89_mac_size.dle_input18},
75 	[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18_v1,
76 			    &rtw89_mac_size.ple_size22_v1, &rtw89_mac_size.wde_qt3,
77 			    &rtw89_mac_size.wde_qt3, &rtw89_mac_size.ple_qt5_v2,
78 			    &rtw89_mac_size.ple_qt5_v2, &rtw89_mac_size.ple_rsvd_qt1,
79 			    &rtw89_mac_size.rsvd0_size6, &rtw89_mac_size.rsvd1_size2,
80 			    &rtw89_mac_size.dle_input3},
81 	[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
82 			       NULL},
83 };
84 
85 static const u32 rtw8922d_h2c_regs[RTW89_H2CREG_MAX] = {
86 	R_BE_H2CREG_DATA0, R_BE_H2CREG_DATA1, R_BE_H2CREG_DATA2,
87 	R_BE_H2CREG_DATA3
88 };
89 
90 static const u32 rtw8922d_c2h_regs[RTW89_H2CREG_MAX] = {
91 	R_BE_C2HREG_DATA0, R_BE_C2HREG_DATA1, R_BE_C2HREG_DATA2,
92 	R_BE_C2HREG_DATA3
93 };
94 
95 static const u32 rtw8922d_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
96 	R_BE_DBG_WOW, R_BE_DBG_WOW,
97 };
98 
99 static const struct rtw89_page_regs rtw8922d_page_regs = {
100 	.hci_fc_ctrl	= R_BE_HCI_FC_CTRL,
101 	.ch_page_ctrl	= R_BE_CH_PAGE_CTRL,
102 	.ach_page_ctrl	= R_BE_CH0_PAGE_CTRL,
103 	.ach_page_info	= R_BE_CH0_PAGE_INFO,
104 	.pub_page_info3	= R_BE_PUB_PAGE_INFO3,
105 	.pub_page_ctrl1	= R_BE_PUB_PAGE_CTRL1,
106 	.pub_page_ctrl2	= R_BE_PUB_PAGE_CTRL2,
107 	.pub_page_info1	= R_BE_PUB_PAGE_INFO1,
108 	.pub_page_info2 = R_BE_PUB_PAGE_INFO2,
109 	.wp_page_ctrl1	= R_BE_WP_PAGE_CTRL1,
110 	.wp_page_ctrl2	= R_BE_WP_PAGE_CTRL2,
111 	.wp_page_info1	= R_BE_WP_PAGE_INFO1,
112 };
113 
114 static const struct rtw89_reg_imr rtw8922d_imr_dmac_regs[] = {
115 	{R_BE_HCI_BUF_IMR, B_BE_HCI_BUF_IMR_CLR, B_BE_HCI_BUF_IMR_SET},
116 	{R_BE_DISP_HOST_IMR, B_BE_DISP_HOST_IMR_CLR_V1, B_BE_DISP_HOST_IMR_SET_V1},
117 	{R_BE_DISP_CPU_IMR, B_BE_DISP_CPU_IMR_CLR_V1, B_BE_DISP_CPU_IMR_SET_V1},
118 	{R_BE_DISP_OTHER_IMR, B_BE_DISP_OTHER_IMR_CLR_V1, B_BE_DISP_OTHER_IMR_SET_V1},
119 	{R_BE_PKTIN_ERR_IMR, B_BE_PKTIN_ERR_IMR_CLR, B_BE_PKTIN_ERR_IMR_SET},
120 	{R_BE_MLO_ERR_IDCT_IMR, B_BE_MLO_ERR_IDCT_IMR_CLR, B_BE_MLO_ERR_IDCT_IMR_SET},
121 	{R_BE_MPDU_TX_ERR_IMR, B_BE_MPDU_TX_ERR_IMR_CLR, B_BE_MPDU_TX_ERR_IMR_SET},
122 	{R_BE_MPDU_RX_ERR_IMR, B_BE_MPDU_RX_ERR_IMR_CLR, B_BE_MPDU_RX_ERR_IMR_SET},
123 	{R_BE_SEC_ERROR_IMR, B_BE_SEC_ERROR_IMR_CLR, B_BE_SEC_ERROR_IMR_SET},
124 	{R_BE_CPUIO_ERR_IMR, B_BE_CPUIO_ERR_IMR_CLR, B_BE_CPUIO_ERR_IMR_SET},
125 	{R_BE_WDE_ERR_IMR, B_BE_WDE_ERR_IMR_CLR, B_BE_WDE_ERR_IMR_SET},
126 	{R_BE_PLE_ERR_IMR, B_BE_PLE_ERR_IMR_CLR, B_BE_PLE_ERR_IMR_SET},
127 	{R_BE_WDRLS_ERR_IMR, B_BE_WDRLS_ERR_IMR_CLR, B_BE_WDRLS_ERR_IMR_SET},
128 	{R_BE_TXPKTCTL_B0_ERRFLAG_IMR, B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR,
129 	 B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET},
130 	{R_BE_TXPKTCTL_B1_ERRFLAG_IMR, B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR,
131 	 B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET},
132 	{R_BE_BBRPT_COM_ERR_IMR, B_BE_BBRPT_COM_ERR_IMR_CLR, B_BE_BBRPT_COM_ERR_IMR_SET},
133 	{R_BE_BBRPT_CHINFO_ERR_IMR, B_BE_BBRPT_CHINFO_ERR_IMR_CLR,
134 	 B_BE_BBRPT_CHINFO_ERR_IMR_SET},
135 	{R_BE_BBRPT_DFS_ERR_IMR, B_BE_BBRPT_DFS_ERR_IMR_CLR, B_BE_BBRPT_DFS_ERR_IMR_SET},
136 	{R_BE_LA_ERRFLAG_IMR, B_BE_LA_ERRFLAG_IMR_CLR, B_BE_LA_ERRFLAG_IMR_SET},
137 	{R_BE_CH_INFO_DBGFLAG_IMR, B_BE_CH_INFO_DBGFLAG_IMR_CLR, B_BE_CH_INFO_DBGFLAG_IMR_SET},
138 	{R_BE_PLRLS_ERR_IMR_V1, B_BE_PLRLS_ERR_IMR_V1_CLR, B_BE_PLRLS_ERR_IMR_V1_SET},
139 	{R_BE_HAXI_IDCT_MSK, B_BE_HAXI_IDCT_MSK_CLR, B_BE_HAXI_IDCT_MSK_SET},
140 };
141 
142 static const struct rtw89_imr_table rtw8922d_imr_dmac_table = {
143 	.regs = rtw8922d_imr_dmac_regs,
144 	.n_regs = ARRAY_SIZE(rtw8922d_imr_dmac_regs),
145 };
146 
147 static const struct rtw89_reg_imr rtw8922d_imr_cmac_regs[] = {
148 	{R_BE_RESP_IMR, B_BE_RESP_IMR_CLR_V1, B_BE_RESP_IMR_SET_V1},
149 	{R_BE_RESP_IMR1, B_BE_RESP_IMR1_CLR, B_BE_RESP_IMR1_SET},
150 	{R_BE_RX_ERROR_FLAG_IMR, B_BE_RX_ERROR_FLAG_IMR_CLR_V1, B_BE_RX_ERROR_FLAG_IMR_SET_V1},
151 	{R_BE_TX_ERROR_FLAG_IMR, B_BE_TX_ERROR_FLAG_IMR_CLR, B_BE_TX_ERROR_FLAG_IMR_SET},
152 	{R_BE_RX_ERROR_FLAG_IMR_1, B_BE_TX_ERROR_FLAG_IMR_1_CLR, B_BE_TX_ERROR_FLAG_IMR_1_SET},
153 	{R_BE_PTCL_IMR1, B_BE_PTCL_IMR1_CLR, B_BE_PTCL_IMR1_SET},
154 	{R_BE_PTCL_IMR0, B_BE_PTCL_IMR0_CLR, B_BE_PTCL_IMR0_SET},
155 	{R_BE_PTCL_IMR_2, B_BE_PTCL_IMR_2_CLR, B_BE_PTCL_IMR_2_SET},
156 	{R_BE_SCHEDULE_ERR_IMR, B_BE_SCHEDULE_ERR_IMR_CLR, B_BE_SCHEDULE_ERR_IMR_SET},
157 	{R_BE_C0_TXPWR_IMR, B_BE_C0_TXPWR_IMR_CLR, B_BE_C0_TXPWR_IMR_SET},
158 	{R_BE_TRXPTCL_ERROR_INDICA_MASK, B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR,
159 	 B_BE_TRXPTCL_ERROR_INDICA_MASK_SET},
160 	{R_BE_RX_ERR_IMR, B_BE_RX_ERR_IMR_CLR, B_BE_RX_ERR_IMR_SET},
161 	{R_BE_PHYINFO_ERR_IMR_V1, B_BE_PHYINFO_ERR_IMR_V1_CLR, B_BE_PHYINFO_ERR_IMR_V1_SET},
162 };
163 
164 static const struct rtw89_imr_table rtw8922d_imr_cmac_table = {
165 	.regs = rtw8922d_imr_cmac_regs,
166 	.n_regs = ARRAY_SIZE(rtw8922d_imr_cmac_regs),
167 };
168 
169 static const struct rtw89_rrsr_cfgs rtw8922d_rrsr_cfgs = {
170 	.ref_rate = {R_BE_TRXPTCL_RESP_1, B_BE_WMAC_RESP_REF_RATE_SEL, 0},
171 	.rsc = {R_BE_PTCL_RRSR1, B_BE_RSC_MASK, 2},
172 };
173 
174 static const struct rtw89_rfkill_regs rtw8922d_rfkill_regs = {
175 	.pinmux = {R_BE_GPIO8_15_FUNC_SEL,
176 		   B_BE_PINMUX_GPIO9_FUNC_SEL_MASK,
177 		   0xf},
178 	.mode = {R_BE_GPIO_EXT_CTRL + 2,
179 		 (B_BE_GPIO_MOD_9 | B_BE_GPIO_IO_SEL_9) >> 16,
180 		 0x0},
181 };
182 
183 static const struct rtw89_dig_regs rtw8922d_dig_regs = {
184 	.seg0_pd_reg = R_SEG0R_PD_BE4,
185 	.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
186 	.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1,
187 	.bmode_pd_reg = R_BMODE_PDTH_EN_BE4,
188 	.bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
189 	.bmode_pd_lower_bound_reg = R_BMODE_PDTH_BE4,
190 	.bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
191 	.p0_lna_init = {R_PATH0_LNA_INIT_BE4, B_PATH0_LNA_INIT_IDX_BE4},
192 	.p1_lna_init = {R_PATH1_LNA_INIT_BE4, B_PATH1_LNA_INIT_IDX_BE4},
193 	.p0_tia_init = {R_PATH0_TIA_INIT_BE4, B_PATH0_TIA_INIT_IDX_BE4},
194 	.p1_tia_init = {R_PATH1_TIA_INIT_BE4, B_PATH1_TIA_INIT_IDX_BE4},
195 	.p0_rxb_init = {R_PATH0_RXIDX_INIT_BE4, B_PATH0_RXIDX_INIT_BE4},
196 	.p1_rxb_init = {R_PATH1_RXIDX_INIT_BE4, B_PATH1_RXIDX_INIT_BE4},
197 	.p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_BE4,
198 			      B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
199 	.p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_BE4,
200 			      B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
201 	.p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_BE4,
202 			      B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
203 	.p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_BE4,
204 			      B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
205 };
206 
207 static const struct rtw89_edcca_regs rtw8922d_edcca_regs = {
208 	.edcca_level			= R_SEG0R_EDCCA_LVL_BE4,
209 	.edcca_mask			= B_EDCCA_LVL_MSK0,
210 	.edcca_p_mask			= B_EDCCA_LVL_MSK1,
211 	.ppdu_level			= R_SEG0R_PPDU_LVL_BE4,
212 	.ppdu_mask			= B_EDCCA_LVL_MSK1,
213 	.p = {{
214 		.rpt_a			= R_EDCCA_RPT_A_BE4,
215 		.rpt_b			= R_EDCCA_RPT_B_BE4,
216 		.rpt_sel		= R_EDCCA_RPT_SEL_BE4,
217 		.rpt_sel_mask		= B_EDCCA_RPT_SEL_BE4_MSK,
218 	}, {
219 		.rpt_a			= R_EDCCA_RPT_A_BE4_C1,
220 		.rpt_b			= R_EDCCA_RPT_A_BE4_C1,
221 		.rpt_sel		= R_EDCCA_RPT_SEL_BE4_C1,
222 		.rpt_sel_mask		= B_EDCCA_RPT_SEL_BE4_MSK,
223 	}},
224 	.rpt_sel_be			= R_EDCCA_RPTREG_SEL_BE4,
225 	.rpt_sel_be_mask		= B_EDCCA_RPTREG_SEL_BE_MSK,
226 	.tx_collision_t2r_st		= R_TX_COLLISION_T2R_ST_BE4,
227 	.tx_collision_t2r_st_mask	= B_TX_COLLISION_T2R_ST_BE_M,
228 };
229 
230 static const struct rtw89_efuse_block_cfg rtw8922d_efuse_blocks[] = {
231 	[RTW89_EFUSE_BLOCK_SYS]			= {.offset = 0x00000, .size = 0x310},
232 	[RTW89_EFUSE_BLOCK_RF]			= {.offset = 0x10000, .size = 0x240},
233 	[RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO]	= {.offset = 0x20000, .size = 0x4800},
234 	[RTW89_EFUSE_BLOCK_HCI_DIG_USB]		= {.offset = 0x30000, .size = 0x890},
235 	[RTW89_EFUSE_BLOCK_HCI_PHY_PCIE]	= {.offset = 0x40000, .size = 0x400},
236 	[RTW89_EFUSE_BLOCK_HCI_PHY_USB3]	= {.offset = 0x50000, .size = 0x80},
237 	[RTW89_EFUSE_BLOCK_HCI_PHY_USB2]	= {.offset = 0x60000, .size = 0x50},
238 	[RTW89_EFUSE_BLOCK_ADIE]		= {.offset = 0x70000, .size = 0x10},
239 };
240 
241 static void rtw8922d_sel_bt_rx_path(struct rtw89_dev *rtwdev, u8 val,
242 				    enum rtw89_rf_path rx_path)
243 {
244 	if (rx_path == RF_PATH_A)
245 		rtw89_phy_write32_mask(rtwdev, R_SEL_GNT_BT_RX_BE4,
246 				       B_SEL_GNT_BT_RX_PATH0_BE4, val);
247 	else if (rx_path == RF_PATH_B)
248 		rtw89_phy_write32_mask(rtwdev, R_SEL_GNT_BT_RX_BE4,
249 				       B_SEL_GNT_BT_RX_PATH1_BE4, val);
250 	else
251 		rtw89_warn(rtwdev, "[%s] Not support path = %d\n", __func__, rx_path);
252 }
253 
254 static void rtw8922d_sel_bt_rx_phy(struct rtw89_dev *rtwdev, u8 val,
255 				   enum rtw89_phy_idx phy_idx)
256 {
257 	rtw89_phy_write32_idx(rtwdev, R_SEL_GNT_BT_RXPHY_BE4,
258 			      B_SEL_GNT_BT_RXPHY_BE4, val, phy_idx);
259 }
260 
261 static void rtw8922d_set_gbt_bt_rx_sel(struct rtw89_dev *rtwdev, bool en,
262 				       enum rtw89_phy_idx phy_idx)
263 {
264 	rtw8922d_sel_bt_rx_path(rtwdev, 0x3, RF_PATH_A);
265 	rtw8922d_sel_bt_rx_phy(rtwdev, 0x0, RTW89_PHY_0);
266 	rtw8922d_sel_bt_rx_path(rtwdev, 0x3, RF_PATH_B);
267 	rtw8922d_sel_bt_rx_phy(rtwdev, 0x0, RTW89_PHY_1);
268 }
269 
270 static int rtw8922d_pwr_on_func(struct rtw89_dev *rtwdev)
271 {
272 	struct rtw89_hal *hal = &rtwdev->hal;
273 	u32 val32;
274 	int ret;
275 
276 	if (hal->cid != RTL8922D_CID7025)
277 		goto begin;
278 
279 	switch (hal->cv) {
280 	case CHIP_CAV:
281 	case CHIP_CBV:
282 		rtw89_write32_set(rtwdev, R_BE_SPS_DIG_ON_CTRL1, B_BE_PWM_FORCE);
283 		rtw89_write32_set(rtwdev, R_BE_SPS_ANA_ON_CTRL1, B_BE_PWM_FORCE_ANA);
284 		break;
285 	default:
286 		break;
287 	}
288 
289 begin:
290 	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_AFSM_WLSUS_EN |
291 						    B_BE_AFSM_PCIE_SUS_EN);
292 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_DIS_WLBT_PDNSUSEN_SOPC);
293 	rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_DIS_WLBT_LPSEN_LOPC);
294 	if (hal->cid != RTL8922D_CID7090)
295 		rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APDM_HPDN);
296 	rtw89_write32_clr(rtwdev, R_BE_FWS1ISR, B_BE_FS_WL_HW_RADIO_OFF_INT);
297 	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
298 
299 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_RDY_SYSPWR,
300 				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
301 	if (ret)
302 		return ret;
303 
304 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
305 	rtw89_write32_set(rtwdev, R_BE_WLRESUME_CTRL, B_BE_LPSROP_CMAC0 |
306 						      B_BE_LPSROP_CMAC1);
307 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFN_ONMAC);
308 
309 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFN_ONMAC),
310 				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
311 	if (ret)
312 		return ret;
313 
314 	rtw89_write8_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_PLATFORM_EN);
315 	rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
316 
317 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HAXIDMA_IO_ST,
318 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
319 	if (ret)
320 		return ret;
321 
322 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
323 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
324 	if (ret)
325 		return ret;
326 
327 	rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
328 
329 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HCI_WLAN_IO_ST,
330 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
331 	if (ret)
332 		return ret;
333 
334 	rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN);
335 
336 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_NORMAL_WRITE, 0x10, 0x10);
337 	if (ret)
338 		return ret;
339 
340 	rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3);
341 
342 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x40, 0x40);
343 	if (ret)
344 		return ret;
345 
346 	rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3);
347 
348 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x20, 0x20);
349 	if (ret)
350 		return ret;
351 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x04, 0x04);
352 	if (ret)
353 		return ret;
354 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x08, 0x08);
355 	if (ret)
356 		return ret;
357 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x10);
358 	if (ret)
359 		return ret;
360 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xEB, 0xFF);
361 	if (ret)
362 		return ret;
363 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xEB, 0xFF);
364 	if (ret)
365 		return ret;
366 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x01, 0x01);
367 	if (ret)
368 		return ret;
369 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x02, 0x02);
370 	if (ret)
371 		return ret;
372 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x80);
373 	if (ret)
374 		return ret;
375 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, 0x70);
376 	if (ret)
377 		return ret;
378 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, 0x02);
379 	if (ret)
380 		return ret;
381 
382 	rtw89_write32_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
383 	rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE);
384 	rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B);
385 
386 	mdelay(1);
387 
388 	rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S);
389 	rtw89_write32_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
390 
391 	rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN,
392 			  B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN |
393 			  B_BE_MPDU_PROC_EN | B_BE_WD_RLS_EN |
394 			  B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN |
395 			  B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN |
396 			  B_BE_PKT_BUF_EN | B_BE_DMAC_TBL_EN |
397 			  B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN |
398 			  B_BE_DISPATCHER_EN | B_BE_BBRPT_EN |
399 			  B_BE_MAC_SEC_EN | B_BE_H_AXIDMA_EN |
400 			  B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN |
401 			  B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN |
402 			  B_BE_LTR_CTL_EN);
403 
404 	set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
405 
406 	rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN,
407 			  B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN |
408 			  B_BE_ADDRSRCH_EN | B_BE_BTCOEX_EN);
409 
410 	rtw89_write32_set(rtwdev, R_BE_CMAC_FUNC_EN,
411 			  B_BE_CMAC_EN | B_BE_CMAC_TXEN |
412 			  B_BE_CMAC_RXEN | B_BE_SIGB_EN |
413 			  B_BE_PHYINTF_EN | B_BE_CMAC_DMA_EN |
414 			  B_BE_PTCLTOP_EN | B_BE_SCHEDULER_EN |
415 			  B_BE_TMAC_EN | B_BE_RMAC_EN |
416 			  B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN);
417 
418 	set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
419 
420 	rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE,
421 			  B_BE_FEN_BB_IP_RSTN | B_BE_FEN_BBPLAT_RSTB);
422 
423 	return 0;
424 }
425 
426 static int rtw8922d_pwr_off_func(struct rtw89_dev *rtwdev)
427 {
428 	u32 val32;
429 	int ret;
430 
431 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x10, 0x10);
432 	if (ret)
433 		return ret;
434 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x08);
435 	if (ret)
436 		return ret;
437 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x04);
438 	if (ret)
439 		return ret;
440 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, 0x01);
441 	if (ret)
442 		return ret;
443 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, 0x01);
444 	if (ret)
445 		return ret;
446 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x80, 0x80);
447 	if (ret)
448 		return ret;
449 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x02);
450 	if (ret)
451 		return ret;
452 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x01);
453 	if (ret)
454 		return ret;
455 
456 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
457 	rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
458 						      B_BE_FEN_BBPLAT_RSTB);
459 	rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL,
460 			  B_BE_SYM_PADPDN_WL_RFC0_1P3);
461 
462 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x20);
463 	if (ret)
464 		return ret;
465 
466 	rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL,
467 			  B_BE_SYM_PADPDN_WL_RFC1_1P3);
468 
469 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x40);
470 	if (ret)
471 		return ret;
472 
473 	rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
474 
475 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_IO_ST),
476 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
477 	if (ret)
478 		return ret;
479 	ret = read_poll_timeout(rtw89_read32, val32,
480 				!(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
481 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
482 	if (ret)
483 		return ret;
484 
485 	rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
486 
487 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HCI_WLAN_IO_ST),
488 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
489 	if (ret)
490 		return ret;
491 
492 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC);
493 
494 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFM_OFFMAC),
495 				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
496 	if (ret)
497 		return ret;
498 
499 	rtw89_write32(rtwdev, R_BE_WLLPS_CTRL, 0x00015002);
500 	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_XTAL_OFF_A_DIE);
501 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
502 	rtw89_write32(rtwdev, R_BE_UDM1, 0);
503 
504 	return 0;
505 }
506 
507 static void rtw8922d_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
508 					struct rtw8922d_efuse *map)
509 {
510 	const struct rtw8922d_tssi_offset_6g * const ofst_6g[] = {
511 		&map->path_a_tssi_6g,
512 		&map->path_b_tssi_6g,
513 	};
514 	const struct rtw8922d_tssi_offset * const ofst[] = {
515 		&map->path_a_tssi,
516 		&map->path_b_tssi,
517 	};
518 	struct rtw89_tssi_info *tssi = &rtwdev->tssi;
519 	u8 i, j;
520 
521 	tssi->thermal[RF_PATH_A] = map->path_a_therm;
522 	tssi->thermal[RF_PATH_B] = map->path_b_therm;
523 
524 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
525 		memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, TSSI_CCK_CH_GROUP_NUM);
526 
527 		for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
528 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
529 				    "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
530 				    i, j, tssi->tssi_cck[i][j]);
531 
532 		memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
533 		       TSSI_MCS_2G_CH_GROUP_NUM);
534 		memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
535 		       ofst[i]->bw40_1s_tssi_5g, TSSI_MCS_5G_CH_GROUP_NUM);
536 		memcpy(tssi->tssi_6g_mcs[i], ofst_6g[i]->bw40_1s_tssi_6g,
537 		       TSSI_MCS_6G_CH_GROUP_NUM);
538 
539 		for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
540 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
541 				    "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
542 				    i, j, tssi->tssi_mcs[i][j]);
543 
544 		for (j = 0; j < TSSI_MCS_6G_CH_GROUP_NUM; j++)
545 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
546 				    "[TSSI][EFUSE] path=%d mcs_6g[%d]=0x%x\n",
547 				    i, j, tssi->tssi_6g_mcs[i][j]);
548 	}
549 }
550 
551 static void
552 __rtw8922d_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
553 				     s8 offset[RTW89_GAIN_OFFSET_NR],
554 				     const s8 *offset_default,
555 				     const struct rtw8922d_rx_gain *rx_gain,
556 				     const struct rtw8922d_rx_gain_6g *rx_gain_6g)
557 {
558 	int i;
559 	u8 t;
560 
561 	offset[RTW89_GAIN_OFFSET_2G_CCK] = rx_gain->_2g_cck;
562 	offset[RTW89_GAIN_OFFSET_2G_OFDM] = rx_gain->_2g_ofdm;
563 	offset[RTW89_GAIN_OFFSET_5G_LOW] = rx_gain->_5g_low;
564 	offset[RTW89_GAIN_OFFSET_5G_MID] = rx_gain->_5g_mid;
565 	offset[RTW89_GAIN_OFFSET_5G_HIGH] = rx_gain->_5g_high;
566 	offset[RTW89_GAIN_OFFSET_6G_L0] = rx_gain_6g->_6g_l0;
567 	offset[RTW89_GAIN_OFFSET_6G_L1] = rx_gain_6g->_6g_l1;
568 	offset[RTW89_GAIN_OFFSET_6G_M0] = rx_gain_6g->_6g_m0;
569 	offset[RTW89_GAIN_OFFSET_6G_M1] = rx_gain_6g->_6g_m1;
570 	offset[RTW89_GAIN_OFFSET_6G_H0] = rx_gain_6g->_6g_h0;
571 	offset[RTW89_GAIN_OFFSET_6G_H1] = rx_gain_6g->_6g_h1;
572 	offset[RTW89_GAIN_OFFSET_6G_UH0] = rx_gain_6g->_6g_uh0;
573 	offset[RTW89_GAIN_OFFSET_6G_UH1] = rx_gain_6g->_6g_uh1;
574 
575 	for (i = 0; i < RTW89_GAIN_OFFSET_NR; i++) {
576 		t = offset[i];
577 		if (t == 0xff) {
578 			if (offset_default) {
579 				offset[i] = offset_default[i];
580 				continue;
581 			}
582 			t = 0;
583 		}
584 
585 		/* transform: sign-bit + U(7,2) to S(8,2) */
586 		if (t & 0x80)
587 			offset[i] = (t ^ 0x7f) + 1;
588 		else
589 			offset[i] = t;
590 	}
591 }
592 
593 static void rtw8922d_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
594 					       struct rtw8922d_efuse *map)
595 {
596 	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
597 
598 	__rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset[RF_PATH_A],
599 					     NULL,
600 					     &map->rx_gain_a, &map->rx_gain_6g_a);
601 	__rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset[RF_PATH_B],
602 					     NULL,
603 					     &map->rx_gain_b, &map->rx_gain_6g_b);
604 
605 	__rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset2[RF_PATH_A],
606 					     gain->offset[RF_PATH_A],
607 					     &map->rx_gain_a_2, &map->rx_gain_6g_a_2);
608 	__rtw8922d_efuse_parsing_gain_offset(rtwdev, gain->offset2[RF_PATH_B],
609 					     gain->offset[RF_PATH_B],
610 					     &map->rx_gain_b_2, &map->rx_gain_6g_b_2);
611 
612 	gain->offset_valid = true;
613 }
614 
615 static int rtw8922d_read_efuse_pci_sdio(struct rtw89_dev *rtwdev, u8 *log_map)
616 {
617 	struct rtw89_efuse *efuse = &rtwdev->efuse;
618 
619 	if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
620 		ether_addr_copy(efuse->addr, log_map + 0x4104);
621 	else
622 		ether_addr_copy(efuse->addr, log_map + 0x001A);
623 
624 	return 0;
625 }
626 
627 static int rtw8922d_read_efuse_usb(struct rtw89_dev *rtwdev, u8 *log_map)
628 {
629 	struct rtw89_efuse *efuse = &rtwdev->efuse;
630 
631 	ether_addr_copy(efuse->addr, log_map + 0x0078);
632 
633 	return 0;
634 }
635 
636 static int rtw8922d_read_efuse_rf(struct rtw89_dev *rtwdev, u8 *log_map)
637 {
638 	struct rtw8922d_efuse *map = (struct rtw8922d_efuse *)log_map;
639 	struct rtw89_efuse *efuse = &rtwdev->efuse;
640 
641 	efuse->rfe_type = map->rfe_type;
642 	efuse->xtal_cap = map->xtal_k;
643 	efuse->country_code[0] = map->country_code[0];
644 	efuse->country_code[1] = map->country_code[1];
645 	efuse->bt_setting_2 = map->bt_setting_2;
646 	efuse->bt_setting_3 = map->bt_setting_3;
647 	rtw8922d_efuse_parsing_tssi(rtwdev, map);
648 	rtw8922d_efuse_parsing_gain_offset(rtwdev, map);
649 
650 	return 0;
651 }
652 
653 static int rtw8922d_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
654 			       enum rtw89_efuse_block block)
655 {
656 	switch (block) {
657 	case RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO:
658 		return rtw8922d_read_efuse_pci_sdio(rtwdev, log_map);
659 	case RTW89_EFUSE_BLOCK_HCI_DIG_USB:
660 		return rtw8922d_read_efuse_usb(rtwdev, log_map);
661 	case RTW89_EFUSE_BLOCK_RF:
662 		return rtw8922d_read_efuse_rf(rtwdev, log_map);
663 	default:
664 		return 0;
665 	}
666 }
667 
668 static void rtw8922d_phycap_parsing_vco_trim(struct rtw89_dev *rtwdev,
669 					     u8 *phycap_map)
670 {
671 	static const u32 vco_trim_addr[RF_PATH_NUM_8922D] = {0x175E, 0x175F};
672 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
673 	u32 addr = rtwdev->chip->phycap_addr;
674 	const u32 vco_check_addr = 0x1700;
675 	u8 val;
676 
677 	val = phycap_map[vco_check_addr - addr];
678 	if (val & BIT(1))
679 		return;
680 
681 	info->pg_vco_trim = true;
682 
683 	info->vco_trim[0] = u8_get_bits(phycap_map[vco_trim_addr[0] - addr], GENMASK(4, 0));
684 	info->vco_trim[1] = u8_get_bits(phycap_map[vco_trim_addr[1] - addr], GENMASK(4, 0));
685 }
686 
687 static void rtw8922d_vco_trim(struct rtw89_dev *rtwdev)
688 {
689 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
690 
691 	if (!info->pg_vco_trim)
692 		return;
693 
694 	rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCO, RR_VCO_VAL, info->vco_trim[0]);
695 	rtw89_write_rf(rtwdev, RF_PATH_B, RR_VCO, RR_VCO_VAL, info->vco_trim[1]);
696 }
697 
698 #define THM_TRIM_POSITIVE_MASK BIT(6)
699 #define THM_TRIM_MAGNITUDE_MASK GENMASK(5, 0)
700 #define THM_TRIM_MAX (15)
701 #define THM_TRIM_MIN (-15)
702 
703 static void rtw8922d_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
704 						 u8 *phycap_map)
705 {
706 	static const u32 thm_trim_addr[RF_PATH_NUM_8922D] = {0x1706, 0x1732};
707 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
708 	u32 addr = rtwdev->chip->phycap_addr;
709 	bool pg = true;
710 	u8 pg_th;
711 	s8 val;
712 	u8 i;
713 
714 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
715 		pg_th = phycap_map[thm_trim_addr[i] - addr];
716 		if (pg_th == 0xff) {
717 			memset(info->thermal_trim, 0, sizeof(info->thermal_trim));
718 			pg = false;
719 			goto out;
720 		}
721 
722 		val = u8_get_bits(pg_th, THM_TRIM_MAGNITUDE_MASK);
723 
724 		if (!(pg_th & THM_TRIM_POSITIVE_MASK))
725 			val *= -1;
726 
727 		if (val <= THM_TRIM_MIN || val >= THM_TRIM_MAX) {
728 			val = 0;
729 			info->thermal_trim[i] = 0;
730 		} else {
731 			info->thermal_trim[i] = pg_th;
732 		}
733 
734 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
735 			    "[THERMAL][TRIM] path=%d thermal_trim=0x%x (%d)\n",
736 			    i, pg_th, val);
737 	}
738 
739 out:
740 	info->pg_thermal_trim = pg;
741 }
742 
743 static void rtw8922d_thermal_trim(struct rtw89_dev *rtwdev)
744 {
745 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
746 	u8 thermal;
747 	int i;
748 
749 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
750 		thermal = info->pg_thermal_trim ? info->thermal_trim[i] : 0;
751 		rtw89_write_rf(rtwdev, i, RR_TM, RR_TM_TRM, thermal & 0x7f);
752 	}
753 }
754 
755 static void rtw8922d_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
756 						 u8 *phycap_map)
757 {
758 	static const u32 pabias_trim_addr[RF_PATH_NUM_8922D] = {0x1707, 0x1733};
759 	static const u32 check_pa_pad_trim_addr = 0x1700;
760 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
761 	u32 addr = rtwdev->chip->phycap_addr;
762 	bool pg = true;
763 	u8 val;
764 	u8 i;
765 
766 	val = phycap_map[check_pa_pad_trim_addr - addr];
767 	if (val == 0xff) {
768 		pg = false;
769 		goto out;
770 	}
771 
772 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
773 		info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
774 
775 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
776 			    "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
777 			    i, info->pa_bias_trim[i]);
778 	}
779 
780 out:
781 	info->pg_pa_bias_trim = pg;
782 }
783 
784 static void rtw8922d_pa_bias_trim(struct rtw89_dev *rtwdev)
785 {
786 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
787 	u8 pabias_2g, pabias_5g;
788 	u8 i;
789 
790 	if (!info->pg_pa_bias_trim) {
791 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
792 			    "[PA_BIAS][TRIM] no PG, do nothing\n");
793 
794 		return;
795 	}
796 
797 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
798 		pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
799 		pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
800 
801 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
802 			    "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
803 			    i, pabias_2g, pabias_5g);
804 
805 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG_V1, pabias_2g);
806 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA_V1, pabias_5g);
807 	}
808 }
809 
810 static void rtw8922d_phycap_parsing_pad_bias_trim(struct rtw89_dev *rtwdev,
811 						  u8 *phycap_map)
812 {
813 	static const u32 pad_bias_trim_addr[RF_PATH_NUM_8922D] = {0x1708, 0x1734};
814 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
815 	u32 addr = rtwdev->chip->phycap_addr;
816 	u8 i;
817 
818 	if (!info->pg_pa_bias_trim)
819 		return;
820 
821 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
822 		info->pad_bias_trim[i] = phycap_map[pad_bias_trim_addr[i] - addr];
823 
824 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
825 			    "[PAD_BIAS][TRIM] path=%d pad_bias_trim=0x%x\n",
826 			    i, info->pad_bias_trim[i]);
827 	}
828 }
829 
830 static void rtw8922d_pad_bias_trim(struct rtw89_dev *rtwdev)
831 {
832 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
833 	u8 pad_bias_2g, pad_bias_5g;
834 	u8 i;
835 
836 	if (!info->pg_pa_bias_trim) {
837 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
838 			    "[PAD_BIAS][TRIM] no PG, do nothing\n");
839 		return;
840 	}
841 
842 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
843 		pad_bias_2g = u8_get_bits(info->pad_bias_trim[i], GENMASK(3, 0));
844 		pad_bias_5g = u8_get_bits(info->pad_bias_trim[i], GENMASK(7, 4));
845 
846 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
847 			    "[PAD_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
848 			    i, pad_bias_2g, pad_bias_5g);
849 
850 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXG_V1, pad_bias_2g);
851 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASD_TXA_V1, pad_bias_5g);
852 	}
853 }
854 
855 static int rtw8922d_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
856 {
857 	rtw8922d_phycap_parsing_vco_trim(rtwdev, phycap_map);
858 	rtw8922d_phycap_parsing_thermal_trim(rtwdev, phycap_map);
859 	rtw8922d_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
860 	rtw8922d_phycap_parsing_pad_bias_trim(rtwdev, phycap_map);
861 
862 	return 0;
863 }
864 
865 static void rtw8922d_power_trim(struct rtw89_dev *rtwdev)
866 {
867 	rtw8922d_vco_trim(rtwdev);
868 	rtw8922d_thermal_trim(rtwdev);
869 	rtw8922d_pa_bias_trim(rtwdev);
870 	rtw8922d_pad_bias_trim(rtwdev);
871 }
872 
873 static void rtw8922d_set_channel_mac(struct rtw89_dev *rtwdev,
874 				     const struct rtw89_chan *chan,
875 				     u8 mac_idx)
876 {
877 	u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_BE_TX_SUB_BAND_VALUE, mac_idx);
878 	u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_BE_TXRATE_CHK, mac_idx);
879 	u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_RFMOD, mac_idx);
880 	u8 txsb20 = 0, txsb40 = 0, txsb80 = 0;
881 	u8 rf_mod_val, chk_rate_mask, sifs;
882 	u32 txsb;
883 	u32 reg;
884 
885 	switch (chan->band_width) {
886 	case RTW89_CHANNEL_WIDTH_160:
887 		txsb80 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_80);
888 		fallthrough;
889 	case RTW89_CHANNEL_WIDTH_80:
890 		txsb40 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_40);
891 		fallthrough;
892 	case RTW89_CHANNEL_WIDTH_40:
893 		txsb20 = rtw89_phy_get_txsb(rtwdev, chan, RTW89_CHANNEL_WIDTH_20);
894 		break;
895 	default:
896 		break;
897 	}
898 
899 	switch (chan->band_width) {
900 	case RTW89_CHANNEL_WIDTH_160:
901 		rf_mod_val = BE_WMAC_RFMOD_160M;
902 		txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) |
903 		       u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK) |
904 		       u32_encode_bits(txsb80, B_BE_TXSB_80M_MASK);
905 		break;
906 	case RTW89_CHANNEL_WIDTH_80:
907 		rf_mod_val = BE_WMAC_RFMOD_80M;
908 		txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK) |
909 		       u32_encode_bits(txsb40, B_BE_TXSB_40M_MASK);
910 		break;
911 	case RTW89_CHANNEL_WIDTH_40:
912 		rf_mod_val = BE_WMAC_RFMOD_40M;
913 		txsb = u32_encode_bits(txsb20, B_BE_TXSB_20M_MASK);
914 		break;
915 	case RTW89_CHANNEL_WIDTH_20:
916 	default:
917 		rf_mod_val = BE_WMAC_RFMOD_20M;
918 		txsb = 0;
919 		break;
920 	}
921 
922 	if (txsb20 <= BE_PRI20_BITMAP_MAX)
923 		txsb |= u32_encode_bits(BIT(txsb20), B_BE_PRI20_BITMAP_MASK);
924 
925 	rtw89_write8_mask(rtwdev, rf_mod, B_BE_WMAC_RFMOD_MASK, rf_mod_val);
926 	rtw89_write32(rtwdev, sub_carr, txsb);
927 
928 	switch (chan->band_type) {
929 	case RTW89_BAND_2G:
930 		chk_rate_mask = B_BE_BAND_MODE;
931 		break;
932 	case RTW89_BAND_5G:
933 	case RTW89_BAND_6G:
934 		chk_rate_mask = B_BE_CHECK_CCK_EN | B_BE_RTS_LIMIT_IN_OFDM6;
935 		break;
936 	default:
937 		rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type);
938 		return;
939 	}
940 
941 	rtw89_write8_clr(rtwdev, chk_rate, B_BE_BAND_MODE | B_BE_CHECK_CCK_EN |
942 					   B_BE_RTS_LIMIT_IN_OFDM6);
943 	rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask);
944 
945 	switch (chan->band_width) {
946 	case RTW89_CHANNEL_WIDTH_160:
947 		sifs = 0x8C;
948 		break;
949 	case RTW89_CHANNEL_WIDTH_80:
950 		sifs = 0x8A;
951 		break;
952 	case RTW89_CHANNEL_WIDTH_40:
953 		sifs = 0x84;
954 		break;
955 	case RTW89_CHANNEL_WIDTH_20:
956 	default:
957 		sifs = 0x82;
958 	}
959 
960 	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx);
961 	rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_DOT05US_MASK, sifs);
962 }
963 
964 static const u32 rtw8922d_sco_barker_threshold[14] = {
965 	0x1fe4f, 0x1ff5e, 0x2006c, 0x2017b, 0x2028a, 0x20399, 0x204a8, 0x205b6,
966 	0x206c5, 0x207d4, 0x208e3, 0x209f2, 0x20b00, 0x20d8a
967 };
968 
969 static const u32 rtw8922d_sco_cck_threshold[14] = {
970 	0x2bdac, 0x2bf21, 0x2c095, 0x2c209, 0x2c37e, 0x2c4f2, 0x2c666, 0x2c7db,
971 	0x2c94f, 0x2cac3, 0x2cc38, 0x2cdac, 0x2cf21, 0x2d29e
972 };
973 
974 static int rtw8922d_ctrl_sco_cck(struct rtw89_dev *rtwdev,
975 				 u8 primary_ch, enum rtw89_bandwidth bw,
976 				 enum rtw89_phy_idx phy_idx)
977 {
978 	u8 ch_element;
979 
980 	if (primary_ch >= 14)
981 		return -EINVAL;
982 
983 	ch_element = primary_ch - 1;
984 
985 	rtw89_phy_write32_idx(rtwdev, R_BK_FC0_INV_BE4, B_BK_FC0_INV_BE4,
986 			      rtw8922d_sco_barker_threshold[ch_element],
987 			      phy_idx);
988 	rtw89_phy_write32_idx(rtwdev, R_CCK_FC0_INV_BE4, B_CCK_FC0_INV_BE4,
989 			      rtw8922d_sco_cck_threshold[ch_element],
990 			      phy_idx);
991 
992 	return 0;
993 }
994 
995 static void rtw8922d_ctrl_ch_core(struct rtw89_dev *rtwdev,
996 				  const struct rtw89_chan *chan,
997 				  enum rtw89_phy_idx phy_idx)
998 {
999 	u16 central_freq = chan->freq;
1000 	u16 sco;
1001 
1002 	if (chan->band_type == RTW89_BAND_2G) {
1003 		rtw89_phy_write32_idx(rtwdev, R_BAND_SEL0_BE4, B_BAND_SEL0_BE4,
1004 				      1, phy_idx);
1005 		rtw89_phy_write32_idx(rtwdev, R_BAND_SEL1_BE4, B_BAND_SEL1_BE4,
1006 				      1, phy_idx);
1007 		rtw89_phy_write32_idx(rtwdev, R_ENABLE_CCK0_BE4, B_ENABLE_CCK0_BE4,
1008 				      1, phy_idx);
1009 	} else {
1010 		rtw89_phy_write32_idx(rtwdev, R_BAND_SEL0_BE4, B_BAND_SEL0_BE4,
1011 				      0, phy_idx);
1012 		rtw89_phy_write32_idx(rtwdev, R_BAND_SEL1_BE4, B_BAND_SEL1_BE4,
1013 				      0, phy_idx);
1014 		rtw89_phy_write32_idx(rtwdev, R_ENABLE_CCK0_BE4, B_ENABLE_CCK0_BE4,
1015 				      0, phy_idx);
1016 	}
1017 
1018 	rtw89_phy_write32_idx(rtwdev, R_FC0_BE4, B_FC0_BE4, central_freq, phy_idx);
1019 
1020 	sco = phy_div((BIT(0) << 27) + (central_freq / 2), central_freq);
1021 	rtw89_phy_write32_idx(rtwdev, R_FC0_INV_BE4, B_FC0_INV_BE4, sco, phy_idx);
1022 }
1023 
1024 struct rtw8922d_bb_gain {
1025 	u32 gain_g[BB_PATH_NUM_8922D];
1026 	u32 gain_a[BB_PATH_NUM_8922D];
1027 	u32 gain_g_mask;
1028 	u32 gain_a_mask;
1029 };
1030 
1031 static const struct rtw89_reg_def rpl_comp_bw160[RTW89_BW20_SC_160M] = {
1032 	{ .addr = 0x241E8, .mask = 0xFF00},
1033 	{ .addr = 0x241E8, .mask = 0xFF0000},
1034 	{ .addr = 0x241E8, .mask = 0xFF000000},
1035 	{ .addr = 0x241EC, .mask = 0xFF},
1036 	{ .addr = 0x241EC, .mask = 0xFF00},
1037 	{ .addr = 0x241EC, .mask = 0xFF0000},
1038 	{ .addr = 0x241EC, .mask = 0xFF000000},
1039 	{ .addr = 0x241F0, .mask = 0xFF}
1040 };
1041 
1042 static const struct rtw89_reg_def rpl_comp_bw80[RTW89_BW20_SC_80M] = {
1043 	{ .addr = 0x241F4, .mask = 0xFF},
1044 	{ .addr = 0x241F4, .mask = 0xFF00},
1045 	{ .addr = 0x241F4, .mask = 0xFF0000},
1046 	{ .addr = 0x241F4, .mask = 0xFF000000}
1047 };
1048 
1049 static const struct rtw89_reg_def rpl_comp_bw40[RTW89_BW20_SC_40M] = {
1050 	{ .addr = 0x241F0, .mask = 0xFF0000},
1051 	{ .addr = 0x241F0, .mask = 0xFF000000}
1052 };
1053 
1054 static const struct rtw89_reg_def rpl_comp_bw20[RTW89_BW20_SC_20M] = {
1055 	{ .addr = 0x241F0, .mask = 0xFF00}
1056 };
1057 
1058 static const struct rtw8922d_bb_gain bb_gain_lna[LNA_GAIN_NUM] = {
1059 	{ .gain_g = {0x2409C, 0x2449C}, .gain_a = {0x2406C, 0x2446C},
1060 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
1061 	{ .gain_g = {0x2409C, 0x2449C}, .gain_a = {0x2406C, 0x2446C},
1062 	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000},
1063 	{ .gain_g = {0x240A0, 0x244A0}, .gain_a = {0x24070, 0x24470},
1064 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
1065 	{ .gain_g = {0x240A0, 0x244A0}, .gain_a = {0x24070, 0x24470},
1066 	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000},
1067 	{ .gain_g = {0x240A4, 0x244A4}, .gain_a = {0x24074, 0x24474},
1068 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
1069 	{ .gain_g = {0x240A4, 0x244A4}, .gain_a = {0x24074, 0x24474},
1070 	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF0000},
1071 	{ .gain_g = {0x240A8, 0x244A8}, .gain_a = {0x24078, 0x24478},
1072 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF},
1073 };
1074 
1075 static const struct rtw8922d_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
1076 	{ .gain_g = {0x24054, 0x24454}, .gain_a = {0x24054, 0x24454},
1077 	  .gain_g_mask = 0x7FC0000, .gain_a_mask = 0x1FF},
1078 	{ .gain_g = {0x24058, 0x24458}, .gain_a = {0x24054, 0x24454},
1079 	  .gain_g_mask = 0x1FF, .gain_a_mask = 0x3FE00 },
1080 };
1081 
1082 static const struct rtw8922d_bb_gain bb_op1db_lna[LNA_GAIN_NUM] = {
1083 	{ .gain_g = {0x240AC, 0x244AC}, .gain_a = {0x24078, 0x24478},
1084 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
1085 	{ .gain_g = {0x240AC, 0x244AC}, .gain_a = {0x2407C, 0x2447C},
1086 	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
1087 	{ .gain_g = {0x240AC, 0x244AC}, .gain_a = {0x2407C, 0x2447C},
1088 	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
1089 	{ .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x2407C, 0x2447C},
1090 	  .gain_g_mask = 0xFF, .gain_a_mask = 0xFF0000},
1091 	{ .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x2407C, 0x2447C},
1092 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
1093 	{ .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x24080, 0x24480},
1094 	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
1095 	{ .gain_g = {0x240B0, 0x244B0}, .gain_a = {0x24080, 0x24480},
1096 	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
1097 };
1098 
1099 static const struct rtw8922d_bb_gain bb_op1db_tia_lna[TIA_LNA_OP1DB_NUM] = {
1100 	{ .gain_g = {0x240B4, 0x244B4}, .gain_a = {0x24080, 0x24480},
1101 	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
1102 	{ .gain_g = {0x240B4, 0x244B4}, .gain_a = {0x24084, 0x24484},
1103 	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
1104 	{ .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24084, 0x24484},
1105 	  .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
1106 	{ .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24084, 0x24484},
1107 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
1108 	{ .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24084, 0x24484},
1109 	  .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
1110 	{ .gain_g = {0x240B8, 0x244B8}, .gain_a = {0x24088, 0x24488},
1111 	  .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
1112 	{ .gain_g = {0x240BC, 0x244BC}, .gain_a = {0x24088, 0x24488},
1113 	  .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
1114 	{ .gain_g = {0x240BC, 0x244BC}, .gain_a = {0x24088, 0x24488},
1115 	  .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
1116 };
1117 
1118 static void rtw8922d_set_rpl_gain(struct rtw89_dev *rtwdev,
1119 				  const struct rtw89_chan *chan,
1120 				  enum rtw89_rf_path path,
1121 				  enum rtw89_phy_idx phy_idx)
1122 {
1123 	const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
1124 	u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type);
1125 	u32 reg_path_ofst = 0;
1126 	u32 mask;
1127 	s32 val;
1128 	u32 reg;
1129 	int i;
1130 
1131 	if (path == RF_PATH_B)
1132 		reg_path_ofst = 0x400;
1133 
1134 	for (i = 0; i < RTW89_BW20_SC_160M; i++) {
1135 		reg = rpl_comp_bw160[i].addr | reg_path_ofst;
1136 		mask = rpl_comp_bw160[i].mask;
1137 		val = gain->rpl_ofst_160[gain_band][path][i];
1138 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1139 	}
1140 
1141 	for (i = 0; i < RTW89_BW20_SC_80M; i++) {
1142 		reg = rpl_comp_bw80[i].addr | reg_path_ofst;
1143 		mask = rpl_comp_bw80[i].mask;
1144 		val = gain->rpl_ofst_80[gain_band][path][i];
1145 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1146 	}
1147 
1148 	for (i = 0; i < RTW89_BW20_SC_40M; i++) {
1149 		reg = rpl_comp_bw40[i].addr | reg_path_ofst;
1150 		mask = rpl_comp_bw40[i].mask;
1151 		val = gain->rpl_ofst_40[gain_band][path][i];
1152 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1153 	}
1154 
1155 	for (i = 0; i < RTW89_BW20_SC_20M; i++) {
1156 		reg = rpl_comp_bw20[i].addr | reg_path_ofst;
1157 		mask = rpl_comp_bw20[i].mask;
1158 		val = gain->rpl_ofst_20[gain_band][path][i];
1159 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1160 	}
1161 }
1162 
1163 static void rtw8922d_set_lna_tia_gain(struct rtw89_dev *rtwdev,
1164 				      const struct rtw89_chan *chan,
1165 				      enum rtw89_rf_path path,
1166 				      enum rtw89_phy_idx phy_idx)
1167 {
1168 	const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
1169 	u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type);
1170 	enum rtw89_phy_bb_bw_be bw_type;
1171 	u32 mask;
1172 	s32 val;
1173 	u32 reg;
1174 	int i;
1175 
1176 	bw_type = chan->band_width <= RTW89_CHANNEL_WIDTH_40 ?
1177 		  RTW89_BB_BW_20_40 : RTW89_BB_BW_80_160_320;
1178 
1179 	for (i = 0; i < LNA_GAIN_NUM; i++) {
1180 		if (chan->band_type == RTW89_BAND_2G) {
1181 			reg = bb_gain_lna[i].gain_g[path];
1182 			mask = bb_gain_lna[i].gain_g_mask;
1183 		} else {
1184 			reg = bb_gain_lna[i].gain_a[path];
1185 			mask = bb_gain_lna[i].gain_a_mask;
1186 		}
1187 		val = gain->lna_gain[gain_band][bw_type][path][i];
1188 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1189 	}
1190 
1191 	for (i = 0; i < TIA_GAIN_NUM; i++) {
1192 		if (chan->band_type == RTW89_BAND_2G) {
1193 			reg = bb_gain_tia[i].gain_g[path];
1194 			mask = bb_gain_tia[i].gain_g_mask;
1195 		} else {
1196 			reg = bb_gain_tia[i].gain_a[path];
1197 			mask = bb_gain_tia[i].gain_a_mask;
1198 		}
1199 		val = gain->tia_gain[gain_band][bw_type][path][i];
1200 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1201 	}
1202 }
1203 
1204 static void rtw8922d_set_op1db(struct rtw89_dev *rtwdev,
1205 			       const struct rtw89_chan *chan,
1206 			       enum rtw89_rf_path path,
1207 			       enum rtw89_phy_idx phy_idx)
1208 {
1209 	const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
1210 	u8 gain_band = rtw89_subband_to_gain_band_be(chan->subband_type);
1211 	enum rtw89_phy_bb_bw_be bw_type;
1212 	u32 mask;
1213 	s32 val;
1214 	u32 reg;
1215 	int i;
1216 
1217 	bw_type = chan->band_width <= RTW89_CHANNEL_WIDTH_40 ?
1218 		  RTW89_BB_BW_20_40 : RTW89_BB_BW_80_160_320;
1219 
1220 	for (i = 0; i < LNA_GAIN_NUM; i++) {
1221 		if (chan->band_type == RTW89_BAND_2G) {
1222 			reg = bb_op1db_lna[i].gain_g[path];
1223 			mask = bb_op1db_lna[i].gain_g_mask;
1224 		} else {
1225 			reg = bb_op1db_lna[i].gain_a[path];
1226 			mask = bb_op1db_lna[i].gain_a_mask;
1227 		}
1228 		val = gain->lna_op1db[gain_band][bw_type][path][i];
1229 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1230 	}
1231 
1232 	for (i = 0; i < TIA_LNA_OP1DB_NUM; i++) {
1233 		if (chan->band_type == RTW89_BAND_2G) {
1234 			reg = bb_op1db_tia_lna[i].gain_g[path];
1235 			mask = bb_op1db_tia_lna[i].gain_g_mask;
1236 		} else {
1237 			reg = bb_op1db_tia_lna[i].gain_a[path];
1238 			mask = bb_op1db_tia_lna[i].gain_a_mask;
1239 		}
1240 		val = gain->tia_lna_op1db[gain_band][bw_type][path][i];
1241 		rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
1242 	}
1243 }
1244 
1245 static void rtw8922d_set_gain(struct rtw89_dev *rtwdev,
1246 			      const struct rtw89_chan *chan,
1247 			      enum rtw89_rf_path path,
1248 			      enum rtw89_phy_idx phy_idx)
1249 {
1250 	rtw8922d_set_rpl_gain(rtwdev, chan, path, phy_idx);
1251 	rtw8922d_set_lna_tia_gain(rtwdev, chan, path, phy_idx);
1252 	rtw8922d_set_op1db(rtwdev, chan, path, phy_idx);
1253 }
1254 
1255 static s8 rtw8922d_get_rx_gain_by_chan(struct rtw89_dev *rtwdev,
1256 				       const struct rtw89_chan *chan,
1257 				       enum rtw89_rf_path path, bool is_cck)
1258 {
1259 	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1260 	enum rtw89_gain_offset band;
1261 	u8 fc_ch = chan->channel;
1262 	s8 normal_efuse = 0;
1263 
1264 	if (path > RF_PATH_B)
1265 		return 0;
1266 
1267 	if (is_cck) {
1268 		if (fc_ch >= 1 && fc_ch <= 7)
1269 			return gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK];
1270 		else if (fc_ch >= 8 && fc_ch <= 14)
1271 			return gain->offset2[path][RTW89_GAIN_OFFSET_2G_CCK];
1272 
1273 		return 0;
1274 	}
1275 
1276 	band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type);
1277 
1278 	if (band == RTW89_GAIN_OFFSET_2G_OFDM) {
1279 		if (fc_ch >= 1 && fc_ch <= 7)
1280 			normal_efuse = gain->offset[path][band];
1281 		else if (fc_ch >= 8 && fc_ch <= 14)
1282 			normal_efuse = gain->offset2[path][band];
1283 	} else if (band == RTW89_GAIN_OFFSET_5G_LOW) {
1284 		if (fc_ch == 50)
1285 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1286 		else if (fc_ch >= 36 && fc_ch <= 48)
1287 			normal_efuse = gain->offset[path][band];
1288 		else if (fc_ch >= 52 && fc_ch <= 64)
1289 			normal_efuse = gain->offset2[path][band];
1290 
1291 	} else if (band == RTW89_GAIN_OFFSET_5G_MID) {
1292 		if (fc_ch == 122)
1293 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1294 		else if (fc_ch >= 100 && fc_ch <= 120)
1295 			normal_efuse = gain->offset[path][band];
1296 		else if (fc_ch >= 124 && fc_ch <= 144)
1297 			normal_efuse = gain->offset2[path][band];
1298 	} else if (band == RTW89_GAIN_OFFSET_5G_HIGH) {
1299 		if (fc_ch == 163)
1300 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1301 		else if (fc_ch >= 149 && fc_ch <= 161)
1302 			normal_efuse = gain->offset[path][band];
1303 		else if (fc_ch >= 165 && fc_ch <= 177)
1304 			normal_efuse = gain->offset2[path][band];
1305 	} else if (band == RTW89_GAIN_OFFSET_6G_L0) {
1306 		if (fc_ch == 15)
1307 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1308 		else if (fc_ch >= 1 && fc_ch <= 13)
1309 			normal_efuse = gain->offset[path][band];
1310 		else if (fc_ch >= 17 && fc_ch <= 29)
1311 			normal_efuse = gain->offset2[path][band];
1312 	} else if (band == RTW89_GAIN_OFFSET_6G_L1) {
1313 		if (fc_ch == 47)
1314 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1315 		else if (fc_ch >= 33 && fc_ch <= 45)
1316 			normal_efuse = gain->offset[path][band];
1317 		else if (fc_ch >= 49 && fc_ch <= 61)
1318 			normal_efuse = gain->offset2[path][band];
1319 	} else if (band == RTW89_GAIN_OFFSET_6G_M0) {
1320 		if (fc_ch == 79)
1321 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1322 		else if (fc_ch >= 65 && fc_ch <= 77)
1323 			normal_efuse = gain->offset[path][band];
1324 		else if (fc_ch >= 81 && fc_ch <= 93)
1325 			normal_efuse = gain->offset2[path][band];
1326 	} else if (band == RTW89_GAIN_OFFSET_6G_M1) {
1327 		if (fc_ch == 111)
1328 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1329 		else if (fc_ch >= 97 && fc_ch <= 109)
1330 			normal_efuse = gain->offset[path][band];
1331 		else if (fc_ch >= 113 && fc_ch <= 125)
1332 			normal_efuse = gain->offset2[path][band];
1333 	} else if (band == RTW89_GAIN_OFFSET_6G_H0) {
1334 		if (fc_ch == 143)
1335 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1336 		else if (fc_ch >= 129 && fc_ch <= 141)
1337 			normal_efuse = gain->offset[path][band];
1338 		else if (fc_ch >= 145 && fc_ch <= 157)
1339 			normal_efuse = gain->offset2[path][band];
1340 	} else if (band == RTW89_GAIN_OFFSET_6G_H1) {
1341 		if (fc_ch == 175)
1342 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1343 		else if (fc_ch >= 161 && fc_ch <= 173)
1344 			normal_efuse = gain->offset[path][band];
1345 		else if (fc_ch >= 177 && fc_ch <= 189)
1346 			normal_efuse = gain->offset2[path][band];
1347 	} else if (band == RTW89_GAIN_OFFSET_6G_UH0) {
1348 		if (fc_ch == 207)
1349 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1350 		else if (fc_ch >= 193 && fc_ch <= 205)
1351 			normal_efuse = gain->offset[path][band];
1352 		else if (fc_ch >= 209 && fc_ch <= 221)
1353 			normal_efuse = gain->offset2[path][band];
1354 	} else if (band == RTW89_GAIN_OFFSET_6G_UH1) {
1355 		if (fc_ch == 239)
1356 			normal_efuse = (gain->offset[path][band] + gain->offset2[path][band]) >> 1;
1357 		else if (fc_ch >= 225 && fc_ch <= 237)
1358 			normal_efuse = gain->offset[path][band];
1359 		else if (fc_ch >= 241 && fc_ch <= 253)
1360 			normal_efuse = gain->offset2[path][band];
1361 	} else {
1362 		normal_efuse = gain->offset[path][band];
1363 	}
1364 
1365 	return normal_efuse;
1366 }
1367 
1368 static void rtw8922d_calc_rx_gain_normal_cck(struct rtw89_dev *rtwdev,
1369 					     const struct rtw89_chan *chan,
1370 					     enum rtw89_rf_path path,
1371 					     enum rtw89_phy_idx phy_idx,
1372 					     struct rtw89_phy_calc_efuse_gain *calc)
1373 {
1374 	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1375 	s8 rx_gain_offset;
1376 
1377 	rx_gain_offset = -rtw8922d_get_rx_gain_by_chan(rtwdev, chan, path, true);
1378 
1379 	if (chan->band_width == RTW89_CHANNEL_WIDTH_40)
1380 		rx_gain_offset += (3 << 2); /* compensate RPL loss of 3dB */
1381 
1382 	calc->cck_mean_gain_bias = (rx_gain_offset & 0x3) << 1;
1383 	calc->cck_rpl_ofst = (rx_gain_offset >> 2) + gain->cck_rpl_base[phy_idx];
1384 }
1385 
1386 static void rtw8922d_set_rx_gain_normal_cck(struct rtw89_dev *rtwdev,
1387 					    const struct rtw89_chan *chan,
1388 					    enum rtw89_rf_path path,
1389 					    enum rtw89_phy_idx phy_idx)
1390 {
1391 	struct rtw89_phy_calc_efuse_gain calc = {};
1392 
1393 	rtw8922d_calc_rx_gain_normal_cck(rtwdev, chan, path, phy_idx, &calc);
1394 
1395 	rtw89_phy_write32_idx(rtwdev, R_GAIN_BIAS_BE4, B_GAIN_BIAS_BW20_BE4,
1396 			      calc.cck_mean_gain_bias, phy_idx);
1397 	rtw89_phy_write32_idx(rtwdev, R_GAIN_BIAS_BE4, B_GAIN_BIAS_BW40_BE4,
1398 			      calc.cck_mean_gain_bias, phy_idx);
1399 	rtw89_phy_write32_idx(rtwdev, R_CCK_RPL_OFST_BE4, B_CCK_RPL_OFST_BE4,
1400 			      calc.cck_rpl_ofst, phy_idx);
1401 }
1402 
1403 static void rtw8922d_calc_rx_gain_normal_ofdm(struct rtw89_dev *rtwdev,
1404 					      const struct rtw89_chan *chan,
1405 					      enum rtw89_rf_path path,
1406 					      enum rtw89_phy_idx phy_idx,
1407 					      struct rtw89_phy_calc_efuse_gain *calc)
1408 {
1409 	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1410 	s8 rx_gain_offset;
1411 
1412 	rx_gain_offset = rtw8922d_get_rx_gain_by_chan(rtwdev, chan, path, false);
1413 	calc->rssi_ofst = (rx_gain_offset + gain->ref_gain_base[phy_idx]) & 0xff;
1414 }
1415 
1416 static void rtw8922d_set_rx_gain_normal_ofdm(struct rtw89_dev *rtwdev,
1417 					     const struct rtw89_chan *chan,
1418 					     enum rtw89_rf_path path,
1419 					     enum rtw89_phy_idx phy_idx)
1420 {
1421 	static const u32 rssi_ofst_addr[2] = {R_OFDM_OFST_P0_BE4, R_OFDM_OFST_P1_BE4};
1422 	static const u32 rssi_ofst_addr_m[2] = {B_OFDM_OFST_P0_BE4, B_OFDM_OFST_P1_BE4};
1423 	static const u32 rpl_bias_comp[2] = {R_OFDM_RPL_BIAS_P0_BE4, R_OFDM_RPL_BIAS_P1_BE4};
1424 	static const u32 rpl_bias_comp_m[2] = {B_OFDM_RPL_BIAS_P0_BE4, B_OFDM_RPL_BIAS_P1_BE4};
1425 	struct rtw89_phy_calc_efuse_gain calc = {};
1426 
1427 	rtw8922d_calc_rx_gain_normal_ofdm(rtwdev, chan, path, phy_idx, &calc);
1428 
1429 	rtw89_phy_write32_idx(rtwdev, rssi_ofst_addr[path], rssi_ofst_addr_m[path],
1430 			      calc.rssi_ofst, phy_idx);
1431 	rtw89_phy_write32_idx(rtwdev, rpl_bias_comp[path], rpl_bias_comp_m[path], 0, phy_idx);
1432 }
1433 
1434 static void rtw8922d_set_rx_gain_normal(struct rtw89_dev *rtwdev,
1435 					const struct rtw89_chan *chan,
1436 					enum rtw89_rf_path path,
1437 					enum rtw89_phy_idx phy_idx)
1438 {
1439 	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
1440 
1441 	if (!gain->offset_valid)
1442 		return;
1443 
1444 	if (chan->band_type == RTW89_BAND_2G)
1445 		rtw8922d_set_rx_gain_normal_cck(rtwdev, chan, path, phy_idx);
1446 
1447 	rtw8922d_set_rx_gain_normal_ofdm(rtwdev, chan, path, phy_idx);
1448 }
1449 
1450 static void rtw8922d_calc_rx_gain_normal(struct rtw89_dev *rtwdev,
1451 					 const struct rtw89_chan *chan,
1452 					 enum rtw89_rf_path path,
1453 					 enum rtw89_phy_idx phy_idx,
1454 					 struct rtw89_phy_calc_efuse_gain *calc)
1455 {
1456 	rtw8922d_calc_rx_gain_normal_ofdm(rtwdev, chan, path, phy_idx, calc);
1457 
1458 	if (chan->band_type != RTW89_BAND_2G)
1459 		return;
1460 
1461 	rtw8922d_calc_rx_gain_normal_cck(rtwdev, chan, path, phy_idx, calc);
1462 }
1463 
1464 static void rtw8922d_set_cck_parameters(struct rtw89_dev *rtwdev,
1465 					const struct rtw89_chan *chan,
1466 					enum rtw89_phy_idx phy_idx)
1467 {
1468 	u8 regd = rtw89_regd_get(rtwdev, chan->band_type);
1469 	u8 central_ch = chan->channel;
1470 
1471 	if (central_ch == 14) {
1472 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF0_BE4, B_PCOEFF01_BE4, 0x3b13ff, phy_idx);
1473 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF2_BE4, B_PCOEFF23_BE4, 0x1c42de, phy_idx);
1474 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF4_BE4, B_PCOEFF45_BE4, 0xfdb0ad, phy_idx);
1475 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF6_BE4, B_PCOEFF67_BE4, 0xf60f6e, phy_idx);
1476 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF8_BE4, B_PCOEFF89_BE4, 0xfd8f92, phy_idx);
1477 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF10_BE4, B_PCOEFF10_BE4, 0x2d011, phy_idx);
1478 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF12_BE4, B_PCOEFF12_BE4, 0x1c02c, phy_idx);
1479 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF14_BE4, B_PCOEFF14_BE4, 0xfff00a, phy_idx);
1480 
1481 		return;
1482 	}
1483 
1484 	if (regd == RTW89_FCC) {
1485 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF0_BE4, B_PCOEFF01_BE4, 0x39A3BC, phy_idx);
1486 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF2_BE4, B_PCOEFF23_BE4, 0x2AA339, phy_idx);
1487 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF4_BE4, B_PCOEFF45_BE4, 0x15B202, phy_idx);
1488 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF6_BE4, B_PCOEFF67_BE4, 0x0550C7, phy_idx);
1489 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF8_BE4, B_PCOEFF89_BE4, 0xfe0009, phy_idx);
1490 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF10_BE4, B_PCOEFF10_BE4, 0xfd7fd3, phy_idx);
1491 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF12_BE4, B_PCOEFF12_BE4, 0xfeffe2, phy_idx);
1492 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF14_BE4, B_PCOEFF14_BE4, 0xffeff8, phy_idx);
1493 	} else {
1494 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF0_BE4, B_PCOEFF01_BE4, 0x3d23ff, phy_idx);
1495 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF2_BE4, B_PCOEFF23_BE4, 0x29b354, phy_idx);
1496 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF4_BE4, B_PCOEFF45_BE4, 0xfc1c8, phy_idx);
1497 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF6_BE4, B_PCOEFF67_BE4, 0xfdb053, phy_idx);
1498 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF8_BE4, B_PCOEFF89_BE4, 0xf86f9a, phy_idx);
1499 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF10_BE4, B_PCOEFF10_BE4, 0xfaef92, phy_idx);
1500 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF12_BE4, B_PCOEFF12_BE4, 0xfe5fcc, phy_idx);
1501 		rtw89_phy_write32_idx(rtwdev, R_PCOEFF14_BE4, B_PCOEFF14_BE4, 0xffdff5, phy_idx);
1502 	}
1503 }
1504 
1505 static void rtw8922d_ctrl_ch(struct rtw89_dev *rtwdev,
1506 			     const struct rtw89_chan *chan,
1507 			     enum rtw89_phy_idx phy_idx)
1508 {
1509 	u16 central_freq = chan->freq;
1510 	u8 band = chan->band_type;
1511 	u8 chan_idx;
1512 
1513 	if (!central_freq) {
1514 		rtw89_warn(rtwdev, "Invalid central_freq\n");
1515 		return;
1516 	}
1517 
1518 	rtw8922d_ctrl_ch_core(rtwdev, chan, phy_idx);
1519 
1520 	chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band);
1521 	rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL_BE4, B_CH_IDX_SEG0, chan_idx, phy_idx);
1522 
1523 	rtw8922d_set_gain(rtwdev, chan, RF_PATH_A, phy_idx);
1524 	rtw8922d_set_gain(rtwdev, chan, RF_PATH_B, phy_idx);
1525 
1526 	rtw8922d_set_rx_gain_normal(rtwdev, chan, RF_PATH_A, phy_idx);
1527 	rtw8922d_set_rx_gain_normal(rtwdev, chan, RF_PATH_B, phy_idx);
1528 
1529 	if (band == RTW89_BAND_2G)
1530 		rtw8922d_set_cck_parameters(rtwdev, chan, phy_idx);
1531 }
1532 
1533 static void rtw8922d_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_sb, u8 bw,
1534 			     enum rtw89_phy_idx phy_idx)
1535 {
1536 	switch (bw) {
1537 	default:
1538 	case RTW89_CHANNEL_WIDTH_20:
1539 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x0, phy_idx);
1540 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, 0x0, phy_idx);
1541 		rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x2, phy_idx);
1542 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x2, phy_idx);
1543 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x2, phy_idx);
1544 		break;
1545 	case RTW89_CHANNEL_WIDTH_40:
1546 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x1, phy_idx);
1547 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, pri_sb, phy_idx);
1548 		rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x3, phy_idx);
1549 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x3, phy_idx);
1550 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x3, phy_idx);
1551 		break;
1552 	case RTW89_CHANNEL_WIDTH_80:
1553 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x2, phy_idx);
1554 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, pri_sb, phy_idx);
1555 		rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x4, phy_idx);
1556 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x4, phy_idx);
1557 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x4, phy_idx);
1558 		break;
1559 	case RTW89_CHANNEL_WIDTH_160:
1560 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_BW_BE4, 0x3, phy_idx);
1561 		rtw89_phy_write32_idx(rtwdev, R_BW_BE4, B_PRISB_BE4, pri_sb, phy_idx);
1562 		rtw89_phy_write32_idx(rtwdev, R_RXBW_BE4, B_RXBW_BE4, 0x5, phy_idx);
1563 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW6_BE4, 0x5, phy_idx);
1564 		rtw89_phy_write32_idx(rtwdev, R_RXBW67_BE4, B_RXBW7_BE4, 0x5, phy_idx);
1565 		break;
1566 	}
1567 }
1568 
1569 static const u16 spur_nbi_a[] = {6400};
1570 static const u16 spur_csi[] = {6400};
1571 
1572 static u32 rtw8922d_spur_freq(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
1573 			      bool nbi_or_csi, enum rtw89_rf_path path)
1574 {
1575 	static const u16 cbw[RTW89_CHANNEL_WIDTH_ORDINARY_NUM] = {
1576 		20, 40, 80, 160, 320,
1577 	};
1578 	u16 freq_lower, freq_upper, freq;
1579 	const u16 *spur_freq;
1580 	int spur_freq_nr, i;
1581 
1582 	if (rtwdev->hal.aid != RTL8922D_AID7060)
1583 		return 0;
1584 
1585 	if (nbi_or_csi && path == RF_PATH_A) {
1586 		spur_freq = spur_nbi_a;
1587 		spur_freq_nr = ARRAY_SIZE(spur_nbi_a);
1588 	} else if (!nbi_or_csi) {
1589 		spur_freq = spur_csi;
1590 		spur_freq_nr = ARRAY_SIZE(spur_csi);
1591 	} else {
1592 		return 0;
1593 	}
1594 
1595 	if (chan->band_width >= RTW89_CHANNEL_WIDTH_ORDINARY_NUM)
1596 		return 0;
1597 
1598 	freq_lower = chan->freq - cbw[chan->band_width] / 2;
1599 	freq_upper = chan->freq + cbw[chan->band_width] / 2;
1600 
1601 	for (i = 0; i < spur_freq_nr; i++) {
1602 		freq = spur_freq[i];
1603 
1604 		if (freq >= freq_lower && freq <= freq_upper)
1605 			return freq;
1606 	}
1607 
1608 	return 0;
1609 }
1610 
1611 #define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */
1612 #define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */
1613 #define MAX_TONE_NUM 2048
1614 
1615 static void rtw8922d_set_csi_tone_idx(struct rtw89_dev *rtwdev,
1616 				      const struct rtw89_chan *chan,
1617 				      enum rtw89_phy_idx phy_idx)
1618 {
1619 	s32 freq_diff, csi_idx, csi_tone_idx;
1620 	u32 spur_freq;
1621 
1622 	spur_freq = rtw8922d_spur_freq(rtwdev, chan, false, RF_PATH_AB);
1623 	if (spur_freq == 0) {
1624 		rtw89_phy_write32_idx(rtwdev, R_CSI_WGT_BE4, B_CSI_WGT_EN_BE4,
1625 				      0, phy_idx);
1626 		return;
1627 	}
1628 
1629 	freq_diff = (spur_freq - chan->freq) * 1000000;
1630 	csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125);
1631 	s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx);
1632 
1633 	rtw89_phy_write32_idx(rtwdev, R_CSI_WGT_BE4, B_CSI_WGT_IDX_BE4,
1634 			      csi_tone_idx, phy_idx);
1635 	rtw89_phy_write32_idx(rtwdev, R_CSI_WGT_BE4, B_CSI_WGT_EN_BE4, 1, phy_idx);
1636 }
1637 
1638 static const struct rtw89_nbi_reg_def rtw8922d_nbi_reg_def[] = {
1639 	[RF_PATH_A] = {
1640 		.notch1_idx = {0x241A0, 0xFF},
1641 		.notch1_frac_idx = {0x241A0, 0xC00},
1642 		.notch1_en = {0x241A0, 0x1000},
1643 		.notch2_idx = {0x241AC, 0xFF},
1644 		.notch2_frac_idx = {0x241AC, 0xC00},
1645 		.notch2_en = {0x241AC, 0x1000},
1646 	},
1647 	[RF_PATH_B] = {
1648 		.notch1_idx = {0x245A0, 0xFF},
1649 		.notch1_frac_idx = {0x245A0, 0xC00},
1650 		.notch1_en = {0x245A0, 0x1000},
1651 		.notch2_idx = {0x245AC, 0xFF},
1652 		.notch2_frac_idx = {0x245AC, 0xC00},
1653 		.notch2_en = {0x245AC, 0x1000},
1654 	},
1655 };
1656 
1657 static void rtw8922d_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
1658 				      const struct rtw89_chan *chan,
1659 				      enum rtw89_rf_path path,
1660 				      enum rtw89_phy_idx phy_idx)
1661 {
1662 	const struct rtw89_nbi_reg_def *nbi = &rtw8922d_nbi_reg_def[path];
1663 	s32 nbi_frac_idx, nbi_frac_tone_idx;
1664 	s32 nbi_idx, nbi_tone_idx;
1665 	bool notch2_chk = false;
1666 	u32 spur_freq, fc;
1667 	s32 freq_diff;
1668 
1669 	spur_freq = rtw8922d_spur_freq(rtwdev, chan, true, path);
1670 	if (spur_freq == 0) {
1671 		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1672 				      nbi->notch1_en.mask, 0, phy_idx);
1673 		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1674 				      nbi->notch2_en.mask, 0, phy_idx);
1675 		return;
1676 	}
1677 
1678 	fc = chan->freq;
1679 	if (chan->band_width == RTW89_CHANNEL_WIDTH_160) {
1680 		fc = (spur_freq > fc) ? fc + 40 : fc - 40;
1681 		if ((fc > spur_freq &&
1682 		     chan->channel < chan->primary_channel) ||
1683 		    (fc < spur_freq &&
1684 		     chan->channel > chan->primary_channel))
1685 			notch2_chk = true;
1686 	}
1687 
1688 	freq_diff = (spur_freq - fc) * 1000000;
1689 	nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5,
1690 					 &nbi_frac_idx);
1691 
1692 	if (chan->band_width == RTW89_CHANNEL_WIDTH_20) {
1693 		s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx);
1694 	} else {
1695 		u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ?
1696 				128 : 256;
1697 
1698 		s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx);
1699 	}
1700 	nbi_frac_tone_idx =
1701 		s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125);
1702 
1703 	if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
1704 		rtw89_phy_write32_idx(rtwdev, nbi->notch2_idx.addr,
1705 				      nbi->notch2_idx.mask, nbi_tone_idx, phy_idx);
1706 		rtw89_phy_write32_idx(rtwdev, nbi->notch2_frac_idx.addr,
1707 				      nbi->notch2_frac_idx.mask, nbi_frac_tone_idx,
1708 				      phy_idx);
1709 		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1710 				      nbi->notch2_en.mask, 0, phy_idx);
1711 		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1712 				      nbi->notch2_en.mask, 1, phy_idx);
1713 		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1714 				      nbi->notch1_en.mask, 0, phy_idx);
1715 	} else {
1716 		rtw89_phy_write32_idx(rtwdev, nbi->notch1_idx.addr,
1717 				      nbi->notch1_idx.mask, nbi_tone_idx, phy_idx);
1718 		rtw89_phy_write32_idx(rtwdev, nbi->notch1_frac_idx.addr,
1719 				      nbi->notch1_frac_idx.mask, nbi_frac_tone_idx,
1720 				      phy_idx);
1721 		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1722 				      nbi->notch1_en.mask, 0, phy_idx);
1723 		rtw89_phy_write32_idx(rtwdev, nbi->notch1_en.addr,
1724 				      nbi->notch1_en.mask, 1, phy_idx);
1725 		rtw89_phy_write32_idx(rtwdev, nbi->notch2_en.addr,
1726 				      nbi->notch2_en.mask, 0, phy_idx);
1727 	}
1728 }
1729 
1730 static void rtw8922d_spur_elimination(struct rtw89_dev *rtwdev,
1731 				      const struct rtw89_chan *chan,
1732 				      enum rtw89_phy_idx phy_idx)
1733 {
1734 	rtw8922d_set_csi_tone_idx(rtwdev, chan, phy_idx);
1735 	rtw8922d_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A, phy_idx);
1736 	rtw8922d_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B, phy_idx);
1737 }
1738 
1739 static const u32 bbrst_mask[2] = {B_BE_FEN_BBPLAT_RSTB, B_BE_FEN_BB1PLAT_RSTB};
1740 static const u32 glbrst_mask[2] = {B_BE_FEN_BB_IP_RSTN, B_BE_FEN_BB1_IP_RSTN};
1741 static const u32 chip_top_bitmask[2] = {0xffff, 0xffff0000};
1742 
1743 static void rtw8922d_bb_preinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
1744 {
1745 	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x0);
1746 	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx], 0x0);
1747 	rtw89_write32_mask(rtwdev, R_BE_DMAC_SYS_CR32B, chip_top_bitmask[phy_idx], 0x74F9);
1748 	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, glbrst_mask[phy_idx], 0x1);
1749 	rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC_BE4,  B_RSTB_ASYNC_BE4, 0, phy_idx);
1750 	rtw89_write32_mask(rtwdev, R_BE_FEN_RST_ENABLE, bbrst_mask[phy_idx], 0x1);
1751 }
1752 
1753 static void rtw8922d_bb_postinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
1754 {
1755 	rtw89_phy_write32_idx_clr(rtwdev, R_SHAPER_COEFF_BE4, B_SHAPER_COEFF_BE4, phy_idx);
1756 	rtw89_phy_write32_idx_set(rtwdev, R_SHAPER_COEFF_BE4, B_SHAPER_COEFF_BE4, phy_idx);
1757 }
1758 
1759 static void rtw8922d_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band,
1760 				 bool en, enum rtw89_phy_idx phy_idx)
1761 {
1762 	if (en)
1763 		rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC_BE4, B_RSTB_ASYNC_BE4, 1, phy_idx);
1764 	else
1765 		rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC_BE4, B_RSTB_ASYNC_BE4, 0, phy_idx);
1766 }
1767 
1768 static int rtw8922d_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev,
1769 				      enum rtw89_rf_path tx_path,
1770 				      enum rtw89_phy_idx phy_idx)
1771 {
1772 	struct rtw89_reg2_def path_com_cr[] = {
1773 		{0x11A00, 0x21C86900},
1774 		{0x11A04, 0x00E4E433},
1775 		{0x11A08, 0x39390CC9},
1776 		{0x11A10, 0x10CC0000},
1777 		{0x11A14, 0x00240393},
1778 		{0x11A18, 0x201C8600},
1779 		{0x11B38, 0x39393FDB},
1780 		{0x11B3C, 0x00E4E4FF},
1781 	};
1782 	int ret = 0;
1783 	u32 reg;
1784 	int i;
1785 
1786 	rtw89_phy_write32_idx(rtwdev, R_TXINFO_PATH_BE4, B_TXINFO_PATH_EN_BE4, 0x0, phy_idx);
1787 	rtw89_phy_write32_idx(rtwdev, R_TXINFO_PATH_BE4, B_TXINFO_PATH_MA_BE4, 0x0, phy_idx);
1788 	rtw89_phy_write32_idx(rtwdev, R_TXINFO_PATH_BE4, B_TXINFO_PATH_MB_BE4, 0x0, phy_idx);
1789 
1790 	if (phy_idx == RTW89_PHY_1 && !rtwdev->dbcc_en)
1791 		return 0;
1792 
1793 	if (tx_path == RF_PATH_A) {
1794 		path_com_cr[1].data = 0x40031;
1795 		path_com_cr[2].data = 0x1000C48;
1796 		path_com_cr[5].data = 0x200;
1797 		path_com_cr[6].data = 0x1000C48;
1798 		path_com_cr[7].data = 0x40031;
1799 	} else if (tx_path == RF_PATH_B) {
1800 		path_com_cr[1].data = 0x40032;
1801 		path_com_cr[2].data = 0x1000C88;
1802 		path_com_cr[5].data = 0x400;
1803 		path_com_cr[6].data = 0x1000C88;
1804 		path_com_cr[7].data = 0x40032;
1805 	} else if (tx_path == RF_PATH_AB) {
1806 		path_com_cr[1].data = 0x00E4E433;
1807 		path_com_cr[2].data = 0x39390CC9;
1808 		path_com_cr[5].data = 0x201C8600;
1809 		path_com_cr[6].data = 0x1010CC9;
1810 		path_com_cr[7].data = 0x40433;
1811 	} else {
1812 		ret = -EINVAL;
1813 	}
1814 
1815 	for (i = 0; i < ARRAY_SIZE(path_com_cr); i++) {
1816 		reg = rtw89_mac_reg_by_idx(rtwdev, path_com_cr[i].addr, phy_idx);
1817 		rtw89_write32(rtwdev, reg, path_com_cr[i].data);
1818 	}
1819 
1820 	return ret;
1821 }
1822 
1823 static void rtw8922d_bb_reset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
1824 {
1825 }
1826 
1827 static void rtw8922d_tssi_reset(struct rtw89_dev *rtwdev,
1828 				enum rtw89_rf_path path,
1829 				enum rtw89_phy_idx phy_idx)
1830 {
1831 	if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
1832 		if (phy_idx == RTW89_PHY_0) {
1833 			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4,
1834 					       B_TXPWR_RSTB0_BE4, 0x0);
1835 			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4,
1836 					       B_TXPWR_RSTB0_BE4, 0x1);
1837 		} else {
1838 			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4,
1839 					       B_TXPWR_RSTB1_BE4, 0x0);
1840 			rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4,
1841 					       B_TXPWR_RSTB1_BE4, 0x1);
1842 		}
1843 	} else {
1844 		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4, B_TXPWR_RSTB0_BE4, 0x0);
1845 		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB0_BE4, B_TXPWR_RSTB0_BE4, 0x1);
1846 		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4, B_TXPWR_RSTB1_BE4, 0x0);
1847 		rtw89_phy_write32_mask(rtwdev, R_TXPWR_RSTB1_BE4, B_TXPWR_RSTB1_BE4, 0x1);
1848 	}
1849 }
1850 
1851 static int rtw8922d_ctrl_rx_path_tmac(struct rtw89_dev *rtwdev,
1852 				      enum rtw89_rf_path rx_path,
1853 				      enum rtw89_phy_idx phy_idx)
1854 {
1855 	enum rtw89_rf_path_bit path;
1856 
1857 	if (rx_path == RF_PATH_A)
1858 		path = RF_A;
1859 	else if (rx_path == RF_PATH_B)
1860 		path = RF_B;
1861 	else
1862 		path = RF_AB;
1863 
1864 	rtw89_phy_write32_idx(rtwdev, R_ANT_RX_BE4, B_ANT_RX_BE4, path, phy_idx);
1865 	rtw89_phy_write32_idx(rtwdev, R_ANT_RX_1RCCA_BE4, B_ANT_RX_1RCCA_BE4,
1866 			      path, phy_idx);
1867 
1868 	if (rx_path == RF_PATH_AB) {
1869 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC0_BE4, B_RXCH_MCS4_BE4, 8, phy_idx);
1870 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS5_BE4, 4, phy_idx);
1871 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS6_BE4, 3, phy_idx);
1872 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS7_BE4, 7, phy_idx);
1873 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS8_BE4, 2, phy_idx);
1874 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS9_BE4, 2, phy_idx);
1875 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN04_BE4, 4, phy_idx);
1876 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN07_BE4, 2, phy_idx);
1877 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN01_BE4, B_RX_AWGN09_BE4, 0, phy_idx);
1878 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN02_BE4, B_RX_AWGN11_BE4, 1, phy_idx);
1879 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC04_BE4, 8, phy_idx);
1880 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC05_BE4, 5, phy_idx);
1881 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC06_BE4, 3, phy_idx);
1882 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC07_BE4, 5, phy_idx);
1883 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC08_BE4, 1, phy_idx);
1884 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC01_BE4, B_RX_LDPC09_BE4, 2, phy_idx);
1885 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC10_BE4, 4, phy_idx);
1886 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC11_BE4, 2, phy_idx);
1887 	} else {
1888 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC0_BE4, B_RXCH_MCS4_BE4, 13, phy_idx);
1889 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS5_BE4, 15, phy_idx);
1890 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS6_BE4, 6, phy_idx);
1891 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS7_BE4, 15, phy_idx);
1892 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS8_BE4, 4, phy_idx);
1893 		rtw89_phy_write32_idx(rtwdev, R_RXCH_BCC1_BE4, B_RXCH_MCS9_BE4, 15, phy_idx);
1894 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN04_BE4, 9, phy_idx);
1895 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN00_BE4, B_RX_AWGN07_BE4, 3, phy_idx);
1896 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN01_BE4, B_RX_AWGN09_BE4, 1, phy_idx);
1897 		rtw89_phy_write32_idx(rtwdev, R_RX_AWGN02_BE4, B_RX_AWGN11_BE4, 0, phy_idx);
1898 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC04_BE4, 9, phy_idx);
1899 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC05_BE4, 8, phy_idx);
1900 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC06_BE4, 6, phy_idx);
1901 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC07_BE4, 16, phy_idx);
1902 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC00_BE4, B_RX_LDPC08_BE4, 4, phy_idx);
1903 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC01_BE4, B_RX_LDPC09_BE4, 9, phy_idx);
1904 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC10_BE4, 9, phy_idx);
1905 		rtw89_phy_write32_idx(rtwdev, R_RX_LDPC02_BE4, B_RX_LDPC11_BE4, 7, phy_idx);
1906 	}
1907 
1908 	return 0;
1909 }
1910 
1911 static void rtw8922d_set_digital_pwr_comp(struct rtw89_dev *rtwdev,
1912 					  const struct rtw89_chan *chan, u8 nss,
1913 					  enum rtw89_rf_path path,
1914 					  enum rtw89_phy_idx phy_idx)
1915 {
1916 #define DIGITAL_PWR_COMP_REG_NUM 22
1917 	static const u32 pw_comp_cr[2] = {R_RX_PATH0_TBL0_BE4, R_RX_PATH1_TBL0_BE4};
1918 	const __le32 (*pwr_comp_val)[2][RTW89_TX_COMP_BAND_NR]
1919 				    [BB_PATH_NUM_8922D][DIGITAL_PWR_COMP_REG_NUM];
1920 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1921 	const struct rtw89_fw_element_hdr *txcomp_elm = elm_info->tx_comp;
1922 	const __le32 *digital_pwr_comp;
1923 	u32 addr, val;
1924 	u32 i;
1925 
1926 	if (sizeof(*pwr_comp_val) != le32_to_cpu(txcomp_elm->size)) {
1927 		rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
1928 			    "incorrect power comp size %d\n",
1929 			    le32_to_cpu(txcomp_elm->size));
1930 		return;
1931 	}
1932 
1933 	pwr_comp_val = (const void *)txcomp_elm->u.common.contents;
1934 	digital_pwr_comp = (*pwr_comp_val)[nss][chan->tx_comp_band][path];
1935 	addr = pw_comp_cr[path];
1936 
1937 	for (i = 0; i < DIGITAL_PWR_COMP_REG_NUM; i++, addr += 4) {
1938 		val = le32_to_cpu(digital_pwr_comp[i]);
1939 		rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx);
1940 	}
1941 }
1942 
1943 static void rtw8922d_digital_pwr_comp(struct rtw89_dev *rtwdev,
1944 				      enum rtw89_phy_idx phy_idx)
1945 {
1946 	const struct rtw89_chan *chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
1947 	const struct rtw89_chan *chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
1948 
1949 	if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
1950 		rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 0, RF_PATH_A, RTW89_PHY_0);
1951 		rtw8922d_set_digital_pwr_comp(rtwdev, chan1, 0, RF_PATH_B, RTW89_PHY_1);
1952 	} else {
1953 		rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 1, RF_PATH_A, phy_idx);
1954 		rtw8922d_set_digital_pwr_comp(rtwdev, chan0, 1, RF_PATH_B, phy_idx);
1955 	}
1956 }
1957 
1958 static int rtw8922d_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode,
1959 			     bool pwr_comp)
1960 {
1961 	const struct rtw89_chan *chan1;
1962 	u32 reg0, reg1;
1963 	u8 cck_phy_idx;
1964 
1965 	if (mode == MLO_2_PLUS_0_1RF) {
1966 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB);
1967 		udelay(1);
1968 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3);
1969 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xAFFF);
1970 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEBAD);
1971 		udelay(1);
1972 
1973 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0);
1974 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEAAD);
1975 	} else if (mode == MLO_0_PLUS_2_1RF) {
1976 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB);
1977 		udelay(1);
1978 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3);
1979 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xAFFF);
1980 		udelay(1);
1981 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEFFF);
1982 
1983 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0);
1984 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEEFF);
1985 	} else if ((mode == MLO_1_PLUS_1_1RF) || (mode == DBCC_LEGACY)) {
1986 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB);
1987 		udelay(1);
1988 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3);
1989 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xAFFF);
1990 		udelay(1);
1991 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0);
1992 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x3AAB);
1993 	} else {
1994 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x6180);
1995 		udelay(1);
1996 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3);
1997 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x180);
1998 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0);
1999 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0x0);
2000 	}
2001 
2002 	if (pwr_comp)
2003 		rtw8922d_digital_pwr_comp(rtwdev, RTW89_PHY_0);
2004 
2005 	reg0 = R_BBWRAP_ELMSR_BE4;
2006 	reg1 = rtw89_mac_reg_by_idx(rtwdev, reg0, 1);
2007 
2008 	if (mode == MLO_2_PLUS_0_1RF) {
2009 		rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4,
2010 				       B_SYS_DBCC_24G_BAND_SEL_BE4, RTW89_PHY_0);
2011 		rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0);
2012 		rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0);
2013 	} else if (mode == MLO_0_PLUS_2_1RF) {
2014 		rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4,
2015 				       B_SYS_DBCC_24G_BAND_SEL_BE4, RTW89_PHY_0);
2016 		rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0);
2017 		rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0);
2018 	} else if ((mode == MLO_1_PLUS_1_1RF) || (mode == DBCC_LEGACY)) {
2019 		chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
2020 		cck_phy_idx = chan1->band_type == RTW89_BAND_2G ?
2021 			      RTW89_PHY_1 : RTW89_PHY_0;
2022 
2023 		rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4,
2024 				       B_SYS_DBCC_24G_BAND_SEL_BE4, cck_phy_idx);
2025 		rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0x3);
2026 		rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0x3);
2027 	} else {
2028 		rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4,
2029 				       B_SYS_DBCC_24G_BAND_SEL_BE4, RTW89_PHY_0);
2030 		rtw89_write32_mask(rtwdev, reg0, B_BBWRAP_ELMSR_EN_BE4, 0);
2031 		rtw89_write32_mask(rtwdev, reg1, B_BBWRAP_ELMSR_EN_BE4, 0);
2032 	}
2033 
2034 	udelay(1);
2035 
2036 	return 0;
2037 }
2038 
2039 static void rtw8922d_bb_sethw(struct rtw89_dev *rtwdev)
2040 {
2041 	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
2042 	struct rtw89_hal *hal = &rtwdev->hal;
2043 	enum rtw89_phy_idx phy_idx;
2044 	u32 reg;
2045 
2046 	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_BOOST, RTW89_PHY_0);
2047 	rtw89_write32_clr(rtwdev, reg, B_BE_PWR_CTRL_SEL);
2048 	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_BOOST, RTW89_PHY_1);
2049 	rtw89_write32_clr(rtwdev, reg, B_BE_PWR_CTRL_SEL);
2050 
2051 	if (hal->cid == RTL8922D_CID7090) {
2052 		reg = rtw89_mac_reg_by_idx(rtwdev, R_PWR_BOOST_BE4, RTW89_PHY_0);
2053 		rtw89_write32_set(rtwdev, reg, B_PWR_BOOST_BE4);
2054 		reg = rtw89_mac_reg_by_idx(rtwdev, R_PWR_BOOST_BE4, RTW89_PHY_1);
2055 		rtw89_write32_set(rtwdev, reg, B_PWR_BOOST_BE4);
2056 	}
2057 
2058 	rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_PSDU_BE4, 0);
2059 	rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_NSYM_BE4, 1);
2060 	rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_LSIG_BE4, 1);
2061 	rtw89_phy_write32_mask(rtwdev, R_TX_ERROR_SEL_BE4, B_TX_ERROR_TXINFO_BE4, 1);
2062 	rtw89_phy_write32_mask(rtwdev, R_TXERRCT_EN_BE4, B_TXERRCT_EN_BE4, 0);
2063 	rtw89_phy_write32_mask(rtwdev, R_TXERRCT1_EN_BE4, B_TXERRCT1_EN_BE4, 0);
2064 	rtw89_phy_write32_idx(rtwdev, R_IMR_TX_ERROR_BE4, B_IMR_TX_ERROR_BE4, 1, RTW89_PHY_0);
2065 	rtw89_phy_write32_idx(rtwdev, R_IMR_TX_ERROR_BE4, B_IMR_TX_ERROR_BE4, 1, RTW89_PHY_1);
2066 
2067 	rtw8922d_ctrl_mlo(rtwdev, rtwdev->mlo_dbcc_mode, false);
2068 
2069 	/* read these registers after loading BB parameters */
2070 	for (phy_idx = RTW89_PHY_0; phy_idx < RTW89_PHY_NUM; phy_idx++) {
2071 		gain->ref_gain_base[phy_idx] =
2072 			rtw89_phy_read32_idx(rtwdev, R_OFDM_OFST_P0_BE4,
2073 					     B_OFDM_OFST_P0_BE4, phy_idx);
2074 		gain->cck_rpl_base[phy_idx] =
2075 			rtw89_phy_read32_idx(rtwdev, R_CCK_RPL_OFST_BE4,
2076 					     B_CCK_RPL_OFST_BE4, phy_idx);
2077 	}
2078 }
2079 
2080 static void rtw8922d_set_channel_bb(struct rtw89_dev *rtwdev,
2081 				    const struct rtw89_chan *chan,
2082 				    enum rtw89_phy_idx phy_idx)
2083 {
2084 	struct rtw89_hal *hal = &rtwdev->hal;
2085 	bool cck_en = chan->band_type == RTW89_BAND_2G;
2086 	u8 pri_sb = chan->pri_sb_idx;
2087 	u32 val;
2088 
2089 	rtw89_phy_bb_wrap_set_rfsi_ct_opt(rtwdev, phy_idx);
2090 	rtw8922d_ctrl_ch(rtwdev, chan, phy_idx);
2091 	rtw8922d_ctrl_bw(rtwdev, pri_sb, chan->band_width, phy_idx);
2092 	rtw89_phy_bb_wrap_set_rfsi_bandedge_ch(rtwdev, chan, phy_idx);
2093 
2094 	if (cck_en)
2095 		rtw8922d_ctrl_sco_cck(rtwdev, chan->primary_channel,
2096 				      chan->band_width, phy_idx);
2097 
2098 	rtw8922d_spur_elimination(rtwdev, chan, phy_idx);
2099 
2100 	if (hal->cid == RTL8922D_CID7025) {
2101 		if (chan->band_width == RTW89_CHANNEL_WIDTH_160)
2102 			val = 0x1f9;
2103 		else if (chan->band_width == RTW89_CHANNEL_WIDTH_80)
2104 			val = 0x1f5;
2105 		else
2106 			val = 0x1e2;
2107 
2108 		rtw89_phy_write32_idx(rtwdev, R_AWGN_DET_BE4, B_AWGN_DET_BE4, val, phy_idx);
2109 	}
2110 
2111 	rtw8922d_tssi_reset(rtwdev, RF_PATH_AB, phy_idx);
2112 }
2113 
2114 static void rtw8922d_pre_set_channel_bb(struct rtw89_dev *rtwdev,
2115 					enum rtw89_phy_idx phy_idx)
2116 {
2117 	if (!rtwdev->dbcc_en)
2118 		return;
2119 
2120 	rtw89_phy_write32_mask(rtwdev, R_SYS_DBCC_BE4, B_SYS_DBCC_BE4, 0x0);
2121 
2122 	if (phy_idx == RTW89_PHY_0) {
2123 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB);
2124 		fsleep(1);
2125 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3);
2126 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xAFFF);
2127 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEBAD);
2128 		fsleep(1);
2129 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0);
2130 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEAAD);
2131 	} else {
2132 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xBBBB);
2133 		fsleep(1);
2134 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x3);
2135 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xAFFF);
2136 		fsleep(1);
2137 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEFFF);
2138 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_BB_CLK_BE4, 0x0);
2139 		rtw89_phy_write32_mask(rtwdev, R_EMLSR_SWITCH_BE4, B_EMLSR_SWITCH_BE4, 0xEEFF);
2140 	}
2141 
2142 	fsleep(1);
2143 }
2144 
2145 static void rtw8922d_post_set_channel_bb(struct rtw89_dev *rtwdev,
2146 					 enum rtw89_mlo_dbcc_mode mode,
2147 					 enum rtw89_phy_idx phy_idx)
2148 {
2149 	if (!rtwdev->dbcc_en)
2150 		return;
2151 
2152 	rtw8922d_ctrl_mlo(rtwdev, mode, true);
2153 }
2154 
2155 static void rtw8922d_set_channel(struct rtw89_dev *rtwdev,
2156 				 const struct rtw89_chan *chan,
2157 				 enum rtw89_mac_idx mac_idx,
2158 				 enum rtw89_phy_idx phy_idx)
2159 {
2160 	rtw8922d_set_channel_mac(rtwdev, chan, mac_idx);
2161 	rtw8922d_set_channel_bb(rtwdev, chan, phy_idx);
2162 	rtw8922d_set_channel_rf(rtwdev, chan, phy_idx);
2163 }
2164 
2165 static void __rtw8922d_dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
2166 {
2167 	rtw89_phy_write32_mask(rtwdev, 0x3c000 + (path << 8), BIT(17), 0x0);
2168 	rtw89_phy_write32_mask(rtwdev, 0x3c000 + (path << 8), BIT(17), 0x1);
2169 }
2170 
2171 static void rtw8922d_dack_reset(struct rtw89_dev *rtwdev)
2172 {
2173 	__rtw8922d_dack_reset(rtwdev, RF_PATH_A);
2174 	__rtw8922d_dack_reset(rtwdev, RF_PATH_B);
2175 }
2176 
2177 static
2178 void rtw8922d_hal_reset(struct rtw89_dev *rtwdev,
2179 			enum rtw89_phy_idx phy_idx, enum rtw89_mac_idx mac_idx,
2180 			enum rtw89_band band, u32 *tx_en, bool enter)
2181 {
2182 	if (enter) {
2183 		rtw89_chip_stop_sch_tx(rtwdev, mac_idx, tx_en, RTW89_SCH_TX_SEL_ALL);
2184 		rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false);
2185 		rtw8922d_dack_reset(rtwdev);
2186 		rtw8922d_tssi_cont_en_phyidx(rtwdev, false, phy_idx);
2187 		fsleep(40);
2188 		rtw8922d_bb_reset_en(rtwdev, band, false, phy_idx);
2189 	} else {
2190 		rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true);
2191 		rtw8922d_tssi_cont_en_phyidx(rtwdev, true, phy_idx);
2192 		rtw8922d_bb_reset_en(rtwdev, band, true, phy_idx);
2193 		rtw89_chip_resume_sch_tx(rtwdev, mac_idx, *tx_en);
2194 	}
2195 }
2196 
2197 static void rtw8922d_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
2198 				      struct rtw89_channel_help_params *p,
2199 				      const struct rtw89_chan *chan,
2200 				      enum rtw89_mac_idx mac_idx,
2201 				      enum rtw89_phy_idx phy_idx)
2202 {
2203 	if (enter) {
2204 		rtw8922d_pre_set_channel_bb(rtwdev, phy_idx);
2205 		rtw8922d_pre_set_channel_rf(rtwdev, phy_idx);
2206 	}
2207 
2208 	rtw8922d_hal_reset(rtwdev, phy_idx, mac_idx, chan->band_type, &p->tx_en, enter);
2209 
2210 	if (!enter) {
2211 		rtw8922d_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode, phy_idx);
2212 		rtw8922d_post_set_channel_rf(rtwdev, phy_idx);
2213 	}
2214 }
2215 
2216 static void rtw8922d_rfk_init(struct rtw89_dev *rtwdev)
2217 {
2218 	struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
2219 	struct rtw89_lck_info *lck = &rtwdev->lck;
2220 
2221 	rtwdev->is_tssi_mode[RF_PATH_A] = false;
2222 	rtwdev->is_tssi_mode[RF_PATH_B] = false;
2223 	memset(rfk_mcc, 0, sizeof(*rfk_mcc));
2224 	memset(lck, 0, sizeof(*lck));
2225 }
2226 
2227 static void __rtw8922d_rfk_init_late(struct rtw89_dev *rtwdev,
2228 				     enum rtw89_phy_idx phy_idx,
2229 				     const struct rtw89_chan *chan)
2230 {
2231 	rtw8922d_rfk_mlo_ctrl(rtwdev);
2232 
2233 	rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
2234 	if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
2235 		rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 128);
2236 	if (phy_idx == RTW89_PHY_0)
2237 		rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58);
2238 }
2239 
2240 static void rtw8922d_rfk_init_late(struct rtw89_dev *rtwdev)
2241 {
2242 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
2243 
2244 	__rtw8922d_rfk_init_late(rtwdev, RTW89_PHY_0, chan);
2245 	if (rtwdev->dbcc_en)
2246 		__rtw8922d_rfk_init_late(rtwdev, RTW89_PHY_1, chan);
2247 }
2248 
2249 static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
2250 {
2251 	u32 rf_mode;
2252 	u8 path;
2253 	int ret;
2254 
2255 	for (path = 0; path < RF_PATH_NUM_8922D; path++) {
2256 		if (!(kpath & BIT(path)))
2257 			continue;
2258 
2259 		ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2,
2260 					       2, 5000, false, rtwdev, path, 0x00,
2261 					       RR_MOD_MASK);
2262 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
2263 			    "[RFK] Wait S%d to Rx mode!! (ret = %d)\n",
2264 			    path, ret);
2265 	}
2266 }
2267 
2268 static void __rtw8922d_tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
2269 {
2270 	u8 path;
2271 
2272 	for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
2273 		u32 addr_ofst = (phy_idx << 12) + (path << 8);
2274 
2275 		rtw89_phy_write32_mask(rtwdev, R_TSSI_DCK_MOV_AVG_LEN_P0_BE4 + addr_ofst,
2276 				       B_TSSI_DCK_MOV_AVG_LEN_P0_BE4, 0x4);
2277 		rtw89_phy_write32_clr(rtwdev, R_USED_TSSI_TRK_ON_P0_BE4 + addr_ofst,
2278 				      B_USED_TSSI_TRK_ON_P0_BE4);
2279 		rtw89_phy_write32_set(rtwdev, R_USED_TSSI_TRK_ON_P0_BE4 + addr_ofst,
2280 				      B_USED_TSSI_TRK_ON_P0_BE4);
2281 		rtw89_phy_write32_clr(rtwdev, R_TSSI_EN_P0_BE4 + addr_ofst,
2282 				      B_TSSI_EN_P0_BE4);
2283 		rtw89_phy_write32_mask(rtwdev, R_TSSI_EN_P0_BE4 + addr_ofst,
2284 				       B_TSSI_EN_P0_BE4, 0x3);
2285 	}
2286 }
2287 
2288 static void __rtw8922d_tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
2289 {
2290 	u8 path;
2291 
2292 	for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
2293 		u32 addr_ofst = (phy_idx << 12) + (path << 8);
2294 
2295 		rtw89_phy_write32_clr(rtwdev, R_TSSI_DCK_MOV_AVG_LEN_P0_BE4 + addr_ofst,
2296 				      B_TSSI_DCK_MOV_AVG_LEN_P0_BE4);
2297 		rtw89_phy_write32_clr(rtwdev, R_USED_TSSI_TRK_ON_P0_BE4 + addr_ofst,
2298 				      B_USED_TSSI_TRK_ON_P0_BE4);
2299 		rtw89_phy_write32_clr(rtwdev, R_TSSI_EN_P0_BE4 + addr_ofst,
2300 				      B_TSSI_EN_P0_BE4);
2301 	}
2302 }
2303 
2304 static void rtw8922d_rfk_tssi(struct rtw89_dev *rtwdev,
2305 			      enum rtw89_phy_idx phy_idx,
2306 			      const struct rtw89_chan *chan,
2307 			      enum rtw89_tssi_mode tssi_mode,
2308 			      unsigned int ms)
2309 {
2310 	int ret;
2311 
2312 	ret = rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, tssi_mode, ms);
2313 	if (ret) {
2314 		rtwdev->is_tssi_mode[RF_PATH_A] = false;
2315 		rtwdev->is_tssi_mode[RF_PATH_B] = false;
2316 	} else {
2317 		rtwdev->is_tssi_mode[RF_PATH_A] = true;
2318 		rtwdev->is_tssi_mode[RF_PATH_B] = true;
2319 	}
2320 }
2321 
2322 static void rtw8922d_rfk_channel(struct rtw89_dev *rtwdev,
2323 				 struct rtw89_vif_link *rtwvif_link)
2324 {
2325 	enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
2326 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
2327 	enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
2328 	u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
2329 	u32 tx_en;
2330 
2331 	rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_START);
2332 	rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
2333 	_wait_rx_mode(rtwdev, RF_AB);
2334 
2335 	rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
2336 	rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54);
2337 	rtw89_phy_rfk_txiqk_and_wait(rtwdev, phy_idx, chan, 45);
2338 	rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84);
2339 	rtw8922d_rfk_tssi(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20);
2340 	rtw89_phy_rfk_cim3k_and_wait(rtwdev, phy_idx, chan, 44);
2341 	rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 68);
2342 	rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32);
2343 
2344 	rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
2345 	rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP);
2346 }
2347 
2348 static void rtw8922d_rfk_band_changed(struct rtw89_dev *rtwdev,
2349 				      enum rtw89_phy_idx phy_idx,
2350 				      const struct rtw89_chan *chan)
2351 {
2352 }
2353 
2354 static void rtw8922d_rfk_scan(struct rtw89_dev *rtwdev,
2355 			      struct rtw89_vif_link *rtwvif_link,
2356 			      bool start)
2357 {
2358 	if (start)
2359 		__rtw8922d_tssi_disable(rtwdev, rtwvif_link->phy_idx);
2360 	else
2361 		__rtw8922d_tssi_enable(rtwdev, rtwvif_link->phy_idx);
2362 }
2363 
2364 static void rtw8922d_rfk_track(struct rtw89_dev *rtwdev)
2365 {
2366 	rtw8922d_lck_track(rtwdev);
2367 }
2368 
2369 static const struct rtw89_reg_def rtw8922d_txpwr_ref[][3] = {
2370 	{{ .addr = R_TXAGC_REF_DBM_PATH0_TBL0_BE4,
2371 	   .mask = B_TXAGC_OFDM_REF_DBM_PATH0_TBL0_BE4 },
2372 	 { .addr = R_TXAGC_REF_DBM_PATH0_TBL0_BE4,
2373 	   .mask = B_TXAGC_CCK_REF_DBM_PATH0_TBL0_BE4 },
2374 	 { .addr = R_TSSI_K_OFDM_PATH0_TBL0_BE4,
2375 	   .mask = B_TSSI_K_OFDM_PATH0_TBL0_BE4 }
2376 	},
2377 	{{ .addr = R_TXAGC_REF_DBM_PATH0_TBL1_BE4,
2378 	   .mask = B_TXAGC_OFDM_REF_DBM_PATH0_TBL1_BE4 },
2379 	 { .addr = R_TXAGC_REF_DBM_PATH0_TBL1_BE4,
2380 	   .mask = B_TXAGC_CCK_REF_DBM_PATH0_TBL1_BE4 },
2381 	 { .addr = R_TSSI_K_OFDM_PATH0_TBL1_BE4,
2382 	   .mask = B_TSSI_K_OFDM_PATH0_TBL1_BE4 }
2383 	},
2384 };
2385 
2386 static void rtw8922d_set_txpwr_diff(struct rtw89_dev *rtwdev,
2387 				    const struct rtw89_chan *chan,
2388 				    enum rtw89_phy_idx phy_idx)
2389 {
2390 	s16 pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
2391 	const struct rtw89_chip_info *chip = rtwdev->chip;
2392 	static const u32 path_ofst[] = {0x0, 0x100};
2393 	const struct rtw89_reg_def *txpwr_ref;
2394 	s16 tssi_k_ofst = abs(pwr_ofst);
2395 	s16 ofst_dec[RF_PATH_NUM_8922D];
2396 	s16 tssi_k[RF_PATH_NUM_8922D];
2397 	s16 pwr_ref_ofst;
2398 	s16 pwr_ref = 16;
2399 	u8 i;
2400 
2401 	pwr_ref <<= chip->txpwr_factor_rf;
2402 	pwr_ref_ofst = pwr_ref - rtw89_phy_txpwr_bb_to_rf(rtwdev, abs(pwr_ofst));
2403 
2404 	ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? pwr_ref : pwr_ref_ofst;
2405 	ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ref_ofst : pwr_ref;
2406 	tssi_k[RF_PATH_A] = pwr_ofst > 0 ? 0 : tssi_k_ofst;
2407 	tssi_k[RF_PATH_B] = pwr_ofst > 0 ? tssi_k_ofst : 0;
2408 
2409 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
2410 		txpwr_ref = rtw8922d_txpwr_ref[phy_idx];
2411 
2412 		rtw89_phy_write32_mask(rtwdev, txpwr_ref[0].addr + path_ofst[i],
2413 				       txpwr_ref[0].mask, ofst_dec[i]);
2414 		rtw89_phy_write32_mask(rtwdev, txpwr_ref[1].addr + path_ofst[i],
2415 				       txpwr_ref[1].mask, ofst_dec[i]);
2416 		rtw89_phy_write32_mask(rtwdev, txpwr_ref[2].addr + path_ofst[i],
2417 				       txpwr_ref[2].mask, tssi_k[i]);
2418 	}
2419 }
2420 
2421 static void rtw8922d_set_txpwr_ref(struct rtw89_dev *rtwdev,
2422 				   const struct rtw89_chan *chan,
2423 				   enum rtw89_phy_idx phy_idx)
2424 {
2425 	s16 ref_ofdm = 0;
2426 	s16 ref_cck = 0;
2427 
2428 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n");
2429 
2430 	rtw8922d_set_txpwr_diff(rtwdev, chan, phy_idx);
2431 
2432 	rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL,
2433 				     B_BE_PWR_REF_CTRL_OFDM, ref_ofdm);
2434 	rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_BE_PWR_REF_CTRL,
2435 				     B_BE_PWR_REF_CTRL_CCK, ref_cck);
2436 }
2437 
2438 static void rtw8922d_set_txpwr_sar_diff(struct rtw89_dev *rtwdev,
2439 					const struct rtw89_chan *chan,
2440 					enum rtw89_phy_idx phy_idx)
2441 {
2442 	struct rtw89_sar_parm sar_parm = {
2443 		.center_freq = chan->freq,
2444 		.force_path = true,
2445 	};
2446 	s16 sar_rf;
2447 	s8 sar_mac;
2448 
2449 	if (phy_idx != RTW89_PHY_0)
2450 		return;
2451 
2452 	sar_parm.path = RF_PATH_A;
2453 	sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
2454 	sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
2455 	rtw89_phy_write32_mask(rtwdev, R_P0_TXPWRB_BE4, B_TXPWRB_MAX_BE, sar_rf);
2456 
2457 	sar_parm.path = RF_PATH_B;
2458 	sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
2459 	sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
2460 	rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB_BE4, B_TXPWRB_MAX_BE, sar_rf);
2461 }
2462 
2463 static void rtw8922d_set_txpwr(struct rtw89_dev *rtwdev,
2464 			       const struct rtw89_chan *chan,
2465 			       enum rtw89_phy_idx phy_idx)
2466 {
2467 	rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
2468 	rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
2469 	rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
2470 	rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
2471 	rtw8922d_set_txpwr_ref(rtwdev, chan, phy_idx);
2472 	rtw8922d_set_txpwr_sar_diff(rtwdev, chan, phy_idx);
2473 }
2474 
2475 static void rtw8922d_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
2476 				    enum rtw89_phy_idx phy_idx)
2477 {
2478 	const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, phy_idx);
2479 
2480 	rtw8922d_set_txpwr_ref(rtwdev, chan, phy_idx);
2481 }
2482 
2483 static void rtw8922d_ctrl_trx_path(struct rtw89_dev *rtwdev,
2484 				   enum rtw89_rf_path tx_path, u8 tx_nss,
2485 				   enum rtw89_rf_path rx_path, u8 rx_nss)
2486 {
2487 	enum rtw89_phy_idx phy_idx;
2488 
2489 	for (phy_idx = RTW89_PHY_0; phy_idx <= RTW89_PHY_1; phy_idx++) {
2490 		rtw8922d_ctrl_tx_path_tmac(rtwdev, tx_path, phy_idx);
2491 		rtw8922d_ctrl_rx_path_tmac(rtwdev, rx_path, phy_idx);
2492 
2493 		rtw8922d_tssi_reset(rtwdev, rx_path, phy_idx);
2494 	}
2495 }
2496 
2497 static void rtw8922d_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
2498 				     enum rtw89_phy_idx phy_idx)
2499 {
2500 	if (en) {
2501 		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x3, phy_idx);
2502 		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A,
2503 				      0xf, phy_idx);
2504 		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A,
2505 				      0x0, phy_idx);
2506 		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x0, phy_idx);
2507 		rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x80, phy_idx);
2508 		rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x8080, phy_idx);
2509 		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x34, phy_idx);
2510 		rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x34, phy_idx);
2511 		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x3, phy_idx);
2512 		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B,
2513 				      0xf, phy_idx);
2514 		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B,
2515 				      0x0, phy_idx);
2516 		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x0, phy_idx);
2517 		rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA1_B, 0x80, phy_idx);
2518 		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x34, phy_idx);
2519 		rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x34, phy_idx);
2520 	} else {
2521 		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_A, B_FORCE_FIR_A, 0x0, phy_idx);
2522 		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_A, B_RXBY_WBADC_A,
2523 				      0x0, phy_idx);
2524 		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_A, B_BT_RXBY_WBADC_A,
2525 				      0x1, phy_idx);
2526 		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_A, B_BT_TRK_OFF_A, 0x1, phy_idx);
2527 		rtw89_phy_write32_idx(rtwdev, R_OP1DB_A, B_OP1DB_A, 0x1a, phy_idx);
2528 		rtw89_phy_write32_idx(rtwdev, R_OP1DB1_A, B_TIA10_A, 0x2a2a, phy_idx);
2529 		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_A, B_LNA_IBADC_A, 0x7a6, phy_idx);
2530 		rtw89_phy_write32_idx(rtwdev, R_BKOFF_A, B_BKOFF_IBADC_A, 0x26, phy_idx);
2531 		rtw89_phy_write32_idx(rtwdev, R_FORCE_FIR_B, B_FORCE_FIR_B, 0x0, phy_idx);
2532 		rtw89_phy_write32_idx(rtwdev, R_RXBY_WBADC_B, B_RXBY_WBADC_B,
2533 				      0x0, phy_idx);
2534 		rtw89_phy_write32_idx(rtwdev, R_BT_RXBY_WBADC_B, B_BT_RXBY_WBADC_B,
2535 				      0x1, phy_idx);
2536 		rtw89_phy_write32_idx(rtwdev, R_BT_SHARE_B, B_BT_TRK_OFF_B, 0x1, phy_idx);
2537 		rtw89_phy_write32_idx(rtwdev, R_LNA_TIA, B_TIA1_B, 0x2a, phy_idx);
2538 		rtw89_phy_write32_idx(rtwdev, R_BACKOFF_B, B_LNA_IBADC_B, 0x7a6, phy_idx);
2539 		rtw89_phy_write32_idx(rtwdev, R_BKOFF_B, B_BKOFF_IBADC_B, 0x26, phy_idx);
2540 	}
2541 }
2542 
2543 static void rtw8922d_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
2544 {
2545 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
2546 	enum rtw89_band band = chan->band_type;
2547 	struct rtw89_hal *hal = &rtwdev->hal;
2548 	u8 ntx_path = RF_PATH_AB;
2549 	u8 nrx_path = RF_PATH_AB;
2550 	u32 tx_en0, tx_en1;
2551 	u8 rx_nss = 2;
2552 
2553 	if (hal->antenna_tx == RF_A)
2554 		ntx_path = RF_PATH_A;
2555 	else if (hal->antenna_tx == RF_B)
2556 		ntx_path = RF_PATH_B;
2557 
2558 	if (hal->antenna_rx == RF_A)
2559 		nrx_path = RF_PATH_A;
2560 	else if (hal->antenna_rx == RF_B)
2561 		nrx_path = RF_PATH_B;
2562 
2563 	if (nrx_path != RF_PATH_AB)
2564 		rx_nss = 1;
2565 
2566 	rtw8922d_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, true);
2567 	if (rtwdev->dbcc_en)
2568 		rtw8922d_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band,
2569 				   &tx_en1, true);
2570 
2571 	rtw8922d_ctrl_trx_path(rtwdev, ntx_path, 2, nrx_path, rx_nss);
2572 
2573 	rtw8922d_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false);
2574 	if (rtwdev->dbcc_en)
2575 		rtw8922d_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band,
2576 				   &tx_en1, false);
2577 }
2578 
2579 static u8 rtw8922d_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
2580 {
2581 	u8 val;
2582 
2583 	rtw89_phy_write32_mask(rtwdev, R_TC_EN_BE4, B_TC_EN_BE4, 0x1);
2584 	rtw89_phy_write32_mask(rtwdev, R_TC_EN_BE4, B_TC_TRIG_BE4, 0x0);
2585 	rtw89_phy_write32_mask(rtwdev, R_TC_EN_BE4, B_TC_TRIG_BE4, 0x1);
2586 
2587 	fsleep(100);
2588 
2589 	val = rtw89_phy_read32_mask(rtwdev, R_TC_VAL_BE4, B_TC_VAL_BE4);
2590 
2591 	return val;
2592 }
2593 
2594 static u32 rtw8922d_chan_to_rf18_val(struct rtw89_dev *rtwdev,
2595 				     const struct rtw89_chan *chan)
2596 {
2597 	u32 val = u32_encode_bits(chan->channel, RR_CFGCH_CH);
2598 
2599 	switch (chan->band_type) {
2600 	case RTW89_BAND_2G:
2601 	default:
2602 		break;
2603 	case RTW89_BAND_5G:
2604 		val |= u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) |
2605 		       u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0);
2606 		break;
2607 	case RTW89_BAND_6G:
2608 		val |= u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) |
2609 		       u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0);
2610 		break;
2611 	}
2612 
2613 	switch (chan->band_width) {
2614 	case RTW89_CHANNEL_WIDTH_5:
2615 	case RTW89_CHANNEL_WIDTH_10:
2616 	case RTW89_CHANNEL_WIDTH_20:
2617 	default:
2618 		break;
2619 	case RTW89_CHANNEL_WIDTH_40:
2620 		val |= u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2);
2621 		break;
2622 	case RTW89_CHANNEL_WIDTH_80:
2623 		val |= u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2);
2624 		break;
2625 	case RTW89_CHANNEL_WIDTH_160:
2626 		val |= u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2);
2627 		break;
2628 	case RTW89_CHANNEL_WIDTH_320:
2629 		val |= u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2);
2630 		break;
2631 	}
2632 
2633 	return val;
2634 }
2635 
2636 static void rtw8922d_btc_set_rfe(struct rtw89_dev *rtwdev)
2637 {
2638 }
2639 
2640 static void rtw8922d_btc_init_cfg(struct rtw89_dev *rtwdev)
2641 {
2642 	/* offload to firmware */
2643 }
2644 
2645 static void
2646 rtw8922d_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
2647 {
2648 	u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0));
2649 	u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16));
2650 
2651 	switch (ctrl_all_time) {
2652 	case 0xffff:
2653 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2654 					     B_BE_FORCE_PWR_BY_RATE_EN, 0x0);
2655 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2656 					     B_BE_FORCE_PWR_BY_RATE_VAL, 0x0);
2657 		break;
2658 	default:
2659 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2660 					     B_BE_FORCE_PWR_BY_RATE_VAL, ctrl_all_time);
2661 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
2662 					     B_BE_FORCE_PWR_BY_RATE_EN, 0x1);
2663 		break;
2664 	}
2665 
2666 	switch (ctrl_gnt_bt) {
2667 	case 0xffff:
2668 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL,
2669 					     B_BE_PWR_BT_EN, 0x0);
2670 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL,
2671 					     B_BE_PWR_BT_VAL, 0x0);
2672 		break;
2673 	default:
2674 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL,
2675 					     B_BE_PWR_BT_VAL, ctrl_gnt_bt);
2676 		rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL,
2677 					     B_BE_PWR_BT_EN, 0x1);
2678 		break;
2679 	}
2680 }
2681 
2682 static
2683 s8 rtw8922d_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
2684 {
2685 	return clamp_t(s8, val, -100, 0) + 100;
2686 }
2687 
2688 static const struct rtw89_btc_rf_trx_para_v9 rtw89_btc_8922d_rf_ul_v9[] = {
2689 	/*
2690 	 * 0 -> original
2691 	 * 1 -> for BT-connected ACI issue && BTG co-rx
2692 	 * 2 ~ 4 ->reserved for shared-antenna
2693 	 * 5 ~ 8 ->for non-shared-antenna free-run
2694 	 */
2695 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2696 	{{15, 15}, {2, 2}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2697 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2698 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2699 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2700 	{{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2701 	{{ 6,  6}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2702 	{{13, 13}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2703 	{{13, 13}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2704 };
2705 
2706 static const struct rtw89_btc_rf_trx_para_v9 rtw89_btc_8922d_rf_dl_v9[] = {
2707 	/*
2708 	 * 0 -> original
2709 	 * 1 -> for BT-connected ACI issue && BTG co-rx
2710 	 * 2 ~ 4 ->reserved for shared-antenna
2711 	 * 5 ~ 8 ->for non-shared-antenna free-run
2712 	 */
2713 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2714 	{{15, 15}, {2, 2}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2715 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2716 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2717 	{{15, 15}, {0, 0}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2718 	{{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2719 	{{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2720 	{{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2721 	{{15, 15}, {1, 1}, {0, 0}, {7, 7}, {0, 0}, {0, 0}},
2722 };
2723 
2724 static const u8 rtw89_btc_8922d_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30};
2725 static const u8 rtw89_btc_8922d_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20};
2726 
2727 static const struct rtw89_btc_fbtc_mreg rtw89_btc_8922d_mon_reg[] = {
2728 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe300),
2729 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe330),
2730 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe334),
2731 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe338),
2732 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe344),
2733 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe348),
2734 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe34c),
2735 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe350),
2736 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe354),
2737 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe35c),
2738 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe370),
2739 	RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe380),
2740 };
2741 
2742 static
2743 void rtw8922d_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
2744 {
2745 	/* Feature move to firmware */
2746 }
2747 
2748 static
2749 void rtw8922d_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
2750 {
2751 	/* Feature move to firmware */
2752 }
2753 
2754 static void rtw8922d_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
2755 {
2756 	/* Feature move to firmware */
2757 }
2758 
2759 static void rtw8922d_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
2760 					 struct rtw89_rx_phy_ppdu *phy_ppdu,
2761 					 struct ieee80211_rx_status *status)
2762 {
2763 	u8 chan_idx = phy_ppdu->chan_idx;
2764 	enum nl80211_band band;
2765 	u8 ch;
2766 
2767 	if (chan_idx == 0)
2768 		return;
2769 
2770 	rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band);
2771 	status->freq = ieee80211_channel_to_frequency(ch, band);
2772 	status->band = band;
2773 }
2774 
2775 static void rtw8922d_query_ppdu(struct rtw89_dev *rtwdev,
2776 				struct rtw89_rx_phy_ppdu *phy_ppdu,
2777 				struct ieee80211_rx_status *status)
2778 {
2779 	u8 path;
2780 	u8 *rx_power = phy_ppdu->rssi;
2781 
2782 	if (!status->signal)
2783 		status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A],
2784 							   rx_power[RF_PATH_B]));
2785 
2786 	for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
2787 		status->chains |= BIT(path);
2788 		status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
2789 	}
2790 	if (phy_ppdu->valid)
2791 		rtw8922d_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
2792 }
2793 
2794 static void rtw8922d_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
2795 					 struct rtw89_rx_phy_ppdu *phy_ppdu)
2796 {
2797 	/* Mapping to BW: 5, 10, 20, 40, 80, 160, 80_80 */
2798 	static const u8 bw_compensate[] = {0, 0, 0, 6, 12, 18, 0};
2799 	u8 *rssi = phy_ppdu->rssi;
2800 	u8 compensate = 0;
2801 	u8 i;
2802 
2803 	if (phy_ppdu->bw_idx < ARRAY_SIZE(bw_compensate))
2804 		compensate = bw_compensate[phy_ppdu->bw_idx];
2805 
2806 	for (i = 0; i < RF_PATH_NUM_8922D; i++) {
2807 		if (!(phy_ppdu->rx_path_en & BIT(i))) {
2808 			rssi[i] = 0;
2809 			phy_ppdu->rpl_path[i] = 0;
2810 			phy_ppdu->rpl_fd[i] = 0;
2811 		}
2812 
2813 		if (phy_ppdu->ie != RTW89_CCK_PKT && rssi[i])
2814 			rssi[i] += compensate;
2815 
2816 		phy_ppdu->rpl_path[i] = rssi[i];
2817 	}
2818 }
2819 
2820 static void rtw8922d_phy_rpt_to_rssi(struct rtw89_dev *rtwdev,
2821 				     struct rtw89_rx_desc_info *desc_info,
2822 				     struct ieee80211_rx_status *rx_status)
2823 {
2824 	if (desc_info->rssi <= 0x1 || (desc_info->rssi >> 2) > MAX_RSSI)
2825 		return;
2826 
2827 	rx_status->signal = (desc_info->rssi >> 2) - MAX_RSSI;
2828 }
2829 
2830 static int rtw8922d_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
2831 {
2832 	return 0;
2833 }
2834 
2835 static int rtw8922d_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
2836 {
2837 	return 0;
2838 }
2839 
2840 static const struct rtw89_chanctx_listener rtw8922d_chanctx_listener = {
2841 	.callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb,
2842 };
2843 
2844 #ifdef CONFIG_PM
2845 static const struct wiphy_wowlan_support rtw_wowlan_stub_8922d = {
2846 	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
2847 		 WIPHY_WOWLAN_NET_DETECT,
2848 	.n_patterns = RTW89_MAX_PATTERN_NUM,
2849 	.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
2850 	.pattern_min_len = 1,
2851 	.max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID,
2852 };
2853 #endif
2854 
2855 static const struct rtw89_chip_ops rtw8922d_chip_ops = {
2856 	.enable_bb_rf		= rtw8922d_mac_enable_bb_rf,
2857 	.disable_bb_rf		= rtw8922d_mac_disable_bb_rf,
2858 	.bb_preinit		= rtw8922d_bb_preinit,
2859 	.bb_postinit		= rtw8922d_bb_postinit,
2860 	.bb_reset		= rtw8922d_bb_reset,
2861 	.bb_sethw		= rtw8922d_bb_sethw,
2862 	.read_rf		= rtw89_phy_read_rf_v3,
2863 	.write_rf		= rtw89_phy_write_rf_v3,
2864 	.set_channel		= rtw8922d_set_channel,
2865 	.set_channel_help	= rtw8922d_set_channel_help,
2866 	.read_efuse		= rtw8922d_read_efuse,
2867 	.read_phycap		= rtw8922d_read_phycap,
2868 	.fem_setup		= NULL,
2869 	.rfe_gpio		= NULL,
2870 	.rfk_hw_init		= rtw8922d_rfk_hw_init,
2871 	.rfk_init		= rtw8922d_rfk_init,
2872 	.rfk_init_late		= rtw8922d_rfk_init_late,
2873 	.rfk_channel		= rtw8922d_rfk_channel,
2874 	.rfk_band_changed	= rtw8922d_rfk_band_changed,
2875 	.rfk_scan		= rtw8922d_rfk_scan,
2876 	.rfk_track		= rtw8922d_rfk_track,
2877 	.power_trim		= rtw8922d_power_trim,
2878 	.set_txpwr		= rtw8922d_set_txpwr,
2879 	.set_txpwr_ctrl		= rtw8922d_set_txpwr_ctrl,
2880 	.init_txpwr_unit	= NULL,
2881 	.get_thermal		= rtw8922d_get_thermal,
2882 	.chan_to_rf18_val	= rtw8922d_chan_to_rf18_val,
2883 	.ctrl_btg_bt_rx		= rtw8922d_set_gbt_bt_rx_sel,
2884 	.query_ppdu		= rtw8922d_query_ppdu,
2885 	.convert_rpl_to_rssi	= rtw8922d_convert_rpl_to_rssi,
2886 	.phy_rpt_to_rssi	= rtw8922d_phy_rpt_to_rssi,
2887 	.ctrl_nbtg_bt_tx	= rtw8922d_ctrl_nbtg_bt_tx,
2888 	.cfg_txrx_path		= rtw8922d_bb_cfg_txrx_path,
2889 	.set_txpwr_ul_tb_offset	= NULL,
2890 	.digital_pwr_comp	= rtw8922d_digital_pwr_comp,
2891 	.calc_rx_gain_normal	= rtw8922d_calc_rx_gain_normal,
2892 	.pwr_on_func		= rtw8922d_pwr_on_func,
2893 	.pwr_off_func		= rtw8922d_pwr_off_func,
2894 	.query_rxdesc		= rtw89_core_query_rxdesc_v3,
2895 	.fill_txdesc		= rtw89_core_fill_txdesc_v3,
2896 	.fill_txdesc_fwcmd	= rtw89_core_fill_txdesc_fwcmd_v2,
2897 	.get_ch_dma		= {rtw89_core_get_ch_dma_v1,
2898 				   NULL,
2899 				   NULL,},
2900 	.cfg_ctrl_path		= rtw89_mac_cfg_ctrl_path_v2,
2901 	.mac_cfg_gnt		= rtw89_mac_cfg_gnt_v3,
2902 	.stop_sch_tx		= rtw89_mac_stop_sch_tx_v2,
2903 	.resume_sch_tx		= rtw89_mac_resume_sch_tx_v2,
2904 	.h2c_dctl_sec_cam	= rtw89_fw_h2c_dctl_sec_cam_v3,
2905 	.h2c_default_cmac_tbl	= rtw89_fw_h2c_default_cmac_tbl_be,
2906 	.h2c_assoc_cmac_tbl	= rtw89_fw_h2c_assoc_cmac_tbl_be,
2907 	.h2c_ampdu_cmac_tbl	= rtw89_fw_h2c_ampdu_cmac_tbl_be,
2908 	.h2c_txtime_cmac_tbl	= rtw89_fw_h2c_txtime_cmac_tbl_be,
2909 	.h2c_punctured_cmac_tbl	= rtw89_fw_h2c_punctured_cmac_tbl_be,
2910 	.h2c_default_dmac_tbl	= rtw89_fw_h2c_default_dmac_tbl_v3,
2911 	.h2c_update_beacon	= rtw89_fw_h2c_update_beacon_be,
2912 	.h2c_ba_cam		= rtw89_fw_h2c_ba_cam_v1,
2913 	.h2c_wow_cam_update	= rtw89_fw_h2c_wow_cam_update_v1,
2914 
2915 	.btc_set_rfe		= rtw8922d_btc_set_rfe,
2916 	.btc_init_cfg		= rtw8922d_btc_init_cfg,
2917 	.btc_set_wl_pri		= NULL,
2918 	.btc_set_wl_txpwr_ctrl	= rtw8922d_btc_set_wl_txpwr_ctrl,
2919 	.btc_get_bt_rssi	= rtw8922d_btc_get_bt_rssi,
2920 	.btc_update_bt_cnt	= rtw8922d_btc_update_bt_cnt,
2921 	.btc_wl_s1_standby	= rtw8922d_btc_wl_s1_standby,
2922 	.btc_set_wl_rx_gain	= rtw8922d_btc_set_wl_rx_gain,
2923 	.btc_set_policy		= rtw89_btc_set_policy_v1,
2924 };
2925 
2926 const struct rtw89_chip_info rtw8922d_chip_info = {
2927 	.chip_id		= RTL8922D,
2928 	.chip_gen		= RTW89_CHIP_BE,
2929 	.ops			= &rtw8922d_chip_ops,
2930 	.mac_def		= &rtw89_mac_gen_be,
2931 	.phy_def		= &rtw89_phy_gen_be_v1,
2932 	.fw_def			= {
2933 		.fw_basename	= RTW8922D_FW_BASENAME,
2934 		.fw_format_max	= RTW8922D_FW_FORMAT_MAX,
2935 		.fw_b_aid	= RTL8922D_AID7102,
2936 	},
2937 	.try_ce_fw		= false,
2938 	.bbmcu_nr		= 0,
2939 	.needed_fw_elms		= RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS_V1,
2940 	.fw_blacklist		= &rtw89_fw_blacklist_default,
2941 	.fifo_size		= 393216,
2942 	.small_fifo_size	= false,
2943 	.dle_scc_rsvd_size	= 0,
2944 	.max_amsdu_limit	= 11000,
2945 	.max_vht_mpdu_cap	= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991,
2946 	.max_eht_mpdu_cap	= IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991,
2947 	.max_tx_agg_num		= 128,
2948 	.max_rx_agg_num		= 256,
2949 	.dis_2g_40m_ul_ofdma	= false,
2950 	.rsvd_ple_ofst		= 0x5f800,
2951 	.hfc_param_ini		= {rtw8922d_hfc_param_ini_pcie, NULL, NULL},
2952 	.dle_mem		= {rtw8922d_dle_mem_pcie, NULL, NULL, NULL},
2953 	.wde_qempty_acq_grpnum	= 8,
2954 	.wde_qempty_mgq_grpsel	= 8,
2955 	.rf_base_addr		= {0x3e000, 0x3f000},
2956 	.thermal_th		= {0xac, 0xad},
2957 	.pwr_on_seq		= NULL,
2958 	.pwr_off_seq		= NULL,
2959 	.bb_table		= NULL,
2960 	.bb_gain_table		= NULL,
2961 	.rf_table		= {},
2962 	.nctl_table		= NULL,
2963 	.nctl_post_table	= &rtw8922d_nctl_post_defs_tbl,
2964 	.dflt_parms		= NULL, /* load parm from fw */
2965 	.rfe_parms_conf		= NULL, /* load parm from fw */
2966 	.chanctx_listener	= &rtw8922d_chanctx_listener,
2967 	.txpwr_factor_bb	= 3,
2968 	.txpwr_factor_rf	= 2,
2969 	.txpwr_factor_mac	= 1,
2970 	.dig_table		= NULL,
2971 	.dig_regs		= &rtw8922d_dig_regs,
2972 	.tssi_dbw_table		= NULL,
2973 	.support_macid_num	= 64,
2974 	.support_link_num	= 2,
2975 	.support_chanctx_num	= 2,
2976 	.support_rnr		= true,
2977 	.support_bands		= BIT(NL80211_BAND_2GHZ) |
2978 				  BIT(NL80211_BAND_5GHZ) |
2979 				  BIT(NL80211_BAND_6GHZ),
2980 	.support_bandwidths	= BIT(NL80211_CHAN_WIDTH_20) |
2981 				  BIT(NL80211_CHAN_WIDTH_40) |
2982 				  BIT(NL80211_CHAN_WIDTH_80) |
2983 				  BIT(NL80211_CHAN_WIDTH_160),
2984 	.support_unii4		= true,
2985 	.support_ant_gain	= false,
2986 	.support_tas		= false,
2987 	.support_sar_by_ant	= true,
2988 	.support_noise		= false,
2989 	.ul_tb_waveform_ctrl	= false,
2990 	.ul_tb_pwr_diff		= false,
2991 	.rx_freq_frome_ie	= false,
2992 	.hw_sec_hdr		= true,
2993 	.hw_mgmt_tx_encrypt	= true,
2994 	.hw_tkip_crypto		= true,
2995 	.hw_mlo_bmc_crypto	= true,
2996 	.rf_path_num		= 2,
2997 	.tx_nss			= 2,
2998 	.rx_nss			= 2,
2999 	.acam_num		= 128,
3000 	.bcam_num		= 16,
3001 	.scam_num		= 32,
3002 	.bacam_num		= 24,
3003 	.bacam_dynamic_num	= 8,
3004 	.bacam_ver		= RTW89_BACAM_V1,
3005 	.addrcam_ver		= 1,
3006 	.ppdu_max_usr		= 16,
3007 	.sec_ctrl_efuse_size	= 4,
3008 	.physical_efuse_size	= 0x1300,
3009 	.logical_efuse_size	= 0x70000,
3010 	.limit_efuse_size	= 0x40000,
3011 	.dav_phy_efuse_size	= 0,
3012 	.dav_log_efuse_size	= 0,
3013 	.efuse_blocks		= rtw8922d_efuse_blocks,
3014 	.phycap_addr		= 0x1700,
3015 	.phycap_size		= 0x60,
3016 	.para_ver		= 0x3ff,
3017 	.wlcx_desired		= 0x09150000,
3018 	.scbd			= 0x1,
3019 	.mailbox		= 0x1,
3020 
3021 	.afh_guard_ch		= 6,
3022 	.wl_rssi_thres		= rtw89_btc_8922d_wl_rssi_thres,
3023 	.bt_rssi_thres		= rtw89_btc_8922d_bt_rssi_thres,
3024 	.rssi_tol		= 2,
3025 	.mon_reg_num		= ARRAY_SIZE(rtw89_btc_8922d_mon_reg),
3026 	.mon_reg		= rtw89_btc_8922d_mon_reg,
3027 	.rf_para_ulink_v9	= rtw89_btc_8922d_rf_ul_v9,
3028 	.rf_para_dlink_v9	= rtw89_btc_8922d_rf_dl_v9,
3029 	.rf_para_ulink_num_v9	= ARRAY_SIZE(rtw89_btc_8922d_rf_ul_v9),
3030 	.rf_para_dlink_num_v9	= ARRAY_SIZE(rtw89_btc_8922d_rf_dl_v9),
3031 	.ps_mode_supported	= BIT(RTW89_PS_MODE_RFOFF) |
3032 				  BIT(RTW89_PS_MODE_CLK_GATED) |
3033 				  BIT(RTW89_PS_MODE_PWR_GATED),
3034 	.low_power_hci_modes	= 0,
3035 	.h2c_cctl_func_id	= H2C_FUNC_MAC_CCTLINFO_UD_G7,
3036 	.hci_func_en_addr	= R_BE_HCI_FUNC_EN,
3037 	.h2c_desc_size		= sizeof(struct rtw89_rxdesc_short_v3),
3038 	.txwd_body_size		= sizeof(struct rtw89_txwd_body_v2),
3039 	.txwd_info_size		= sizeof(struct rtw89_txwd_info_v2),
3040 	.h2c_ctrl_reg		= R_BE_H2CREG_CTRL,
3041 	.h2c_counter_reg	= {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8},
3042 	.h2c_regs		= rtw8922d_h2c_regs,
3043 	.c2h_ctrl_reg		= R_BE_C2HREG_CTRL,
3044 	.c2h_counter_reg	= {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
3045 	.c2h_regs		= rtw8922d_c2h_regs,
3046 	.page_regs		= &rtw8922d_page_regs,
3047 	.wow_reason_reg		= rtw8922d_wow_wakeup_regs,
3048 	.cfo_src_fd		= true,
3049 	.cfo_hw_comp            = true,
3050 	.dcfo_comp		= NULL,
3051 	.dcfo_comp_sft		= 0,
3052 	.nhm_report		= NULL,
3053 	.nhm_th			= NULL,
3054 	.imr_info		= NULL,
3055 	.imr_dmac_table		= &rtw8922d_imr_dmac_table,
3056 	.imr_cmac_table		= &rtw8922d_imr_cmac_table,
3057 	.rrsr_cfgs		= &rtw8922d_rrsr_cfgs,
3058 	.bss_clr_vld		= {R_BSS_CLR_VLD_BE4, B_BSS_CLR_VLD_BE4},
3059 	.bss_clr_map_reg	= R_BSS_CLR_MAP_BE4,
3060 	.rfkill_init		= &rtw8922d_rfkill_regs,
3061 	.rfkill_get		= {R_BE_GPIO_EXT_CTRL, B_BE_GPIO_IN_9},
3062 	.btc_sb			= {{{R_BE_SCOREBOARD_0, R_BE_SCOREBOARD_0_BT_DATA},
3063 				    {R_BE_SCOREBOARD_1, R_BE_SCOREBOARD_1_BT_DATA}}},
3064 	.dma_ch_mask		= BIT(RTW89_DMA_ACH1) | BIT(RTW89_DMA_ACH3) |
3065 				  BIT(RTW89_DMA_ACH5) | BIT(RTW89_DMA_ACH7) |
3066 				  BIT(RTW89_DMA_B0HI) | BIT(RTW89_DMA_B1HI),
3067 	.edcca_regs		= &rtw8922d_edcca_regs,
3068 #ifdef CONFIG_PM
3069 	.wowlan_stub		= &rtw_wowlan_stub_8922d,
3070 #endif
3071 	.xtal_info		= NULL,
3072 	.default_quirks		= BIT(RTW89_QUIRK_THERMAL_PROT_120C),
3073 };
3074 EXPORT_SYMBOL(rtw8922d_chip_info);
3075 
3076 static const struct rtw89_fw_def rtw8922de_vs_fw_def = {
3077 	.fw_basename		= RTW8922DS_FW_BASENAME,
3078 	.fw_format_max		= RTW8922DS_FW_FORMAT_MAX,
3079 	.fw_b_aid		= RTL8922D_AID7060,
3080 };
3081 
3082 const struct rtw89_chip_variant rtw8922de_vs_variant = {
3083 	.no_mcs_12_13 = true,
3084 	.fw_min_ver_code = RTW89_FW_VER_CODE(0, 0, 0, 0),
3085 	.fw_def_override = &rtw8922de_vs_fw_def,
3086 };
3087 EXPORT_SYMBOL(rtw8922de_vs_variant);
3088 
3089 MODULE_FIRMWARE(RTW8922D_MODULE_FIRMWARE);
3090 MODULE_FIRMWARE(RTW8922DS_MODULE_FIRMWARE);
3091 MODULE_AUTHOR("Realtek Corporation");
3092 MODULE_DESCRIPTION("Realtek 802.11be wireless 8922D driver");
3093 MODULE_LICENSE("Dual BSD/GPL");
3094