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