xref: /freebsd/sys/contrib/dev/rtw88/rtw8821a.c (revision a0ccc12f6882a886d89ae279c541b2c2b62c6aca)
1*a0ccc12fSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2*a0ccc12fSBjoern A. Zeeb /* Copyright(c) 2024  Realtek Corporation
3*a0ccc12fSBjoern A. Zeeb  */
4*a0ccc12fSBjoern A. Zeeb 
5*a0ccc12fSBjoern A. Zeeb #include "main.h"
6*a0ccc12fSBjoern A. Zeeb #include "coex.h"
7*a0ccc12fSBjoern A. Zeeb #include "phy.h"
8*a0ccc12fSBjoern A. Zeeb #include "reg.h"
9*a0ccc12fSBjoern A. Zeeb #include "rtw88xxa.h"
10*a0ccc12fSBjoern A. Zeeb #include "rtw8821a.h"
11*a0ccc12fSBjoern A. Zeeb #include "rtw8821a_table.h"
12*a0ccc12fSBjoern A. Zeeb #include "tx.h"
13*a0ccc12fSBjoern A. Zeeb 
14*a0ccc12fSBjoern A. Zeeb static void rtw8821a_power_off(struct rtw_dev *rtwdev)
15*a0ccc12fSBjoern A. Zeeb {
16*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a);
17*a0ccc12fSBjoern A. Zeeb }
18*a0ccc12fSBjoern A. Zeeb 
19*a0ccc12fSBjoern A. Zeeb static s8 rtw8821a_cck_rx_pwr(u8 lna_idx, u8 vga_idx)
20*a0ccc12fSBjoern A. Zeeb {
21*a0ccc12fSBjoern A. Zeeb 	static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38};
22*a0ccc12fSBjoern A. Zeeb 	s8 rx_pwr_all = 0;
23*a0ccc12fSBjoern A. Zeeb 	s8 lna_gain;
24*a0ccc12fSBjoern A. Zeeb 
25*a0ccc12fSBjoern A. Zeeb 	switch (lna_idx) {
26*a0ccc12fSBjoern A. Zeeb 	case 5:
27*a0ccc12fSBjoern A. Zeeb 	case 4:
28*a0ccc12fSBjoern A. Zeeb 	case 2:
29*a0ccc12fSBjoern A. Zeeb 	case 1:
30*a0ccc12fSBjoern A. Zeeb 	case 0:
31*a0ccc12fSBjoern A. Zeeb 		lna_gain = lna_gain_table[lna_idx];
32*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = lna_gain - 2 * vga_idx;
33*a0ccc12fSBjoern A. Zeeb 		break;
34*a0ccc12fSBjoern A. Zeeb 	default:
35*a0ccc12fSBjoern A. Zeeb 		break;
36*a0ccc12fSBjoern A. Zeeb 	}
37*a0ccc12fSBjoern A. Zeeb 
38*a0ccc12fSBjoern A. Zeeb 	return rx_pwr_all;
39*a0ccc12fSBjoern A. Zeeb }
40*a0ccc12fSBjoern A. Zeeb 
41*a0ccc12fSBjoern A. Zeeb static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
42*a0ccc12fSBjoern A. Zeeb 				      struct rtw_rx_pkt_stat *pkt_stat)
43*a0ccc12fSBjoern A. Zeeb {
44*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat,
45*a0ccc12fSBjoern A. Zeeb 				  rtw8821a_cck_rx_pwr);
46*a0ccc12fSBjoern A. Zeeb }
47*a0ccc12fSBjoern A. Zeeb 
48*a0ccc12fSBjoern A. Zeeb static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
49*a0ccc12fSBjoern A. Zeeb {
50*a0ccc12fSBjoern A. Zeeb }
51*a0ccc12fSBjoern A. Zeeb 
52*a0ccc12fSBjoern A. Zeeb #define CAL_NUM_8821A 3
53*a0ccc12fSBjoern A. Zeeb #define MACBB_REG_NUM_8821A 8
54*a0ccc12fSBjoern A. Zeeb #define AFE_REG_NUM_8821A 4
55*a0ccc12fSBjoern A. Zeeb #define RF_REG_NUM_8821A 3
56*a0ccc12fSBjoern A. Zeeb 
57*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup,
58*a0ccc12fSBjoern A. Zeeb 				   const u32 *backup_rf_reg, u32 rf_num)
59*a0ccc12fSBjoern A. Zeeb {
60*a0ccc12fSBjoern A. Zeeb 	u32 i;
61*a0ccc12fSBjoern A. Zeeb 
62*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
63*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
64*a0ccc12fSBjoern A. Zeeb 
65*a0ccc12fSBjoern A. Zeeb 	/* Save RF Parameters */
66*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < rf_num; i++)
67*a0ccc12fSBjoern A. Zeeb 		rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A,
68*a0ccc12fSBjoern A. Zeeb 					    backup_rf_reg[i], MASKDWORD);
69*a0ccc12fSBjoern A. Zeeb }
70*a0ccc12fSBjoern A. Zeeb 
71*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev,
72*a0ccc12fSBjoern A. Zeeb 				    const u32 *backup_rf_reg,
73*a0ccc12fSBjoern A. Zeeb 				    u32 *RF_backup, u32 rf_reg_num)
74*a0ccc12fSBjoern A. Zeeb {
75*a0ccc12fSBjoern A. Zeeb 	u32 i;
76*a0ccc12fSBjoern A. Zeeb 
77*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
78*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
79*a0ccc12fSBjoern A. Zeeb 
80*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < rf_reg_num; i++)
81*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i],
82*a0ccc12fSBjoern A. Zeeb 			     RFREG_MASK, RF_backup[i]);
83*a0ccc12fSBjoern A. Zeeb }
84*a0ccc12fSBjoern A. Zeeb 
85*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
86*a0ccc12fSBjoern A. Zeeb 				     const u32 *backup_afe_reg, u32 afe_num)
87*a0ccc12fSBjoern A. Zeeb {
88*a0ccc12fSBjoern A. Zeeb 	u32 i;
89*a0ccc12fSBjoern A. Zeeb 
90*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
91*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
92*a0ccc12fSBjoern A. Zeeb 
93*a0ccc12fSBjoern A. Zeeb 	/* Reload AFE Parameters */
94*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < afe_num; i++)
95*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]);
96*a0ccc12fSBjoern A. Zeeb 
97*a0ccc12fSBjoern A. Zeeb 	/* [31] = 1 --> Page C1 */
98*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
99*a0ccc12fSBjoern A. Zeeb 
100*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0);
101*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0);
102*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0);
103*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);
104*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
105*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_TXAGCIDX, 0x00000000);
106*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000);
107*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000);
108*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RFECTL_A, 0x0);
109*a0ccc12fSBjoern A. Zeeb }
110*a0ccc12fSBjoern A. Zeeb 
111*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev,
112*a0ccc12fSBjoern A. Zeeb 				 unsigned int rx_x, unsigned int rx_y)
113*a0ccc12fSBjoern A. Zeeb {
114*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
115*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
116*a0ccc12fSBjoern A. Zeeb 
117*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
118*a0ccc12fSBjoern A. Zeeb 			 0x000003ff, rx_x >> 1);
119*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
120*a0ccc12fSBjoern A. Zeeb 			 0x03ff0000, (rx_y >> 1) & 0x3ff);
121*a0ccc12fSBjoern A. Zeeb }
122*a0ccc12fSBjoern A. Zeeb 
123*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev,
124*a0ccc12fSBjoern A. Zeeb 				 unsigned int tx_x, unsigned int tx_y)
125*a0ccc12fSBjoern A. Zeeb {
126*a0ccc12fSBjoern A. Zeeb 	/* [31] = 1 --> Page C1 */
127*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
128*a0ccc12fSBjoern A. Zeeb 
129*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080);
130*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000);
131*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000);
132*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y);
133*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x);
134*a0ccc12fSBjoern A. Zeeb }
135*a0ccc12fSBjoern A. Zeeb 
136*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal,
137*a0ccc12fSBjoern A. Zeeb 				     bool *tx0iqkok,
138*a0ccc12fSBjoern A. Zeeb 				     int tx_x0[CAL_NUM_8821A],
139*a0ccc12fSBjoern A. Zeeb 				     int tx_y0[CAL_NUM_8821A])
140*a0ccc12fSBjoern A. Zeeb {
141*a0ccc12fSBjoern A. Zeeb 	u32 cal_retry, delay_count, iqk_ready, tx_fail;
142*a0ccc12fSBjoern A. Zeeb 	int tx_dt[3], vdf_y[3], vdf_x[3];
143*a0ccc12fSBjoern A. Zeeb 	int k;
144*a0ccc12fSBjoern A. Zeeb 
145*a0ccc12fSBjoern A. Zeeb 	for (k = 0; k < 3; k++) {
146*a0ccc12fSBjoern A. Zeeb 		switch (k) {
147*a0ccc12fSBjoern A. Zeeb 		case 0:
148*a0ccc12fSBjoern A. Zeeb 			/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
149*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE,
150*a0ccc12fSBjoern A. Zeeb 				    0x18008c38);
151*a0ccc12fSBjoern A. Zeeb 			/* RX_Tone_idx[9:0], RxK_Mask[29] */
152*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c38);
153*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0);
154*a0ccc12fSBjoern A. Zeeb 			break;
155*a0ccc12fSBjoern A. Zeeb 		case 1:
156*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE,
157*a0ccc12fSBjoern A. Zeeb 					 BIT(28), 0x0);
158*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_OFDM0_A_TX_AFE,
159*a0ccc12fSBjoern A. Zeeb 					 BIT(28), 0x0);
160*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0);
161*a0ccc12fSBjoern A. Zeeb 			break;
162*a0ccc12fSBjoern A. Zeeb 		case 2:
163*a0ccc12fSBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
164*a0ccc12fSBjoern A. Zeeb 				"vdf_y[1] = %x vdf_y[0] = %x\n",
165*a0ccc12fSBjoern A. Zeeb 				vdf_y[1] >> 21 & 0x00007ff,
166*a0ccc12fSBjoern A. Zeeb 				vdf_y[0] >> 21 & 0x00007ff);
167*a0ccc12fSBjoern A. Zeeb 
168*a0ccc12fSBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
169*a0ccc12fSBjoern A. Zeeb 				"vdf_x[1] = %x vdf_x[0] = %x\n",
170*a0ccc12fSBjoern A. Zeeb 				vdf_x[1] >> 21 & 0x00007ff,
171*a0ccc12fSBjoern A. Zeeb 				vdf_x[0] >> 21 & 0x00007ff);
172*a0ccc12fSBjoern A. Zeeb 
173*a0ccc12fSBjoern A. Zeeb 			tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20);
174*a0ccc12fSBjoern A. Zeeb 			tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708;
175*a0ccc12fSBjoern A. Zeeb 			tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0));
176*a0ccc12fSBjoern A. Zeeb 
177*a0ccc12fSBjoern A. Zeeb 			/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
178*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE,
179*a0ccc12fSBjoern A. Zeeb 				    0x18008c20);
180*a0ccc12fSBjoern A. Zeeb 			/* RX_Tone_idx[9:0], RxK_Mask[29] */
181*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c20);
182*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x1);
183*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_INTPO_SETA, 0x3fff0000,
184*a0ccc12fSBjoern A. Zeeb 					 tx_dt[cal] & 0x00003fff);
185*a0ccc12fSBjoern A. Zeeb 			break;
186*a0ccc12fSBjoern A. Zeeb 		}
187*a0ccc12fSBjoern A. Zeeb 
188*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
189*a0ccc12fSBjoern A. Zeeb 
190*a0ccc12fSBjoern A. Zeeb 		for (cal_retry = 0; cal_retry < 10; cal_retry++) {
191*a0ccc12fSBjoern A. Zeeb 			/* one shot */
192*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
193*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
194*a0ccc12fSBjoern A. Zeeb 
195*a0ccc12fSBjoern A. Zeeb 			mdelay(10);
196*a0ccc12fSBjoern A. Zeeb 
197*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
198*a0ccc12fSBjoern A. Zeeb 
199*a0ccc12fSBjoern A. Zeeb 			for (delay_count = 0; delay_count < 20; delay_count++) {
200*a0ccc12fSBjoern A. Zeeb 				iqk_ready = rtw_read32_mask(rtwdev,
201*a0ccc12fSBjoern A. Zeeb 							    REG_IQKA_END,
202*a0ccc12fSBjoern A. Zeeb 							    BIT(10));
203*a0ccc12fSBjoern A. Zeeb 
204*a0ccc12fSBjoern A. Zeeb 				/* Originally: if (~iqk_ready || delay_count > 20)
205*a0ccc12fSBjoern A. Zeeb 				 * that looks like a typo so make it more explicit
206*a0ccc12fSBjoern A. Zeeb 				 */
207*a0ccc12fSBjoern A. Zeeb 				iqk_ready = true;
208*a0ccc12fSBjoern A. Zeeb 
209*a0ccc12fSBjoern A. Zeeb 				if (iqk_ready)
210*a0ccc12fSBjoern A. Zeeb 					break;
211*a0ccc12fSBjoern A. Zeeb 
212*a0ccc12fSBjoern A. Zeeb 				mdelay(1);
213*a0ccc12fSBjoern A. Zeeb 			}
214*a0ccc12fSBjoern A. Zeeb 
215*a0ccc12fSBjoern A. Zeeb 			if (delay_count < 20) {
216*a0ccc12fSBjoern A. Zeeb 				/* ============TXIQK Check============== */
217*a0ccc12fSBjoern A. Zeeb 				tx_fail = rtw_read32_mask(rtwdev,
218*a0ccc12fSBjoern A. Zeeb 							  REG_IQKA_END,
219*a0ccc12fSBjoern A. Zeeb 							  BIT(12));
220*a0ccc12fSBjoern A. Zeeb 
221*a0ccc12fSBjoern A. Zeeb 				/* Originally: if (~tx_fail) {
222*a0ccc12fSBjoern A. Zeeb 				 * It looks like a typo, so make it more explicit.
223*a0ccc12fSBjoern A. Zeeb 				 */
224*a0ccc12fSBjoern A. Zeeb 				tx_fail = false;
225*a0ccc12fSBjoern A. Zeeb 
226*a0ccc12fSBjoern A. Zeeb 				if (!tx_fail) {
227*a0ccc12fSBjoern A. Zeeb 					rtw_write32(rtwdev, REG_RFECTL_A,
228*a0ccc12fSBjoern A. Zeeb 						    0x02000000);
229*a0ccc12fSBjoern A. Zeeb 					vdf_x[k] = rtw_read32_mask(rtwdev,
230*a0ccc12fSBjoern A. Zeeb 								   REG_IQKA_END,
231*a0ccc12fSBjoern A. Zeeb 								   0x07ff0000);
232*a0ccc12fSBjoern A. Zeeb 					vdf_x[k] <<= 21;
233*a0ccc12fSBjoern A. Zeeb 
234*a0ccc12fSBjoern A. Zeeb 					rtw_write32(rtwdev, REG_RFECTL_A,
235*a0ccc12fSBjoern A. Zeeb 						    0x04000000);
236*a0ccc12fSBjoern A. Zeeb 					vdf_y[k] = rtw_read32_mask(rtwdev,
237*a0ccc12fSBjoern A. Zeeb 								   REG_IQKA_END,
238*a0ccc12fSBjoern A. Zeeb 								   0x07ff0000);
239*a0ccc12fSBjoern A. Zeeb 					vdf_y[k] <<= 21;
240*a0ccc12fSBjoern A. Zeeb 
241*a0ccc12fSBjoern A. Zeeb 					*tx0iqkok = true;
242*a0ccc12fSBjoern A. Zeeb 					break;
243*a0ccc12fSBjoern A. Zeeb 				}
244*a0ccc12fSBjoern A. Zeeb 
245*a0ccc12fSBjoern A. Zeeb 				rtw_write32_mask(rtwdev, REG_IQC_Y,
246*a0ccc12fSBjoern A. Zeeb 						 0x000007ff, 0x0);
247*a0ccc12fSBjoern A. Zeeb 				rtw_write32_mask(rtwdev, REG_IQC_X,
248*a0ccc12fSBjoern A. Zeeb 						 0x000007ff, 0x200);
249*a0ccc12fSBjoern A. Zeeb 			}
250*a0ccc12fSBjoern A. Zeeb 
251*a0ccc12fSBjoern A. Zeeb 			*tx0iqkok = false;
252*a0ccc12fSBjoern A. Zeeb 		}
253*a0ccc12fSBjoern A. Zeeb 	}
254*a0ccc12fSBjoern A. Zeeb 
255*a0ccc12fSBjoern A. Zeeb 	if (k == 3) {
256*a0ccc12fSBjoern A. Zeeb 		tx_x0[cal] = vdf_x[k - 1];
257*a0ccc12fSBjoern A. Zeeb 		tx_y0[cal] = vdf_y[k - 1];
258*a0ccc12fSBjoern A. Zeeb 	}
259*a0ccc12fSBjoern A. Zeeb }
260*a0ccc12fSBjoern A. Zeeb 
261*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal,
262*a0ccc12fSBjoern A. Zeeb 				      bool *tx0iqkok,
263*a0ccc12fSBjoern A. Zeeb 				      int tx_x0[CAL_NUM_8821A],
264*a0ccc12fSBjoern A. Zeeb 				      int tx_y0[CAL_NUM_8821A])
265*a0ccc12fSBjoern A. Zeeb {
266*a0ccc12fSBjoern A. Zeeb 	u32 cal_retry, delay_count, iqk_ready, tx_fail;
267*a0ccc12fSBjoern A. Zeeb 
268*a0ccc12fSBjoern A. Zeeb 	/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
269*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10);
270*a0ccc12fSBjoern A. Zeeb 	/* RX_Tone_idx[9:0], RxK_Mask[29] */
271*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10);
272*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
273*a0ccc12fSBjoern A. Zeeb 
274*a0ccc12fSBjoern A. Zeeb 	for (cal_retry = 0; cal_retry < 10; cal_retry++) {
275*a0ccc12fSBjoern A. Zeeb 		/* one shot */
276*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
277*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
278*a0ccc12fSBjoern A. Zeeb 
279*a0ccc12fSBjoern A. Zeeb 		mdelay(10);
280*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
281*a0ccc12fSBjoern A. Zeeb 
282*a0ccc12fSBjoern A. Zeeb 		for (delay_count = 0; delay_count < 20; delay_count++) {
283*a0ccc12fSBjoern A. Zeeb 			iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10));
284*a0ccc12fSBjoern A. Zeeb 
285*a0ccc12fSBjoern A. Zeeb 			/* Originally: if (~iqk_ready || delay_count > 20)
286*a0ccc12fSBjoern A. Zeeb 			 * that looks like a typo so make it more explicit
287*a0ccc12fSBjoern A. Zeeb 			 */
288*a0ccc12fSBjoern A. Zeeb 			iqk_ready = true;
289*a0ccc12fSBjoern A. Zeeb 
290*a0ccc12fSBjoern A. Zeeb 			if (iqk_ready)
291*a0ccc12fSBjoern A. Zeeb 				break;
292*a0ccc12fSBjoern A. Zeeb 
293*a0ccc12fSBjoern A. Zeeb 			mdelay(1);
294*a0ccc12fSBjoern A. Zeeb 		}
295*a0ccc12fSBjoern A. Zeeb 
296*a0ccc12fSBjoern A. Zeeb 		if (delay_count < 20) {
297*a0ccc12fSBjoern A. Zeeb 			/* ============TXIQK Check============== */
298*a0ccc12fSBjoern A. Zeeb 			tx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12));
299*a0ccc12fSBjoern A. Zeeb 
300*a0ccc12fSBjoern A. Zeeb 			/* Originally: if (~tx_fail) {
301*a0ccc12fSBjoern A. Zeeb 			 * It looks like a typo, so make it more explicit.
302*a0ccc12fSBjoern A. Zeeb 			 */
303*a0ccc12fSBjoern A. Zeeb 			tx_fail = false;
304*a0ccc12fSBjoern A. Zeeb 
305*a0ccc12fSBjoern A. Zeeb 			if (!tx_fail) {
306*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000);
307*a0ccc12fSBjoern A. Zeeb 				tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
308*a0ccc12fSBjoern A. Zeeb 							     0x07ff0000);
309*a0ccc12fSBjoern A. Zeeb 				tx_x0[cal] <<= 21;
310*a0ccc12fSBjoern A. Zeeb 
311*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
312*a0ccc12fSBjoern A. Zeeb 				tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
313*a0ccc12fSBjoern A. Zeeb 							     0x07ff0000);
314*a0ccc12fSBjoern A. Zeeb 				tx_y0[cal] <<= 21;
315*a0ccc12fSBjoern A. Zeeb 
316*a0ccc12fSBjoern A. Zeeb 				*tx0iqkok = true;
317*a0ccc12fSBjoern A. Zeeb 				break;
318*a0ccc12fSBjoern A. Zeeb 			}
319*a0ccc12fSBjoern A. Zeeb 
320*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0);
321*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200);
322*a0ccc12fSBjoern A. Zeeb 		}
323*a0ccc12fSBjoern A. Zeeb 
324*a0ccc12fSBjoern A. Zeeb 		*tx0iqkok = false;
325*a0ccc12fSBjoern A. Zeeb 	}
326*a0ccc12fSBjoern A. Zeeb }
327*a0ccc12fSBjoern A. Zeeb 
328*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok,
329*a0ccc12fSBjoern A. Zeeb 			    int rx_x0[CAL_NUM_8821A],
330*a0ccc12fSBjoern A. Zeeb 			    int rx_y0[CAL_NUM_8821A])
331*a0ccc12fSBjoern A. Zeeb {
332*a0ccc12fSBjoern A. Zeeb 	u32 cal_retry, delay_count, iqk_ready, rx_fail;
333*a0ccc12fSBjoern A. Zeeb 
334*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
335*a0ccc12fSBjoern A. Zeeb 
336*a0ccc12fSBjoern A. Zeeb 	for (cal_retry = 0; cal_retry < 10; cal_retry++) {
337*a0ccc12fSBjoern A. Zeeb 		/* one shot */
338*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
339*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
340*a0ccc12fSBjoern A. Zeeb 
341*a0ccc12fSBjoern A. Zeeb 		mdelay(10);
342*a0ccc12fSBjoern A. Zeeb 
343*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
344*a0ccc12fSBjoern A. Zeeb 
345*a0ccc12fSBjoern A. Zeeb 		for (delay_count = 0; delay_count < 20; delay_count++) {
346*a0ccc12fSBjoern A. Zeeb 			iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10));
347*a0ccc12fSBjoern A. Zeeb 
348*a0ccc12fSBjoern A. Zeeb 			/* Originally: if (~iqk_ready || delay_count > 20)
349*a0ccc12fSBjoern A. Zeeb 			 * that looks like a typo so make it more explicit
350*a0ccc12fSBjoern A. Zeeb 			 */
351*a0ccc12fSBjoern A. Zeeb 			iqk_ready = true;
352*a0ccc12fSBjoern A. Zeeb 
353*a0ccc12fSBjoern A. Zeeb 			if (iqk_ready)
354*a0ccc12fSBjoern A. Zeeb 				break;
355*a0ccc12fSBjoern A. Zeeb 
356*a0ccc12fSBjoern A. Zeeb 			mdelay(1);
357*a0ccc12fSBjoern A. Zeeb 		}
358*a0ccc12fSBjoern A. Zeeb 
359*a0ccc12fSBjoern A. Zeeb 		if (delay_count < 20) {
360*a0ccc12fSBjoern A. Zeeb 			/* ============RXIQK Check============== */
361*a0ccc12fSBjoern A. Zeeb 			rx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11));
362*a0ccc12fSBjoern A. Zeeb 			if (!rx_fail) {
363*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);
364*a0ccc12fSBjoern A. Zeeb 				rx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
365*a0ccc12fSBjoern A. Zeeb 							     0x07ff0000);
366*a0ccc12fSBjoern A. Zeeb 				rx_x0[cal] <<= 21;
367*a0ccc12fSBjoern A. Zeeb 
368*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
369*a0ccc12fSBjoern A. Zeeb 				rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END,
370*a0ccc12fSBjoern A. Zeeb 							     0x07ff0000);
371*a0ccc12fSBjoern A. Zeeb 				rx_y0[cal] <<= 21;
372*a0ccc12fSBjoern A. Zeeb 
373*a0ccc12fSBjoern A. Zeeb 				*rx0iqkok = true;
374*a0ccc12fSBjoern A. Zeeb 				break;
375*a0ccc12fSBjoern A. Zeeb 			}
376*a0ccc12fSBjoern A. Zeeb 
377*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
378*a0ccc12fSBjoern A. Zeeb 					 0x000003ff, 0x200 >> 1);
379*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
380*a0ccc12fSBjoern A. Zeeb 					 0x03ff0000, 0x0 >> 1);
381*a0ccc12fSBjoern A. Zeeb 		}
382*a0ccc12fSBjoern A. Zeeb 
383*a0ccc12fSBjoern A. Zeeb 		*rx0iqkok = false;
384*a0ccc12fSBjoern A. Zeeb 	}
385*a0ccc12fSBjoern A. Zeeb }
386*a0ccc12fSBjoern A. Zeeb 
387*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk(struct rtw_dev *rtwdev)
388*a0ccc12fSBjoern A. Zeeb {
389*a0ccc12fSBjoern A. Zeeb 	int tx_average = 0, rx_average = 0, rx_iqk_loop = 0;
390*a0ccc12fSBjoern A. Zeeb 	const struct rtw_efuse *efuse = &rtwdev->efuse;
391*a0ccc12fSBjoern A. Zeeb 	int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0;
392*a0ccc12fSBjoern A. Zeeb 	const struct rtw_hal *hal = &rtwdev->hal;
393*a0ccc12fSBjoern A. Zeeb 	bool tx0iqkok = false, rx0iqkok = false;
394*a0ccc12fSBjoern A. Zeeb 	int rx_x_temp = 0, rx_y_temp = 0;
395*a0ccc12fSBjoern A. Zeeb 	int rx_x0[2][CAL_NUM_8821A];
396*a0ccc12fSBjoern A. Zeeb 	int rx_y0[2][CAL_NUM_8821A];
397*a0ccc12fSBjoern A. Zeeb 	int tx_x0[CAL_NUM_8821A];
398*a0ccc12fSBjoern A. Zeeb 	int tx_y0[CAL_NUM_8821A];
399*a0ccc12fSBjoern A. Zeeb 	bool rx_finish1 = false;
400*a0ccc12fSBjoern A. Zeeb 	bool rx_finish2 = false;
401*a0ccc12fSBjoern A. Zeeb 	bool vdf_enable;
402*a0ccc12fSBjoern A. Zeeb 	u32 cal;
403*a0ccc12fSBjoern A. Zeeb 	int i;
404*a0ccc12fSBjoern A. Zeeb 
405*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK,
406*a0ccc12fSBjoern A. Zeeb 		"band_width = %d, ext_pa = %d, ext_pa_5g = %d\n",
407*a0ccc12fSBjoern A. Zeeb 		hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g);
408*a0ccc12fSBjoern A. Zeeb 
409*a0ccc12fSBjoern A. Zeeb 	vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80;
410*a0ccc12fSBjoern A. Zeeb 
411*a0ccc12fSBjoern A. Zeeb 	for (cal = 0; cal < CAL_NUM_8821A; cal++) {
412*a0ccc12fSBjoern A. Zeeb 		/* path-A LOK */
413*a0ccc12fSBjoern A. Zeeb 
414*a0ccc12fSBjoern A. Zeeb 		/* [31] = 0 --> Page C */
415*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
416*a0ccc12fSBjoern A. Zeeb 
417*a0ccc12fSBjoern A. Zeeb 		/* ========path-A AFE all on======== */
418*a0ccc12fSBjoern A. Zeeb 		/* Port 0 DAC/ADC on */
419*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777);
420*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777);
421*a0ccc12fSBjoern A. Zeeb 
422*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979);
423*a0ccc12fSBjoern A. Zeeb 
424*a0ccc12fSBjoern A. Zeeb 		/* hardware 3-wire off */
425*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4);
426*a0ccc12fSBjoern A. Zeeb 
427*a0ccc12fSBjoern A. Zeeb 		/* LOK setting */
428*a0ccc12fSBjoern A. Zeeb 
429*a0ccc12fSBjoern A. Zeeb 		/* 1. DAC/ADC sampling rate (160 MHz) */
430*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7);
431*a0ccc12fSBjoern A. Zeeb 
432*a0ccc12fSBjoern A. Zeeb 		/* 2. LoK RF setting (at BW = 20M) */
433*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002);
434*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x00c00, 0x3);
435*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
436*a0ccc12fSBjoern A. Zeeb 			     0x20000);
437*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
438*a0ccc12fSBjoern A. Zeeb 			     0x0003f);
439*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
440*a0ccc12fSBjoern A. Zeeb 			     0xf3fc3);
441*a0ccc12fSBjoern A. Zeeb 
442*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK,
443*a0ccc12fSBjoern A. Zeeb 			     0x931d5);
444*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001);
445*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
446*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1);
447*a0ccc12fSBjoern A. Zeeb 		/* TX (X,Y) */
448*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000);
449*a0ccc12fSBjoern A. Zeeb 		/* RX (X,Y) */
450*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000);
451*a0ccc12fSBjoern A. Zeeb 		/* [0]:AGC_en, [15]:idac_K_Mask */
452*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910);
453*a0ccc12fSBjoern A. Zeeb 
454*a0ccc12fSBjoern A. Zeeb 		/* [31] = 1 --> Page C1 */
455*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
456*a0ccc12fSBjoern A. Zeeb 
457*a0ccc12fSBjoern A. Zeeb 		if (efuse->ext_pa_5g)
458*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
459*a0ccc12fSBjoern A. Zeeb 				    0x821403f7);
460*a0ccc12fSBjoern A. Zeeb 		else
461*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
462*a0ccc12fSBjoern A. Zeeb 				    0x821403f4);
463*a0ccc12fSBjoern A. Zeeb 
464*a0ccc12fSBjoern A. Zeeb 		if (hal->current_band_type == RTW_BAND_5G)
465*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96);
466*a0ccc12fSBjoern A. Zeeb 		else
467*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96);
468*a0ccc12fSBjoern A. Zeeb 
469*a0ccc12fSBjoern A. Zeeb 		/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
470*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10);
471*a0ccc12fSBjoern A. Zeeb 		/* RX_Tone_idx[9:0], RxK_Mask[29] */
472*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10);
473*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
474*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
475*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
476*a0ccc12fSBjoern A. Zeeb 
477*a0ccc12fSBjoern A. Zeeb 		mdelay(10);
478*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
479*a0ccc12fSBjoern A. Zeeb 
480*a0ccc12fSBjoern A. Zeeb 		/* [31] = 0 --> Page C */
481*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
482*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00,
483*a0ccc12fSBjoern A. Zeeb 			     rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00));
484*a0ccc12fSBjoern A. Zeeb 
485*a0ccc12fSBjoern A. Zeeb 		if (hal->current_band_width == RTW_CHANNEL_WIDTH_40)
486*a0ccc12fSBjoern A. Zeeb 			rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH,
487*a0ccc12fSBjoern A. Zeeb 				     RF18_BW_MASK, 0x1);
488*a0ccc12fSBjoern A. Zeeb 		else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80)
489*a0ccc12fSBjoern A. Zeeb 			rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH,
490*a0ccc12fSBjoern A. Zeeb 				     RF18_BW_MASK, 0x0);
491*a0ccc12fSBjoern A. Zeeb 
492*a0ccc12fSBjoern A. Zeeb 		/* [31] = 1 --> Page C1 */
493*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
494*a0ccc12fSBjoern A. Zeeb 
495*a0ccc12fSBjoern A. Zeeb 		/* 3. TX RF setting */
496*a0ccc12fSBjoern A. Zeeb 		/* [31] = 0 --> Page C */
497*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
498*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
499*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
500*a0ccc12fSBjoern A. Zeeb 			     0x20000);
501*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
502*a0ccc12fSBjoern A. Zeeb 			     0x0003f);
503*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
504*a0ccc12fSBjoern A. Zeeb 			     0xf3fc3);
505*a0ccc12fSBjoern A. Zeeb 
506*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);
507*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001);
508*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
509*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
510*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1);
511*a0ccc12fSBjoern A. Zeeb 		/* TX (X,Y) */
512*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000);
513*a0ccc12fSBjoern A. Zeeb 		/* RX (X,Y) */
514*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000);
515*a0ccc12fSBjoern A. Zeeb 		/* [0]:AGC_en, [15]:idac_K_Mask */
516*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a910);
517*a0ccc12fSBjoern A. Zeeb 
518*a0ccc12fSBjoern A. Zeeb 		/* [31] = 1 --> Page C1 */
519*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
520*a0ccc12fSBjoern A. Zeeb 
521*a0ccc12fSBjoern A. Zeeb 		if (efuse->ext_pa_5g)
522*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
523*a0ccc12fSBjoern A. Zeeb 				    0x821403f7);
524*a0ccc12fSBjoern A. Zeeb 		else
525*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
526*a0ccc12fSBjoern A. Zeeb 				    0x821403e3);
527*a0ccc12fSBjoern A. Zeeb 
528*a0ccc12fSBjoern A. Zeeb 		if (hal->current_band_type == RTW_BAND_5G)
529*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96);
530*a0ccc12fSBjoern A. Zeeb 		else
531*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96);
532*a0ccc12fSBjoern A. Zeeb 
533*a0ccc12fSBjoern A. Zeeb 		if (vdf_enable)
534*a0ccc12fSBjoern A. Zeeb 			rtw8821a_iqk_tx_vdf_true(rtwdev, cal, &tx0iqkok,
535*a0ccc12fSBjoern A. Zeeb 						 tx_x0, tx_y0);
536*a0ccc12fSBjoern A. Zeeb 		else
537*a0ccc12fSBjoern A. Zeeb 			rtw8821a_iqk_tx_vdf_false(rtwdev, cal, &tx0iqkok,
538*a0ccc12fSBjoern A. Zeeb 						  tx_x0, tx_y0);
539*a0ccc12fSBjoern A. Zeeb 
540*a0ccc12fSBjoern A. Zeeb 		if (!tx0iqkok)
541*a0ccc12fSBjoern A. Zeeb 			break; /* TXK fail, Don't do RXK */
542*a0ccc12fSBjoern A. Zeeb 
543*a0ccc12fSBjoern A. Zeeb 		/* ====== RX IQK ====== */
544*a0ccc12fSBjoern A. Zeeb 		/* [31] = 0 --> Page C */
545*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
546*a0ccc12fSBjoern A. Zeeb 		/* 1. RX RF setting */
547*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
548*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
549*a0ccc12fSBjoern A. Zeeb 			     0x30000);
550*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
551*a0ccc12fSBjoern A. Zeeb 			     0x0002f);
552*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
553*a0ccc12fSBjoern A. Zeeb 			     0xfffbb);
554*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001);
555*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d8);
556*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
557*a0ccc12fSBjoern A. Zeeb 
558*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,
559*a0ccc12fSBjoern A. Zeeb 				 (tx_x0[cal] >> 21) & 0x000007ff);
560*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,
561*a0ccc12fSBjoern A. Zeeb 				 (tx_y0[cal] >> 21) & 0x000007ff);
562*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1);
563*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0);
564*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
565*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911);
566*a0ccc12fSBjoern A. Zeeb 
567*a0ccc12fSBjoern A. Zeeb 		/* [31] = 1 --> Page C1 */
568*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
569*a0ccc12fSBjoern A. Zeeb 
570*a0ccc12fSBjoern A. Zeeb 		/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
571*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10);
572*a0ccc12fSBjoern A. Zeeb 		/* RX_Tone_idx[9:0], RxK_Mask[29] */
573*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10);
574*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x02140119);
575*a0ccc12fSBjoern A. Zeeb 
576*a0ccc12fSBjoern A. Zeeb 		if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
577*a0ccc12fSBjoern A. Zeeb 			rx_iqk_loop = 2; /* for 2% fail; */
578*a0ccc12fSBjoern A. Zeeb 		else
579*a0ccc12fSBjoern A. Zeeb 			rx_iqk_loop = 1;
580*a0ccc12fSBjoern A. Zeeb 
581*a0ccc12fSBjoern A. Zeeb 		for (i = 0; i < rx_iqk_loop; i++) {
582*a0ccc12fSBjoern A. Zeeb 			if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && i == 0)
583*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */
584*a0ccc12fSBjoern A. Zeeb 			else
585*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00);
586*a0ccc12fSBjoern A. Zeeb 
587*a0ccc12fSBjoern A. Zeeb 			rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok,
588*a0ccc12fSBjoern A. Zeeb 					rx_x0[i], rx_y0[i]);
589*a0ccc12fSBjoern A. Zeeb 		}
590*a0ccc12fSBjoern A. Zeeb 
591*a0ccc12fSBjoern A. Zeeb 		if (tx0iqkok)
592*a0ccc12fSBjoern A. Zeeb 			tx_average++;
593*a0ccc12fSBjoern A. Zeeb 		if (rx0iqkok)
594*a0ccc12fSBjoern A. Zeeb 			rx_average++;
595*a0ccc12fSBjoern A. Zeeb 	}
596*a0ccc12fSBjoern A. Zeeb 
597*a0ccc12fSBjoern A. Zeeb 	/* FillIQK Result */
598*a0ccc12fSBjoern A. Zeeb 
599*a0ccc12fSBjoern A. Zeeb 	if (tx_average == 0)
600*a0ccc12fSBjoern A. Zeeb 		return;
601*a0ccc12fSBjoern A. Zeeb 
602*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < tx_average; i++)
603*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
604*a0ccc12fSBjoern A. Zeeb 			"tx_x0[%d] = %x ;; tx_y0[%d] = %x\n",
605*a0ccc12fSBjoern A. Zeeb 			i, (tx_x0[i] >> 21) & 0x000007ff,
606*a0ccc12fSBjoern A. Zeeb 			i, (tx_y0[i] >> 21) & 0x000007ff);
607*a0ccc12fSBjoern A. Zeeb 
608*a0ccc12fSBjoern A. Zeeb 	if (rtw88xxa_iqk_finish(tx_average, 3, tx_x0, tx_y0,
609*a0ccc12fSBjoern A. Zeeb 				&tx_x, &tx_y, true, true))
610*a0ccc12fSBjoern A. Zeeb 		rtw8821a_iqk_tx_fill(rtwdev, tx_x, tx_y);
611*a0ccc12fSBjoern A. Zeeb 	else
612*a0ccc12fSBjoern A. Zeeb 		rtw8821a_iqk_tx_fill(rtwdev, 0x200, 0x0);
613*a0ccc12fSBjoern A. Zeeb 
614*a0ccc12fSBjoern A. Zeeb 	if (rx_average == 0)
615*a0ccc12fSBjoern A. Zeeb 		return;
616*a0ccc12fSBjoern A. Zeeb 
617*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < rx_average; i++) {
618*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
619*a0ccc12fSBjoern A. Zeeb 			"rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n",
620*a0ccc12fSBjoern A. Zeeb 			i, (rx_x0[0][i] >> 21) & 0x000007ff,
621*a0ccc12fSBjoern A. Zeeb 			i, (rx_y0[0][i] >> 21) & 0x000007ff);
622*a0ccc12fSBjoern A. Zeeb 
623*a0ccc12fSBjoern A. Zeeb 		if (rx_iqk_loop == 2)
624*a0ccc12fSBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
625*a0ccc12fSBjoern A. Zeeb 				"rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n",
626*a0ccc12fSBjoern A. Zeeb 				i, (rx_x0[1][i] >> 21) & 0x000007ff,
627*a0ccc12fSBjoern A. Zeeb 				i, (rx_y0[1][i] >> 21) & 0x000007ff);
628*a0ccc12fSBjoern A. Zeeb 	}
629*a0ccc12fSBjoern A. Zeeb 
630*a0ccc12fSBjoern A. Zeeb 	rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0],
631*a0ccc12fSBjoern A. Zeeb 					 &rx_x_temp, &rx_y_temp, true, true);
632*a0ccc12fSBjoern A. Zeeb 
633*a0ccc12fSBjoern A. Zeeb 	if (rx_finish1) {
634*a0ccc12fSBjoern A. Zeeb 		rx_x = rx_x_temp;
635*a0ccc12fSBjoern A. Zeeb 		rx_y = rx_y_temp;
636*a0ccc12fSBjoern A. Zeeb 	}
637*a0ccc12fSBjoern A. Zeeb 
638*a0ccc12fSBjoern A. Zeeb 	if (rx_iqk_loop == 2) {
639*a0ccc12fSBjoern A. Zeeb 		rx_finish2 = rtw88xxa_iqk_finish(rx_average, 4,
640*a0ccc12fSBjoern A. Zeeb 						 rx_x0[1], rx_y0[1],
641*a0ccc12fSBjoern A. Zeeb 						 &rx_x, &rx_y, true, true);
642*a0ccc12fSBjoern A. Zeeb 
643*a0ccc12fSBjoern A. Zeeb 		if (rx_finish1 && rx_finish2) {
644*a0ccc12fSBjoern A. Zeeb 			rx_x = (rx_x + rx_x_temp) / 2;
645*a0ccc12fSBjoern A. Zeeb 			rx_y = (rx_y + rx_y_temp) / 2;
646*a0ccc12fSBjoern A. Zeeb 		}
647*a0ccc12fSBjoern A. Zeeb 	}
648*a0ccc12fSBjoern A. Zeeb 
649*a0ccc12fSBjoern A. Zeeb 	if (rx_finish1 || rx_finish2)
650*a0ccc12fSBjoern A. Zeeb 		rtw8821a_iqk_rx_fill(rtwdev, rx_x, rx_y);
651*a0ccc12fSBjoern A. Zeeb 	else
652*a0ccc12fSBjoern A. Zeeb 		rtw8821a_iqk_rx_fill(rtwdev, 0x200, 0x0);
653*a0ccc12fSBjoern A. Zeeb }
654*a0ccc12fSBjoern A. Zeeb 
655*a0ccc12fSBjoern A. Zeeb static void rtw8821a_do_iqk(struct rtw_dev *rtwdev)
656*a0ccc12fSBjoern A. Zeeb {
657*a0ccc12fSBjoern A. Zeeb 	static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = {
658*a0ccc12fSBjoern A. Zeeb 		0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c
659*a0ccc12fSBjoern A. Zeeb 	};
660*a0ccc12fSBjoern A. Zeeb 	static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = {
661*a0ccc12fSBjoern A. Zeeb 		0xc5c, 0xc60, 0xc64, 0xc68
662*a0ccc12fSBjoern A. Zeeb 	};
663*a0ccc12fSBjoern A. Zeeb 	static const u32 backup_rf_reg[RF_REG_NUM_8821A] = {
664*a0ccc12fSBjoern A. Zeeb 		0x65, 0x8f, 0x0
665*a0ccc12fSBjoern A. Zeeb 	};
666*a0ccc12fSBjoern A. Zeeb 	u32 macbb_backup[MACBB_REG_NUM_8821A];
667*a0ccc12fSBjoern A. Zeeb 	u32 afe_backup[AFE_REG_NUM_8821A];
668*a0ccc12fSBjoern A. Zeeb 	u32 rfa_backup[RF_REG_NUM_8821A];
669*a0ccc12fSBjoern A. Zeeb 
670*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup,
671*a0ccc12fSBjoern A. Zeeb 				   backup_macbb_reg, MACBB_REG_NUM_8821A);
672*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_backup_afe(rtwdev, afe_backup,
673*a0ccc12fSBjoern A. Zeeb 				backup_afe_reg, AFE_REG_NUM_8821A);
674*a0ccc12fSBjoern A. Zeeb 	rtw8821a_iqk_backup_rf(rtwdev, rfa_backup,
675*a0ccc12fSBjoern A. Zeeb 			       backup_rf_reg, RF_REG_NUM_8821A);
676*a0ccc12fSBjoern A. Zeeb 
677*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_configure_mac(rtwdev);
678*a0ccc12fSBjoern A. Zeeb 
679*a0ccc12fSBjoern A. Zeeb 	rtw8821a_iqk(rtwdev);
680*a0ccc12fSBjoern A. Zeeb 
681*a0ccc12fSBjoern A. Zeeb 	rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg,
682*a0ccc12fSBjoern A. Zeeb 				rfa_backup, RF_REG_NUM_8821A);
683*a0ccc12fSBjoern A. Zeeb 	rtw8821a_iqk_restore_afe(rtwdev, afe_backup,
684*a0ccc12fSBjoern A. Zeeb 				 backup_afe_reg, AFE_REG_NUM_8821A);
685*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup,
686*a0ccc12fSBjoern A. Zeeb 				    backup_macbb_reg, MACBB_REG_NUM_8821A);
687*a0ccc12fSBjoern A. Zeeb }
688*a0ccc12fSBjoern A. Zeeb 
689*a0ccc12fSBjoern A. Zeeb static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev)
690*a0ccc12fSBjoern A. Zeeb {
691*a0ccc12fSBjoern A. Zeeb 	rtw8821a_do_iqk(rtwdev);
692*a0ccc12fSBjoern A. Zeeb }
693*a0ccc12fSBjoern A. Zeeb 
694*a0ccc12fSBjoern A. Zeeb static void rtw8821a_pwr_track(struct rtw_dev *rtwdev)
695*a0ccc12fSBjoern A. Zeeb {
696*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
697*a0ccc12fSBjoern A. Zeeb 
698*a0ccc12fSBjoern A. Zeeb 	if (!dm_info->pwr_trk_triggered) {
699*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
700*a0ccc12fSBjoern A. Zeeb 			     GENMASK(17, 16), 0x03);
701*a0ccc12fSBjoern A. Zeeb 		dm_info->pwr_trk_triggered = true;
702*a0ccc12fSBjoern A. Zeeb 		return;
703*a0ccc12fSBjoern A. Zeeb 	}
704*a0ccc12fSBjoern A. Zeeb 
705*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk);
706*a0ccc12fSBjoern A. Zeeb 	dm_info->pwr_trk_triggered = false;
707*a0ccc12fSBjoern A. Zeeb }
708*a0ccc12fSBjoern A. Zeeb 
709*a0ccc12fSBjoern A. Zeeb static void rtw8821a_led_set(struct led_classdev *led,
710*a0ccc12fSBjoern A. Zeeb 			     enum led_brightness brightness)
711*a0ccc12fSBjoern A. Zeeb {
712*a0ccc12fSBjoern A. Zeeb 	struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
713*a0ccc12fSBjoern A. Zeeb 	u32 gpio8_cfg;
714*a0ccc12fSBjoern A. Zeeb 	u8 ledcfg;
715*a0ccc12fSBjoern A. Zeeb 
716*a0ccc12fSBjoern A. Zeeb 	if (brightness == LED_OFF) {
717*a0ccc12fSBjoern A. Zeeb 		gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2);
718*a0ccc12fSBjoern A. Zeeb 		gpio8_cfg &= ~BIT(24);
719*a0ccc12fSBjoern A. Zeeb 		gpio8_cfg |= BIT(16) | BIT(8);
720*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg);
721*a0ccc12fSBjoern A. Zeeb 	} else {
722*a0ccc12fSBjoern A. Zeeb 		ledcfg = rtw_read8(rtwdev, REG_LED_CFG + 2);
723*a0ccc12fSBjoern A. Zeeb 		gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2);
724*a0ccc12fSBjoern A. Zeeb 
725*a0ccc12fSBjoern A. Zeeb 		ledcfg &= BIT(7) | BIT(6);
726*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_LED_CFG + 2, ledcfg);
727*a0ccc12fSBjoern A. Zeeb 
728*a0ccc12fSBjoern A. Zeeb 		gpio8_cfg &= ~(BIT(24) | BIT(8));
729*a0ccc12fSBjoern A. Zeeb 		gpio8_cfg |= BIT(16);
730*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg);
731*a0ccc12fSBjoern A. Zeeb 	}
732*a0ccc12fSBjoern A. Zeeb }
733*a0ccc12fSBjoern A. Zeeb 
734*a0ccc12fSBjoern A. Zeeb static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
735*a0ccc12fSBjoern A. Zeeb 					  struct rtw_tx_pkt_info *pkt_info,
736*a0ccc12fSBjoern A. Zeeb 					  u8 *txdesc)
737*a0ccc12fSBjoern A. Zeeb {
738*a0ccc12fSBjoern A. Zeeb 	fill_txdesc_checksum_common(txdesc, 16);
739*a0ccc12fSBjoern A. Zeeb }
740*a0ccc12fSBjoern A. Zeeb 
741*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_init(struct rtw_dev *rtwdev)
742*a0ccc12fSBjoern A. Zeeb {
743*a0ccc12fSBjoern A. Zeeb 	u8 val8;
744*a0ccc12fSBjoern A. Zeeb 
745*a0ccc12fSBjoern A. Zeeb 	/* BT report packet sample rate */
746*a0ccc12fSBjoern A. Zeeb 	rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
747*a0ccc12fSBjoern A. Zeeb 
748*a0ccc12fSBjoern A. Zeeb 	val8 = BIT_STATIS_BT_EN;
749*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->efuse.share_ant)
750*a0ccc12fSBjoern A. Zeeb 		val8 |= BIT_R_GRANTALL_WLMASK;
751*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, val8);
752*a0ccc12fSBjoern A. Zeeb 
753*a0ccc12fSBjoern A. Zeeb 	/* enable BT counter statistics */
754*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x3);
755*a0ccc12fSBjoern A. Zeeb 
756*a0ccc12fSBjoern A. Zeeb 	/* enable PTA */
757*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
758*a0ccc12fSBjoern A. Zeeb }
759*a0ccc12fSBjoern A. Zeeb 
760*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type,
761*a0ccc12fSBjoern A. Zeeb 					 u8 pos_type)
762*a0ccc12fSBjoern A. Zeeb {
763*a0ccc12fSBjoern A. Zeeb 	bool share_ant = rtwdev->efuse.share_ant;
764*a0ccc12fSBjoern A. Zeeb 	struct rtw_coex *coex = &rtwdev->coex;
765*a0ccc12fSBjoern A. Zeeb 	struct rtw_coex_dm *coex_dm = &coex->dm;
766*a0ccc12fSBjoern A. Zeeb 	u32 phase = coex_dm->cur_ant_pos_type;
767*a0ccc12fSBjoern A. Zeeb 
768*a0ccc12fSBjoern A. Zeeb 	if (!rtwdev->efuse.btcoex)
769*a0ccc12fSBjoern A. Zeeb 		return;
770*a0ccc12fSBjoern A. Zeeb 
771*a0ccc12fSBjoern A. Zeeb 	switch (phase) {
772*a0ccc12fSBjoern A. Zeeb 	case COEX_SET_ANT_POWERON:
773*a0ccc12fSBjoern A. Zeeb 	case COEX_SET_ANT_INIT:
774*a0ccc12fSBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
775*a0ccc12fSBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
776*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
777*a0ccc12fSBjoern A. Zeeb 
778*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RFE_CTRL8,
779*a0ccc12fSBjoern A. Zeeb 			   share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN);
780*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1);
781*a0ccc12fSBjoern A. Zeeb 		break;
782*a0ccc12fSBjoern A. Zeeb 	case COEX_SET_ANT_WONLY:
783*a0ccc12fSBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
784*a0ccc12fSBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
785*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
786*a0ccc12fSBjoern A. Zeeb 
787*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN);
788*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1);
789*a0ccc12fSBjoern A. Zeeb 		break;
790*a0ccc12fSBjoern A. Zeeb 	case COEX_SET_ANT_2G:
791*a0ccc12fSBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
792*a0ccc12fSBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
793*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
794*a0ccc12fSBjoern A. Zeeb 
795*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RFE_CTRL8,
796*a0ccc12fSBjoern A. Zeeb 			   share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN);
797*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1);
798*a0ccc12fSBjoern A. Zeeb 		break;
799*a0ccc12fSBjoern A. Zeeb 	case COEX_SET_ANT_5G:
800*a0ccc12fSBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
801*a0ccc12fSBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
802*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
803*a0ccc12fSBjoern A. Zeeb 
804*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN);
805*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000,
806*a0ccc12fSBjoern A. Zeeb 				 share_ant ? 0x2 : 0x1);
807*a0ccc12fSBjoern A. Zeeb 		break;
808*a0ccc12fSBjoern A. Zeeb 	case COEX_SET_ANT_WOFF:
809*a0ccc12fSBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
810*a0ccc12fSBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
811*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL);
812*a0ccc12fSBjoern A. Zeeb 
813*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN);
814*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000,
815*a0ccc12fSBjoern A. Zeeb 				 share_ant ? 0x2 : 0x1);
816*a0ccc12fSBjoern A. Zeeb 		break;
817*a0ccc12fSBjoern A. Zeeb 	default:
818*a0ccc12fSBjoern A. Zeeb 		rtw_warn(rtwdev, "%s: not handling phase %d\n",
819*a0ccc12fSBjoern A. Zeeb 			 __func__, phase);
820*a0ccc12fSBjoern A. Zeeb 		break;
821*a0ccc12fSBjoern A. Zeeb 	}
822*a0ccc12fSBjoern A. Zeeb }
823*a0ccc12fSBjoern A. Zeeb 
824*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
825*a0ccc12fSBjoern A. Zeeb {
826*a0ccc12fSBjoern A. Zeeb }
827*a0ccc12fSBjoern A. Zeeb 
828*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
829*a0ccc12fSBjoern A. Zeeb {
830*a0ccc12fSBjoern A. Zeeb }
831*a0ccc12fSBjoern A. Zeeb 
832*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
833*a0ccc12fSBjoern A. Zeeb {
834*a0ccc12fSBjoern A. Zeeb 	struct rtw_coex *coex = &rtwdev->coex;
835*a0ccc12fSBjoern A. Zeeb 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
836*a0ccc12fSBjoern A. Zeeb 
837*a0ccc12fSBjoern A. Zeeb 	coex_rfe->ant_switch_exist = true;
838*a0ccc12fSBjoern A. Zeeb }
839*a0ccc12fSBjoern A. Zeeb 
840*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
841*a0ccc12fSBjoern A. Zeeb {
842*a0ccc12fSBjoern A. Zeeb 	struct rtw_coex *coex = &rtwdev->coex;
843*a0ccc12fSBjoern A. Zeeb 	struct rtw_coex_dm *coex_dm = &coex->dm;
844*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
845*a0ccc12fSBjoern A. Zeeb 	bool share_ant = efuse->share_ant;
846*a0ccc12fSBjoern A. Zeeb 
847*a0ccc12fSBjoern A. Zeeb 	if (share_ant)
848*a0ccc12fSBjoern A. Zeeb 		return;
849*a0ccc12fSBjoern A. Zeeb 
850*a0ccc12fSBjoern A. Zeeb 	if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
851*a0ccc12fSBjoern A. Zeeb 		return;
852*a0ccc12fSBjoern A. Zeeb 
853*a0ccc12fSBjoern A. Zeeb 	coex_dm->cur_wl_pwr_lvl = wl_pwr;
854*a0ccc12fSBjoern A. Zeeb }
855*a0ccc12fSBjoern A. Zeeb 
856*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
857*a0ccc12fSBjoern A. Zeeb {
858*a0ccc12fSBjoern A. Zeeb }
859*a0ccc12fSBjoern A. Zeeb 
860*a0ccc12fSBjoern A. Zeeb static const struct rtw_chip_ops rtw8821a_ops = {
861*a0ccc12fSBjoern A. Zeeb 	.power_on		= rtw88xxa_power_on,
862*a0ccc12fSBjoern A. Zeeb 	.power_off		= rtw8821a_power_off,
863*a0ccc12fSBjoern A. Zeeb 	.phy_set_param		= NULL,
864*a0ccc12fSBjoern A. Zeeb 	.read_efuse		= rtw88xxa_read_efuse,
865*a0ccc12fSBjoern A. Zeeb 	.query_phy_status	= rtw8821a_query_phy_status,
866*a0ccc12fSBjoern A. Zeeb 	.set_channel		= rtw88xxa_set_channel,
867*a0ccc12fSBjoern A. Zeeb 	.mac_init		= NULL,
868*a0ccc12fSBjoern A. Zeeb 	.read_rf		= rtw88xxa_phy_read_rf,
869*a0ccc12fSBjoern A. Zeeb 	.write_rf		= rtw_phy_write_rf_reg_sipi,
870*a0ccc12fSBjoern A. Zeeb 	.set_antenna		= NULL,
871*a0ccc12fSBjoern A. Zeeb 	.set_tx_power_index	= rtw88xxa_set_tx_power_index,
872*a0ccc12fSBjoern A. Zeeb 	.cfg_ldo25		= rtw8821a_cfg_ldo25,
873*a0ccc12fSBjoern A. Zeeb 	.efuse_grant		= rtw88xxa_efuse_grant,
874*a0ccc12fSBjoern A. Zeeb 	.false_alarm_statistics	= rtw88xxa_false_alarm_statistics,
875*a0ccc12fSBjoern A. Zeeb 	.phy_calibration	= rtw8821a_phy_calibration,
876*a0ccc12fSBjoern A. Zeeb 	.cck_pd_set		= rtw88xxa_phy_cck_pd_set,
877*a0ccc12fSBjoern A. Zeeb 	.pwr_track		= rtw8821a_pwr_track,
878*a0ccc12fSBjoern A. Zeeb 	.config_bfee		= NULL,
879*a0ccc12fSBjoern A. Zeeb 	.set_gid_table		= NULL,
880*a0ccc12fSBjoern A. Zeeb 	.cfg_csi_rate		= NULL,
881*a0ccc12fSBjoern A. Zeeb 	.led_set		= rtw8821a_led_set,
882*a0ccc12fSBjoern A. Zeeb 	.fill_txdesc_checksum	= rtw8821a_fill_txdesc_checksum,
883*a0ccc12fSBjoern A. Zeeb 	.coex_set_init		= rtw8821a_coex_cfg_init,
884*a0ccc12fSBjoern A. Zeeb 	.coex_set_ant_switch	= rtw8821a_coex_cfg_ant_switch,
885*a0ccc12fSBjoern A. Zeeb 	.coex_set_gnt_fix	= rtw8821a_coex_cfg_gnt_fix,
886*a0ccc12fSBjoern A. Zeeb 	.coex_set_gnt_debug	= rtw8821a_coex_cfg_gnt_debug,
887*a0ccc12fSBjoern A. Zeeb 	.coex_set_rfe_type	= rtw8821a_coex_cfg_rfe_type,
888*a0ccc12fSBjoern A. Zeeb 	.coex_set_wl_tx_power	= rtw8821a_coex_cfg_wl_tx_power,
889*a0ccc12fSBjoern A. Zeeb 	.coex_set_wl_rx_gain	= rtw8821a_coex_cfg_wl_rx_gain,
890*a0ccc12fSBjoern A. Zeeb };
891*a0ccc12fSBjoern A. Zeeb 
892*a0ccc12fSBjoern A. Zeeb static const struct rtw_page_table page_table_8821a[] = {
893*a0ccc12fSBjoern A. Zeeb 	/* hq_num, nq_num, lq_num, exq_num, gapq_num */
894*a0ccc12fSBjoern A. Zeeb 	{0, 0, 0, 0, 0},	/* SDIO */
895*a0ccc12fSBjoern A. Zeeb 	{0, 0, 0, 0, 0},	/* PCI */
896*a0ccc12fSBjoern A. Zeeb 	{8, 0, 0, 0, 1},	/* 2 bulk out endpoints */
897*a0ccc12fSBjoern A. Zeeb 	{8, 0, 8, 0, 1},	/* 3 bulk out endpoints */
898*a0ccc12fSBjoern A. Zeeb 	{8, 0, 8, 4, 1},	/* 4 bulk out endpoints */
899*a0ccc12fSBjoern A. Zeeb };
900*a0ccc12fSBjoern A. Zeeb 
901*a0ccc12fSBjoern A. Zeeb static const struct rtw_rqpn rqpn_table_8821a[] = {
902*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
903*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
904*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
905*a0ccc12fSBjoern A. Zeeb 
906*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
907*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
908*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
909*a0ccc12fSBjoern A. Zeeb 
910*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH,
911*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
912*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
913*a0ccc12fSBjoern A. Zeeb 
914*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL,
915*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
916*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
917*a0ccc12fSBjoern A. Zeeb 
918*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
919*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
920*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
921*a0ccc12fSBjoern A. Zeeb };
922*a0ccc12fSBjoern A. Zeeb 
923*a0ccc12fSBjoern A. Zeeb static const struct rtw_prioq_addrs prioq_addrs_8821a = {
924*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_EXTRA] = {
925*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
926*a0ccc12fSBjoern A. Zeeb 	},
927*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_LOW] = {
928*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
929*a0ccc12fSBjoern A. Zeeb 	},
930*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_NORMAL] = {
931*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
932*a0ccc12fSBjoern A. Zeeb 	},
933*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_HIGH] = {
934*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
935*a0ccc12fSBjoern A. Zeeb 	},
936*a0ccc12fSBjoern A. Zeeb 	.wsize = false,
937*a0ccc12fSBjoern A. Zeeb };
938*a0ccc12fSBjoern A. Zeeb 
939*a0ccc12fSBjoern A. Zeeb static const struct rtw_hw_reg rtw8821a_dig[] = {
940*a0ccc12fSBjoern A. Zeeb 	[0] = { .addr = REG_RXIGI_A, .mask = 0x7f },
941*a0ccc12fSBjoern A. Zeeb };
942*a0ccc12fSBjoern A. Zeeb 
943*a0ccc12fSBjoern A. Zeeb static const struct rtw_rfe_def rtw8821a_rfe_defs[] = {
944*a0ccc12fSBjoern A. Zeeb 	[0] = { .phy_pg_tbl	= &rtw8821a_bb_pg_tbl,
945*a0ccc12fSBjoern A. Zeeb 		.txpwr_lmt_tbl	= &rtw8821a_txpwr_lmt_tbl,
946*a0ccc12fSBjoern A. Zeeb 		.pwr_track_tbl	= &rtw8821a_rtw_pwr_track_tbl, },
947*a0ccc12fSBjoern A. Zeeb };
948*a0ccc12fSBjoern A. Zeeb 
949*a0ccc12fSBjoern A. Zeeb /* TODO */
950*a0ccc12fSBjoern A. Zeeb /* rssi in percentage % (dbm = % - 100) */
951*a0ccc12fSBjoern A. Zeeb static const u8 wl_rssi_step_8821a[] = {101, 45, 101, 40};
952*a0ccc12fSBjoern A. Zeeb static const u8 bt_rssi_step_8821a[] = {101, 101, 101, 101};
953*a0ccc12fSBjoern A. Zeeb 
954*a0ccc12fSBjoern A. Zeeb /* table_sant_8821a, table_nsant_8821a, tdma_sant_8821a, and tdma_nsant_8821a
955*a0ccc12fSBjoern A. Zeeb  * are copied from rtw8821c.c because the 8821au driver's tables are not
956*a0ccc12fSBjoern A. Zeeb  * compatible with the coex code in rtw88.
957*a0ccc12fSBjoern A. Zeeb  *
958*a0ccc12fSBjoern A. Zeeb  * tdma case 112 (A2DP) byte 0 had to be modified from 0x61 to 0x51,
959*a0ccc12fSBjoern A. Zeeb  * otherwise the firmware gets confused after pausing the music:
960*a0ccc12fSBjoern A. Zeeb  * rtw_8821au 1-2:1.2: [BTCoex], Bt_info[1], len=7, data=[81 00 0a 01 00 00]
961*a0ccc12fSBjoern A. Zeeb  * - 81 means PAN (personal area network) when it should be 4x (A2DP)
962*a0ccc12fSBjoern A. Zeeb  * The music is not smooth with the PAN algorithm.
963*a0ccc12fSBjoern A. Zeeb  */
964*a0ccc12fSBjoern A. Zeeb 
965*a0ccc12fSBjoern A. Zeeb /* Shared-Antenna Coex Table */
966*a0ccc12fSBjoern A. Zeeb static const struct coex_table_para table_sant_8821a[] = {
967*a0ccc12fSBjoern A. Zeeb 	{0x55555555, 0x55555555}, /* case-0 */
968*a0ccc12fSBjoern A. Zeeb 	{0x55555555, 0x55555555},
969*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x66555555},
970*a0ccc12fSBjoern A. Zeeb 	{0xaaaaaaaa, 0xaaaaaaaa},
971*a0ccc12fSBjoern A. Zeeb 	{0x5a5a5a5a, 0x5a5a5a5a},
972*a0ccc12fSBjoern A. Zeeb 	{0xfafafafa, 0xfafafafa}, /* case-5 */
973*a0ccc12fSBjoern A. Zeeb 	{0x6a5a5555, 0xaaaaaaaa},
974*a0ccc12fSBjoern A. Zeeb 	{0x6a5a56aa, 0x6a5a56aa},
975*a0ccc12fSBjoern A. Zeeb 	{0x6a5a5a5a, 0x6a5a5a5a},
976*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x5a5a5a5a},
977*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x6a5a5a5a}, /* case-10 */
978*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0xaaaaaaaa},
979*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x6a5a5aaa},
980*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x6aaa6aaa},
981*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x6a5a5aaa},
982*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0xaaaaaaaa}, /* case-15 */
983*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0xfafafafa},
984*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0x6afa5afa},
985*a0ccc12fSBjoern A. Zeeb 	{0xaaffffaa, 0xfafafafa},
986*a0ccc12fSBjoern A. Zeeb 	{0xaa5555aa, 0x5a5a5a5a},
987*a0ccc12fSBjoern A. Zeeb 	{0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
988*a0ccc12fSBjoern A. Zeeb 	{0xaa5555aa, 0xaaaaaaaa},
989*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0x55555555},
990*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0x5a5a5a5a},
991*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0x5a5a5a5a},
992*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0x5a5a5aaa}, /* case-25 */
993*a0ccc12fSBjoern A. Zeeb 	{0x55555555, 0x5a5a5a5a},
994*a0ccc12fSBjoern A. Zeeb 	{0x55555555, 0xaaaaaaaa},
995*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x6a5a6a5a},
996*a0ccc12fSBjoern A. Zeeb 	{0x66556655, 0x66556655},
997*a0ccc12fSBjoern A. Zeeb 	{0x66556aaa, 0x6a5a6aaa}, /* case-30 */
998*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0x5aaa5aaa},
999*a0ccc12fSBjoern A. Zeeb 	{0x56555555, 0x5a5a5aaa}
1000*a0ccc12fSBjoern A. Zeeb };
1001*a0ccc12fSBjoern A. Zeeb 
1002*a0ccc12fSBjoern A. Zeeb /* Non-Shared-Antenna Coex Table */
1003*a0ccc12fSBjoern A. Zeeb static const struct coex_table_para table_nsant_8821a[] = {
1004*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0xffffffff}, /* case-100 */
1005*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0xfafafafa},
1006*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x66555555},
1007*a0ccc12fSBjoern A. Zeeb 	{0xaaaaaaaa, 0xaaaaaaaa},
1008*a0ccc12fSBjoern A. Zeeb 	{0x5a5a5a5a, 0x5a5a5a5a},
1009*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0xffffffff}, /* case-105 */
1010*a0ccc12fSBjoern A. Zeeb 	{0x5afa5afa, 0x5afa5afa},
1011*a0ccc12fSBjoern A. Zeeb 	{0x55555555, 0xfafafafa},
1012*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0xfafafafa},
1013*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x5a5a5a5a},
1014*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0x6a5a5a5a}, /* case-110 */
1015*a0ccc12fSBjoern A. Zeeb 	{0x66555555, 0xaaaaaaaa},
1016*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0xfafafafa},
1017*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0x5afa5afa},
1018*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0xaaaaaaaa},
1019*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0xffff55ff}, /* case-115 */
1020*a0ccc12fSBjoern A. Zeeb 	{0xaaffffaa, 0x5afa5afa},
1021*a0ccc12fSBjoern A. Zeeb 	{0xaaffffaa, 0xaaaaaaaa},
1022*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0xfafafafa},
1023*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0xfafafafa},
1024*a0ccc12fSBjoern A. Zeeb 	{0xffffffff, 0xaaaaaaaa}, /* case-120 */
1025*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0x5afa5afa},
1026*a0ccc12fSBjoern A. Zeeb 	{0xffff55ff, 0x5afa5afa},
1027*a0ccc12fSBjoern A. Zeeb 	{0x55ff55ff, 0x55ff55ff}
1028*a0ccc12fSBjoern A. Zeeb };
1029*a0ccc12fSBjoern A. Zeeb 
1030*a0ccc12fSBjoern A. Zeeb /* Shared-Antenna TDMA */
1031*a0ccc12fSBjoern A. Zeeb static const struct coex_tdma_para tdma_sant_8821a[] = {
1032*a0ccc12fSBjoern A. Zeeb 	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
1033*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */
1034*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
1035*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x35, 0x03, 0x11, 0x11} },
1036*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
1037*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */
1038*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
1039*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x35, 0x03, 0x11, 0x10} },
1040*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
1041*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
1042*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
1043*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x11, 0x15} },
1044*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
1045*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
1046*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
1047*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
1048*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
1049*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x3a, 0x03, 0x11, 0x50} },
1050*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
1051*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x21, 0x03, 0x10, 0x50} },
1052*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
1053*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x4a, 0x03, 0x10, 0x50} },
1054*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x30, 0x54} },
1055*a0ccc12fSBjoern A. Zeeb 	{ {0x55, 0x08, 0x03, 0x10, 0x54} },
1056*a0ccc12fSBjoern A. Zeeb 	{ {0x65, 0x10, 0x03, 0x11, 0x10} },
1057*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
1058*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x21, 0x03, 0x10, 0x50} },
1059*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x08, 0x03, 0x11, 0x11} }
1060*a0ccc12fSBjoern A. Zeeb };
1061*a0ccc12fSBjoern A. Zeeb 
1062*a0ccc12fSBjoern A. Zeeb /* Non-Shared-Antenna TDMA */
1063*a0ccc12fSBjoern A. Zeeb static const struct coex_tdma_para tdma_nsant_8821a[] = {
1064*a0ccc12fSBjoern A. Zeeb 	{ {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */
1065*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x11} },
1066*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x25, 0x03, 0x11, 0x11} },
1067*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x35, 0x03, 0x11, 0x11} },
1068*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
1069*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
1070*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
1071*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
1072*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
1073*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
1074*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
1075*a0ccc12fSBjoern A. Zeeb 	{ {0x61, 0x10, 0x03, 0x11, 0x11} },
1076*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x14} }, /* a2dp high rssi */
1077*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x54} }, /* a2dp not high rssi */
1078*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
1079*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
1080*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
1081*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
1082*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
1083*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x21, 0x03, 0x10, 0x50} },
1084*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */
1085*a0ccc12fSBjoern A. Zeeb 	{ {0x51, 0x10, 0x03, 0x10, 0x50} }
1086*a0ccc12fSBjoern A. Zeeb };
1087*a0ccc12fSBjoern A. Zeeb 
1088*a0ccc12fSBjoern A. Zeeb /* TODO */
1089*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_tx_8821a[] = {
1090*a0ccc12fSBjoern A. Zeeb 	{0, 0, false, 7},  /* for normal */
1091*a0ccc12fSBjoern A. Zeeb 	{0, 20, false, 7}, /* for WL-CPT */
1092*a0ccc12fSBjoern A. Zeeb 	{8, 17, true, 4},
1093*a0ccc12fSBjoern A. Zeeb 	{7, 18, true, 4},
1094*a0ccc12fSBjoern A. Zeeb 	{6, 19, true, 4},
1095*a0ccc12fSBjoern A. Zeeb 	{5, 20, true, 4}
1096*a0ccc12fSBjoern A. Zeeb };
1097*a0ccc12fSBjoern A. Zeeb 
1098*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_rx_8821a[] = {
1099*a0ccc12fSBjoern A. Zeeb 	{0, 0, false, 7},  /* for normal */
1100*a0ccc12fSBjoern A. Zeeb 	{0, 20, false, 7}, /* for WL-CPT */
1101*a0ccc12fSBjoern A. Zeeb 	{3, 24, true, 5},
1102*a0ccc12fSBjoern A. Zeeb 	{2, 26, true, 5},
1103*a0ccc12fSBjoern A. Zeeb 	{1, 27, true, 5},
1104*a0ccc12fSBjoern A. Zeeb 	{0, 28, true, 5}
1105*a0ccc12fSBjoern A. Zeeb };
1106*a0ccc12fSBjoern A. Zeeb 
1107*a0ccc12fSBjoern A. Zeeb static_assert(ARRAY_SIZE(rf_para_tx_8821a) == ARRAY_SIZE(rf_para_rx_8821a));
1108*a0ccc12fSBjoern A. Zeeb 
1109*a0ccc12fSBjoern A. Zeeb static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} };
1110*a0ccc12fSBjoern A. Zeeb 
1111*a0ccc12fSBjoern A. Zeeb static const struct rtw_reg_domain coex_info_hw_regs_8821a[] = {
1112*a0ccc12fSBjoern A. Zeeb 	{0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1113*a0ccc12fSBjoern A. Zeeb 	{0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1114*a0ccc12fSBjoern A. Zeeb 	{0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1115*a0ccc12fSBjoern A. Zeeb 	{0, 0, RTW_REG_DOMAIN_NL},
1116*a0ccc12fSBjoern A. Zeeb 	{0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1117*a0ccc12fSBjoern A. Zeeb 	{0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1118*a0ccc12fSBjoern A. Zeeb 	{0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
1119*a0ccc12fSBjoern A. Zeeb 	{0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1120*a0ccc12fSBjoern A. Zeeb 	{0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
1121*a0ccc12fSBjoern A. Zeeb 	{0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
1122*a0ccc12fSBjoern A. Zeeb 	{0, 0, RTW_REG_DOMAIN_NL},
1123*a0ccc12fSBjoern A. Zeeb 	{0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
1124*a0ccc12fSBjoern A. Zeeb 	{0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
1125*a0ccc12fSBjoern A. Zeeb 	{0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
1126*a0ccc12fSBjoern A. Zeeb 	{0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
1127*a0ccc12fSBjoern A. Zeeb 	{0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A},
1128*a0ccc12fSBjoern A. Zeeb 	{0, 0, RTW_REG_DOMAIN_NL},
1129*a0ccc12fSBjoern A. Zeeb 	{0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1130*a0ccc12fSBjoern A. Zeeb 	{0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1131*a0ccc12fSBjoern A. Zeeb 	{0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
1132*a0ccc12fSBjoern A. Zeeb 	{0xc50,  MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1133*a0ccc12fSBjoern A. Zeeb 	{0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1134*a0ccc12fSBjoern A. Zeeb };
1135*a0ccc12fSBjoern A. Zeeb 
1136*a0ccc12fSBjoern A. Zeeb const struct rtw_chip_info rtw8821a_hw_spec = {
1137*a0ccc12fSBjoern A. Zeeb 	.ops = &rtw8821a_ops,
1138*a0ccc12fSBjoern A. Zeeb 	.id = RTW_CHIP_TYPE_8821A,
1139*a0ccc12fSBjoern A. Zeeb 	.fw_name = "rtw88/rtw8821a_fw.bin",
1140*a0ccc12fSBjoern A. Zeeb 	.wlan_cpu = RTW_WCPU_11N,
1141*a0ccc12fSBjoern A. Zeeb 	.tx_pkt_desc_sz = 40,
1142*a0ccc12fSBjoern A. Zeeb 	.tx_buf_desc_sz = 16,
1143*a0ccc12fSBjoern A. Zeeb 	.rx_pkt_desc_sz = 24,
1144*a0ccc12fSBjoern A. Zeeb 	.rx_buf_desc_sz = 8,
1145*a0ccc12fSBjoern A. Zeeb 	.phy_efuse_size = 512,
1146*a0ccc12fSBjoern A. Zeeb 	.log_efuse_size = 512,
1147*a0ccc12fSBjoern A. Zeeb 	.ptct_efuse_size = 0,
1148*a0ccc12fSBjoern A. Zeeb 	.txff_size = 65536,
1149*a0ccc12fSBjoern A. Zeeb 	.rxff_size = 16128,
1150*a0ccc12fSBjoern A. Zeeb 	.rsvd_drv_pg_num = 8,
1151*a0ccc12fSBjoern A. Zeeb 	.txgi_factor = 1,
1152*a0ccc12fSBjoern A. Zeeb 	.is_pwr_by_rate_dec = true,
1153*a0ccc12fSBjoern A. Zeeb 	.max_power_index = 0x3f,
1154*a0ccc12fSBjoern A. Zeeb 	.csi_buf_pg_num = 0,
1155*a0ccc12fSBjoern A. Zeeb 	.band = RTW_BAND_2G | RTW_BAND_5G,
1156*a0ccc12fSBjoern A. Zeeb 	.page_size = 256,
1157*a0ccc12fSBjoern A. Zeeb 	.dig_min = 0x20,
1158*a0ccc12fSBjoern A. Zeeb 	.ht_supported = true,
1159*a0ccc12fSBjoern A. Zeeb 	.vht_supported = true,
1160*a0ccc12fSBjoern A. Zeeb 	.lps_deep_mode_supported = 0,
1161*a0ccc12fSBjoern A. Zeeb 	.sys_func_en = 0xFD,
1162*a0ccc12fSBjoern A. Zeeb 	.pwr_on_seq = card_enable_flow_8821a,
1163*a0ccc12fSBjoern A. Zeeb 	.pwr_off_seq = card_disable_flow_8821a,
1164*a0ccc12fSBjoern A. Zeeb 	.page_table = page_table_8821a,
1165*a0ccc12fSBjoern A. Zeeb 	.rqpn_table = rqpn_table_8821a,
1166*a0ccc12fSBjoern A. Zeeb 	.prioq_addrs = &prioq_addrs_8821a,
1167*a0ccc12fSBjoern A. Zeeb 	.intf_table = NULL,
1168*a0ccc12fSBjoern A. Zeeb 	.dig = rtw8821a_dig,
1169*a0ccc12fSBjoern A. Zeeb 	.rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B},
1170*a0ccc12fSBjoern A. Zeeb 	.ltecoex_addr = NULL,
1171*a0ccc12fSBjoern A. Zeeb 	.mac_tbl = &rtw8821a_mac_tbl,
1172*a0ccc12fSBjoern A. Zeeb 	.agc_tbl = &rtw8821a_agc_tbl,
1173*a0ccc12fSBjoern A. Zeeb 	.bb_tbl = &rtw8821a_bb_tbl,
1174*a0ccc12fSBjoern A. Zeeb 	.rf_tbl = {&rtw8821a_rf_a_tbl},
1175*a0ccc12fSBjoern A. Zeeb 	.rfe_defs = rtw8821a_rfe_defs,
1176*a0ccc12fSBjoern A. Zeeb 	.rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs),
1177*a0ccc12fSBjoern A. Zeeb 	.rx_ldpc = false,
1178*a0ccc12fSBjoern A. Zeeb 	.hw_feature_report = false,
1179*a0ccc12fSBjoern A. Zeeb 	.c2h_ra_report_size = 4,
1180*a0ccc12fSBjoern A. Zeeb 	.old_datarate_fb_limit = true,
1181*a0ccc12fSBjoern A. Zeeb 	.usb_tx_agg_desc_num = 6,
1182*a0ccc12fSBjoern A. Zeeb 	.iqk_threshold = 8,
1183*a0ccc12fSBjoern A. Zeeb 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1184*a0ccc12fSBjoern A. Zeeb 	.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
1185*a0ccc12fSBjoern A. Zeeb 
1186*a0ccc12fSBjoern A. Zeeb 	.coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */
1187*a0ccc12fSBjoern A. Zeeb 	.bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */
1188*a0ccc12fSBjoern A. Zeeb 	.scbd_support = false,
1189*a0ccc12fSBjoern A. Zeeb 	.new_scbd10_def = false,
1190*a0ccc12fSBjoern A. Zeeb 	.ble_hid_profile_support = false,
1191*a0ccc12fSBjoern A. Zeeb 	.wl_mimo_ps_support = false,
1192*a0ccc12fSBjoern A. Zeeb 	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
1193*a0ccc12fSBjoern A. Zeeb 	.bt_rssi_type = COEX_BTRSSI_RATIO,
1194*a0ccc12fSBjoern A. Zeeb 	.ant_isolation = 10,
1195*a0ccc12fSBjoern A. Zeeb 	.rssi_tolerance = 2,
1196*a0ccc12fSBjoern A. Zeeb 	.wl_rssi_step = wl_rssi_step_8821a,
1197*a0ccc12fSBjoern A. Zeeb 	.bt_rssi_step = bt_rssi_step_8821a,
1198*a0ccc12fSBjoern A. Zeeb 	.table_sant_num = ARRAY_SIZE(table_sant_8821a),
1199*a0ccc12fSBjoern A. Zeeb 	.table_sant = table_sant_8821a,
1200*a0ccc12fSBjoern A. Zeeb 	.table_nsant_num = ARRAY_SIZE(table_nsant_8821a),
1201*a0ccc12fSBjoern A. Zeeb 	.table_nsant = table_nsant_8821a,
1202*a0ccc12fSBjoern A. Zeeb 	.tdma_sant_num = ARRAY_SIZE(tdma_sant_8821a),
1203*a0ccc12fSBjoern A. Zeeb 	.tdma_sant = tdma_sant_8821a,
1204*a0ccc12fSBjoern A. Zeeb 	.tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821a),
1205*a0ccc12fSBjoern A. Zeeb 	.tdma_nsant = tdma_nsant_8821a,
1206*a0ccc12fSBjoern A. Zeeb 	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a),
1207*a0ccc12fSBjoern A. Zeeb 	.wl_rf_para_tx = rf_para_tx_8821a,
1208*a0ccc12fSBjoern A. Zeeb 	.wl_rf_para_rx = rf_para_rx_8821a,
1209*a0ccc12fSBjoern A. Zeeb 	.bt_afh_span_bw20 = 0x20,
1210*a0ccc12fSBjoern A. Zeeb 	.bt_afh_span_bw40 = 0x30,
1211*a0ccc12fSBjoern A. Zeeb 	.afh_5g_num = ARRAY_SIZE(afh_5g_8821a),
1212*a0ccc12fSBjoern A. Zeeb 	.afh_5g = afh_5g_8821a,
1213*a0ccc12fSBjoern A. Zeeb 
1214*a0ccc12fSBjoern A. Zeeb 	.coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821a),
1215*a0ccc12fSBjoern A. Zeeb 	.coex_info_hw_regs = coex_info_hw_regs_8821a,
1216*a0ccc12fSBjoern A. Zeeb };
1217*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw8821a_hw_spec);
1218*a0ccc12fSBjoern A. Zeeb 
1219*a0ccc12fSBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin");
1220*a0ccc12fSBjoern A. Zeeb 
1221*a0ccc12fSBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation");
1222*a0ccc12fSBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver");
1223*a0ccc12fSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL");
1224