1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019  Realtek Corporation
3  */
4 
5 #include <linux/module.h>
6 #include "main.h"
7 #include "coex.h"
8 #include "fw.h"
9 #include "tx.h"
10 #include "rx.h"
11 #include "phy.h"
12 #include "rtw8822b.h"
13 #include "rtw8822b_table.h"
14 #include "mac.h"
15 #include "reg.h"
16 #include "debug.h"
17 #include "bf.h"
18 
19 static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
20 				     u8 rx_path, bool is_tx2_path);
21 
22 static void rtw8822be_efuse_parsing(struct rtw_efuse *efuse,
23 				    struct rtw8822b_efuse *map)
24 {
25 	ether_addr_copy(efuse->addr, map->e.mac_addr);
26 }
27 
28 static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
29 {
30 	struct rtw_efuse *efuse = &rtwdev->efuse;
31 	struct rtw8822b_efuse *map;
32 	int i;
33 
34 	map = (struct rtw8822b_efuse *)log_map;
35 
36 	efuse->rfe_option = map->rfe_option;
37 	efuse->rf_board_option = map->rf_board_option;
38 	efuse->crystal_cap = map->xtal_k;
39 	efuse->pa_type_2g = map->pa_type;
40 	efuse->pa_type_5g = map->pa_type;
41 	efuse->lna_type_2g = map->lna_type_2g[0];
42 	efuse->lna_type_5g = map->lna_type_5g[0];
43 	efuse->channel_plan = map->channel_plan;
44 	efuse->country_code[0] = map->country_code[0];
45 	efuse->country_code[1] = map->country_code[1];
46 	efuse->bt_setting = map->rf_bt_setting;
47 	efuse->regd = map->rf_board_option & 0x7;
48 	efuse->thermal_meter[RF_PATH_A] = map->thermal_meter;
49 	efuse->thermal_meter_k = map->thermal_meter;
50 
51 	for (i = 0; i < 4; i++)
52 		efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
53 
54 	switch (rtw_hci_type(rtwdev)) {
55 	case RTW_HCI_TYPE_PCIE:
56 		rtw8822be_efuse_parsing(efuse, map);
57 		break;
58 	default:
59 		/* unsupported now */
60 		return -ENOTSUPP;
61 	}
62 
63 	return 0;
64 }
65 
66 static void rtw8822b_phy_rfe_init(struct rtw_dev *rtwdev)
67 {
68 	/* chip top mux */
69 	rtw_write32_mask(rtwdev, 0x64, BIT(29) | BIT(28), 0x3);
70 	rtw_write32_mask(rtwdev, 0x4c, BIT(26) | BIT(25), 0x0);
71 	rtw_write32_mask(rtwdev, 0x40, BIT(2), 0x1);
72 
73 	/* from s0 or s1 */
74 	rtw_write32_mask(rtwdev, 0x1990, 0x3f, 0x30);
75 	rtw_write32_mask(rtwdev, 0x1990, (BIT(11) | BIT(10)), 0x3);
76 
77 	/* input or output */
78 	rtw_write32_mask(rtwdev, 0x974, 0x3f, 0x3f);
79 	rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3);
80 }
81 
82 #define RTW_TXSCALE_SIZE 37
83 static const u32 rtw8822b_txscale_tbl[RTW_TXSCALE_SIZE] = {
84 	0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8,
85 	0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180,
86 	0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab,
87 	0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe
88 };
89 
90 static const u8 rtw8822b_get_swing_index(struct rtw_dev *rtwdev)
91 {
92 	u8 i = 0;
93 	u32 swing, table_value;
94 
95 	swing = rtw_read32_mask(rtwdev, 0xc1c, 0xffe00000);
96 	for (i = 0; i < RTW_TXSCALE_SIZE; i++) {
97 		table_value = rtw8822b_txscale_tbl[i];
98 		if (swing == table_value)
99 			break;
100 	}
101 
102 	return i;
103 }
104 
105 static void rtw8822b_pwrtrack_init(struct rtw_dev *rtwdev)
106 {
107 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
108 	u8 swing_idx = rtw8822b_get_swing_index(rtwdev);
109 	u8 path;
110 
111 	if (swing_idx >= RTW_TXSCALE_SIZE)
112 		dm_info->default_ofdm_index = 24;
113 	else
114 		dm_info->default_ofdm_index = swing_idx;
115 
116 	for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
117 		ewma_thermal_init(&dm_info->avg_thermal[path]);
118 		dm_info->delta_power_index[path] = 0;
119 	}
120 	dm_info->pwr_trk_triggered = false;
121 	dm_info->pwr_trk_init_trigger = true;
122 	dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
123 }
124 
125 static void rtw8822b_phy_bf_init(struct rtw_dev *rtwdev)
126 {
127 	rtw_bf_phy_init(rtwdev);
128 	/* Grouping bitmap parameters */
129 	rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF);
130 }
131 
132 static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev)
133 {
134 	struct rtw_hal *hal = &rtwdev->hal;
135 	u8 crystal_cap;
136 	bool is_tx2_path;
137 
138 	/* power on BB/RF domain */
139 	rtw_write8_set(rtwdev, REG_SYS_FUNC_EN,
140 		       BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
141 	rtw_write8_set(rtwdev, REG_RF_CTRL,
142 		       BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
143 	rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN);
144 
145 	/* pre init before header files config */
146 	rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
147 
148 	rtw_phy_load_tables(rtwdev);
149 
150 	crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
151 	rtw_write32_mask(rtwdev, 0x24, 0x7e000000, crystal_cap);
152 	rtw_write32_mask(rtwdev, 0x28, 0x7e, crystal_cap);
153 
154 	/* post init after header files config */
155 	rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
156 
157 	is_tx2_path = false;
158 	rtw8822b_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx,
159 				 is_tx2_path);
160 	rtw_phy_init(rtwdev);
161 
162 	rtw8822b_phy_rfe_init(rtwdev);
163 	rtw8822b_pwrtrack_init(rtwdev);
164 
165 	rtw8822b_phy_bf_init(rtwdev);
166 }
167 
168 #define WLAN_SLOT_TIME		0x09
169 #define WLAN_PIFS_TIME		0x19
170 #define WLAN_SIFS_CCK_CONT_TX	0xA
171 #define WLAN_SIFS_OFDM_CONT_TX	0xE
172 #define WLAN_SIFS_CCK_TRX	0x10
173 #define WLAN_SIFS_OFDM_TRX	0x10
174 #define WLAN_VO_TXOP_LIMIT	0x186 /* unit : 32us */
175 #define WLAN_VI_TXOP_LIMIT	0x3BC /* unit : 32us */
176 #define WLAN_RDG_NAV		0x05
177 #define WLAN_TXOP_NAV		0x1B
178 #define WLAN_CCK_RX_TSF		0x30
179 #define WLAN_OFDM_RX_TSF	0x30
180 #define WLAN_TBTT_PROHIBIT	0x04 /* unit : 32us */
181 #define WLAN_TBTT_HOLD_TIME	0x064 /* unit : 32us */
182 #define WLAN_DRV_EARLY_INT	0x04
183 #define WLAN_BCN_DMA_TIME	0x02
184 
185 #define WLAN_RX_FILTER0		0x0FFFFFFF
186 #define WLAN_RX_FILTER2		0xFFFF
187 #define WLAN_RCR_CFG		0xE400220E
188 #define WLAN_RXPKT_MAX_SZ	12288
189 #define WLAN_RXPKT_MAX_SZ_512	(WLAN_RXPKT_MAX_SZ >> 9)
190 
191 #define WLAN_AMPDU_MAX_TIME		0x70
192 #define WLAN_RTS_LEN_TH			0xFF
193 #define WLAN_RTS_TX_TIME_TH		0x08
194 #define WLAN_MAX_AGG_PKT_LIMIT		0x20
195 #define WLAN_RTS_MAX_AGG_PKT_LIMIT	0x20
196 #define FAST_EDCA_VO_TH		0x06
197 #define FAST_EDCA_VI_TH		0x06
198 #define FAST_EDCA_BE_TH		0x06
199 #define FAST_EDCA_BK_TH		0x06
200 #define WLAN_BAR_RETRY_LIMIT		0x01
201 #define WLAN_RA_TRY_RATE_AGG_LIMIT	0x08
202 
203 #define WLAN_TX_FUNC_CFG1		0x30
204 #define WLAN_TX_FUNC_CFG2		0x30
205 #define WLAN_MAC_OPT_NORM_FUNC1		0x98
206 #define WLAN_MAC_OPT_LB_FUNC1		0x80
207 #define WLAN_MAC_OPT_FUNC2		0x30810041
208 
209 #define WLAN_SIFS_CFG	(WLAN_SIFS_CCK_CONT_TX | \
210 			(WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
211 			(WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
212 			(WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
213 
214 #define WLAN_TBTT_TIME	(WLAN_TBTT_PROHIBIT |\
215 			(WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
216 
217 #define WLAN_NAV_CFG		(WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
218 #define WLAN_RX_TSF_CFG		(WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
219 
220 static int rtw8822b_mac_init(struct rtw_dev *rtwdev)
221 {
222 	u32 value32;
223 
224 	/* protocol configuration */
225 	rtw_write8_clr(rtwdev, REG_SW_AMPDU_BURST_MODE_CTRL, BIT_PRE_TX_CMD);
226 	rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME);
227 	rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
228 	value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) |
229 		  (WLAN_MAX_AGG_PKT_LIMIT << 16) |
230 		  (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24);
231 	rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32);
232 	rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2,
233 		    WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8);
234 	rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH);
235 	rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH);
236 	rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH);
237 	rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH);
238 	/* EDCA configuration */
239 	rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0);
240 	rtw_write16(rtwdev, REG_TXPAUSE, 0x0000);
241 	rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
242 	rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME);
243 	rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG);
244 	rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT);
245 	rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT);
246 	rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG);
247 	rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG);
248 	/* Set beacon cotnrol - enable TSF and other related functions */
249 	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
250 	/* Set send beacon related registers */
251 	rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME);
252 	rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT);
253 	rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
254 	rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8);
255 	/* WMAC configuration */
256 	rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
257 	rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
258 	rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
259 	rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512);
260 	rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2);
261 	rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
262 	rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
263 	rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1);
264 
265 	return 0;
266 }
267 
268 static void rtw8822b_set_channel_rfe_efem(struct rtw_dev *rtwdev, u8 channel)
269 {
270 	struct rtw_hal *hal = &rtwdev->hal;
271 
272 	if (IS_CH_2G_BAND(channel)) {
273 		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x705770);
274 		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57);
275 		rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(4), 0);
276 	} else {
277 		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x177517);
278 		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75);
279 		rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(5), 0);
280 	}
281 
282 	rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0);
283 
284 	if (hal->antenna_rx == BB_PATH_AB ||
285 	    hal->antenna_tx == BB_PATH_AB) {
286 		/* 2TX or 2RX */
287 		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501);
288 	} else if (hal->antenna_rx == hal->antenna_tx) {
289 		/* TXA+RXA or TXB+RXB */
290 		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500);
291 	} else {
292 		/* TXB+RXA or TXA+RXB */
293 		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005);
294 	}
295 }
296 
297 static void rtw8822b_set_channel_rfe_ifem(struct rtw_dev *rtwdev, u8 channel)
298 {
299 	struct rtw_hal *hal = &rtwdev->hal;
300 
301 	if (IS_CH_2G_BAND(channel)) {
302 		/* signal source */
303 		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x745774);
304 		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57);
305 	} else {
306 		/* signal source */
307 		rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x477547);
308 		rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75);
309 	}
310 
311 	rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0);
312 
313 	if (IS_CH_2G_BAND(channel)) {
314 		if (hal->antenna_rx == BB_PATH_AB ||
315 		    hal->antenna_tx == BB_PATH_AB) {
316 			/* 2TX or 2RX */
317 			rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501);
318 		} else if (hal->antenna_rx == hal->antenna_tx) {
319 			/* TXA+RXA or TXB+RXB */
320 			rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500);
321 		} else {
322 			/* TXB+RXA or TXA+RXB */
323 			rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005);
324 		}
325 	} else {
326 		rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa5a5);
327 	}
328 }
329 
330 enum {
331 	CCUT_IDX_1R_2G,
332 	CCUT_IDX_2R_2G,
333 	CCUT_IDX_1R_5G,
334 	CCUT_IDX_2R_5G,
335 	CCUT_IDX_NR,
336 };
337 
338 struct cca_ccut {
339 	u32 reg82c[CCUT_IDX_NR];
340 	u32 reg830[CCUT_IDX_NR];
341 	u32 reg838[CCUT_IDX_NR];
342 };
343 
344 static const struct cca_ccut cca_ifem_ccut = {
345 	{0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/
346 	{0x79a0eaaa, 0x79A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/
347 	{0x87765541, 0x87746341, 0x87765541, 0x87746341}, /*Reg838*/
348 };
349 
350 static const struct cca_ccut cca_efem_ccut = {
351 	{0x75B86010, 0x75B76010, 0x75B86010, 0x75B76010}, /*Reg82C*/
352 	{0x79A0EAA8, 0x79A0EAAC, 0x79A0EAA8, 0x79a0eaaa}, /*Reg830*/
353 	{0x87766451, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/
354 };
355 
356 static const struct cca_ccut cca_ifem_ccut_ext = {
357 	{0x75da8010, 0x75da8010, 0x75da8010, 0x75da8010}, /*Reg82C*/
358 	{0x79a0eaaa, 0x97A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/
359 	{0x87765541, 0x86666341, 0x87765561, 0x86666361}, /*Reg838*/
360 };
361 
362 static void rtw8822b_get_cca_val(const struct cca_ccut *cca_ccut, u8 col,
363 				 u32 *reg82c, u32 *reg830, u32 *reg838)
364 {
365 	*reg82c = cca_ccut->reg82c[col];
366 	*reg830 = cca_ccut->reg830[col];
367 	*reg838 = cca_ccut->reg838[col];
368 }
369 
370 struct rtw8822b_rfe_info {
371 	const struct cca_ccut *cca_ccut_2g;
372 	const struct cca_ccut *cca_ccut_5g;
373 	enum rtw_rfe_fem fem;
374 	bool ifem_ext;
375 	void (*rtw_set_channel_rfe)(struct rtw_dev *rtwdev, u8 channel);
376 };
377 
378 #define I2GE5G_CCUT(set_ch) {						\
379 	.cca_ccut_2g = &cca_ifem_ccut,					\
380 	.cca_ccut_5g = &cca_efem_ccut,					\
381 	.fem = RTW_RFE_IFEM2G_EFEM5G,					\
382 	.ifem_ext = false,						\
383 	.rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch,	\
384 	}
385 #define IFEM_EXT_CCUT(set_ch) {						\
386 	.cca_ccut_2g = &cca_ifem_ccut_ext,				\
387 	.cca_ccut_5g = &cca_ifem_ccut_ext,				\
388 	.fem = RTW_RFE_IFEM,						\
389 	.ifem_ext = true,						\
390 	.rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch,	\
391 	}
392 
393 static const struct rtw8822b_rfe_info rtw8822b_rfe_info[] = {
394 	[2] = I2GE5G_CCUT(efem),
395 	[3] = IFEM_EXT_CCUT(ifem),
396 	[5] = IFEM_EXT_CCUT(ifem),
397 };
398 
399 static void rtw8822b_set_channel_cca(struct rtw_dev *rtwdev, u8 channel, u8 bw,
400 				     const struct rtw8822b_rfe_info *rfe_info)
401 {
402 	struct rtw_hal *hal = &rtwdev->hal;
403 	struct rtw_efuse *efuse = &rtwdev->efuse;
404 	const struct cca_ccut *cca_ccut;
405 	u8 col;
406 	u32 reg82c, reg830, reg838;
407 	bool is_efem_cca = false, is_ifem_cca = false, is_rfe_type = false;
408 
409 	if (IS_CH_2G_BAND(channel)) {
410 		cca_ccut = rfe_info->cca_ccut_2g;
411 
412 		if (hal->antenna_rx == BB_PATH_A ||
413 		    hal->antenna_rx == BB_PATH_B)
414 			col = CCUT_IDX_1R_2G;
415 		else
416 			col = CCUT_IDX_2R_2G;
417 	} else {
418 		cca_ccut = rfe_info->cca_ccut_5g;
419 
420 		if (hal->antenna_rx == BB_PATH_A ||
421 		    hal->antenna_rx == BB_PATH_B)
422 			col = CCUT_IDX_1R_5G;
423 		else
424 			col = CCUT_IDX_2R_5G;
425 	}
426 
427 	rtw8822b_get_cca_val(cca_ccut, col, &reg82c, &reg830, &reg838);
428 
429 	switch (rfe_info->fem) {
430 	case RTW_RFE_IFEM:
431 	default:
432 		is_ifem_cca = true;
433 		if (rfe_info->ifem_ext)
434 			is_rfe_type = true;
435 		break;
436 	case RTW_RFE_EFEM:
437 		is_efem_cca = true;
438 		break;
439 	case RTW_RFE_IFEM2G_EFEM5G:
440 		if (IS_CH_2G_BAND(channel))
441 			is_ifem_cca = true;
442 		else
443 			is_efem_cca = true;
444 		break;
445 	}
446 
447 	if (is_ifem_cca) {
448 		if ((hal->cut_version == RTW_CHIP_VER_CUT_B &&
449 		     (col == CCUT_IDX_2R_2G || col == CCUT_IDX_2R_5G) &&
450 		     bw == RTW_CHANNEL_WIDTH_40) ||
451 		    (!is_rfe_type && col == CCUT_IDX_2R_5G &&
452 		     bw == RTW_CHANNEL_WIDTH_40) ||
453 		    (efuse->rfe_option == 5 && col == CCUT_IDX_2R_5G))
454 			reg830 = 0x79a0ea28;
455 	}
456 
457 	rtw_write32_mask(rtwdev, REG_CCASEL, MASKDWORD, reg82c);
458 	rtw_write32_mask(rtwdev, REG_PDMFTH, MASKDWORD, reg830);
459 	rtw_write32_mask(rtwdev, REG_CCA2ND, MASKDWORD, reg838);
460 
461 	if (is_efem_cca && !(hal->cut_version == RTW_CHIP_VER_CUT_B))
462 		rtw_write32_mask(rtwdev, REG_L1WT, MASKDWORD, 0x9194b2b9);
463 
464 	if (bw == RTW_CHANNEL_WIDTH_20 && IS_CH_5G_BAND_MID(channel))
465 		rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0, 0x4);
466 }
467 
468 static const u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff, 0x6,
469 				0x5, 0x0, 0x0, 0x7, 0x6, 0x6};
470 static const u8 middle_band[23] = {0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6, 0xff, 0x0,
471 				   0x0, 0x7, 0x6, 0x6, 0x5, 0x0, 0xff, 0x7, 0x6,
472 				   0x6, 0x5, 0x0, 0x0, 0x7};
473 static const u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff, 0x0,
474 				 0x7, 0x7, 0x6, 0x5, 0x5, 0x0};
475 
476 static void rtw8822b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
477 {
478 #define RF18_BAND_MASK		(BIT(16) | BIT(9) | BIT(8))
479 #define RF18_BAND_2G		(0)
480 #define RF18_BAND_5G		(BIT(16) | BIT(8))
481 #define RF18_CHANNEL_MASK	(MASKBYTE0)
482 #define RF18_RFSI_MASK		(BIT(18) | BIT(17))
483 #define RF18_RFSI_GE_CH80	(BIT(17))
484 #define RF18_RFSI_GT_CH144	(BIT(18))
485 #define RF18_BW_MASK		(BIT(11) | BIT(10))
486 #define RF18_BW_20M		(BIT(11) | BIT(10))
487 #define RF18_BW_40M		(BIT(11))
488 #define RF18_BW_80M		(BIT(10))
489 #define RFBE_MASK		(BIT(17) | BIT(16) | BIT(15))
490 
491 	struct rtw_hal *hal = &rtwdev->hal;
492 	u32 rf_reg18, rf_reg_be;
493 
494 	rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK);
495 
496 	rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK |
497 		      RF18_BW_MASK);
498 
499 	rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G);
500 	rf_reg18 |= (channel & RF18_CHANNEL_MASK);
501 	if (channel > 144)
502 		rf_reg18 |= RF18_RFSI_GT_CH144;
503 	else if (channel >= 80)
504 		rf_reg18 |= RF18_RFSI_GE_CH80;
505 
506 	switch (bw) {
507 	case RTW_CHANNEL_WIDTH_5:
508 	case RTW_CHANNEL_WIDTH_10:
509 	case RTW_CHANNEL_WIDTH_20:
510 	default:
511 		rf_reg18 |= RF18_BW_20M;
512 		break;
513 	case RTW_CHANNEL_WIDTH_40:
514 		rf_reg18 |= RF18_BW_40M;
515 		break;
516 	case RTW_CHANNEL_WIDTH_80:
517 		rf_reg18 |= RF18_BW_80M;
518 		break;
519 	}
520 
521 	if (IS_CH_2G_BAND(channel))
522 		rf_reg_be = 0x0;
523 	else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel))
524 		rf_reg_be = low_band[(channel - 36) >> 1];
525 	else if (IS_CH_5G_BAND_3(channel))
526 		rf_reg_be = middle_band[(channel - 100) >> 1];
527 	else if (IS_CH_5G_BAND_4(channel))
528 		rf_reg_be = high_band[(channel - 149) >> 1];
529 	else
530 		goto err;
531 
532 	rtw_write_rf(rtwdev, RF_PATH_A, RF_MALSEL, RFBE_MASK, rf_reg_be);
533 
534 	/* need to set 0xdf[18]=1 before writing RF18 when channel 144 */
535 	if (channel == 144)
536 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x1);
537 	else
538 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x0);
539 
540 	rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18);
541 	if (hal->rf_type > RF_1T1R)
542 		rtw_write_rf(rtwdev, RF_PATH_B, 0x18, RFREG_MASK, rf_reg18);
543 
544 	rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0);
545 	rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1);
546 
547 	return;
548 
549 err:
550 	WARN_ON(1);
551 }
552 
553 static void rtw8822b_toggle_igi(struct rtw_dev *rtwdev)
554 {
555 	struct rtw_hal *hal = &rtwdev->hal;
556 	u32 igi;
557 
558 	igi = rtw_read32_mask(rtwdev, REG_RXIGI_A, 0x7f);
559 	rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi - 2);
560 	rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi);
561 	rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi - 2);
562 	rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi);
563 
564 	rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, 0x0);
565 	rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0,
566 			 hal->antenna_rx | (hal->antenna_rx << 4));
567 }
568 
569 static void rtw8822b_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw)
570 {
571 	if (bw == RTW_CHANNEL_WIDTH_40) {
572 		/* RX DFIR for BW40 */
573 		rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x1);
574 		rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x0);
575 		rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
576 	} else if (bw == RTW_CHANNEL_WIDTH_80) {
577 		/* RX DFIR for BW80 */
578 		rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
579 		rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1);
580 		rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
581 	} else {
582 		/* RX DFIR for BW20, BW10 and BW5*/
583 		rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
584 		rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2);
585 		rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1);
586 	}
587 }
588 
589 static void rtw8822b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
590 				    u8 primary_ch_idx)
591 {
592 	struct rtw_efuse *efuse = &rtwdev->efuse;
593 	u8 rfe_option = efuse->rfe_option;
594 	u32 val32;
595 
596 	if (IS_CH_2G_BAND(channel)) {
597 		rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1);
598 		rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0);
599 		rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0);
600 		rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15);
601 
602 		rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x0);
603 		rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a);
604 		if (channel == 14) {
605 			rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x00006577);
606 			rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000);
607 		} else {
608 			rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x384f6577);
609 			rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x1525);
610 		}
611 
612 		rtw_write32_mask(rtwdev, REG_RFEINV, 0x300, 0x2);
613 	} else if (IS_CH_5G_BAND(channel)) {
614 		rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1);
615 		rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1);
616 		rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0);
617 		rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 34);
618 
619 		if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel))
620 			rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x1);
621 		else if (IS_CH_5G_BAND_3(channel))
622 			rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x2);
623 		else if (IS_CH_5G_BAND_4(channel))
624 			rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x3);
625 
626 		if (IS_CH_5G_BAND_1(channel))
627 			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494);
628 		else if (IS_CH_5G_BAND_2(channel))
629 			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453);
630 		else if (channel >= 100 && channel <= 116)
631 			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452);
632 		else if (channel >= 118 && channel <= 177)
633 			rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412);
634 
635 		rtw_write32_mask(rtwdev, 0xcbc, 0x300, 0x1);
636 	}
637 
638 	switch (bw) {
639 	case RTW_CHANNEL_WIDTH_20:
640 	default:
641 		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
642 		val32 &= 0xFFCFFC00;
643 		val32 |= (RTW_CHANNEL_WIDTH_20);
644 		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
645 
646 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
647 		break;
648 	case RTW_CHANNEL_WIDTH_40:
649 		if (primary_ch_idx == RTW_SC_20_UPPER)
650 			rtw_write32_set(rtwdev, REG_RXSB, BIT(4));
651 		else
652 			rtw_write32_clr(rtwdev, REG_RXSB, BIT(4));
653 
654 		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
655 		val32 &= 0xFF3FF300;
656 		val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_40);
657 		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
658 
659 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
660 		break;
661 	case RTW_CHANNEL_WIDTH_80:
662 		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
663 		val32 &= 0xFCEFCF00;
664 		val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_80);
665 		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
666 
667 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
668 
669 		if (rfe_option == 2 || rfe_option == 3) {
670 			rtw_write32_mask(rtwdev, REG_L1PKWT, 0x0000f000, 0x6);
671 			rtw_write32_mask(rtwdev, REG_ADC40, BIT(10), 0x1);
672 		}
673 		break;
674 	case RTW_CHANNEL_WIDTH_5:
675 		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
676 		val32 &= 0xEFEEFE00;
677 		val32 |= ((BIT(6) | RTW_CHANNEL_WIDTH_20));
678 		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
679 
680 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
681 		rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
682 		break;
683 	case RTW_CHANNEL_WIDTH_10:
684 		val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
685 		val32 &= 0xEFFEFF00;
686 		val32 |= ((BIT(7) | RTW_CHANNEL_WIDTH_20));
687 		rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
688 
689 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
690 		rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
691 		break;
692 	}
693 }
694 
695 static void rtw8822b_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
696 				 u8 primary_chan_idx)
697 {
698 	struct rtw_efuse *efuse = &rtwdev->efuse;
699 	const struct rtw8822b_rfe_info *rfe_info;
700 
701 	if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info),
702 		 "rfe_option %d is out of boundary\n", efuse->rfe_option))
703 		return;
704 
705 	rfe_info = &rtw8822b_rfe_info[efuse->rfe_option];
706 
707 	rtw8822b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
708 	rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
709 	rtw8822b_set_channel_rf(rtwdev, channel, bw);
710 	rtw8822b_set_channel_rxdfir(rtwdev, bw);
711 	rtw8822b_toggle_igi(rtwdev);
712 	rtw8822b_set_channel_cca(rtwdev, channel, bw, rfe_info);
713 	(*rfe_info->rtw_set_channel_rfe)(rtwdev, channel);
714 }
715 
716 static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
717 				     u8 rx_path, bool is_tx2_path)
718 {
719 	struct rtw_efuse *efuse = &rtwdev->efuse;
720 	const struct rtw8822b_rfe_info *rfe_info;
721 	u8 ch = rtwdev->hal.current_channel;
722 	u8 tx_path_sel, rx_path_sel;
723 	int counter;
724 
725 	if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info),
726 		 "rfe_option %d is out of boundary\n", efuse->rfe_option))
727 		return;
728 
729 	rfe_info = &rtw8822b_rfe_info[efuse->rfe_option];
730 
731 	if ((tx_path | rx_path) & BB_PATH_A)
732 		rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x3231);
733 	else
734 		rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x1111);
735 
736 	if ((tx_path | rx_path) & BB_PATH_B)
737 		rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x3231);
738 	else
739 		rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x1111);
740 
741 	rtw_write32_mask(rtwdev, REG_CDDTXP, (BIT(19) | BIT(18)), 0x3);
742 	rtw_write32_mask(rtwdev, REG_TXPSEL, (BIT(29) | BIT(28)), 0x1);
743 	rtw_write32_mask(rtwdev, REG_TXPSEL, BIT(30), 0x1);
744 
745 	if (tx_path & BB_PATH_A) {
746 		rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x001);
747 		rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x8);
748 	} else if (tx_path & BB_PATH_B) {
749 		rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x002);
750 		rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x4);
751 	}
752 
753 	if (tx_path == BB_PATH_A || tx_path == BB_PATH_B)
754 		rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x01);
755 	else
756 		rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x43);
757 
758 	tx_path_sel = (tx_path << 4) | tx_path;
759 	rtw_write32_mask(rtwdev, REG_TXPSEL, MASKBYTE0, tx_path_sel);
760 
761 	if (tx_path != BB_PATH_A && tx_path != BB_PATH_B) {
762 		if (is_tx2_path || rtwdev->mp_mode) {
763 			rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x043);
764 			rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0xc);
765 		}
766 	}
767 
768 	rtw_write32_mask(rtwdev, REG_RXDESC, BIT(22), 0x0);
769 	rtw_write32_mask(rtwdev, REG_RXDESC, BIT(18), 0x0);
770 
771 	if (rx_path & BB_PATH_A)
772 		rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x0);
773 	else if (rx_path & BB_PATH_B)
774 		rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x5);
775 
776 	rx_path_sel = (rx_path << 4) | rx_path;
777 	rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, rx_path_sel);
778 
779 	if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) {
780 		rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x0);
781 		rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x0);
782 		rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x0);
783 	} else {
784 		rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x1);
785 		rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x1);
786 		rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x1);
787 	}
788 
789 	for (counter = 100; counter > 0; counter--) {
790 		u32 rf_reg33;
791 
792 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
793 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001);
794 
795 		udelay(2);
796 		rf_reg33 = rtw_read_rf(rtwdev, RF_PATH_A, 0x33, RFREG_MASK);
797 
798 		if (rf_reg33 == 0x00001)
799 			break;
800 	}
801 
802 	if (WARN(counter <= 0, "write RF mode table fail\n"))
803 		return;
804 
805 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
806 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001);
807 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x00034);
808 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x4080c);
809 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
810 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
811 
812 	rtw8822b_toggle_igi(rtwdev);
813 	rtw8822b_set_channel_cca(rtwdev, 1, RTW_CHANNEL_WIDTH_20, rfe_info);
814 	(*rfe_info->rtw_set_channel_rfe)(rtwdev, ch);
815 }
816 
817 static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
818 				   struct rtw_rx_pkt_stat *pkt_stat)
819 {
820 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
821 	s8 min_rx_power = -120;
822 	u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status);
823 
824 	/* 8822B uses only 1 antenna to RX CCK rates */
825 	pkt_stat->rx_power[RF_PATH_A] = pwdb - 110;
826 	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
827 	pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
828 	pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
829 				     min_rx_power);
830 	dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
831 }
832 
833 static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
834 				   struct rtw_rx_pkt_stat *pkt_stat)
835 {
836 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
837 	u8 rxsc, bw;
838 	s8 min_rx_power = -120;
839 	s8 rx_evm;
840 	u8 evm_dbm = 0;
841 	u8 rssi;
842 	int path;
843 
844 	if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
845 		rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
846 	else
847 		rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
848 
849 	if (rxsc >= 1 && rxsc <= 8)
850 		bw = RTW_CHANNEL_WIDTH_20;
851 	else if (rxsc >= 9 && rxsc <= 12)
852 		bw = RTW_CHANNEL_WIDTH_40;
853 	else if (rxsc >= 13)
854 		bw = RTW_CHANNEL_WIDTH_80;
855 	else
856 		bw = GET_PHY_STAT_P1_RF_MODE(phy_status);
857 
858 	pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
859 	pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110;
860 	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2);
861 	pkt_stat->bw = bw;
862 	pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A],
863 				      pkt_stat->rx_power[RF_PATH_B],
864 				      min_rx_power);
865 
866 	dm_info->curr_rx_rate = pkt_stat->rate;
867 
868 	pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status);
869 	pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status);
870 
871 	pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status);
872 	pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status);
873 
874 	pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status);
875 	pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status);
876 
877 	for (path = 0; path <= rtwdev->hal.rf_path_num; path++) {
878 		rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1);
879 		dm_info->rssi[path] = rssi;
880 		dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1;
881 		dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1;
882 
883 		rx_evm = pkt_stat->rx_evm[path];
884 
885 		if (rx_evm < 0) {
886 			if (rx_evm == S8_MIN)
887 				evm_dbm = 0;
888 			else
889 				evm_dbm = ((u8)-rx_evm >> 1);
890 		}
891 		dm_info->rx_evm_dbm[path] = evm_dbm;
892 	}
893 }
894 
895 static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
896 			     struct rtw_rx_pkt_stat *pkt_stat)
897 {
898 	u8 page;
899 
900 	page = *phy_status & 0xf;
901 
902 	switch (page) {
903 	case 0:
904 		query_phy_status_page0(rtwdev, phy_status, pkt_stat);
905 		break;
906 	case 1:
907 		query_phy_status_page1(rtwdev, phy_status, pkt_stat);
908 		break;
909 	default:
910 		rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
911 		return;
912 	}
913 }
914 
915 static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
916 				   struct rtw_rx_pkt_stat *pkt_stat,
917 				   struct ieee80211_rx_status *rx_status)
918 {
919 	struct ieee80211_hdr *hdr;
920 	u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
921 	u8 *phy_status = NULL;
922 
923 	memset(pkt_stat, 0, sizeof(*pkt_stat));
924 
925 	pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
926 	pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
927 	pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
928 	pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
929 			      GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
930 	pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
931 	pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
932 	pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
933 	pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
934 	pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
935 	pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
936 	pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
937 	pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
938 
939 	/* drv_info_sz is in unit of 8-bytes */
940 	pkt_stat->drv_info_sz *= 8;
941 
942 	/* c2h cmd pkt's rx/phy status is not interested */
943 	if (pkt_stat->is_c2h)
944 		return;
945 
946 	hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
947 				       pkt_stat->drv_info_sz);
948 	if (pkt_stat->phy_status) {
949 		phy_status = rx_desc + desc_sz + pkt_stat->shift;
950 		query_phy_status(rtwdev, phy_status, pkt_stat);
951 	}
952 
953 	rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
954 }
955 
956 static void
957 rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
958 {
959 	struct rtw_hal *hal = &rtwdev->hal;
960 	static const u32 offset_txagc[2] = {0x1d00, 0x1d80};
961 	static u32 phy_pwr_idx;
962 	u8 rate, rate_idx, pwr_index, shift;
963 	int j;
964 
965 	for (j = 0; j < rtw_rate_size[rs]; j++) {
966 		rate = rtw_rate_section[rs][j];
967 		pwr_index = hal->tx_pwr_tbl[path][rate];
968 		shift = rate & 0x3;
969 		phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
970 		if (shift == 0x3) {
971 			rate_idx = rate & 0xfc;
972 			rtw_write32(rtwdev, offset_txagc[path] + rate_idx,
973 				    phy_pwr_idx);
974 			phy_pwr_idx = 0;
975 		}
976 	}
977 }
978 
979 static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev)
980 {
981 	struct rtw_hal *hal = &rtwdev->hal;
982 	int rs, path;
983 
984 	for (path = 0; path < hal->rf_path_num; path++) {
985 		for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
986 			rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs);
987 	}
988 }
989 
990 static bool rtw8822b_check_rf_path(u8 antenna)
991 {
992 	switch (antenna) {
993 	case BB_PATH_A:
994 	case BB_PATH_B:
995 	case BB_PATH_AB:
996 		return true;
997 	default:
998 		return false;
999 	}
1000 }
1001 
1002 static int rtw8822b_set_antenna(struct rtw_dev *rtwdev,
1003 				u32 antenna_tx,
1004 				u32 antenna_rx)
1005 {
1006 	struct rtw_hal *hal = &rtwdev->hal;
1007 
1008 	rtw_dbg(rtwdev, RTW_DBG_PHY, "config RF path, tx=0x%x rx=0x%x\n",
1009 		antenna_tx, antenna_rx);
1010 
1011 	if (!rtw8822b_check_rf_path(antenna_tx)) {
1012 		rtw_info(rtwdev, "unsupport tx path 0x%x\n", antenna_tx);
1013 		return -EINVAL;
1014 	}
1015 
1016 	if (!rtw8822b_check_rf_path(antenna_rx)) {
1017 		rtw_info(rtwdev, "unsupport rx path 0x%x\n", antenna_rx);
1018 		return -EINVAL;
1019 	}
1020 
1021 	hal->antenna_tx = antenna_tx;
1022 	hal->antenna_rx = antenna_rx;
1023 
1024 	rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
1025 
1026 	return 0;
1027 }
1028 
1029 static void rtw8822b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
1030 {
1031 	u8 ldo_pwr;
1032 
1033 	ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
1034 	ldo_pwr = enable ? ldo_pwr | BIT_LDO25_EN : ldo_pwr & ~BIT_LDO25_EN;
1035 	rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
1036 }
1037 
1038 static void rtw8822b_false_alarm_statistics(struct rtw_dev *rtwdev)
1039 {
1040 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1041 	u32 cck_enable;
1042 	u32 cck_fa_cnt;
1043 	u32 ofdm_fa_cnt;
1044 	u32 crc32_cnt;
1045 	u32 cca32_cnt;
1046 
1047 	cck_enable = rtw_read32(rtwdev, 0x808) & BIT(28);
1048 	cck_fa_cnt = rtw_read16(rtwdev, 0xa5c);
1049 	ofdm_fa_cnt = rtw_read16(rtwdev, 0xf48);
1050 
1051 	dm_info->cck_fa_cnt = cck_fa_cnt;
1052 	dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
1053 	dm_info->total_fa_cnt = ofdm_fa_cnt;
1054 	dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0;
1055 
1056 	crc32_cnt = rtw_read32(rtwdev, 0xf04);
1057 	dm_info->cck_ok_cnt = crc32_cnt & 0xffff;
1058 	dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1059 	crc32_cnt = rtw_read32(rtwdev, 0xf14);
1060 	dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff;
1061 	dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1062 	crc32_cnt = rtw_read32(rtwdev, 0xf10);
1063 	dm_info->ht_ok_cnt = crc32_cnt & 0xffff;
1064 	dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1065 	crc32_cnt = rtw_read32(rtwdev, 0xf0c);
1066 	dm_info->vht_ok_cnt = crc32_cnt & 0xffff;
1067 	dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1068 
1069 	cca32_cnt = rtw_read32(rtwdev, 0xf08);
1070 	dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16);
1071 	dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
1072 	if (cck_enable) {
1073 		cca32_cnt = rtw_read32(rtwdev, 0xfcc);
1074 		dm_info->cck_cca_cnt = cca32_cnt & 0xffff;
1075 		dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
1076 	}
1077 
1078 	rtw_write32_set(rtwdev, 0x9a4, BIT(17));
1079 	rtw_write32_clr(rtwdev, 0x9a4, BIT(17));
1080 	rtw_write32_clr(rtwdev, 0xa2c, BIT(15));
1081 	rtw_write32_set(rtwdev, 0xa2c, BIT(15));
1082 	rtw_write32_set(rtwdev, 0xb58, BIT(0));
1083 	rtw_write32_clr(rtwdev, 0xb58, BIT(0));
1084 }
1085 
1086 static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)
1087 {
1088 	static int do_iqk_cnt;
1089 	struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
1090 	u32 rf_reg, iqk_fail_mask;
1091 	int counter;
1092 	bool reload;
1093 
1094 	rtw_fw_do_iqk(rtwdev, &para);
1095 
1096 	for (counter = 0; counter < 300; counter++) {
1097 		rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK);
1098 		if (rf_reg == 0xabcde)
1099 			break;
1100 		msleep(20);
1101 	}
1102 	rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
1103 
1104 	reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
1105 	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
1106 	rtw_dbg(rtwdev, RTW_DBG_PHY,
1107 		"iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
1108 		counter, reload, ++do_iqk_cnt, iqk_fail_mask);
1109 }
1110 
1111 static void rtw8822b_phy_calibration(struct rtw_dev *rtwdev)
1112 {
1113 	rtw8822b_do_iqk(rtwdev);
1114 }
1115 
1116 static void rtw8822b_coex_cfg_init(struct rtw_dev *rtwdev)
1117 {
1118 	/* enable TBTT nterrupt */
1119 	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
1120 
1121 	/* BT report packet sample rate */
1122 	/* 0x790[5:0]=0x5 */
1123 	rtw_write8_set(rtwdev, REG_BT_TDMA_TIME, 0x05);
1124 
1125 	/* enable BT counter statistics */
1126 	rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
1127 
1128 	/* enable PTA (3-wire function form BT side) */
1129 	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
1130 	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_AOD_GPIO3);
1131 
1132 	/* enable PTA (tx/rx signal form WiFi side) */
1133 	rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
1134 	/* wl tx signal to PTA not case EDCCA */
1135 	rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN);
1136 	/* GNT_BT=1 while select both */
1137 	rtw_write8_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY);
1138 }
1139 
1140 static void rtw8822b_coex_cfg_ant_switch(struct rtw_dev *rtwdev,
1141 					 u8 ctrl_type, u8 pos_type)
1142 {
1143 	struct rtw_coex *coex = &rtwdev->coex;
1144 	struct rtw_coex_dm *coex_dm = &coex->dm;
1145 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
1146 	bool polarity_inverse;
1147 	u8 regval = 0;
1148 
1149 	if (((ctrl_type << 8) + pos_type) == coex_dm->cur_switch_status)
1150 		return;
1151 
1152 	coex_dm->cur_switch_status = (ctrl_type << 8) + pos_type;
1153 
1154 	if (coex_rfe->ant_switch_diversity &&
1155 	    ctrl_type == COEX_SWITCH_CTRL_BY_BBSW)
1156 		ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV;
1157 
1158 	polarity_inverse = (coex_rfe->ant_switch_polarity == 1);
1159 
1160 	switch (ctrl_type) {
1161 	default:
1162 	case COEX_SWITCH_CTRL_BY_BBSW:
1163 		/* 0x4c[23] = 0 */
1164 		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1165 		/* 0x4c[24] = 1 */
1166 		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1167 		/* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
1168 		rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x77);
1169 
1170 		if (pos_type == COEX_SWITCH_TO_WLG_BT) {
1171 			if (coex_rfe->rfe_module_type != 0x4 &&
1172 			    coex_rfe->rfe_module_type != 0x2)
1173 				regval = 0x3;
1174 			else
1175 				regval = (!polarity_inverse ? 0x2 : 0x1);
1176 		} else if (pos_type == COEX_SWITCH_TO_WLG) {
1177 			regval = (!polarity_inverse ? 0x2 : 0x1);
1178 		} else {
1179 			regval = (!polarity_inverse ? 0x1 : 0x2);
1180 		}
1181 
1182 		rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval);
1183 		break;
1184 	case COEX_SWITCH_CTRL_BY_PTA:
1185 		/* 0x4c[23] = 0 */
1186 		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1187 		/* 0x4c[24] = 1 */
1188 		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1189 		/* PTA,  DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
1190 		rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x66);
1191 
1192 		regval = (!polarity_inverse ? 0x2 : 0x1);
1193 		rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval);
1194 		break;
1195 	case COEX_SWITCH_CTRL_BY_ANTDIV:
1196 		/* 0x4c[23] = 0 */
1197 		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1198 		/* 0x4c[24] = 1 */
1199 		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1200 		rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x88);
1201 		break;
1202 	case COEX_SWITCH_CTRL_BY_MAC:
1203 		/* 0x4c[23] = 1 */
1204 		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x1);
1205 
1206 		regval = (!polarity_inverse ? 0x0 : 0x1);
1207 		rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA, regval);
1208 		break;
1209 	case COEX_SWITCH_CTRL_BY_FW:
1210 		/* 0x4c[23] = 0 */
1211 		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1212 		/* 0x4c[24] = 1 */
1213 		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1214 		break;
1215 	case COEX_SWITCH_CTRL_BY_BT:
1216 		/* 0x4c[23] = 0 */
1217 		rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1218 		/* 0x4c[24] = 0 */
1219 		rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x0);
1220 		break;
1221 	}
1222 }
1223 
1224 static void rtw8822b_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
1225 {
1226 }
1227 
1228 static void rtw8822b_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
1229 {
1230 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0);
1231 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0);
1232 	rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0);
1233 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0);
1234 	rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0);
1235 }
1236 
1237 static void rtw8822b_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
1238 {
1239 	struct rtw_coex *coex = &rtwdev->coex;
1240 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
1241 	struct rtw_efuse *efuse = &rtwdev->efuse;
1242 	bool is_ext_fem = false;
1243 
1244 	coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;
1245 	coex_rfe->ant_switch_polarity = 0;
1246 	coex_rfe->ant_switch_diversity = false;
1247 	if (coex_rfe->rfe_module_type == 0x12 ||
1248 	    coex_rfe->rfe_module_type == 0x15 ||
1249 	    coex_rfe->rfe_module_type == 0x16)
1250 		coex_rfe->ant_switch_exist = false;
1251 	else
1252 		coex_rfe->ant_switch_exist = true;
1253 
1254 	if (coex_rfe->rfe_module_type == 2 ||
1255 	    coex_rfe->rfe_module_type == 4) {
1256 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, true);
1257 		is_ext_fem = true;
1258 	} else {
1259 		rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, false);
1260 	}
1261 
1262 	coex_rfe->wlg_at_btg = false;
1263 
1264 	if (efuse->share_ant &&
1265 	    coex_rfe->ant_switch_exist && !is_ext_fem)
1266 		coex_rfe->ant_switch_with_bt = true;
1267 	else
1268 		coex_rfe->ant_switch_with_bt = false;
1269 
1270 	/* Ext switch buffer mux */
1271 	rtw_write8(rtwdev, REG_RFE_CTRL_E, 0xff);
1272 	rtw_write8_mask(rtwdev, REG_RFESEL_CTRL + 1, 0x3, 0x0);
1273 	rtw_write8_mask(rtwdev, REG_RFE_INV16, BIT_RFE_BUF_EN, 0x0);
1274 
1275 	/* Disable LTE Coex Function in WiFi side */
1276 	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0);
1277 
1278 	/* BTC_CTT_WL_VS_LTE */
1279 	rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff);
1280 
1281 	/* BTC_CTT_BT_VS_LTE */
1282 	rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff);
1283 }
1284 
1285 static void rtw8822b_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
1286 {
1287 	struct rtw_coex *coex = &rtwdev->coex;
1288 	struct rtw_coex_dm *coex_dm = &coex->dm;
1289 	static const u16 reg_addr[] = {0xc58, 0xe58};
1290 	static const u8	wl_tx_power[] = {0xd8, 0xd4, 0xd0, 0xcc, 0xc8};
1291 	u8 i, pwr;
1292 
1293 	if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
1294 		return;
1295 
1296 	coex_dm->cur_wl_pwr_lvl = wl_pwr;
1297 
1298 	if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power))
1299 		coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1;
1300 
1301 	pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl];
1302 
1303 	for (i = 0; i < ARRAY_SIZE(reg_addr); i++)
1304 		rtw_write8_mask(rtwdev, reg_addr[i], 0xff, pwr);
1305 }
1306 
1307 static void rtw8822b_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
1308 {
1309 	struct rtw_coex *coex = &rtwdev->coex;
1310 	struct rtw_coex_dm *coex_dm = &coex->dm;
1311 	/* WL Rx Low gain on */
1312 	static const u32 wl_rx_low_gain_on[] = {
1313 		0xff000003, 0xbd120003, 0xbe100003, 0xbf080003, 0xbf060003,
1314 		0xbf050003, 0xbc140003, 0xbb160003, 0xba180003, 0xb91a0003,
1315 		0xb81c0003, 0xb71e0003, 0xb4200003, 0xb5220003, 0xb4240003,
1316 		0xb3260003, 0xb2280003, 0xb12a0003, 0xb02c0003, 0xaf2e0003,
1317 		0xae300003, 0xad320003, 0xac340003, 0xab360003, 0x8d380003,
1318 		0x8c3a0003, 0x8b3c0003, 0x8a3e0003, 0x6e400003, 0x6d420003,
1319 		0x6c440003, 0x6b460003, 0x6a480003, 0x694a0003, 0x684c0003,
1320 		0x674e0003, 0x66500003, 0x65520003, 0x64540003, 0x64560003,
1321 		0x007e0403
1322 	};
1323 
1324 	/* WL Rx Low gain off */
1325 	static const u32 wl_rx_low_gain_off[] = {
1326 		0xff000003, 0xf4120003, 0xf5100003, 0xf60e0003, 0xf70c0003,
1327 		0xf80a0003, 0xf3140003, 0xf2160003, 0xf1180003, 0xf01a0003,
1328 		0xef1c0003, 0xee1e0003, 0xed200003, 0xec220003, 0xeb240003,
1329 		0xea260003, 0xe9280003, 0xe82a0003, 0xe72c0003, 0xe62e0003,
1330 		0xe5300003, 0xc8320003, 0xc7340003, 0xc6360003, 0xc5380003,
1331 		0xc43a0003, 0xc33c0003, 0xc23e0003, 0xc1400003, 0xc0420003,
1332 		0xa5440003, 0xa4460003, 0xa3480003, 0xa24a0003, 0xa14c0003,
1333 		0x834e0003, 0x82500003, 0x81520003, 0x80540003, 0x65560003,
1334 		0x007e0403
1335 	};
1336 	u8 i;
1337 
1338 	if (low_gain == coex_dm->cur_wl_rx_low_gain_en)
1339 		return;
1340 
1341 	coex_dm->cur_wl_rx_low_gain_en = low_gain;
1342 
1343 	if (coex_dm->cur_wl_rx_low_gain_en) {
1344 		for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++)
1345 			rtw_write32(rtwdev, REG_RX_GAIN_EN, wl_rx_low_gain_on[i]);
1346 
1347 		/* set Rx filter corner RCK offset */
1348 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x1);
1349 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x3f);
1350 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x1);
1351 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x3f);
1352 	} else {
1353 		for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++)
1354 			rtw_write32(rtwdev, 0x81c, wl_rx_low_gain_off[i]);
1355 
1356 		/* set Rx filter corner RCK offset */
1357 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x4);
1358 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x0);
1359 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x4);
1360 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x0);
1361 	}
1362 }
1363 
1364 static void rtw8822b_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path,
1365 					u8 tx_pwr_idx_offset,
1366 					s8 *txagc_idx, u8 *swing_idx)
1367 {
1368 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1369 	s8 delta_pwr_idx = dm_info->delta_power_index[path];
1370 	u8 swing_upper_bound = dm_info->default_ofdm_index + 10;
1371 	u8 swing_lower_bound = 0;
1372 	u8 max_tx_pwr_idx_offset = 0xf;
1373 	s8 agc_index = 0;
1374 	u8 swing_index = dm_info->default_ofdm_index;
1375 
1376 	tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset);
1377 
1378 	if (delta_pwr_idx >= 0) {
1379 		if (delta_pwr_idx <= tx_pwr_idx_offset) {
1380 			agc_index = delta_pwr_idx;
1381 			swing_index = dm_info->default_ofdm_index;
1382 		} else if (delta_pwr_idx > tx_pwr_idx_offset) {
1383 			agc_index = tx_pwr_idx_offset;
1384 			swing_index = dm_info->default_ofdm_index +
1385 					delta_pwr_idx - tx_pwr_idx_offset;
1386 			swing_index = min_t(u8, swing_index, swing_upper_bound);
1387 		}
1388 	} else {
1389 		if (dm_info->default_ofdm_index > abs(delta_pwr_idx))
1390 			swing_index =
1391 				dm_info->default_ofdm_index + delta_pwr_idx;
1392 		else
1393 			swing_index = swing_lower_bound;
1394 		swing_index = max_t(u8, swing_index, swing_lower_bound);
1395 
1396 		agc_index = 0;
1397 	}
1398 
1399 	if (swing_index >= RTW_TXSCALE_SIZE) {
1400 		rtw_warn(rtwdev, "swing index overflow\n");
1401 		swing_index = RTW_TXSCALE_SIZE - 1;
1402 	}
1403 	*txagc_idx = agc_index;
1404 	*swing_idx = swing_index;
1405 }
1406 
1407 static void rtw8822b_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path,
1408 				      u8 pwr_idx_offset)
1409 {
1410 	s8 txagc_idx;
1411 	u8 swing_idx;
1412 	u32 reg1, reg2;
1413 
1414 	if (path == RF_PATH_A) {
1415 		reg1 = 0xc94;
1416 		reg2 = 0xc1c;
1417 	} else if (path == RF_PATH_B) {
1418 		reg1 = 0xe94;
1419 		reg2 = 0xe1c;
1420 	} else {
1421 		return;
1422 	}
1423 
1424 	rtw8822b_txagc_swing_offset(rtwdev, path, pwr_idx_offset,
1425 				    &txagc_idx, &swing_idx);
1426 	rtw_write32_mask(rtwdev, reg1, GENMASK(29, 25), txagc_idx);
1427 	rtw_write32_mask(rtwdev, reg2, GENMASK(31, 21),
1428 			 rtw8822b_txscale_tbl[swing_idx]);
1429 }
1430 
1431 static void rtw8822b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
1432 {
1433 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1434 	u8 pwr_idx_offset, tx_pwr_idx;
1435 	u8 channel = rtwdev->hal.current_channel;
1436 	u8 band_width = rtwdev->hal.current_band_width;
1437 	u8 regd = rtwdev->regd.txpwr_regd;
1438 	u8 tx_rate = dm_info->tx_rate;
1439 	u8 max_pwr_idx = rtwdev->chip->max_power_index;
1440 
1441 	tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate,
1442 						band_width, channel, regd);
1443 
1444 	tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx);
1445 
1446 	pwr_idx_offset = max_pwr_idx - tx_pwr_idx;
1447 
1448 	rtw8822b_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset);
1449 }
1450 
1451 static void rtw8822b_phy_pwrtrack_path(struct rtw_dev *rtwdev,
1452 				       struct rtw_swing_table *swing_table,
1453 				       u8 path)
1454 {
1455 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1456 	u8 power_idx_cur, power_idx_last;
1457 	u8 delta;
1458 
1459 	/* 8822B only has one thermal meter at PATH A */
1460 	delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
1461 
1462 	power_idx_last = dm_info->delta_power_index[path];
1463 	power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table,
1464 						    path, RF_PATH_A, delta);
1465 
1466 	/* if delta of power indexes are the same, just skip */
1467 	if (power_idx_cur == power_idx_last)
1468 		return;
1469 
1470 	dm_info->delta_power_index[path] = power_idx_cur;
1471 	rtw8822b_pwrtrack_set(rtwdev, path);
1472 }
1473 
1474 static void rtw8822b_phy_pwrtrack(struct rtw_dev *rtwdev)
1475 {
1476 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1477 	struct rtw_swing_table swing_table;
1478 	u8 thermal_value, path;
1479 
1480 	rtw_phy_config_swing_table(rtwdev, &swing_table);
1481 
1482 	if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff)
1483 		return;
1484 
1485 	thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
1486 
1487 	rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
1488 
1489 	if (dm_info->pwr_trk_init_trigger)
1490 		dm_info->pwr_trk_init_trigger = false;
1491 	else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
1492 						   RF_PATH_A))
1493 		goto iqk;
1494 
1495 	for (path = 0; path < rtwdev->hal.rf_path_num; path++)
1496 		rtw8822b_phy_pwrtrack_path(rtwdev, &swing_table, path);
1497 
1498 iqk:
1499 	if (rtw_phy_pwrtrack_need_iqk(rtwdev))
1500 		rtw8822b_do_iqk(rtwdev);
1501 }
1502 
1503 static void rtw8822b_pwr_track(struct rtw_dev *rtwdev)
1504 {
1505 	struct rtw_efuse *efuse = &rtwdev->efuse;
1506 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1507 
1508 	if (efuse->power_track_type != 0)
1509 		return;
1510 
1511 	if (!dm_info->pwr_trk_triggered) {
1512 		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
1513 			     GENMASK(17, 16), 0x03);
1514 		dm_info->pwr_trk_triggered = true;
1515 		return;
1516 	}
1517 
1518 	rtw8822b_phy_pwrtrack(rtwdev);
1519 	dm_info->pwr_trk_triggered = false;
1520 }
1521 
1522 static void rtw8822b_bf_config_bfee_su(struct rtw_dev *rtwdev,
1523 				       struct rtw_vif *vif,
1524 				       struct rtw_bfee *bfee, bool enable)
1525 {
1526 	if (enable)
1527 		rtw_bf_enable_bfee_su(rtwdev, vif, bfee);
1528 	else
1529 		rtw_bf_remove_bfee_su(rtwdev, bfee);
1530 }
1531 
1532 static void rtw8822b_bf_config_bfee_mu(struct rtw_dev *rtwdev,
1533 				       struct rtw_vif *vif,
1534 				       struct rtw_bfee *bfee, bool enable)
1535 {
1536 	if (enable)
1537 		rtw_bf_enable_bfee_mu(rtwdev, vif, bfee);
1538 	else
1539 		rtw_bf_remove_bfee_mu(rtwdev, bfee);
1540 }
1541 
1542 static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
1543 				    struct rtw_bfee *bfee, bool enable)
1544 {
1545 	if (bfee->role == RTW_BFEE_SU)
1546 		rtw8822b_bf_config_bfee_su(rtwdev, vif, bfee, enable);
1547 	else if (bfee->role == RTW_BFEE_MU)
1548 		rtw8822b_bf_config_bfee_mu(rtwdev, vif, bfee, enable);
1549 	else
1550 		rtw_warn(rtwdev, "wrong bfee role\n");
1551 }
1552 
1553 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
1554 	{0x004A,
1555 	 RTW_PWR_CUT_ALL_MSK,
1556 	 RTW_PWR_INTF_USB_MSK,
1557 	 RTW_PWR_ADDR_MAC,
1558 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1559 	{0x0005,
1560 	 RTW_PWR_CUT_ALL_MSK,
1561 	 RTW_PWR_INTF_ALL_MSK,
1562 	 RTW_PWR_ADDR_MAC,
1563 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
1564 	{0x0300,
1565 	 RTW_PWR_CUT_ALL_MSK,
1566 	 RTW_PWR_INTF_PCI_MSK,
1567 	 RTW_PWR_ADDR_MAC,
1568 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1569 	{0x0301,
1570 	 RTW_PWR_CUT_ALL_MSK,
1571 	 RTW_PWR_INTF_PCI_MSK,
1572 	 RTW_PWR_ADDR_MAC,
1573 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1574 	{0xFFFF,
1575 	 RTW_PWR_CUT_ALL_MSK,
1576 	 RTW_PWR_INTF_ALL_MSK,
1577 	 0,
1578 	 RTW_PWR_CMD_END, 0, 0},
1579 };
1580 
1581 static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822b[] = {
1582 	{0x0012,
1583 	 RTW_PWR_CUT_ALL_MSK,
1584 	 RTW_PWR_INTF_ALL_MSK,
1585 	 RTW_PWR_ADDR_MAC,
1586 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1587 	{0x0012,
1588 	 RTW_PWR_CUT_ALL_MSK,
1589 	 RTW_PWR_INTF_ALL_MSK,
1590 	 RTW_PWR_ADDR_MAC,
1591 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1592 	{0x0020,
1593 	 RTW_PWR_CUT_ALL_MSK,
1594 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1595 	 RTW_PWR_ADDR_MAC,
1596 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1597 	{0x0001,
1598 	 RTW_PWR_CUT_ALL_MSK,
1599 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1600 	 RTW_PWR_ADDR_MAC,
1601 	 RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
1602 	{0x0000,
1603 	 RTW_PWR_CUT_ALL_MSK,
1604 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1605 	 RTW_PWR_ADDR_MAC,
1606 	 RTW_PWR_CMD_WRITE, BIT(5), 0},
1607 	{0x0005,
1608 	 RTW_PWR_CUT_ALL_MSK,
1609 	 RTW_PWR_INTF_ALL_MSK,
1610 	 RTW_PWR_ADDR_MAC,
1611 	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
1612 	{0x0075,
1613 	 RTW_PWR_CUT_ALL_MSK,
1614 	 RTW_PWR_INTF_PCI_MSK,
1615 	 RTW_PWR_ADDR_MAC,
1616 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1617 	{0x0006,
1618 	 RTW_PWR_CUT_ALL_MSK,
1619 	 RTW_PWR_INTF_ALL_MSK,
1620 	 RTW_PWR_ADDR_MAC,
1621 	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
1622 	{0x0075,
1623 	 RTW_PWR_CUT_ALL_MSK,
1624 	 RTW_PWR_INTF_PCI_MSK,
1625 	 RTW_PWR_ADDR_MAC,
1626 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1627 	{0xFF1A,
1628 	 RTW_PWR_CUT_ALL_MSK,
1629 	 RTW_PWR_INTF_USB_MSK,
1630 	 RTW_PWR_ADDR_MAC,
1631 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1632 	{0x0006,
1633 	 RTW_PWR_CUT_ALL_MSK,
1634 	 RTW_PWR_INTF_ALL_MSK,
1635 	 RTW_PWR_ADDR_MAC,
1636 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1637 	{0x0005,
1638 	 RTW_PWR_CUT_ALL_MSK,
1639 	 RTW_PWR_INTF_ALL_MSK,
1640 	 RTW_PWR_ADDR_MAC,
1641 	 RTW_PWR_CMD_WRITE, BIT(7), 0},
1642 	{0x0005,
1643 	 RTW_PWR_CUT_ALL_MSK,
1644 	 RTW_PWR_INTF_ALL_MSK,
1645 	 RTW_PWR_ADDR_MAC,
1646 	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
1647 	{0x10C3,
1648 	 RTW_PWR_CUT_ALL_MSK,
1649 	 RTW_PWR_INTF_USB_MSK,
1650 	 RTW_PWR_ADDR_MAC,
1651 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1652 	{0x0005,
1653 	 RTW_PWR_CUT_ALL_MSK,
1654 	 RTW_PWR_INTF_ALL_MSK,
1655 	 RTW_PWR_ADDR_MAC,
1656 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1657 	{0x0005,
1658 	 RTW_PWR_CUT_ALL_MSK,
1659 	 RTW_PWR_INTF_ALL_MSK,
1660 	 RTW_PWR_ADDR_MAC,
1661 	 RTW_PWR_CMD_POLLING, BIT(0), 0},
1662 	{0x0020,
1663 	 RTW_PWR_CUT_ALL_MSK,
1664 	 RTW_PWR_INTF_ALL_MSK,
1665 	 RTW_PWR_ADDR_MAC,
1666 	 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
1667 	{0x10A8,
1668 	 RTW_PWR_CUT_C_MSK,
1669 	 RTW_PWR_INTF_ALL_MSK,
1670 	 RTW_PWR_ADDR_MAC,
1671 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1672 	{0x10A9,
1673 	 RTW_PWR_CUT_C_MSK,
1674 	 RTW_PWR_INTF_ALL_MSK,
1675 	 RTW_PWR_ADDR_MAC,
1676 	 RTW_PWR_CMD_WRITE, 0xFF, 0xef},
1677 	{0x10AA,
1678 	 RTW_PWR_CUT_C_MSK,
1679 	 RTW_PWR_INTF_ALL_MSK,
1680 	 RTW_PWR_ADDR_MAC,
1681 	 RTW_PWR_CMD_WRITE, 0xFF, 0x0c},
1682 	{0x0029,
1683 	 RTW_PWR_CUT_ALL_MSK,
1684 	 RTW_PWR_INTF_ALL_MSK,
1685 	 RTW_PWR_ADDR_MAC,
1686 	 RTW_PWR_CMD_WRITE, 0xFF, 0xF9},
1687 	{0x0024,
1688 	 RTW_PWR_CUT_ALL_MSK,
1689 	 RTW_PWR_INTF_ALL_MSK,
1690 	 RTW_PWR_ADDR_MAC,
1691 	 RTW_PWR_CMD_WRITE, BIT(2), 0},
1692 	{0x0074,
1693 	 RTW_PWR_CUT_ALL_MSK,
1694 	 RTW_PWR_INTF_PCI_MSK,
1695 	 RTW_PWR_ADDR_MAC,
1696 	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1697 	{0x00AF,
1698 	 RTW_PWR_CUT_ALL_MSK,
1699 	 RTW_PWR_INTF_ALL_MSK,
1700 	 RTW_PWR_ADDR_MAC,
1701 	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1702 	{0xFFFF,
1703 	 RTW_PWR_CUT_ALL_MSK,
1704 	 RTW_PWR_INTF_ALL_MSK,
1705 	 0,
1706 	 RTW_PWR_CMD_END, 0, 0},
1707 };
1708 
1709 static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822b[] = {
1710 	{0x0093,
1711 	 RTW_PWR_CUT_ALL_MSK,
1712 	 RTW_PWR_INTF_ALL_MSK,
1713 	 RTW_PWR_ADDR_MAC,
1714 	 RTW_PWR_CMD_WRITE, BIT(3), 0},
1715 	{0x001F,
1716 	 RTW_PWR_CUT_ALL_MSK,
1717 	 RTW_PWR_INTF_ALL_MSK,
1718 	 RTW_PWR_ADDR_MAC,
1719 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1720 	{0x00EF,
1721 	 RTW_PWR_CUT_ALL_MSK,
1722 	 RTW_PWR_INTF_ALL_MSK,
1723 	 RTW_PWR_ADDR_MAC,
1724 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1725 	{0xFF1A,
1726 	 RTW_PWR_CUT_ALL_MSK,
1727 	 RTW_PWR_INTF_USB_MSK,
1728 	 RTW_PWR_ADDR_MAC,
1729 	 RTW_PWR_CMD_WRITE, 0xFF, 0x30},
1730 	{0x0049,
1731 	 RTW_PWR_CUT_ALL_MSK,
1732 	 RTW_PWR_INTF_ALL_MSK,
1733 	 RTW_PWR_ADDR_MAC,
1734 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1735 	{0x0006,
1736 	 RTW_PWR_CUT_ALL_MSK,
1737 	 RTW_PWR_INTF_ALL_MSK,
1738 	 RTW_PWR_ADDR_MAC,
1739 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1740 	{0x0002,
1741 	 RTW_PWR_CUT_ALL_MSK,
1742 	 RTW_PWR_INTF_ALL_MSK,
1743 	 RTW_PWR_ADDR_MAC,
1744 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1745 	{0x10C3,
1746 	 RTW_PWR_CUT_ALL_MSK,
1747 	 RTW_PWR_INTF_USB_MSK,
1748 	 RTW_PWR_ADDR_MAC,
1749 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1750 	{0x0005,
1751 	 RTW_PWR_CUT_ALL_MSK,
1752 	 RTW_PWR_INTF_ALL_MSK,
1753 	 RTW_PWR_ADDR_MAC,
1754 	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
1755 	{0x0005,
1756 	 RTW_PWR_CUT_ALL_MSK,
1757 	 RTW_PWR_INTF_ALL_MSK,
1758 	 RTW_PWR_ADDR_MAC,
1759 	 RTW_PWR_CMD_POLLING, BIT(1), 0},
1760 	{0x0020,
1761 	 RTW_PWR_CUT_ALL_MSK,
1762 	 RTW_PWR_INTF_ALL_MSK,
1763 	 RTW_PWR_ADDR_MAC,
1764 	 RTW_PWR_CMD_WRITE, BIT(3), 0},
1765 	{0x0000,
1766 	 RTW_PWR_CUT_ALL_MSK,
1767 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1768 	 RTW_PWR_ADDR_MAC,
1769 	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1770 	{0xFFFF,
1771 	 RTW_PWR_CUT_ALL_MSK,
1772 	 RTW_PWR_INTF_ALL_MSK,
1773 	 0,
1774 	 RTW_PWR_CMD_END, 0, 0},
1775 };
1776 
1777 static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
1778 	{0x0007,
1779 	 RTW_PWR_CUT_ALL_MSK,
1780 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1781 	 RTW_PWR_ADDR_MAC,
1782 	 RTW_PWR_CMD_WRITE, 0xFF, 0x20},
1783 	{0x0067,
1784 	 RTW_PWR_CUT_ALL_MSK,
1785 	 RTW_PWR_INTF_ALL_MSK,
1786 	 RTW_PWR_ADDR_MAC,
1787 	 RTW_PWR_CMD_WRITE, BIT(5), 0},
1788 	{0x0005,
1789 	 RTW_PWR_CUT_ALL_MSK,
1790 	 RTW_PWR_INTF_PCI_MSK,
1791 	 RTW_PWR_ADDR_MAC,
1792 	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
1793 	{0x004A,
1794 	 RTW_PWR_CUT_ALL_MSK,
1795 	 RTW_PWR_INTF_USB_MSK,
1796 	 RTW_PWR_ADDR_MAC,
1797 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1798 	{0x0081,
1799 	 RTW_PWR_CUT_ALL_MSK,
1800 	 RTW_PWR_INTF_ALL_MSK,
1801 	 RTW_PWR_ADDR_MAC,
1802 	 RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0},
1803 	{0x0005,
1804 	 RTW_PWR_CUT_ALL_MSK,
1805 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1806 	 RTW_PWR_ADDR_MAC,
1807 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
1808 	{0x0090,
1809 	 RTW_PWR_CUT_ALL_MSK,
1810 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK,
1811 	 RTW_PWR_ADDR_MAC,
1812 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1813 	{0xFFFF,
1814 	 RTW_PWR_CUT_ALL_MSK,
1815 	 RTW_PWR_INTF_ALL_MSK,
1816 	 0,
1817 	 RTW_PWR_CMD_END, 0, 0},
1818 };
1819 
1820 static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
1821 	trans_carddis_to_cardemu_8822b,
1822 	trans_cardemu_to_act_8822b,
1823 	NULL
1824 };
1825 
1826 static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
1827 	trans_act_to_cardemu_8822b,
1828 	trans_cardemu_to_carddis_8822b,
1829 	NULL
1830 };
1831 
1832 static const struct rtw_intf_phy_para usb2_param_8822b[] = {
1833 	{0xFFFF, 0x00,
1834 	 RTW_IP_SEL_PHY,
1835 	 RTW_INTF_PHY_CUT_ALL,
1836 	 RTW_INTF_PHY_PLATFORM_ALL},
1837 };
1838 
1839 static const struct rtw_intf_phy_para usb3_param_8822b[] = {
1840 	{0x0001, 0xA841,
1841 	 RTW_IP_SEL_PHY,
1842 	 RTW_INTF_PHY_CUT_D,
1843 	 RTW_INTF_PHY_PLATFORM_ALL},
1844 	{0xFFFF, 0x0000,
1845 	 RTW_IP_SEL_PHY,
1846 	 RTW_INTF_PHY_CUT_ALL,
1847 	 RTW_INTF_PHY_PLATFORM_ALL},
1848 };
1849 
1850 static const struct rtw_intf_phy_para pcie_gen1_param_8822b[] = {
1851 	{0x0001, 0xA841,
1852 	 RTW_IP_SEL_PHY,
1853 	 RTW_INTF_PHY_CUT_C,
1854 	 RTW_INTF_PHY_PLATFORM_ALL},
1855 	{0x0002, 0x60C6,
1856 	 RTW_IP_SEL_PHY,
1857 	 RTW_INTF_PHY_CUT_C,
1858 	 RTW_INTF_PHY_PLATFORM_ALL},
1859 	{0x0008, 0x3596,
1860 	 RTW_IP_SEL_PHY,
1861 	 RTW_INTF_PHY_CUT_C,
1862 	 RTW_INTF_PHY_PLATFORM_ALL},
1863 	{0x0009, 0x321C,
1864 	 RTW_IP_SEL_PHY,
1865 	 RTW_INTF_PHY_CUT_C,
1866 	 RTW_INTF_PHY_PLATFORM_ALL},
1867 	{0x000A, 0x9623,
1868 	 RTW_IP_SEL_PHY,
1869 	 RTW_INTF_PHY_CUT_C,
1870 	 RTW_INTF_PHY_PLATFORM_ALL},
1871 	{0x0020, 0x94FF,
1872 	 RTW_IP_SEL_PHY,
1873 	 RTW_INTF_PHY_CUT_C,
1874 	 RTW_INTF_PHY_PLATFORM_ALL},
1875 	{0x0021, 0xFFCF,
1876 	 RTW_IP_SEL_PHY,
1877 	 RTW_INTF_PHY_CUT_C,
1878 	 RTW_INTF_PHY_PLATFORM_ALL},
1879 	{0x0026, 0xC006,
1880 	 RTW_IP_SEL_PHY,
1881 	 RTW_INTF_PHY_CUT_C,
1882 	 RTW_INTF_PHY_PLATFORM_ALL},
1883 	{0x0029, 0xFF0E,
1884 	 RTW_IP_SEL_PHY,
1885 	 RTW_INTF_PHY_CUT_C,
1886 	 RTW_INTF_PHY_PLATFORM_ALL},
1887 	{0x002A, 0x1840,
1888 	 RTW_IP_SEL_PHY,
1889 	 RTW_INTF_PHY_CUT_C,
1890 	 RTW_INTF_PHY_PLATFORM_ALL},
1891 	{0xFFFF, 0x0000,
1892 	 RTW_IP_SEL_PHY,
1893 	 RTW_INTF_PHY_CUT_ALL,
1894 	 RTW_INTF_PHY_PLATFORM_ALL},
1895 };
1896 
1897 static const struct rtw_intf_phy_para pcie_gen2_param_8822b[] = {
1898 	{0x0001, 0xA841,
1899 	 RTW_IP_SEL_PHY,
1900 	 RTW_INTF_PHY_CUT_C,
1901 	 RTW_INTF_PHY_PLATFORM_ALL},
1902 	{0x0002, 0x60C6,
1903 	 RTW_IP_SEL_PHY,
1904 	 RTW_INTF_PHY_CUT_C,
1905 	 RTW_INTF_PHY_PLATFORM_ALL},
1906 	{0x0008, 0x3597,
1907 	 RTW_IP_SEL_PHY,
1908 	 RTW_INTF_PHY_CUT_C,
1909 	 RTW_INTF_PHY_PLATFORM_ALL},
1910 	{0x0009, 0x321C,
1911 	 RTW_IP_SEL_PHY,
1912 	 RTW_INTF_PHY_CUT_C,
1913 	 RTW_INTF_PHY_PLATFORM_ALL},
1914 	{0x000A, 0x9623,
1915 	 RTW_IP_SEL_PHY,
1916 	 RTW_INTF_PHY_CUT_C,
1917 	 RTW_INTF_PHY_PLATFORM_ALL},
1918 	{0x0020, 0x94FF,
1919 	 RTW_IP_SEL_PHY,
1920 	 RTW_INTF_PHY_CUT_C,
1921 	 RTW_INTF_PHY_PLATFORM_ALL},
1922 	{0x0021, 0xFFCF,
1923 	 RTW_IP_SEL_PHY,
1924 	 RTW_INTF_PHY_CUT_C,
1925 	 RTW_INTF_PHY_PLATFORM_ALL},
1926 	{0x0026, 0xC006,
1927 	 RTW_IP_SEL_PHY,
1928 	 RTW_INTF_PHY_CUT_C,
1929 	 RTW_INTF_PHY_PLATFORM_ALL},
1930 	{0x0029, 0xFF0E,
1931 	 RTW_IP_SEL_PHY,
1932 	 RTW_INTF_PHY_CUT_C,
1933 	 RTW_INTF_PHY_PLATFORM_ALL},
1934 	{0x002A, 0x3040,
1935 	 RTW_IP_SEL_PHY,
1936 	 RTW_INTF_PHY_CUT_C,
1937 	 RTW_INTF_PHY_PLATFORM_ALL},
1938 	{0xFFFF, 0x0000,
1939 	 RTW_IP_SEL_PHY,
1940 	 RTW_INTF_PHY_CUT_ALL,
1941 	 RTW_INTF_PHY_PLATFORM_ALL},
1942 };
1943 
1944 static const struct rtw_intf_phy_para_table phy_para_table_8822b = {
1945 	.usb2_para	= usb2_param_8822b,
1946 	.usb3_para	= usb3_param_8822b,
1947 	.gen1_para	= pcie_gen1_param_8822b,
1948 	.gen2_para	= pcie_gen2_param_8822b,
1949 	.n_usb2_para	= ARRAY_SIZE(usb2_param_8822b),
1950 	.n_usb3_para	= ARRAY_SIZE(usb2_param_8822b),
1951 	.n_gen1_para	= ARRAY_SIZE(pcie_gen1_param_8822b),
1952 	.n_gen2_para	= ARRAY_SIZE(pcie_gen2_param_8822b),
1953 };
1954 
1955 static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
1956 	[2] = RTW_DEF_RFE(8822b, 2, 2),
1957 	[3] = RTW_DEF_RFE(8822b, 3, 0),
1958 	[5] = RTW_DEF_RFE(8822b, 5, 5),
1959 };
1960 
1961 static const struct rtw_hw_reg rtw8822b_dig[] = {
1962 	[0] = { .addr = 0xc50, .mask = 0x7f },
1963 	[1] = { .addr = 0xe50, .mask = 0x7f },
1964 };
1965 
1966 static const struct rtw_ltecoex_addr rtw8822b_ltecoex_addr = {
1967 	.ctrl = LTECOEX_ACCESS_CTRL,
1968 	.wdata = LTECOEX_WRITE_DATA,
1969 	.rdata = LTECOEX_READ_DATA,
1970 };
1971 
1972 static const struct rtw_page_table page_table_8822b[] = {
1973 	{64, 64, 64, 64, 1},
1974 	{64, 64, 64, 64, 1},
1975 	{64, 64, 0, 0, 1},
1976 	{64, 64, 64, 0, 1},
1977 	{64, 64, 64, 64, 1},
1978 };
1979 
1980 static const struct rtw_rqpn rqpn_table_8822b[] = {
1981 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1982 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1983 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
1984 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1985 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1986 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
1987 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1988 	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
1989 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
1990 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1991 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1992 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
1993 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1994 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1995 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
1996 };
1997 
1998 static struct rtw_prioq_addrs prioq_addrs_8822b = {
1999 	.prio[RTW_DMA_MAPPING_EXTRA] = {
2000 		.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
2001 	},
2002 	.prio[RTW_DMA_MAPPING_LOW] = {
2003 		.rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2,
2004 	},
2005 	.prio[RTW_DMA_MAPPING_NORMAL] = {
2006 		.rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2,
2007 	},
2008 	.prio[RTW_DMA_MAPPING_HIGH] = {
2009 		.rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2,
2010 	},
2011 	.wsize = true,
2012 };
2013 
2014 static struct rtw_chip_ops rtw8822b_ops = {
2015 	.phy_set_param		= rtw8822b_phy_set_param,
2016 	.read_efuse		= rtw8822b_read_efuse,
2017 	.query_rx_desc		= rtw8822b_query_rx_desc,
2018 	.set_channel		= rtw8822b_set_channel,
2019 	.mac_init		= rtw8822b_mac_init,
2020 	.read_rf		= rtw_phy_read_rf,
2021 	.write_rf		= rtw_phy_write_rf_reg_sipi,
2022 	.set_tx_power_index	= rtw8822b_set_tx_power_index,
2023 	.set_antenna		= rtw8822b_set_antenna,
2024 	.cfg_ldo25		= rtw8822b_cfg_ldo25,
2025 	.false_alarm_statistics	= rtw8822b_false_alarm_statistics,
2026 	.phy_calibration	= rtw8822b_phy_calibration,
2027 	.pwr_track		= rtw8822b_pwr_track,
2028 	.config_bfee		= rtw8822b_bf_config_bfee,
2029 	.set_gid_table		= rtw_bf_set_gid_table,
2030 	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
2031 
2032 	.coex_set_init		= rtw8822b_coex_cfg_init,
2033 	.coex_set_ant_switch	= rtw8822b_coex_cfg_ant_switch,
2034 	.coex_set_gnt_fix	= rtw8822b_coex_cfg_gnt_fix,
2035 	.coex_set_gnt_debug	= rtw8822b_coex_cfg_gnt_debug,
2036 	.coex_set_rfe_type	= rtw8822b_coex_cfg_rfe_type,
2037 	.coex_set_wl_tx_power	= rtw8822b_coex_cfg_wl_tx_power,
2038 	.coex_set_wl_rx_gain	= rtw8822b_coex_cfg_wl_rx_gain,
2039 };
2040 
2041 /* Shared-Antenna Coex Table */
2042 static const struct coex_table_para table_sant_8822b[] = {
2043 	{0xffffffff, 0xffffffff}, /* case-0 */
2044 	{0x55555555, 0x55555555},
2045 	{0x66555555, 0x66555555},
2046 	{0xaaaaaaaa, 0xaaaaaaaa},
2047 	{0x5a5a5a5a, 0x5a5a5a5a},
2048 	{0xfafafafa, 0xfafafafa}, /* case-5 */
2049 	{0x6a5a6a5a, 0xaaaaaaaa},
2050 	{0x6a5a56aa, 0x6a5a56aa},
2051 	{0x6a5a5a5a, 0x6a5a5a5a},
2052 	{0x66555555, 0x5a5a5a5a},
2053 	{0x66555555, 0x6a5a5a5a}, /* case-10 */
2054 	{0x66555555, 0xfafafafa},
2055 	{0x66555555, 0x6a5a5aaa},
2056 	{0x66555555, 0x5aaa5aaa},
2057 	{0x66555555, 0xaaaa5aaa},
2058 	{0x66555555, 0xaaaaaaaa}, /* case-15 */
2059 	{0xffff55ff, 0xfafafafa},
2060 	{0xffff55ff, 0x6afa5afa},
2061 	{0xaaffffaa, 0xfafafafa},
2062 	{0xaa5555aa, 0x5a5a5a5a},
2063 	{0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
2064 	{0xaa5555aa, 0xaaaaaaaa},
2065 	{0xffffffff, 0x5a5a5a5a},
2066 	{0xffffffff, 0x6a5a5a5a},
2067 	{0xffffffff, 0x55555555},
2068 	{0xffffffff, 0x6a5a5aaa}, /* case-25 */
2069 	{0x55555555, 0x5a5a5a5a},
2070 	{0x55555555, 0xaaaaaaaa},
2071 	{0x55555555, 0x6a5a6a5a},
2072 	{0x66556655, 0x66556655}
2073 };
2074 
2075 /* Non-Shared-Antenna Coex Table */
2076 static const struct coex_table_para table_nsant_8822b[] = {
2077 	{0xffffffff, 0xffffffff}, /* case-100 */
2078 	{0x55555555, 0x55555555},
2079 	{0x66555555, 0x66555555},
2080 	{0xaaaaaaaa, 0xaaaaaaaa},
2081 	{0x5a5a5a5a, 0x5a5a5a5a},
2082 	{0xfafafafa, 0xfafafafa}, /* case-105 */
2083 	{0x5afa5afa, 0x5afa5afa},
2084 	{0x55555555, 0xfafafafa},
2085 	{0x66555555, 0xfafafafa},
2086 	{0x66555555, 0x5a5a5a5a},
2087 	{0x66555555, 0x6a5a5a5a}, /* case-110 */
2088 	{0x66555555, 0xaaaaaaaa},
2089 	{0xffff55ff, 0xfafafafa},
2090 	{0xffff55ff, 0x5afa5afa},
2091 	{0xffff55ff, 0xaaaaaaaa},
2092 	{0xaaffffaa, 0xfafafafa}, /* case-115 */
2093 	{0xaaffffaa, 0x5afa5afa},
2094 	{0xaaffffaa, 0xaaaaaaaa},
2095 	{0xffffffff, 0xfafafafa},
2096 	{0xffffffff, 0x5afa5afa},
2097 	{0xffffffff, 0xaaaaaaaa}, /* case-120 */
2098 	{0x55ff55ff, 0x5afa5afa},
2099 	{0x55ff55ff, 0xaaaaaaaa},
2100 	{0x55ff55ff, 0x55ff55ff}
2101 };
2102 
2103 /* Shared-Antenna TDMA */
2104 static const struct coex_tdma_para tdma_sant_8822b[] = {
2105 	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
2106 	{ {0x61, 0x45, 0x03, 0x11, 0x11} },
2107 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
2108 	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
2109 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
2110 	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */
2111 	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
2112 	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
2113 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
2114 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
2115 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
2116 	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
2117 	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
2118 	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
2119 	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
2120 	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
2121 	{ {0x51, 0x45, 0x03, 0x10, 0x10} },
2122 	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
2123 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
2124 	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
2125 	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
2126 	{ {0x51, 0x4a, 0x03, 0x10, 0x50} },
2127 	{ {0x51, 0x0c, 0x03, 0x10, 0x54} },
2128 	{ {0x55, 0x08, 0x03, 0x10, 0x54} },
2129 	{ {0x65, 0x10, 0x03, 0x11, 0x11} },
2130 	{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
2131 	{ {0x51, 0x08, 0x03, 0x10, 0x50} }
2132 };
2133 
2134 /* Non-Shared-Antenna TDMA */
2135 static const struct coex_tdma_para tdma_nsant_8822b[] = {
2136 	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */
2137 	{ {0x61, 0x45, 0x03, 0x11, 0x11} },
2138 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
2139 	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
2140 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
2141 	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
2142 	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
2143 	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
2144 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
2145 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
2146 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
2147 	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
2148 	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
2149 	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
2150 	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
2151 	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
2152 	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
2153 	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
2154 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
2155 	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
2156 	{ {0x51, 0x10, 0x03, 0x10, 0x50} }  /* case-120 */
2157 };
2158 
2159 /* rssi in percentage % (dbm = % - 100) */
2160 static const u8 wl_rssi_step_8822b[] = {60, 50, 44, 30};
2161 static const u8 bt_rssi_step_8822b[] = {30, 30, 30, 30};
2162 static const struct coex_5g_afh_map afh_5g_8822b[] = { {0, 0, 0} };
2163 
2164 /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
2165 static const struct coex_rf_para rf_para_tx_8822b[] = {
2166 	{0, 0, false, 7},  /* for normal */
2167 	{0, 16, false, 7}, /* for WL-CPT */
2168 	{4, 0, true, 1},
2169 	{3, 6, true, 1},
2170 	{2, 9, true, 1},
2171 	{1, 13, true, 1}
2172 };
2173 
2174 static const struct coex_rf_para rf_para_rx_8822b[] = {
2175 	{0, 0, false, 7},  /* for normal */
2176 	{0, 16, false, 7}, /* for WL-CPT */
2177 	{4, 0, true, 1},
2178 	{3, 6, true, 1},
2179 	{2, 9, true, 1},
2180 	{1, 13, true, 1}
2181 };
2182 
2183 static_assert(ARRAY_SIZE(rf_para_tx_8822b) == ARRAY_SIZE(rf_para_rx_8822b));
2184 
2185 static const u8
2186 rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2187 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2188 	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2189 	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2190 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2191 	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2192 	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2193 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2194 	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2195 	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2196 };
2197 
2198 static const u8
2199 rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2200 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2201 	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2202 	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2203 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2204 	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2205 	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2206 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2207 	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2208 	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2209 };
2210 
2211 static const u8
2212 rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2213 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2214 	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2215 	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2216 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2217 	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2218 	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2219 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2220 	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2221 	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2222 };
2223 
2224 static const u8
2225 rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2226 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2227 	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2228 	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2229 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2230 	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2231 	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2232 	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2233 	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2234 	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2235 };
2236 
2237 static const u8 rtw8822b_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = {
2238 	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2239 	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2240 	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2241 };
2242 
2243 static const u8 rtw8822b_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = {
2244 	0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
2245 	5,  5,  6,  6,  6,  7,  7,  8,  8,  9,
2246 	9, 10, 10, 11, 11, 12, 12, 12, 13, 13
2247 };
2248 
2249 static const u8 rtw8822b_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = {
2250 	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2251 	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2252 	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2253 };
2254 
2255 static const u8 rtw8822b_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = {
2256 	0,  1,  1,  2,  2,  3,  3,  4,  4,  5,
2257 	5,  6,  6,  7,  7,  8,  8,  9,  9, 10,
2258 	10, 11, 11, 12, 12, 13, 13, 14, 14, 15
2259 };
2260 
2261 static const u8 rtw8822b_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = {
2262 	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2263 	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2264 	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2265 };
2266 
2267 static const u8 rtw8822b_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = {
2268 	0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
2269 	5,  5,  6,  6,  6,  7,  7,  8,  8,  9,
2270 	9, 10, 10, 11, 11, 12, 12, 12, 13, 13
2271 };
2272 
2273 static const u8 rtw8822b_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = {
2274 	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2275 	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2276 	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2277 };
2278 
2279 static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
2280 	 0,  1,  1,  2,  2,  3,  3,  4,  4,  5,
2281 	 5,  6,  6,  7,  7,  8,  8,  9,  9, 10,
2282 	10, 11, 11, 12, 12, 13, 13, 14, 14, 15
2283 };
2284 
2285 static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
2286 	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
2287 	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
2288 	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
2289 	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1],
2290 	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2],
2291 	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3],
2292 	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1],
2293 	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2],
2294 	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3],
2295 	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1],
2296 	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2],
2297 	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3],
2298 	.pwrtrk_2gb_n = rtw8822b_pwrtrk_2gb_n,
2299 	.pwrtrk_2gb_p = rtw8822b_pwrtrk_2gb_p,
2300 	.pwrtrk_2ga_n = rtw8822b_pwrtrk_2ga_n,
2301 	.pwrtrk_2ga_p = rtw8822b_pwrtrk_2ga_p,
2302 	.pwrtrk_2g_cckb_n = rtw8822b_pwrtrk_2g_cck_b_n,
2303 	.pwrtrk_2g_cckb_p = rtw8822b_pwrtrk_2g_cck_b_p,
2304 	.pwrtrk_2g_ccka_n = rtw8822b_pwrtrk_2g_cck_a_n,
2305 	.pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
2306 };
2307 
2308 static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
2309 	{0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2310 	{0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2311 	{0xcba, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2312 	{0xcbd, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2313 	{0xc58, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2314 	{0xcbd, BIT(0), RTW_REG_DOMAIN_MAC8},
2315 	{0, 0, RTW_REG_DOMAIN_NL},
2316 	{0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2317 	{0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2318 	{0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
2319 	{0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2320 	{0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
2321 	{0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
2322 	{0, 0, RTW_REG_DOMAIN_NL},
2323 	{0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
2324 	{0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
2325 	{0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
2326 	{0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
2327 	{0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B},
2328 	{0, 0, RTW_REG_DOMAIN_NL},
2329 	{0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2330 	{0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2331 	{0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
2332 	{0xc50,  MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2333 };
2334 
2335 struct rtw_chip_info rtw8822b_hw_spec = {
2336 	.ops = &rtw8822b_ops,
2337 	.id = RTW_CHIP_TYPE_8822B,
2338 	.fw_name = "rtw88/rtw8822b_fw.bin",
2339 	.wlan_cpu = RTW_WCPU_11AC,
2340 	.tx_pkt_desc_sz = 48,
2341 	.tx_buf_desc_sz = 16,
2342 	.rx_pkt_desc_sz = 24,
2343 	.rx_buf_desc_sz = 8,
2344 	.phy_efuse_size = 1024,
2345 	.log_efuse_size = 768,
2346 	.ptct_efuse_size = 96,
2347 	.txff_size = 262144,
2348 	.rxff_size = 24576,
2349 	.txgi_factor = 1,
2350 	.is_pwr_by_rate_dec = true,
2351 	.max_power_index = 0x3f,
2352 	.csi_buf_pg_num = 0,
2353 	.band = RTW_BAND_2G | RTW_BAND_5G,
2354 	.page_size = 128,
2355 	.dig_min = 0x1c,
2356 	.ht_supported = true,
2357 	.vht_supported = true,
2358 	.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
2359 	.sys_func_en = 0xDC,
2360 	.pwr_on_seq = card_enable_flow_8822b,
2361 	.pwr_off_seq = card_disable_flow_8822b,
2362 	.page_table = page_table_8822b,
2363 	.rqpn_table = rqpn_table_8822b,
2364 	.prioq_addrs = &prioq_addrs_8822b,
2365 	.intf_table = &phy_para_table_8822b,
2366 	.dig = rtw8822b_dig,
2367 	.dig_cck = NULL,
2368 	.rf_base_addr = {0x2800, 0x2c00},
2369 	.rf_sipi_addr = {0xc90, 0xe90},
2370 	.ltecoex_addr = &rtw8822b_ltecoex_addr,
2371 	.mac_tbl = &rtw8822b_mac_tbl,
2372 	.agc_tbl = &rtw8822b_agc_tbl,
2373 	.bb_tbl = &rtw8822b_bb_tbl,
2374 	.rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl},
2375 	.rfe_defs = rtw8822b_rfe_defs,
2376 	.rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs),
2377 	.pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl,
2378 	.iqk_threshold = 8,
2379 	.bfer_su_max_num = 2,
2380 	.bfer_mu_max_num = 1,
2381 	.rx_ldpc = true,
2382 
2383 	.coex_para_ver = 0x19062706,
2384 	.bt_desired_ver = 0x6,
2385 	.scbd_support = true,
2386 	.new_scbd10_def = false,
2387 	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
2388 	.bt_rssi_type = COEX_BTRSSI_RATIO,
2389 	.ant_isolation = 15,
2390 	.rssi_tolerance = 2,
2391 	.wl_rssi_step = wl_rssi_step_8822b,
2392 	.bt_rssi_step = bt_rssi_step_8822b,
2393 	.table_sant_num = ARRAY_SIZE(table_sant_8822b),
2394 	.table_sant = table_sant_8822b,
2395 	.table_nsant_num = ARRAY_SIZE(table_nsant_8822b),
2396 	.table_nsant = table_nsant_8822b,
2397 	.tdma_sant_num = ARRAY_SIZE(tdma_sant_8822b),
2398 	.tdma_sant = tdma_sant_8822b,
2399 	.tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822b),
2400 	.tdma_nsant = tdma_nsant_8822b,
2401 	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822b),
2402 	.wl_rf_para_tx = rf_para_tx_8822b,
2403 	.wl_rf_para_rx = rf_para_rx_8822b,
2404 	.bt_afh_span_bw20 = 0x24,
2405 	.bt_afh_span_bw40 = 0x36,
2406 	.afh_5g_num = ARRAY_SIZE(afh_5g_8822b),
2407 	.afh_5g = afh_5g_8822b,
2408 
2409 	.coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b),
2410 	.coex_info_hw_regs = coex_info_hw_regs_8822b,
2411 };
2412 EXPORT_SYMBOL(rtw8822b_hw_spec);
2413 
2414 MODULE_FIRMWARE("rtw88/rtw8822b_fw.bin");
2415 
2416 MODULE_AUTHOR("Realtek Corporation");
2417 MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822b driver");
2418 MODULE_LICENSE("Dual BSD/GPL");
2419