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
19static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
20				     u8 rx_path, bool is_tx2_path);
21
22static 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
28static 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
66static 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
83static 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
90static 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
105static 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
125static 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
132static 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		0xb0810041
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
220static 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
268static 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
297static 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
330enum {
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
338struct cca_ccut {
339	u32 reg82c[CCUT_IDX_NR];
340	u32 reg830[CCUT_IDX_NR];
341	u32 reg838[CCUT_IDX_NR];
342};
343
344static 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
350static 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
356static 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
362static 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
370struct 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
393static 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
399static 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
468static const u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff, 0x6,
469				0x5, 0x0, 0x0, 0x7, 0x6, 0x6};
470static 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};
473static const u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff, 0x0,
474				 0x7, 0x7, 0x6, 0x5, 0x5, 0x0};
475
476static 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
549err:
550	WARN_ON(1);
551}
552
553static 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
569static 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
589static 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
695static 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
716static 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
817static 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
833static 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
895static 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
915static 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
956static void
957rtw8822b_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
979static 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
990static 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
1002static 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, "unsupported tx path 0x%x\n", antenna_tx);
1013		return -EINVAL;
1014	}
1015
1016	if (!rtw8822b_check_rf_path(antenna_rx)) {
1017		rtw_info(rtwdev, "unsupported 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
1029static 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
1038static 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
1086static 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
1111static void rtw8822b_phy_calibration(struct rtw_dev *rtwdev)
1112{
1113	rtw8822b_do_iqk(rtwdev);
1114}
1115
1116static 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
1140static 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
1224static void rtw8822b_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
1225{
1226}
1227
1228static 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
1237static 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
1285static 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
1307static 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
1364static 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
1407static 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
1431static 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
1451static 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
1474static 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
1498iqk:
1499	if (rtw_phy_pwrtrack_need_iqk(rtwdev))
1500		rtw8822b_do_iqk(rtwdev);
1501}
1502
1503static 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
1522static 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
1532static 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
1542static 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
1553static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
1554	{0x0086,
1555	 RTW_PWR_CUT_ALL_MSK,
1556	 RTW_PWR_INTF_SDIO_MSK,
1557	 RTW_PWR_ADDR_SDIO,
1558	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1559	{0x0086,
1560	 RTW_PWR_CUT_ALL_MSK,
1561	 RTW_PWR_INTF_SDIO_MSK,
1562	 RTW_PWR_ADDR_SDIO,
1563	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
1564	{0x004A,
1565	 RTW_PWR_CUT_ALL_MSK,
1566	 RTW_PWR_INTF_USB_MSK,
1567	 RTW_PWR_ADDR_MAC,
1568	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1569	{0x0005,
1570	 RTW_PWR_CUT_ALL_MSK,
1571	 RTW_PWR_INTF_ALL_MSK,
1572	 RTW_PWR_ADDR_MAC,
1573	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
1574	{0x0300,
1575	 RTW_PWR_CUT_ALL_MSK,
1576	 RTW_PWR_INTF_PCI_MSK,
1577	 RTW_PWR_ADDR_MAC,
1578	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1579	{0x0301,
1580	 RTW_PWR_CUT_ALL_MSK,
1581	 RTW_PWR_INTF_PCI_MSK,
1582	 RTW_PWR_ADDR_MAC,
1583	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1584	{0xFFFF,
1585	 RTW_PWR_CUT_ALL_MSK,
1586	 RTW_PWR_INTF_ALL_MSK,
1587	 0,
1588	 RTW_PWR_CMD_END, 0, 0},
1589};
1590
1591static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822b[] = {
1592	{0x0012,
1593	 RTW_PWR_CUT_ALL_MSK,
1594	 RTW_PWR_INTF_ALL_MSK,
1595	 RTW_PWR_ADDR_MAC,
1596	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1597	{0x0012,
1598	 RTW_PWR_CUT_ALL_MSK,
1599	 RTW_PWR_INTF_ALL_MSK,
1600	 RTW_PWR_ADDR_MAC,
1601	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1602	{0x0020,
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(0), BIT(0)},
1607	{0x0001,
1608	 RTW_PWR_CUT_ALL_MSK,
1609	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1610	 RTW_PWR_ADDR_MAC,
1611	 RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
1612	{0x0000,
1613	 RTW_PWR_CUT_ALL_MSK,
1614	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1615	 RTW_PWR_ADDR_MAC,
1616	 RTW_PWR_CMD_WRITE, BIT(5), 0},
1617	{0x0005,
1618	 RTW_PWR_CUT_ALL_MSK,
1619	 RTW_PWR_INTF_ALL_MSK,
1620	 RTW_PWR_ADDR_MAC,
1621	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
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), BIT(0)},
1627	{0x0006,
1628	 RTW_PWR_CUT_ALL_MSK,
1629	 RTW_PWR_INTF_ALL_MSK,
1630	 RTW_PWR_ADDR_MAC,
1631	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
1632	{0x0075,
1633	 RTW_PWR_CUT_ALL_MSK,
1634	 RTW_PWR_INTF_PCI_MSK,
1635	 RTW_PWR_ADDR_MAC,
1636	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1637	{0xFF1A,
1638	 RTW_PWR_CUT_ALL_MSK,
1639	 RTW_PWR_INTF_USB_MSK,
1640	 RTW_PWR_ADDR_MAC,
1641	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1642	{0x0006,
1643	 RTW_PWR_CUT_ALL_MSK,
1644	 RTW_PWR_INTF_ALL_MSK,
1645	 RTW_PWR_ADDR_MAC,
1646	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1647	{0x0005,
1648	 RTW_PWR_CUT_ALL_MSK,
1649	 RTW_PWR_INTF_ALL_MSK,
1650	 RTW_PWR_ADDR_MAC,
1651	 RTW_PWR_CMD_WRITE, BIT(7), 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(4) | BIT(3)), 0},
1657	{0x10C3,
1658	 RTW_PWR_CUT_ALL_MSK,
1659	 RTW_PWR_INTF_USB_MSK,
1660	 RTW_PWR_ADDR_MAC,
1661	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1662	{0x0005,
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	{0x0005,
1668	 RTW_PWR_CUT_ALL_MSK,
1669	 RTW_PWR_INTF_ALL_MSK,
1670	 RTW_PWR_ADDR_MAC,
1671	 RTW_PWR_CMD_POLLING, BIT(0), 0},
1672	{0x0020,
1673	 RTW_PWR_CUT_ALL_MSK,
1674	 RTW_PWR_INTF_ALL_MSK,
1675	 RTW_PWR_ADDR_MAC,
1676	 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
1677	{0x10A8,
1678	 RTW_PWR_CUT_C_MSK,
1679	 RTW_PWR_INTF_ALL_MSK,
1680	 RTW_PWR_ADDR_MAC,
1681	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1682	{0x10A9,
1683	 RTW_PWR_CUT_C_MSK,
1684	 RTW_PWR_INTF_ALL_MSK,
1685	 RTW_PWR_ADDR_MAC,
1686	 RTW_PWR_CMD_WRITE, 0xFF, 0xef},
1687	{0x10AA,
1688	 RTW_PWR_CUT_C_MSK,
1689	 RTW_PWR_INTF_ALL_MSK,
1690	 RTW_PWR_ADDR_MAC,
1691	 RTW_PWR_CMD_WRITE, 0xFF, 0x0c},
1692	{0x0068,
1693	 RTW_PWR_CUT_C_MSK,
1694	 RTW_PWR_INTF_SDIO_MSK,
1695	 RTW_PWR_ADDR_MAC,
1696	 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
1697	{0x0029,
1698	 RTW_PWR_CUT_ALL_MSK,
1699	 RTW_PWR_INTF_ALL_MSK,
1700	 RTW_PWR_ADDR_MAC,
1701	 RTW_PWR_CMD_WRITE, 0xFF, 0xF9},
1702	{0x0024,
1703	 RTW_PWR_CUT_ALL_MSK,
1704	 RTW_PWR_INTF_ALL_MSK,
1705	 RTW_PWR_ADDR_MAC,
1706	 RTW_PWR_CMD_WRITE, BIT(2), 0},
1707	{0x0074,
1708	 RTW_PWR_CUT_ALL_MSK,
1709	 RTW_PWR_INTF_PCI_MSK,
1710	 RTW_PWR_ADDR_MAC,
1711	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1712	{0x00AF,
1713	 RTW_PWR_CUT_ALL_MSK,
1714	 RTW_PWR_INTF_ALL_MSK,
1715	 RTW_PWR_ADDR_MAC,
1716	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1717	{0xFFFF,
1718	 RTW_PWR_CUT_ALL_MSK,
1719	 RTW_PWR_INTF_ALL_MSK,
1720	 0,
1721	 RTW_PWR_CMD_END, 0, 0},
1722};
1723
1724static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822b[] = {
1725	{0x0003,
1726	 RTW_PWR_CUT_ALL_MSK,
1727	 RTW_PWR_INTF_SDIO_MSK,
1728	 RTW_PWR_ADDR_MAC,
1729	 RTW_PWR_CMD_WRITE, BIT(2), 0},
1730	{0x0093,
1731	 RTW_PWR_CUT_ALL_MSK,
1732	 RTW_PWR_INTF_ALL_MSK,
1733	 RTW_PWR_ADDR_MAC,
1734	 RTW_PWR_CMD_WRITE, BIT(3), 0},
1735	{0x001F,
1736	 RTW_PWR_CUT_ALL_MSK,
1737	 RTW_PWR_INTF_ALL_MSK,
1738	 RTW_PWR_ADDR_MAC,
1739	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1740	{0x00EF,
1741	 RTW_PWR_CUT_ALL_MSK,
1742	 RTW_PWR_INTF_ALL_MSK,
1743	 RTW_PWR_ADDR_MAC,
1744	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1745	{0xFF1A,
1746	 RTW_PWR_CUT_ALL_MSK,
1747	 RTW_PWR_INTF_USB_MSK,
1748	 RTW_PWR_ADDR_MAC,
1749	 RTW_PWR_CMD_WRITE, 0xFF, 0x30},
1750	{0x0049,
1751	 RTW_PWR_CUT_ALL_MSK,
1752	 RTW_PWR_INTF_ALL_MSK,
1753	 RTW_PWR_ADDR_MAC,
1754	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1755	{0x0006,
1756	 RTW_PWR_CUT_ALL_MSK,
1757	 RTW_PWR_INTF_ALL_MSK,
1758	 RTW_PWR_ADDR_MAC,
1759	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1760	{0x0002,
1761	 RTW_PWR_CUT_ALL_MSK,
1762	 RTW_PWR_INTF_ALL_MSK,
1763	 RTW_PWR_ADDR_MAC,
1764	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1765	{0x10C3,
1766	 RTW_PWR_CUT_ALL_MSK,
1767	 RTW_PWR_INTF_USB_MSK,
1768	 RTW_PWR_ADDR_MAC,
1769	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1770	{0x0005,
1771	 RTW_PWR_CUT_ALL_MSK,
1772	 RTW_PWR_INTF_ALL_MSK,
1773	 RTW_PWR_ADDR_MAC,
1774	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
1775	{0x0005,
1776	 RTW_PWR_CUT_ALL_MSK,
1777	 RTW_PWR_INTF_ALL_MSK,
1778	 RTW_PWR_ADDR_MAC,
1779	 RTW_PWR_CMD_POLLING, BIT(1), 0},
1780	{0x0020,
1781	 RTW_PWR_CUT_ALL_MSK,
1782	 RTW_PWR_INTF_ALL_MSK,
1783	 RTW_PWR_ADDR_MAC,
1784	 RTW_PWR_CMD_WRITE, BIT(3), 0},
1785	{0x0000,
1786	 RTW_PWR_CUT_ALL_MSK,
1787	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1788	 RTW_PWR_ADDR_MAC,
1789	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1790	{0xFFFF,
1791	 RTW_PWR_CUT_ALL_MSK,
1792	 RTW_PWR_INTF_ALL_MSK,
1793	 0,
1794	 RTW_PWR_CMD_END, 0, 0},
1795};
1796
1797static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
1798	{0x0005,
1799	 RTW_PWR_CUT_ALL_MSK,
1800	 RTW_PWR_INTF_SDIO_MSK,
1801	 RTW_PWR_ADDR_MAC,
1802	 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
1803	{0x0007,
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, 0xFF, 0x20},
1808	{0x0067,
1809	 RTW_PWR_CUT_ALL_MSK,
1810	 RTW_PWR_INTF_ALL_MSK,
1811	 RTW_PWR_ADDR_MAC,
1812	 RTW_PWR_CMD_WRITE, BIT(5), 0},
1813	{0x0005,
1814	 RTW_PWR_CUT_ALL_MSK,
1815	 RTW_PWR_INTF_PCI_MSK,
1816	 RTW_PWR_ADDR_MAC,
1817	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
1818	{0x004A,
1819	 RTW_PWR_CUT_ALL_MSK,
1820	 RTW_PWR_INTF_USB_MSK,
1821	 RTW_PWR_ADDR_MAC,
1822	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1823	{0x0067,
1824	 RTW_PWR_CUT_ALL_MSK,
1825	 RTW_PWR_INTF_SDIO_MSK,
1826	 RTW_PWR_ADDR_MAC,
1827	 RTW_PWR_CMD_WRITE, BIT(5), 0},
1828	{0x0067,
1829	 RTW_PWR_CUT_ALL_MSK,
1830	 RTW_PWR_INTF_SDIO_MSK,
1831	 RTW_PWR_ADDR_MAC,
1832	 RTW_PWR_CMD_WRITE, BIT(4), 0},
1833	{0x004F,
1834	 RTW_PWR_CUT_ALL_MSK,
1835	 RTW_PWR_INTF_SDIO_MSK,
1836	 RTW_PWR_ADDR_MAC,
1837	 RTW_PWR_CMD_WRITE, BIT(0), 0},
1838	{0x0067,
1839	 RTW_PWR_CUT_ALL_MSK,
1840	 RTW_PWR_INTF_SDIO_MSK,
1841	 RTW_PWR_ADDR_MAC,
1842	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1843	{0x0046,
1844	 RTW_PWR_CUT_ALL_MSK,
1845	 RTW_PWR_INTF_SDIO_MSK,
1846	 RTW_PWR_ADDR_MAC,
1847	 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
1848	{0x0067,
1849	 RTW_PWR_CUT_ALL_MSK,
1850	 RTW_PWR_INTF_SDIO_MSK,
1851	 RTW_PWR_ADDR_MAC,
1852	 RTW_PWR_CMD_WRITE, BIT(2), 0},
1853	{0x0046,
1854	 RTW_PWR_CUT_ALL_MSK,
1855	 RTW_PWR_INTF_SDIO_MSK,
1856	 RTW_PWR_ADDR_MAC,
1857	 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
1858	{0x0062,
1859	 RTW_PWR_CUT_ALL_MSK,
1860	 RTW_PWR_INTF_SDIO_MSK,
1861	 RTW_PWR_ADDR_MAC,
1862	 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
1863	{0x0081,
1864	 RTW_PWR_CUT_ALL_MSK,
1865	 RTW_PWR_INTF_ALL_MSK,
1866	 RTW_PWR_ADDR_MAC,
1867	 RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0},
1868	{0x0005,
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, BIT(3) | BIT(4), BIT(3)},
1873	{0x0086,
1874	 RTW_PWR_CUT_ALL_MSK,
1875	 RTW_PWR_INTF_SDIO_MSK,
1876	 RTW_PWR_ADDR_SDIO,
1877	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1878	{0x0086,
1879	 RTW_PWR_CUT_ALL_MSK,
1880	 RTW_PWR_INTF_SDIO_MSK,
1881	 RTW_PWR_ADDR_SDIO,
1882	 RTW_PWR_CMD_POLLING, BIT(1), 0},
1883	{0x0090,
1884	 RTW_PWR_CUT_ALL_MSK,
1885	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK,
1886	 RTW_PWR_ADDR_MAC,
1887	 RTW_PWR_CMD_WRITE, BIT(1), 0},
1888	{0x0044,
1889	 RTW_PWR_CUT_ALL_MSK,
1890	 RTW_PWR_INTF_SDIO_MSK,
1891	 RTW_PWR_ADDR_SDIO,
1892	 RTW_PWR_CMD_WRITE, 0xFF, 0},
1893	{0x0040,
1894	 RTW_PWR_CUT_ALL_MSK,
1895	 RTW_PWR_INTF_SDIO_MSK,
1896	 RTW_PWR_ADDR_SDIO,
1897	 RTW_PWR_CMD_WRITE, 0xFF, 0x90},
1898	{0x0041,
1899	 RTW_PWR_CUT_ALL_MSK,
1900	 RTW_PWR_INTF_SDIO_MSK,
1901	 RTW_PWR_ADDR_SDIO,
1902	 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
1903	{0x0042,
1904	 RTW_PWR_CUT_ALL_MSK,
1905	 RTW_PWR_INTF_SDIO_MSK,
1906	 RTW_PWR_ADDR_SDIO,
1907	 RTW_PWR_CMD_WRITE, 0xFF, 0x04},
1908	{0xFFFF,
1909	 RTW_PWR_CUT_ALL_MSK,
1910	 RTW_PWR_INTF_ALL_MSK,
1911	 0,
1912	 RTW_PWR_CMD_END, 0, 0},
1913};
1914
1915static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
1916	trans_carddis_to_cardemu_8822b,
1917	trans_cardemu_to_act_8822b,
1918	NULL
1919};
1920
1921static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
1922	trans_act_to_cardemu_8822b,
1923	trans_cardemu_to_carddis_8822b,
1924	NULL
1925};
1926
1927static const struct rtw_intf_phy_para usb2_param_8822b[] = {
1928	{0xFFFF, 0x00,
1929	 RTW_IP_SEL_PHY,
1930	 RTW_INTF_PHY_CUT_ALL,
1931	 RTW_INTF_PHY_PLATFORM_ALL},
1932};
1933
1934static const struct rtw_intf_phy_para usb3_param_8822b[] = {
1935	{0x0001, 0xA841,
1936	 RTW_IP_SEL_PHY,
1937	 RTW_INTF_PHY_CUT_D,
1938	 RTW_INTF_PHY_PLATFORM_ALL},
1939	{0xFFFF, 0x0000,
1940	 RTW_IP_SEL_PHY,
1941	 RTW_INTF_PHY_CUT_ALL,
1942	 RTW_INTF_PHY_PLATFORM_ALL},
1943};
1944
1945static const struct rtw_intf_phy_para pcie_gen1_param_8822b[] = {
1946	{0x0001, 0xA841,
1947	 RTW_IP_SEL_PHY,
1948	 RTW_INTF_PHY_CUT_C,
1949	 RTW_INTF_PHY_PLATFORM_ALL},
1950	{0x0002, 0x60C6,
1951	 RTW_IP_SEL_PHY,
1952	 RTW_INTF_PHY_CUT_C,
1953	 RTW_INTF_PHY_PLATFORM_ALL},
1954	{0x0008, 0x3596,
1955	 RTW_IP_SEL_PHY,
1956	 RTW_INTF_PHY_CUT_C,
1957	 RTW_INTF_PHY_PLATFORM_ALL},
1958	{0x0009, 0x321C,
1959	 RTW_IP_SEL_PHY,
1960	 RTW_INTF_PHY_CUT_C,
1961	 RTW_INTF_PHY_PLATFORM_ALL},
1962	{0x000A, 0x9623,
1963	 RTW_IP_SEL_PHY,
1964	 RTW_INTF_PHY_CUT_C,
1965	 RTW_INTF_PHY_PLATFORM_ALL},
1966	{0x0020, 0x94FF,
1967	 RTW_IP_SEL_PHY,
1968	 RTW_INTF_PHY_CUT_C,
1969	 RTW_INTF_PHY_PLATFORM_ALL},
1970	{0x0021, 0xFFCF,
1971	 RTW_IP_SEL_PHY,
1972	 RTW_INTF_PHY_CUT_C,
1973	 RTW_INTF_PHY_PLATFORM_ALL},
1974	{0x0026, 0xC006,
1975	 RTW_IP_SEL_PHY,
1976	 RTW_INTF_PHY_CUT_C,
1977	 RTW_INTF_PHY_PLATFORM_ALL},
1978	{0x0029, 0xFF0E,
1979	 RTW_IP_SEL_PHY,
1980	 RTW_INTF_PHY_CUT_C,
1981	 RTW_INTF_PHY_PLATFORM_ALL},
1982	{0x002A, 0x1840,
1983	 RTW_IP_SEL_PHY,
1984	 RTW_INTF_PHY_CUT_C,
1985	 RTW_INTF_PHY_PLATFORM_ALL},
1986	{0xFFFF, 0x0000,
1987	 RTW_IP_SEL_PHY,
1988	 RTW_INTF_PHY_CUT_ALL,
1989	 RTW_INTF_PHY_PLATFORM_ALL},
1990};
1991
1992static const struct rtw_intf_phy_para pcie_gen2_param_8822b[] = {
1993	{0x0001, 0xA841,
1994	 RTW_IP_SEL_PHY,
1995	 RTW_INTF_PHY_CUT_C,
1996	 RTW_INTF_PHY_PLATFORM_ALL},
1997	{0x0002, 0x60C6,
1998	 RTW_IP_SEL_PHY,
1999	 RTW_INTF_PHY_CUT_C,
2000	 RTW_INTF_PHY_PLATFORM_ALL},
2001	{0x0008, 0x3597,
2002	 RTW_IP_SEL_PHY,
2003	 RTW_INTF_PHY_CUT_C,
2004	 RTW_INTF_PHY_PLATFORM_ALL},
2005	{0x0009, 0x321C,
2006	 RTW_IP_SEL_PHY,
2007	 RTW_INTF_PHY_CUT_C,
2008	 RTW_INTF_PHY_PLATFORM_ALL},
2009	{0x000A, 0x9623,
2010	 RTW_IP_SEL_PHY,
2011	 RTW_INTF_PHY_CUT_C,
2012	 RTW_INTF_PHY_PLATFORM_ALL},
2013	{0x0020, 0x94FF,
2014	 RTW_IP_SEL_PHY,
2015	 RTW_INTF_PHY_CUT_C,
2016	 RTW_INTF_PHY_PLATFORM_ALL},
2017	{0x0021, 0xFFCF,
2018	 RTW_IP_SEL_PHY,
2019	 RTW_INTF_PHY_CUT_C,
2020	 RTW_INTF_PHY_PLATFORM_ALL},
2021	{0x0026, 0xC006,
2022	 RTW_IP_SEL_PHY,
2023	 RTW_INTF_PHY_CUT_C,
2024	 RTW_INTF_PHY_PLATFORM_ALL},
2025	{0x0029, 0xFF0E,
2026	 RTW_IP_SEL_PHY,
2027	 RTW_INTF_PHY_CUT_C,
2028	 RTW_INTF_PHY_PLATFORM_ALL},
2029	{0x002A, 0x3040,
2030	 RTW_IP_SEL_PHY,
2031	 RTW_INTF_PHY_CUT_C,
2032	 RTW_INTF_PHY_PLATFORM_ALL},
2033	{0xFFFF, 0x0000,
2034	 RTW_IP_SEL_PHY,
2035	 RTW_INTF_PHY_CUT_ALL,
2036	 RTW_INTF_PHY_PLATFORM_ALL},
2037};
2038
2039static const struct rtw_intf_phy_para_table phy_para_table_8822b = {
2040	.usb2_para	= usb2_param_8822b,
2041	.usb3_para	= usb3_param_8822b,
2042	.gen1_para	= pcie_gen1_param_8822b,
2043	.gen2_para	= pcie_gen2_param_8822b,
2044	.n_usb2_para	= ARRAY_SIZE(usb2_param_8822b),
2045	.n_usb3_para	= ARRAY_SIZE(usb2_param_8822b),
2046	.n_gen1_para	= ARRAY_SIZE(pcie_gen1_param_8822b),
2047	.n_gen2_para	= ARRAY_SIZE(pcie_gen2_param_8822b),
2048};
2049
2050static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
2051	[2] = RTW_DEF_RFE(8822b, 2, 2),
2052	[3] = RTW_DEF_RFE(8822b, 3, 0),
2053	[5] = RTW_DEF_RFE(8822b, 5, 5),
2054};
2055
2056static const struct rtw_hw_reg rtw8822b_dig[] = {
2057	[0] = { .addr = 0xc50, .mask = 0x7f },
2058	[1] = { .addr = 0xe50, .mask = 0x7f },
2059};
2060
2061static const struct rtw_ltecoex_addr rtw8822b_ltecoex_addr = {
2062	.ctrl = LTECOEX_ACCESS_CTRL,
2063	.wdata = LTECOEX_WRITE_DATA,
2064	.rdata = LTECOEX_READ_DATA,
2065};
2066
2067static const struct rtw_page_table page_table_8822b[] = {
2068	{64, 64, 64, 64, 1},
2069	{64, 64, 64, 64, 1},
2070	{64, 64, 0, 0, 1},
2071	{64, 64, 64, 0, 1},
2072	{64, 64, 64, 64, 1},
2073};
2074
2075static const struct rtw_rqpn rqpn_table_8822b[] = {
2076	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2077	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2078	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2079	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2080	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2081	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2082	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2083	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
2084	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
2085	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2086	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2087	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
2088	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2089	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2090	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2091};
2092
2093static struct rtw_prioq_addrs prioq_addrs_8822b = {
2094	.prio[RTW_DMA_MAPPING_EXTRA] = {
2095		.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
2096	},
2097	.prio[RTW_DMA_MAPPING_LOW] = {
2098		.rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2,
2099	},
2100	.prio[RTW_DMA_MAPPING_NORMAL] = {
2101		.rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2,
2102	},
2103	.prio[RTW_DMA_MAPPING_HIGH] = {
2104		.rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2,
2105	},
2106	.wsize = true,
2107};
2108
2109static struct rtw_chip_ops rtw8822b_ops = {
2110	.phy_set_param		= rtw8822b_phy_set_param,
2111	.read_efuse		= rtw8822b_read_efuse,
2112	.query_rx_desc		= rtw8822b_query_rx_desc,
2113	.set_channel		= rtw8822b_set_channel,
2114	.mac_init		= rtw8822b_mac_init,
2115	.read_rf		= rtw_phy_read_rf,
2116	.write_rf		= rtw_phy_write_rf_reg_sipi,
2117	.set_tx_power_index	= rtw8822b_set_tx_power_index,
2118	.set_antenna		= rtw8822b_set_antenna,
2119	.cfg_ldo25		= rtw8822b_cfg_ldo25,
2120	.false_alarm_statistics	= rtw8822b_false_alarm_statistics,
2121	.phy_calibration	= rtw8822b_phy_calibration,
2122	.pwr_track		= rtw8822b_pwr_track,
2123	.config_bfee		= rtw8822b_bf_config_bfee,
2124	.set_gid_table		= rtw_bf_set_gid_table,
2125	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
2126
2127	.coex_set_init		= rtw8822b_coex_cfg_init,
2128	.coex_set_ant_switch	= rtw8822b_coex_cfg_ant_switch,
2129	.coex_set_gnt_fix	= rtw8822b_coex_cfg_gnt_fix,
2130	.coex_set_gnt_debug	= rtw8822b_coex_cfg_gnt_debug,
2131	.coex_set_rfe_type	= rtw8822b_coex_cfg_rfe_type,
2132	.coex_set_wl_tx_power	= rtw8822b_coex_cfg_wl_tx_power,
2133	.coex_set_wl_rx_gain	= rtw8822b_coex_cfg_wl_rx_gain,
2134};
2135
2136/* Shared-Antenna Coex Table */
2137static const struct coex_table_para table_sant_8822b[] = {
2138	{0xffffffff, 0xffffffff}, /* case-0 */
2139	{0x55555555, 0x55555555},
2140	{0x66555555, 0x66555555},
2141	{0xaaaaaaaa, 0xaaaaaaaa},
2142	{0x5a5a5a5a, 0x5a5a5a5a},
2143	{0xfafafafa, 0xfafafafa}, /* case-5 */
2144	{0x6a5a6a5a, 0xaaaaaaaa},
2145	{0x6a5a56aa, 0x6a5a56aa},
2146	{0x6a5a5a5a, 0x6a5a5a5a},
2147	{0x66555555, 0x5a5a5a5a},
2148	{0x66555555, 0x6a5a5a5a}, /* case-10 */
2149	{0x66555555, 0xfafafafa},
2150	{0x66555555, 0x5a5a5aaa},
2151	{0x66555555, 0x5aaa5aaa},
2152	{0x66555555, 0xaaaa5aaa},
2153	{0x66555555, 0xaaaaaaaa}, /* case-15 */
2154	{0xffff55ff, 0xfafafafa},
2155	{0xffff55ff, 0x6afa5afa},
2156	{0xaaffffaa, 0xfafafafa},
2157	{0xaa5555aa, 0x5a5a5a5a},
2158	{0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
2159	{0xaa5555aa, 0xaaaaaaaa},
2160	{0xffffffff, 0x5a5a5a5a},
2161	{0xffffffff, 0x6a5a5a5a},
2162	{0xffffffff, 0x55555555},
2163	{0xffffffff, 0x6a5a5aaa}, /* case-25 */
2164	{0x55555555, 0x5a5a5a5a},
2165	{0x55555555, 0xaaaaaaaa},
2166	{0x55555555, 0x6a5a6a5a},
2167	{0x66556655, 0x66556655}
2168};
2169
2170/* Non-Shared-Antenna Coex Table */
2171static const struct coex_table_para table_nsant_8822b[] = {
2172	{0xffffffff, 0xffffffff}, /* case-100 */
2173	{0x55555555, 0x55555555},
2174	{0x66555555, 0x66555555},
2175	{0xaaaaaaaa, 0xaaaaaaaa},
2176	{0x5a5a5a5a, 0x5a5a5a5a},
2177	{0xfafafafa, 0xfafafafa}, /* case-105 */
2178	{0x5afa5afa, 0x5afa5afa},
2179	{0x55555555, 0xfafafafa},
2180	{0x66555555, 0xfafafafa},
2181	{0x66555555, 0x5a5a5a5a},
2182	{0x66555555, 0x6a5a5a5a}, /* case-110 */
2183	{0x66555555, 0xaaaaaaaa},
2184	{0xffff55ff, 0xfafafafa},
2185	{0xffff55ff, 0x5afa5afa},
2186	{0xffff55ff, 0xaaaaaaaa},
2187	{0xaaffffaa, 0xfafafafa}, /* case-115 */
2188	{0xaaffffaa, 0x5afa5afa},
2189	{0xaaffffaa, 0xaaaaaaaa},
2190	{0xffffffff, 0xfafafafa},
2191	{0xffffffff, 0x5afa5afa},
2192	{0xffffffff, 0xaaaaaaaa}, /* case-120 */
2193	{0x55ff55ff, 0x5afa5afa},
2194	{0x55ff55ff, 0xaaaaaaaa},
2195	{0x55ff55ff, 0x55ff55ff}
2196};
2197
2198/* Shared-Antenna TDMA */
2199static const struct coex_tdma_para tdma_sant_8822b[] = {
2200	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
2201	{ {0x61, 0x45, 0x03, 0x11, 0x11} },
2202	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
2203	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
2204	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
2205	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */
2206	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
2207	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
2208	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
2209	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
2210	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
2211	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
2212	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
2213	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
2214	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
2215	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
2216	{ {0x51, 0x45, 0x03, 0x10, 0x10} },
2217	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
2218	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
2219	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
2220	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
2221	{ {0x51, 0x4a, 0x03, 0x10, 0x50} },
2222	{ {0x51, 0x0c, 0x03, 0x10, 0x54} },
2223	{ {0x55, 0x08, 0x03, 0x10, 0x54} },
2224	{ {0x65, 0x10, 0x03, 0x11, 0x11} },
2225	{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
2226	{ {0x51, 0x08, 0x03, 0x10, 0x50} },
2227	{ {0x61, 0x08, 0x03, 0x11, 0x11} }
2228};
2229
2230/* Non-Shared-Antenna TDMA */
2231static const struct coex_tdma_para tdma_nsant_8822b[] = {
2232	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */
2233	{ {0x61, 0x45, 0x03, 0x11, 0x11} },
2234	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
2235	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
2236	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
2237	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
2238	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
2239	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
2240	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
2241	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
2242	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
2243	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
2244	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
2245	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
2246	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
2247	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
2248	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
2249	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
2250	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
2251	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
2252	{ {0x51, 0x10, 0x03, 0x10, 0x50} }  /* case-120 */
2253};
2254
2255/* rssi in percentage % (dbm = % - 100) */
2256static const u8 wl_rssi_step_8822b[] = {60, 50, 44, 30};
2257static const u8 bt_rssi_step_8822b[] = {30, 30, 30, 30};
2258static const struct coex_5g_afh_map afh_5g_8822b[] = { {0, 0, 0} };
2259
2260/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
2261static const struct coex_rf_para rf_para_tx_8822b[] = {
2262	{0, 0, false, 7},  /* for normal */
2263	{0, 16, false, 7}, /* for WL-CPT */
2264	{4, 0, true, 1},
2265	{3, 6, true, 1},
2266	{2, 9, true, 1},
2267	{1, 13, true, 1}
2268};
2269
2270static const struct coex_rf_para rf_para_rx_8822b[] = {
2271	{0, 0, false, 7},  /* for normal */
2272	{0, 16, false, 7}, /* for WL-CPT */
2273	{4, 0, true, 1},
2274	{3, 6, true, 1},
2275	{2, 9, true, 1},
2276	{1, 13, true, 1}
2277};
2278
2279static_assert(ARRAY_SIZE(rf_para_tx_8822b) == ARRAY_SIZE(rf_para_rx_8822b));
2280
2281static const u8
2282rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2283	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2284	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2285	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2286	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2287	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2288	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2289	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2290	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2291	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2292};
2293
2294static const u8
2295rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2296	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2297	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2298	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2299	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2300	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2301	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2302	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2303	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2304	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2305};
2306
2307static const u8
2308rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2309	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2310	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2311	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2312	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2313	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2314	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2315	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2316	  8,  8,  9, 10, 11, 11, 12, 13, 14, 14,
2317	 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2318};
2319
2320static const u8
2321rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2322	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2323	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2324	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2325	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2326	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2327	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2328	{ 0,  1,  2,  2,  3,  4,  5,  5,  6,  7,
2329	  8,  9,  9, 10, 11, 12, 13, 14, 14, 15,
2330	 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2331};
2332
2333static const u8 rtw8822b_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = {
2334	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2335	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2336	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2337};
2338
2339static const u8 rtw8822b_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = {
2340	0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
2341	5,  5,  6,  6,  6,  7,  7,  8,  8,  9,
2342	9, 10, 10, 11, 11, 12, 12, 12, 13, 13
2343};
2344
2345static const u8 rtw8822b_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = {
2346	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2347	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2348	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2349};
2350
2351static const u8 rtw8822b_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = {
2352	0,  1,  1,  2,  2,  3,  3,  4,  4,  5,
2353	5,  6,  6,  7,  7,  8,  8,  9,  9, 10,
2354	10, 11, 11, 12, 12, 13, 13, 14, 14, 15
2355};
2356
2357static const u8 rtw8822b_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = {
2358	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2359	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2360	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2361};
2362
2363static const u8 rtw8822b_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = {
2364	0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
2365	5,  5,  6,  6,  6,  7,  7,  8,  8,  9,
2366	9, 10, 10, 11, 11, 12, 12, 12, 13, 13
2367};
2368
2369static const u8 rtw8822b_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = {
2370	0,  1,  1,  1,  2,  2,  3,  3,  3,  4,
2371	4,  5,  5,  5,  6,  6,  7,  7,  7,  8,
2372	8,  9,  9,  9, 10, 10, 11, 11, 11, 12
2373};
2374
2375static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
2376	 0,  1,  1,  2,  2,  3,  3,  4,  4,  5,
2377	 5,  6,  6,  7,  7,  8,  8,  9,  9, 10,
2378	10, 11, 11, 12, 12, 13, 13, 14, 14, 15
2379};
2380
2381static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
2382	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
2383	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
2384	.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
2385	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1],
2386	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2],
2387	.pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3],
2388	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1],
2389	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2],
2390	.pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3],
2391	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1],
2392	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2],
2393	.pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3],
2394	.pwrtrk_2gb_n = rtw8822b_pwrtrk_2gb_n,
2395	.pwrtrk_2gb_p = rtw8822b_pwrtrk_2gb_p,
2396	.pwrtrk_2ga_n = rtw8822b_pwrtrk_2ga_n,
2397	.pwrtrk_2ga_p = rtw8822b_pwrtrk_2ga_p,
2398	.pwrtrk_2g_cckb_n = rtw8822b_pwrtrk_2g_cck_b_n,
2399	.pwrtrk_2g_cckb_p = rtw8822b_pwrtrk_2g_cck_b_p,
2400	.pwrtrk_2g_ccka_n = rtw8822b_pwrtrk_2g_cck_a_n,
2401	.pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
2402};
2403
2404static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
2405	{0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2406	{0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2407	{0xcba, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2408	{0xcbd, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2409	{0xc58, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2410	{0xcbd, BIT(0), RTW_REG_DOMAIN_MAC8},
2411	{0, 0, RTW_REG_DOMAIN_NL},
2412	{0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2413	{0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2414	{0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
2415	{0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2416	{0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
2417	{0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
2418	{0, 0, RTW_REG_DOMAIN_NL},
2419	{0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
2420	{0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
2421	{0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
2422	{0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
2423	{0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B},
2424	{0, 0, RTW_REG_DOMAIN_NL},
2425	{0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2426	{0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2427	{0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
2428	{0xc50,  MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2429};
2430
2431struct rtw_chip_info rtw8822b_hw_spec = {
2432	.ops = &rtw8822b_ops,
2433	.id = RTW_CHIP_TYPE_8822B,
2434	.fw_name = "rtw88/rtw8822b_fw.bin",
2435	.wlan_cpu = RTW_WCPU_11AC,
2436	.tx_pkt_desc_sz = 48,
2437	.tx_buf_desc_sz = 16,
2438	.rx_pkt_desc_sz = 24,
2439	.rx_buf_desc_sz = 8,
2440	.phy_efuse_size = 1024,
2441	.log_efuse_size = 768,
2442	.ptct_efuse_size = 96,
2443	.txff_size = 262144,
2444	.rxff_size = 24576,
2445	.fw_rxff_size = 12288,
2446	.txgi_factor = 1,
2447	.is_pwr_by_rate_dec = true,
2448	.max_power_index = 0x3f,
2449	.csi_buf_pg_num = 0,
2450	.band = RTW_BAND_2G | RTW_BAND_5G,
2451	.page_size = 128,
2452	.dig_min = 0x1c,
2453	.ht_supported = true,
2454	.vht_supported = true,
2455	.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
2456	.sys_func_en = 0xDC,
2457	.pwr_on_seq = card_enable_flow_8822b,
2458	.pwr_off_seq = card_disable_flow_8822b,
2459	.page_table = page_table_8822b,
2460	.rqpn_table = rqpn_table_8822b,
2461	.prioq_addrs = &prioq_addrs_8822b,
2462	.intf_table = &phy_para_table_8822b,
2463	.dig = rtw8822b_dig,
2464	.dig_cck = NULL,
2465	.rf_base_addr = {0x2800, 0x2c00},
2466	.rf_sipi_addr = {0xc90, 0xe90},
2467	.ltecoex_addr = &rtw8822b_ltecoex_addr,
2468	.mac_tbl = &rtw8822b_mac_tbl,
2469	.agc_tbl = &rtw8822b_agc_tbl,
2470	.bb_tbl = &rtw8822b_bb_tbl,
2471	.rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl},
2472	.rfe_defs = rtw8822b_rfe_defs,
2473	.rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs),
2474	.pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl,
2475	.iqk_threshold = 8,
2476	.bfer_su_max_num = 2,
2477	.bfer_mu_max_num = 1,
2478	.rx_ldpc = true,
2479
2480	.coex_para_ver = 0x20070206,
2481	.bt_desired_ver = 0x6,
2482	.scbd_support = true,
2483	.new_scbd10_def = false,
2484	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
2485	.bt_rssi_type = COEX_BTRSSI_RATIO,
2486	.ant_isolation = 15,
2487	.rssi_tolerance = 2,
2488	.wl_rssi_step = wl_rssi_step_8822b,
2489	.bt_rssi_step = bt_rssi_step_8822b,
2490	.table_sant_num = ARRAY_SIZE(table_sant_8822b),
2491	.table_sant = table_sant_8822b,
2492	.table_nsant_num = ARRAY_SIZE(table_nsant_8822b),
2493	.table_nsant = table_nsant_8822b,
2494	.tdma_sant_num = ARRAY_SIZE(tdma_sant_8822b),
2495	.tdma_sant = tdma_sant_8822b,
2496	.tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822b),
2497	.tdma_nsant = tdma_nsant_8822b,
2498	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822b),
2499	.wl_rf_para_tx = rf_para_tx_8822b,
2500	.wl_rf_para_rx = rf_para_rx_8822b,
2501	.bt_afh_span_bw20 = 0x24,
2502	.bt_afh_span_bw40 = 0x36,
2503	.afh_5g_num = ARRAY_SIZE(afh_5g_8822b),
2504	.afh_5g = afh_5g_8822b,
2505
2506	.coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b),
2507	.coex_info_hw_regs = coex_info_hw_regs_8822b,
2508
2509	.fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680},
2510};
2511EXPORT_SYMBOL(rtw8822b_hw_spec);
2512
2513MODULE_FIRMWARE("rtw88/rtw8822b_fw.bin");
2514
2515MODULE_AUTHOR("Realtek Corporation");
2516MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822b driver");
2517MODULE_LICENSE("Dual BSD/GPL");
2518