xref: /freebsd/sys/contrib/dev/rtw88/rtw88xxa.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 <linux/usb.h>
6*a0ccc12fSBjoern A. Zeeb #include "main.h"
7*a0ccc12fSBjoern A. Zeeb #include "coex.h"
8*a0ccc12fSBjoern A. Zeeb #include "phy.h"
9*a0ccc12fSBjoern A. Zeeb #include "rtw88xxa.h"
10*a0ccc12fSBjoern A. Zeeb #include "mac.h"
11*a0ccc12fSBjoern A. Zeeb #include "reg.h"
12*a0ccc12fSBjoern A. Zeeb #include "sec.h"
13*a0ccc12fSBjoern A. Zeeb #include "debug.h"
14*a0ccc12fSBjoern A. Zeeb #include "bf.h"
15*a0ccc12fSBjoern A. Zeeb #include "efuse.h"
16*a0ccc12fSBjoern A. Zeeb #include "usb.h"
17*a0ccc12fSBjoern A. Zeeb 
18*a0ccc12fSBjoern A. Zeeb void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on)
19*a0ccc12fSBjoern A. Zeeb {
20*a0ccc12fSBjoern A. Zeeb 	if (on) {
21*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
22*a0ccc12fSBjoern A. Zeeb 
23*a0ccc12fSBjoern A. Zeeb 		rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR);
24*a0ccc12fSBjoern A. Zeeb 		rtw_write16_set(rtwdev, REG_SYS_CLKR,
25*a0ccc12fSBjoern A. Zeeb 				BIT_LOADER_CLK_EN | BIT_ANA8M);
26*a0ccc12fSBjoern A. Zeeb 	} else {
27*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
28*a0ccc12fSBjoern A. Zeeb 	}
29*a0ccc12fSBjoern A. Zeeb }
30*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_efuse_grant);
31*a0ccc12fSBjoern A. Zeeb 
32*a0ccc12fSBjoern A. Zeeb static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev)
33*a0ccc12fSBjoern A. Zeeb {
34*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
35*a0ccc12fSBjoern A. Zeeb 
36*a0ccc12fSBjoern A. Zeeb 	efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) &&
37*a0ccc12fSBjoern A. Zeeb 			   (efuse->pa_type_2g & BIT(4));
38*a0ccc12fSBjoern A. Zeeb 	efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) &&
39*a0ccc12fSBjoern A. Zeeb 			    (efuse->lna_type_2g & BIT(3));
40*a0ccc12fSBjoern A. Zeeb 
41*a0ccc12fSBjoern A. Zeeb 	efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) &&
42*a0ccc12fSBjoern A. Zeeb 			   (efuse->pa_type_5g & BIT(0));
43*a0ccc12fSBjoern A. Zeeb 	efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) &&
44*a0ccc12fSBjoern A. Zeeb 			    (efuse->lna_type_5g & BIT(3));
45*a0ccc12fSBjoern A. Zeeb 
46*a0ccc12fSBjoern A. Zeeb 	/* For rtw_phy_cond2: */
47*a0ccc12fSBjoern A. Zeeb 	if (efuse->ext_pa_2g) {
48*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2));
49*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6));
50*a0ccc12fSBjoern A. Zeeb 
51*a0ccc12fSBjoern A. Zeeb 		efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a;
52*a0ccc12fSBjoern A. Zeeb 	}
53*a0ccc12fSBjoern A. Zeeb 
54*a0ccc12fSBjoern A. Zeeb 	if (efuse->ext_pa_5g) {
55*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2));
56*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6));
57*a0ccc12fSBjoern A. Zeeb 
58*a0ccc12fSBjoern A. Zeeb 		efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a;
59*a0ccc12fSBjoern A. Zeeb 	}
60*a0ccc12fSBjoern A. Zeeb 
61*a0ccc12fSBjoern A. Zeeb 	if (efuse->ext_lna_2g) {
62*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g,
63*a0ccc12fSBjoern A. Zeeb 						   BIT(1) | BIT(0));
64*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g,
65*a0ccc12fSBjoern A. Zeeb 						   BIT(5) | BIT(4));
66*a0ccc12fSBjoern A. Zeeb 
67*a0ccc12fSBjoern A. Zeeb 		efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a;
68*a0ccc12fSBjoern A. Zeeb 	}
69*a0ccc12fSBjoern A. Zeeb 
70*a0ccc12fSBjoern A. Zeeb 	if (efuse->ext_lna_5g) {
71*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g,
72*a0ccc12fSBjoern A. Zeeb 						   BIT(1) | BIT(0));
73*a0ccc12fSBjoern A. Zeeb 		u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g,
74*a0ccc12fSBjoern A. Zeeb 						   BIT(5) | BIT(4));
75*a0ccc12fSBjoern A. Zeeb 
76*a0ccc12fSBjoern A. Zeeb 		efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a;
77*a0ccc12fSBjoern A. Zeeb 	}
78*a0ccc12fSBjoern A. Zeeb }
79*a0ccc12fSBjoern A. Zeeb 
80*a0ccc12fSBjoern A. Zeeb static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev,
81*a0ccc12fSBjoern A. Zeeb 				   struct rtw88xxa_efuse *map)
82*a0ccc12fSBjoern A. Zeeb {
83*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
84*a0ccc12fSBjoern A. Zeeb 
85*a0ccc12fSBjoern A. Zeeb 	if (map->rfe_option == 0xff) {
86*a0ccc12fSBjoern A. Zeeb 		if (rtwdev->hci.type == RTW_HCI_TYPE_USB)
87*a0ccc12fSBjoern A. Zeeb 			efuse->rfe_option = 0;
88*a0ccc12fSBjoern A. Zeeb 		else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
89*a0ccc12fSBjoern A. Zeeb 			efuse->rfe_option = 2;
90*a0ccc12fSBjoern A. Zeeb 		else
91*a0ccc12fSBjoern A. Zeeb 			efuse->rfe_option = 4;
92*a0ccc12fSBjoern A. Zeeb 	} else if (map->rfe_option & BIT(7)) {
93*a0ccc12fSBjoern A. Zeeb 		if (efuse->ext_lna_5g) {
94*a0ccc12fSBjoern A. Zeeb 			if (efuse->ext_pa_5g) {
95*a0ccc12fSBjoern A. Zeeb 				if (efuse->ext_lna_2g && efuse->ext_pa_2g)
96*a0ccc12fSBjoern A. Zeeb 					efuse->rfe_option = 3;
97*a0ccc12fSBjoern A. Zeeb 				else
98*a0ccc12fSBjoern A. Zeeb 					efuse->rfe_option = 0;
99*a0ccc12fSBjoern A. Zeeb 			} else {
100*a0ccc12fSBjoern A. Zeeb 				efuse->rfe_option = 2;
101*a0ccc12fSBjoern A. Zeeb 			}
102*a0ccc12fSBjoern A. Zeeb 		} else {
103*a0ccc12fSBjoern A. Zeeb 			efuse->rfe_option = 4;
104*a0ccc12fSBjoern A. Zeeb 		}
105*a0ccc12fSBjoern A. Zeeb 	} else {
106*a0ccc12fSBjoern A. Zeeb 		efuse->rfe_option = map->rfe_option & 0x3f;
107*a0ccc12fSBjoern A. Zeeb 
108*a0ccc12fSBjoern A. Zeeb 		/* Due to other customer already use incorrect EFUSE map for
109*a0ccc12fSBjoern A. Zeeb 		 * their product. We need to add workaround to prevent to
110*a0ccc12fSBjoern A. Zeeb 		 * modify spec and notify all customer to revise the IC 0xca
111*a0ccc12fSBjoern A. Zeeb 		 * content.
112*a0ccc12fSBjoern A. Zeeb 		 */
113*a0ccc12fSBjoern A. Zeeb 		if (efuse->rfe_option == 4 &&
114*a0ccc12fSBjoern A. Zeeb 		    (efuse->ext_pa_5g || efuse->ext_pa_2g ||
115*a0ccc12fSBjoern A. Zeeb 		     efuse->ext_lna_5g || efuse->ext_lna_2g)) {
116*a0ccc12fSBjoern A. Zeeb 			if (rtwdev->hci.type == RTW_HCI_TYPE_USB)
117*a0ccc12fSBjoern A. Zeeb 				efuse->rfe_option = 0;
118*a0ccc12fSBjoern A. Zeeb 			else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
119*a0ccc12fSBjoern A. Zeeb 				efuse->rfe_option = 2;
120*a0ccc12fSBjoern A. Zeeb 		}
121*a0ccc12fSBjoern A. Zeeb 	}
122*a0ccc12fSBjoern A. Zeeb }
123*a0ccc12fSBjoern A. Zeeb 
124*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev)
125*a0ccc12fSBjoern A. Zeeb {
126*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
127*a0ccc12fSBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
128*a0ccc12fSBjoern A. Zeeb 	u8 antenna = 0;
129*a0ccc12fSBjoern A. Zeeb 	u8 wmode = 0;
130*a0ccc12fSBjoern A. Zeeb 	u8 val8, i;
131*a0ccc12fSBjoern A. Zeeb 
132*a0ccc12fSBjoern A. Zeeb 	efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) |
133*a0ccc12fSBjoern A. Zeeb 			   BIT(RTW_CHANNEL_WIDTH_40) |
134*a0ccc12fSBjoern A. Zeeb 			   BIT(RTW_CHANNEL_WIDTH_80);
135*a0ccc12fSBjoern A. Zeeb 	efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT;
136*a0ccc12fSBjoern A. Zeeb 
137*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
138*a0ccc12fSBjoern A. Zeeb 		efuse->hw_cap.nss = 1;
139*a0ccc12fSBjoern A. Zeeb 	else
140*a0ccc12fSBjoern A. Zeeb 		efuse->hw_cap.nss = 2;
141*a0ccc12fSBjoern A. Zeeb 
142*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
143*a0ccc12fSBjoern A. Zeeb 		goto print_hw_cap;
144*a0ccc12fSBjoern A. Zeeb 
145*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < 2; i++) {
146*a0ccc12fSBjoern A. Zeeb 		rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8);
147*a0ccc12fSBjoern A. Zeeb 
148*a0ccc12fSBjoern A. Zeeb 		antenna = u8_get_bits(val8, GENMASK(7, 5));
149*a0ccc12fSBjoern A. Zeeb 		if (antenna)
150*a0ccc12fSBjoern A. Zeeb 			break;
151*a0ccc12fSBjoern A. Zeeb 		antenna = u8_get_bits(val8, GENMASK(3, 1));
152*a0ccc12fSBjoern A. Zeeb 		if (antenna)
153*a0ccc12fSBjoern A. Zeeb 			break;
154*a0ccc12fSBjoern A. Zeeb 	}
155*a0ccc12fSBjoern A. Zeeb 
156*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < 2; i++) {
157*a0ccc12fSBjoern A. Zeeb 		rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8);
158*a0ccc12fSBjoern A. Zeeb 
159*a0ccc12fSBjoern A. Zeeb 		wmode = u8_get_bits(val8, GENMASK(3, 2));
160*a0ccc12fSBjoern A. Zeeb 		if (wmode)
161*a0ccc12fSBjoern A. Zeeb 			break;
162*a0ccc12fSBjoern A. Zeeb 	}
163*a0ccc12fSBjoern A. Zeeb 
164*a0ccc12fSBjoern A. Zeeb 	if (antenna == 1) {
165*a0ccc12fSBjoern A. Zeeb 		rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n");
166*a0ccc12fSBjoern A. Zeeb 
167*a0ccc12fSBjoern A. Zeeb 		efuse->hw_cap.nss = 1;
168*a0ccc12fSBjoern A. Zeeb 		hal->rf_type = RF_1T1R;
169*a0ccc12fSBjoern A. Zeeb 		hal->rf_path_num = 1;
170*a0ccc12fSBjoern A. Zeeb 		hal->rf_phy_num = 1;
171*a0ccc12fSBjoern A. Zeeb 		hal->antenna_tx = BB_PATH_A;
172*a0ccc12fSBjoern A. Zeeb 		hal->antenna_rx = BB_PATH_A;
173*a0ccc12fSBjoern A. Zeeb 	} else {
174*a0ccc12fSBjoern A. Zeeb 		/* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */
175*a0ccc12fSBjoern A. Zeeb 		efuse->hw_cap.nss = 2;
176*a0ccc12fSBjoern A. Zeeb 		hal->rf_type = RF_2T2R;
177*a0ccc12fSBjoern A. Zeeb 		hal->rf_path_num = 2;
178*a0ccc12fSBjoern A. Zeeb 		hal->rf_phy_num = 2;
179*a0ccc12fSBjoern A. Zeeb 		hal->antenna_tx = BB_PATH_AB;
180*a0ccc12fSBjoern A. Zeeb 		hal->antenna_rx = BB_PATH_AB;
181*a0ccc12fSBjoern A. Zeeb 
182*a0ccc12fSBjoern A. Zeeb 		if (antenna == 2 && wmode == 2) {
183*a0ccc12fSBjoern A. Zeeb 			rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n");
184*a0ccc12fSBjoern A. Zeeb 
185*a0ccc12fSBjoern A. Zeeb 			/* Can't be EFUSE_HW_CAP_IGNORE and can't be
186*a0ccc12fSBjoern A. Zeeb 			 * EFUSE_HW_CAP_PTCL_VHT, so make it 1.
187*a0ccc12fSBjoern A. Zeeb 			 */
188*a0ccc12fSBjoern A. Zeeb 			efuse->hw_cap.ptcl = 1;
189*a0ccc12fSBjoern A. Zeeb 			efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80);
190*a0ccc12fSBjoern A. Zeeb 		}
191*a0ccc12fSBjoern A. Zeeb 	}
192*a0ccc12fSBjoern A. Zeeb 
193*a0ccc12fSBjoern A. Zeeb print_hw_cap:
194*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_EFUSE,
195*a0ccc12fSBjoern A. Zeeb 		"hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n",
196*a0ccc12fSBjoern A. Zeeb 		efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl,
197*a0ccc12fSBjoern A. Zeeb 		efuse->hw_cap.ant_num, efuse->hw_cap.nss);
198*a0ccc12fSBjoern A. Zeeb }
199*a0ccc12fSBjoern A. Zeeb 
200*a0ccc12fSBjoern A. Zeeb int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
201*a0ccc12fSBjoern A. Zeeb {
202*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
203*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
204*a0ccc12fSBjoern A. Zeeb 	struct rtw88xxa_efuse *map;
205*a0ccc12fSBjoern A. Zeeb 	int i;
206*a0ccc12fSBjoern A. Zeeb 
207*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A)
208*a0ccc12fSBjoern A. Zeeb 		rtwdev->hal.cut_version += 1;
209*a0ccc12fSBjoern A. Zeeb 
210*a0ccc12fSBjoern A. Zeeb 	if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
211*a0ccc12fSBjoern A. Zeeb 		print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
212*a0ccc12fSBjoern A. Zeeb 			       log_map, chip->log_efuse_size, true);
213*a0ccc12fSBjoern A. Zeeb 
214*a0ccc12fSBjoern A. Zeeb 	map = (struct rtw88xxa_efuse *)log_map;
215*a0ccc12fSBjoern A. Zeeb 
216*a0ccc12fSBjoern A. Zeeb 	efuse->rf_board_option = map->rf_board_option;
217*a0ccc12fSBjoern A. Zeeb 	efuse->crystal_cap = map->xtal_k;
218*a0ccc12fSBjoern A. Zeeb 	if (efuse->crystal_cap == 0xff)
219*a0ccc12fSBjoern A. Zeeb 		efuse->crystal_cap = 0x20;
220*a0ccc12fSBjoern A. Zeeb 	efuse->pa_type_2g = map->pa_type;
221*a0ccc12fSBjoern A. Zeeb 	efuse->pa_type_5g = map->pa_type;
222*a0ccc12fSBjoern A. Zeeb 	efuse->lna_type_2g = map->lna_type_2g;
223*a0ccc12fSBjoern A. Zeeb 	efuse->lna_type_5g = map->lna_type_5g;
224*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A) {
225*a0ccc12fSBjoern A. Zeeb 		rtw8812a_read_amplifier_type(rtwdev);
226*a0ccc12fSBjoern A. Zeeb 		rtw8812a_read_rfe_type(rtwdev, map);
227*a0ccc12fSBjoern A. Zeeb 
228*a0ccc12fSBjoern A. Zeeb 		efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1));
229*a0ccc12fSBjoern A. Zeeb 	}
230*a0ccc12fSBjoern A. Zeeb 	efuse->channel_plan = map->channel_plan;
231*a0ccc12fSBjoern A. Zeeb 	efuse->country_code[0] = map->country_code[0];
232*a0ccc12fSBjoern A. Zeeb 	efuse->country_code[1] = map->country_code[1];
233*a0ccc12fSBjoern A. Zeeb 	efuse->bt_setting = map->rf_bt_setting;
234*a0ccc12fSBjoern A. Zeeb 	efuse->regd = map->rf_board_option & 0x7;
235*a0ccc12fSBjoern A. Zeeb 	efuse->thermal_meter[0] = map->thermal_meter;
236*a0ccc12fSBjoern A. Zeeb 	efuse->thermal_meter[1] = map->thermal_meter;
237*a0ccc12fSBjoern A. Zeeb 	efuse->thermal_meter_k = map->thermal_meter;
238*a0ccc12fSBjoern A. Zeeb 	efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g;
239*a0ccc12fSBjoern A. Zeeb 	efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g;
240*a0ccc12fSBjoern A. Zeeb 
241*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_read_usb_type(rtwdev);
242*a0ccc12fSBjoern A. Zeeb 
243*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A)
244*a0ccc12fSBjoern A. Zeeb 		efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL,
245*a0ccc12fSBjoern A. Zeeb 						BIT_BT_FUNC_EN);
246*a0ccc12fSBjoern A. Zeeb 	else
247*a0ccc12fSBjoern A. Zeeb 		efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20;
248*a0ccc12fSBjoern A. Zeeb 	efuse->share_ant = !!(efuse->bt_setting & BIT(0));
249*a0ccc12fSBjoern A. Zeeb 
250*a0ccc12fSBjoern A. Zeeb 	/* No antenna diversity because it's disabled in the vendor driver */
251*a0ccc12fSBjoern A. Zeeb 	efuse->ant_div_cfg = 0;
252*a0ccc12fSBjoern A. Zeeb 
253*a0ccc12fSBjoern A. Zeeb 	efuse->ant_div_type = map->rf_antenna_option;
254*a0ccc12fSBjoern A. Zeeb 	if (efuse->ant_div_type == 0xff)
255*a0ccc12fSBjoern A. Zeeb 		efuse->ant_div_type = 0x3;
256*a0ccc12fSBjoern A. Zeeb 
257*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < 4; i++)
258*a0ccc12fSBjoern A. Zeeb 		efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
259*a0ccc12fSBjoern A. Zeeb 
260*a0ccc12fSBjoern A. Zeeb 	switch (rtw_hci_type(rtwdev)) {
261*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_USB:
262*a0ccc12fSBjoern A. Zeeb 		if (chip->id == RTW_CHIP_TYPE_8821A)
263*a0ccc12fSBjoern A. Zeeb 			ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr);
264*a0ccc12fSBjoern A. Zeeb 		else
265*a0ccc12fSBjoern A. Zeeb 			ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr);
266*a0ccc12fSBjoern A. Zeeb 		break;
267*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_PCIE:
268*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_SDIO:
269*a0ccc12fSBjoern A. Zeeb 	default:
270*a0ccc12fSBjoern A. Zeeb 		/* unsupported now */
271*a0ccc12fSBjoern A. Zeeb 		return -EOPNOTSUPP;
272*a0ccc12fSBjoern A. Zeeb 	}
273*a0ccc12fSBjoern A. Zeeb 
274*a0ccc12fSBjoern A. Zeeb 	return 0;
275*a0ccc12fSBjoern A. Zeeb }
276*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_read_efuse);
277*a0ccc12fSBjoern A. Zeeb 
278*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev)
279*a0ccc12fSBjoern A. Zeeb {
280*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
281*a0ccc12fSBjoern A. Zeeb 	u8 val8;
282*a0ccc12fSBjoern A. Zeeb 
283*a0ccc12fSBjoern A. Zeeb 	/* Reset MCU IO Wrapper */
284*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1));
285*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A)
286*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3));
287*a0ccc12fSBjoern A. Zeeb 	else
288*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0));
289*a0ccc12fSBjoern A. Zeeb 
290*a0ccc12fSBjoern A. Zeeb 	val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1);
291*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2));
292*a0ccc12fSBjoern A. Zeeb 
293*a0ccc12fSBjoern A. Zeeb 	/* Enable MCU IO Wrapper */
294*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1));
295*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A)
296*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3));
297*a0ccc12fSBjoern A. Zeeb 	else
298*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0));
299*a0ccc12fSBjoern A. Zeeb 
300*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2));
301*a0ccc12fSBjoern A. Zeeb }
302*a0ccc12fSBjoern A. Zeeb 
303*a0ccc12fSBjoern A. Zeeb /* A lightweight deinit function */
304*a0ccc12fSBjoern A. Zeeb static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev)
305*a0ccc12fSBjoern A. Zeeb {
306*a0ccc12fSBjoern A. Zeeb 	u8 val8;
307*a0ccc12fSBjoern A. Zeeb 
308*a0ccc12fSBjoern A. Zeeb 	if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL))
309*a0ccc12fSBjoern A. Zeeb 		return;
310*a0ccc12fSBjoern A. Zeeb 
311*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_reset_8051(rtwdev);
312*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00);
313*a0ccc12fSBjoern A. Zeeb 
314*a0ccc12fSBjoern A. Zeeb 	/* before BB reset should do clock gated */
315*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6));
316*a0ccc12fSBjoern A. Zeeb 
317*a0ccc12fSBjoern A. Zeeb 	/* reset BB */
318*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));
319*a0ccc12fSBjoern A. Zeeb 
320*a0ccc12fSBjoern A. Zeeb 	/* reset RF */
321*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RF_CTRL, 0);
322*a0ccc12fSBjoern A. Zeeb 
323*a0ccc12fSBjoern A. Zeeb 	/* reset TRX path */
324*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_CR, 0);
325*a0ccc12fSBjoern A. Zeeb 
326*a0ccc12fSBjoern A. Zeeb 	/* reset MAC, reg0x5[1], auto FSM off */
327*a0ccc12fSBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8);
328*a0ccc12fSBjoern A. Zeeb 
329*a0ccc12fSBjoern A. Zeeb 	/* check if reg0x5[1] auto cleared */
330*a0ccc12fSBjoern A. Zeeb 	if (read_poll_timeout_atomic(rtw_read8, val8,
331*a0ccc12fSBjoern A. Zeeb 				     !(val8 & (APS_FSMCO_MAC_OFF >> 8)),
332*a0ccc12fSBjoern A. Zeeb 				     1, 5000, false,
333*a0ccc12fSBjoern A. Zeeb 				     rtwdev, REG_APS_FSMCO + 1))
334*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__);
335*a0ccc12fSBjoern A. Zeeb 
336*a0ccc12fSBjoern A. Zeeb 	/* reg0x5[0], auto FSM on */
337*a0ccc12fSBjoern A. Zeeb 	val8 |= APS_FSMCO_MAC_ENABLE >> 8;
338*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8);
339*a0ccc12fSBjoern A. Zeeb 
340*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7));
341*a0ccc12fSBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7));
342*a0ccc12fSBjoern A. Zeeb }
343*a0ccc12fSBjoern A. Zeeb 
344*a0ccc12fSBjoern A. Zeeb static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev)
345*a0ccc12fSBjoern A. Zeeb {
346*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
347*a0ccc12fSBjoern A. Zeeb 	u16 val16;
348*a0ccc12fSBjoern A. Zeeb 	int ret;
349*a0ccc12fSBjoern A. Zeeb 
350*a0ccc12fSBjoern A. Zeeb 	ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq);
351*a0ccc12fSBjoern A. Zeeb 	if (ret) {
352*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "power on flow failed\n");
353*a0ccc12fSBjoern A. Zeeb 		return ret;
354*a0ccc12fSBjoern A. Zeeb 	}
355*a0ccc12fSBjoern A. Zeeb 
356*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_CR, 0);
357*a0ccc12fSBjoern A. Zeeb 	val16 = BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN |
358*a0ccc12fSBjoern A. Zeeb 		BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN |
359*a0ccc12fSBjoern A. Zeeb 		BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN;
360*a0ccc12fSBjoern A. Zeeb 	rtw_write16_set(rtwdev, REG_CR, val16);
361*a0ccc12fSBjoern A. Zeeb 
362*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A) {
363*a0ccc12fSBjoern A. Zeeb 		if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0))
364*a0ccc12fSBjoern A. Zeeb 			rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6));
365*a0ccc12fSBjoern A. Zeeb 	}
366*a0ccc12fSBjoern A. Zeeb 
367*a0ccc12fSBjoern A. Zeeb 	return ret;
368*a0ccc12fSBjoern A. Zeeb }
369*a0ccc12fSBjoern A. Zeeb 
370*a0ccc12fSBjoern A. Zeeb static int rtw88xxa_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data)
371*a0ccc12fSBjoern A. Zeeb {
372*a0ccc12fSBjoern A. Zeeb 	u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data;
373*a0ccc12fSBjoern A. Zeeb 	int count = 0;
374*a0ccc12fSBjoern A. Zeeb 
375*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_LLT_INIT, value);
376*a0ccc12fSBjoern A. Zeeb 
377*a0ccc12fSBjoern A. Zeeb 	do {
378*a0ccc12fSBjoern A. Zeeb 		if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30)))
379*a0ccc12fSBjoern A. Zeeb 			break;
380*a0ccc12fSBjoern A. Zeeb 
381*a0ccc12fSBjoern A. Zeeb 		if (count > 20) {
382*a0ccc12fSBjoern A. Zeeb 			rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n",
383*a0ccc12fSBjoern A. Zeeb 				address);
384*a0ccc12fSBjoern A. Zeeb 			return -EBUSY;
385*a0ccc12fSBjoern A. Zeeb 		}
386*a0ccc12fSBjoern A. Zeeb 	} while (++count);
387*a0ccc12fSBjoern A. Zeeb 
388*a0ccc12fSBjoern A. Zeeb 	return 0;
389*a0ccc12fSBjoern A. Zeeb }
390*a0ccc12fSBjoern A. Zeeb 
391*a0ccc12fSBjoern A. Zeeb static int rtw88xxa_llt_init(struct rtw_dev *rtwdev, u32 boundary)
392*a0ccc12fSBjoern A. Zeeb {
393*a0ccc12fSBjoern A. Zeeb 	u32 last_entry = 255;
394*a0ccc12fSBjoern A. Zeeb 	int status = 0;
395*a0ccc12fSBjoern A. Zeeb 	u32 i;
396*a0ccc12fSBjoern A. Zeeb 
397*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < boundary - 1; i++) {
398*a0ccc12fSBjoern A. Zeeb 		status = rtw88xxa_llt_write(rtwdev, i, i + 1);
399*a0ccc12fSBjoern A. Zeeb 		if (status)
400*a0ccc12fSBjoern A. Zeeb 			return status;
401*a0ccc12fSBjoern A. Zeeb 	}
402*a0ccc12fSBjoern A. Zeeb 
403*a0ccc12fSBjoern A. Zeeb 	status = rtw88xxa_llt_write(rtwdev, boundary - 1, 0xFF);
404*a0ccc12fSBjoern A. Zeeb 	if (status)
405*a0ccc12fSBjoern A. Zeeb 		return status;
406*a0ccc12fSBjoern A. Zeeb 
407*a0ccc12fSBjoern A. Zeeb 	for (i = boundary; i < last_entry; i++) {
408*a0ccc12fSBjoern A. Zeeb 		status = rtw88xxa_llt_write(rtwdev, i, i + 1);
409*a0ccc12fSBjoern A. Zeeb 		if (status)
410*a0ccc12fSBjoern A. Zeeb 			return status;
411*a0ccc12fSBjoern A. Zeeb 	}
412*a0ccc12fSBjoern A. Zeeb 
413*a0ccc12fSBjoern A. Zeeb 	status = rtw88xxa_llt_write(rtwdev, last_entry, boundary);
414*a0ccc12fSBjoern A. Zeeb 
415*a0ccc12fSBjoern A. Zeeb 	return status;
416*a0ccc12fSBjoern A. Zeeb }
417*a0ccc12fSBjoern A. Zeeb 
418*a0ccc12fSBjoern A. Zeeb static void rtw88xxau_init_queue_reserved_page(struct rtw_dev *rtwdev)
419*a0ccc12fSBjoern A. Zeeb {
420*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
421*a0ccc12fSBjoern A. Zeeb 	struct rtw_fifo_conf *fifo = &rtwdev->fifo;
422*a0ccc12fSBjoern A. Zeeb 	const struct rtw_page_table *pg_tbl = NULL;
423*a0ccc12fSBjoern A. Zeeb 	u16 pubq_num;
424*a0ccc12fSBjoern A. Zeeb 	u32 val32;
425*a0ccc12fSBjoern A. Zeeb 
426*a0ccc12fSBjoern A. Zeeb 	switch (rtw_hci_type(rtwdev)) {
427*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_PCIE:
428*a0ccc12fSBjoern A. Zeeb 		pg_tbl = &chip->page_table[1];
429*a0ccc12fSBjoern A. Zeeb 		break;
430*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_USB:
431*a0ccc12fSBjoern A. Zeeb 		if (rtwdev->hci.bulkout_num == 2)
432*a0ccc12fSBjoern A. Zeeb 			pg_tbl = &chip->page_table[2];
433*a0ccc12fSBjoern A. Zeeb 		else if (rtwdev->hci.bulkout_num == 3)
434*a0ccc12fSBjoern A. Zeeb 			pg_tbl = &chip->page_table[3];
435*a0ccc12fSBjoern A. Zeeb 		else if (rtwdev->hci.bulkout_num == 4)
436*a0ccc12fSBjoern A. Zeeb 			pg_tbl = &chip->page_table[4];
437*a0ccc12fSBjoern A. Zeeb 		break;
438*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_SDIO:
439*a0ccc12fSBjoern A. Zeeb 		pg_tbl = &chip->page_table[0];
440*a0ccc12fSBjoern A. Zeeb 		break;
441*a0ccc12fSBjoern A. Zeeb 	default:
442*a0ccc12fSBjoern A. Zeeb 		break;
443*a0ccc12fSBjoern A. Zeeb 	}
444*a0ccc12fSBjoern A. Zeeb 
445*a0ccc12fSBjoern A. Zeeb 	pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num -
446*a0ccc12fSBjoern A. Zeeb 		   pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num;
447*a0ccc12fSBjoern A. Zeeb 
448*a0ccc12fSBjoern A. Zeeb 	val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num);
449*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RQPN_NPQ, val32);
450*a0ccc12fSBjoern A. Zeeb 
451*a0ccc12fSBjoern A. Zeeb 	val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num);
452*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RQPN, val32);
453*a0ccc12fSBjoern A. Zeeb }
454*a0ccc12fSBjoern A. Zeeb 
455*a0ccc12fSBjoern A. Zeeb static void rtw88xxau_init_tx_buffer_boundary(struct rtw_dev *rtwdev)
456*a0ccc12fSBjoern A. Zeeb {
457*a0ccc12fSBjoern A. Zeeb 	struct rtw_fifo_conf *fifo = &rtwdev->fifo;
458*a0ccc12fSBjoern A. Zeeb 
459*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary);
460*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary);
461*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary);
462*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary);
463*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary);
464*a0ccc12fSBjoern A. Zeeb }
465*a0ccc12fSBjoern A. Zeeb 
466*a0ccc12fSBjoern A. Zeeb static int rtw88xxau_init_queue_priority(struct rtw_dev *rtwdev)
467*a0ccc12fSBjoern A. Zeeb {
468*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
469*a0ccc12fSBjoern A. Zeeb 	u8 bulkout_num = rtwdev->hci.bulkout_num;
470*a0ccc12fSBjoern A. Zeeb 	const struct rtw_rqpn *rqpn = NULL;
471*a0ccc12fSBjoern A. Zeeb 	u16 txdma_pq_map;
472*a0ccc12fSBjoern A. Zeeb 
473*a0ccc12fSBjoern A. Zeeb 	switch (rtw_hci_type(rtwdev)) {
474*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_PCIE:
475*a0ccc12fSBjoern A. Zeeb 		rqpn = &chip->rqpn_table[1];
476*a0ccc12fSBjoern A. Zeeb 		break;
477*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_USB:
478*a0ccc12fSBjoern A. Zeeb 		if (bulkout_num == 2)
479*a0ccc12fSBjoern A. Zeeb 			rqpn = &chip->rqpn_table[2];
480*a0ccc12fSBjoern A. Zeeb 		else if (bulkout_num == 3)
481*a0ccc12fSBjoern A. Zeeb 			rqpn = &chip->rqpn_table[3];
482*a0ccc12fSBjoern A. Zeeb 		else if (bulkout_num == 4)
483*a0ccc12fSBjoern A. Zeeb 			rqpn = &chip->rqpn_table[4];
484*a0ccc12fSBjoern A. Zeeb 		else
485*a0ccc12fSBjoern A. Zeeb 			return -EINVAL;
486*a0ccc12fSBjoern A. Zeeb 		break;
487*a0ccc12fSBjoern A. Zeeb 	case RTW_HCI_TYPE_SDIO:
488*a0ccc12fSBjoern A. Zeeb 		rqpn = &chip->rqpn_table[0];
489*a0ccc12fSBjoern A. Zeeb 		break;
490*a0ccc12fSBjoern A. Zeeb 	default:
491*a0ccc12fSBjoern A. Zeeb 		return -EINVAL;
492*a0ccc12fSBjoern A. Zeeb 	}
493*a0ccc12fSBjoern A. Zeeb 
494*a0ccc12fSBjoern A. Zeeb 	rtwdev->fifo.rqpn = rqpn;
495*a0ccc12fSBjoern A. Zeeb 
496*a0ccc12fSBjoern A. Zeeb 	txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7;
497*a0ccc12fSBjoern A. Zeeb 	txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi);
498*a0ccc12fSBjoern A. Zeeb 	txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg);
499*a0ccc12fSBjoern A. Zeeb 	txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk);
500*a0ccc12fSBjoern A. Zeeb 	txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be);
501*a0ccc12fSBjoern A. Zeeb 	txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi);
502*a0ccc12fSBjoern A. Zeeb 	txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo);
503*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map);
504*a0ccc12fSBjoern A. Zeeb 
505*a0ccc12fSBjoern A. Zeeb 	/* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */
506*a0ccc12fSBjoern A. Zeeb 	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4)
507*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff);
508*a0ccc12fSBjoern A. Zeeb 
509*a0ccc12fSBjoern A. Zeeb 	return 0;
510*a0ccc12fSBjoern A. Zeeb }
511*a0ccc12fSBjoern A. Zeeb 
512*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_init_wmac_setting(struct rtw_dev *rtwdev)
513*a0ccc12fSBjoern A. Zeeb {
514*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff);
515*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400);
516*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff);
517*a0ccc12fSBjoern A. Zeeb 
518*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_MAR, 0xffffffff);
519*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff);
520*a0ccc12fSBjoern A. Zeeb }
521*a0ccc12fSBjoern A. Zeeb 
522*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_init_adaptive_ctrl(struct rtw_dev *rtwdev)
523*a0ccc12fSBjoern A. Zeeb {
524*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1);
525*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030);
526*a0ccc12fSBjoern A. Zeeb }
527*a0ccc12fSBjoern A. Zeeb 
528*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_init_edca(struct rtw_dev *rtwdev)
529*a0ccc12fSBjoern A. Zeeb {
530*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a);
531*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a);
532*a0ccc12fSBjoern A. Zeeb 
533*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_SIFS, 0x100a);
534*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_SIFS + 2, 0x100a);
535*a0ccc12fSBjoern A. Zeeb 
536*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B);
537*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F);
538*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324);
539*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226);
540*a0ccc12fSBjoern A. Zeeb 
541*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USTIME_TSF, 0x50);
542*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50);
543*a0ccc12fSBjoern A. Zeeb }
544*a0ccc12fSBjoern A. Zeeb 
545*a0ccc12fSBjoern A. Zeeb static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev)
546*a0ccc12fSBjoern A. Zeeb {
547*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
548*a0ccc12fSBjoern A. Zeeb 
549*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0,
550*a0ccc12fSBjoern A. Zeeb 			 chip->usb_tx_agg_desc_num);
551*a0ccc12fSBjoern A. Zeeb 
552*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A)
553*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_DWBCN1_CTRL,
554*a0ccc12fSBjoern A. Zeeb 			   chip->usb_tx_agg_desc_num << 1);
555*a0ccc12fSBjoern A. Zeeb }
556*a0ccc12fSBjoern A. Zeeb 
557*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev)
558*a0ccc12fSBjoern A. Zeeb {
559*a0ccc12fSBjoern A. Zeeb 	u16 val16;
560*a0ccc12fSBjoern A. Zeeb 
561*a0ccc12fSBjoern A. Zeeb 	val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT;
562*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->efuse.btcoex)
563*a0ccc12fSBjoern A. Zeeb 		val16 |= BIT_EN_BCN_FUNCTION;
564*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_BCN_CTRL, val16);
565*a0ccc12fSBjoern A. Zeeb 
566*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME);
567*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_DRVERLYINT, 0x05);
568*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
569*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_BCNTCFG, 0x4413);
570*a0ccc12fSBjoern A. Zeeb }
571*a0ccc12fSBjoern A. Zeeb 
572*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev)
573*a0ccc12fSBjoern A. Zeeb {
574*a0ccc12fSBjoern A. Zeeb 	u8 val8, crystal_cap;
575*a0ccc12fSBjoern A. Zeeb 
576*a0ccc12fSBjoern A. Zeeb 	/* power on BB/RF domain */
577*a0ccc12fSBjoern A. Zeeb 	val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
578*a0ccc12fSBjoern A. Zeeb 	val8 |= BIT_FEN_USBA;
579*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8);
580*a0ccc12fSBjoern A. Zeeb 
581*a0ccc12fSBjoern A. Zeeb 	/* toggle BB reset */
582*a0ccc12fSBjoern A. Zeeb 	val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST;
583*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8);
584*a0ccc12fSBjoern A. Zeeb 
585*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RF_CTRL,
586*a0ccc12fSBjoern A. Zeeb 		   BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
587*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RF_B_CTRL,
588*a0ccc12fSBjoern A. Zeeb 		   BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
589*a0ccc12fSBjoern A. Zeeb 
590*a0ccc12fSBjoern A. Zeeb 	rtw_load_table(rtwdev, rtwdev->chip->bb_tbl);
591*a0ccc12fSBjoern A. Zeeb 	rtw_load_table(rtwdev, rtwdev->chip->agc_tbl);
592*a0ccc12fSBjoern A. Zeeb 
593*a0ccc12fSBjoern A. Zeeb 	crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
594*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
595*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000,
596*a0ccc12fSBjoern A. Zeeb 				 crystal_cap | (crystal_cap << 6));
597*a0ccc12fSBjoern A. Zeeb 	else
598*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000,
599*a0ccc12fSBjoern A. Zeeb 				 crystal_cap | (crystal_cap << 6));
600*a0ccc12fSBjoern A. Zeeb }
601*a0ccc12fSBjoern A. Zeeb 
602*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev)
603*a0ccc12fSBjoern A. Zeeb {
604*a0ccc12fSBjoern A. Zeeb 	u8 rf_path;
605*a0ccc12fSBjoern A. Zeeb 
606*a0ccc12fSBjoern A. Zeeb 	for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++)
607*a0ccc12fSBjoern A. Zeeb 		rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]);
608*a0ccc12fSBjoern A. Zeeb }
609*a0ccc12fSBjoern A. Zeeb 
610*a0ccc12fSBjoern A. Zeeb static void rtw8812a_config_1t(struct rtw_dev *rtwdev)
611*a0ccc12fSBjoern A. Zeeb {
612*a0ccc12fSBjoern A. Zeeb 	/* BB OFDM RX Path_A */
613*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11);
614*a0ccc12fSBjoern A. Zeeb 
615*a0ccc12fSBjoern A. Zeeb 	/* BB OFDM TX Path_A */
616*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111);
617*a0ccc12fSBjoern A. Zeeb 
618*a0ccc12fSBjoern A. Zeeb 	/* BB CCK R/Rx Path_A */
619*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0);
620*a0ccc12fSBjoern A. Zeeb 
621*a0ccc12fSBjoern A. Zeeb 	/* MCS support */
622*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RX_MCS_LIMIT, 0xc0000060, 0x4);
623*a0ccc12fSBjoern A. Zeeb 
624*a0ccc12fSBjoern A. Zeeb 	/* RF Path_B HSSI OFF */
625*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4);
626*a0ccc12fSBjoern A. Zeeb 
627*a0ccc12fSBjoern A. Zeeb 	/* RF Path_B Power Down */
628*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0);
629*a0ccc12fSBjoern A. Zeeb 
630*a0ccc12fSBjoern A. Zeeb 	/* ADDA Path_B OFF */
631*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0);
632*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0);
633*a0ccc12fSBjoern A. Zeeb }
634*a0ccc12fSBjoern A. Zeeb 
635*a0ccc12fSBjoern A. Zeeb static const u32 rtw88xxa_txscale_tbl[] = {
636*a0ccc12fSBjoern A. Zeeb 	0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8,
637*a0ccc12fSBjoern A. Zeeb 	0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180,
638*a0ccc12fSBjoern A. Zeeb 	0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab,
639*a0ccc12fSBjoern A. Zeeb 	0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe
640*a0ccc12fSBjoern A. Zeeb };
641*a0ccc12fSBjoern A. Zeeb 
642*a0ccc12fSBjoern A. Zeeb static u32 rtw88xxa_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path)
643*a0ccc12fSBjoern A. Zeeb {
644*a0ccc12fSBjoern A. Zeeb 	static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6};
645*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
646*a0ccc12fSBjoern A. Zeeb 	u8 tx_bb_swing;
647*a0ccc12fSBjoern A. Zeeb 
648*a0ccc12fSBjoern A. Zeeb 	if (band == RTW_BAND_2G)
649*a0ccc12fSBjoern A. Zeeb 		tx_bb_swing = efuse->tx_bb_swing_setting_2g;
650*a0ccc12fSBjoern A. Zeeb 	else
651*a0ccc12fSBjoern A. Zeeb 		tx_bb_swing = efuse->tx_bb_swing_setting_5g;
652*a0ccc12fSBjoern A. Zeeb 
653*a0ccc12fSBjoern A. Zeeb 	if (path == RF_PATH_B)
654*a0ccc12fSBjoern A. Zeeb 		tx_bb_swing >>= 2;
655*a0ccc12fSBjoern A. Zeeb 	tx_bb_swing &= 0x3;
656*a0ccc12fSBjoern A. Zeeb 
657*a0ccc12fSBjoern A. Zeeb 	return swing2setting[tx_bb_swing];
658*a0ccc12fSBjoern A. Zeeb }
659*a0ccc12fSBjoern A. Zeeb 
660*a0ccc12fSBjoern A. Zeeb static u8 rtw88xxa_get_swing_index(struct rtw_dev *rtwdev)
661*a0ccc12fSBjoern A. Zeeb {
662*a0ccc12fSBjoern A. Zeeb 	u32 swing, table_value;
663*a0ccc12fSBjoern A. Zeeb 	u8 i;
664*a0ccc12fSBjoern A. Zeeb 
665*a0ccc12fSBjoern A. Zeeb 	swing = rtw88xxa_get_bb_swing(rtwdev, rtwdev->hal.current_band_type,
666*a0ccc12fSBjoern A. Zeeb 				      RF_PATH_A);
667*a0ccc12fSBjoern A. Zeeb 
668*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < ARRAY_SIZE(rtw88xxa_txscale_tbl); i++) {
669*a0ccc12fSBjoern A. Zeeb 		table_value = rtw88xxa_txscale_tbl[i];
670*a0ccc12fSBjoern A. Zeeb 		if (swing == table_value)
671*a0ccc12fSBjoern A. Zeeb 			return i;
672*a0ccc12fSBjoern A. Zeeb 	}
673*a0ccc12fSBjoern A. Zeeb 
674*a0ccc12fSBjoern A. Zeeb 	return 24;
675*a0ccc12fSBjoern A. Zeeb }
676*a0ccc12fSBjoern A. Zeeb 
677*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev)
678*a0ccc12fSBjoern A. Zeeb {
679*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
680*a0ccc12fSBjoern A. Zeeb 	u8 path;
681*a0ccc12fSBjoern A. Zeeb 
682*a0ccc12fSBjoern A. Zeeb 	dm_info->default_ofdm_index = rtw88xxa_get_swing_index(rtwdev);
683*a0ccc12fSBjoern A. Zeeb 
684*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A)
685*a0ccc12fSBjoern A. Zeeb 		dm_info->default_cck_index = 0;
686*a0ccc12fSBjoern A. Zeeb 	else
687*a0ccc12fSBjoern A. Zeeb 		dm_info->default_cck_index = 24;
688*a0ccc12fSBjoern A. Zeeb 
689*a0ccc12fSBjoern A. Zeeb 	for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
690*a0ccc12fSBjoern A. Zeeb 		ewma_thermal_init(&dm_info->avg_thermal[path]);
691*a0ccc12fSBjoern A. Zeeb 		dm_info->delta_power_index[path] = 0;
692*a0ccc12fSBjoern A. Zeeb 		dm_info->delta_power_index_last[path] = 0;
693*a0ccc12fSBjoern A. Zeeb 	}
694*a0ccc12fSBjoern A. Zeeb 
695*a0ccc12fSBjoern A. Zeeb 	dm_info->pwr_trk_triggered = false;
696*a0ccc12fSBjoern A. Zeeb 	dm_info->pwr_trk_init_trigger = true;
697*a0ccc12fSBjoern A. Zeeb 	dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
698*a0ccc12fSBjoern A. Zeeb }
699*a0ccc12fSBjoern A. Zeeb 
700*a0ccc12fSBjoern A. Zeeb void rtw88xxa_power_off(struct rtw_dev *rtwdev,
701*a0ccc12fSBjoern A. Zeeb 			const struct rtw_pwr_seq_cmd *const *enter_lps_flow)
702*a0ccc12fSBjoern A. Zeeb {
703*a0ccc12fSBjoern A. Zeeb 	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
704*a0ccc12fSBjoern A. Zeeb 	enum usb_device_speed speed = rtwusb->udev->speed;
705*a0ccc12fSBjoern A. Zeeb 	u16 ori_fsmc0;
706*a0ccc12fSBjoern A. Zeeb 	u8 reg_cr;
707*a0ccc12fSBjoern A. Zeeb 
708*a0ccc12fSBjoern A. Zeeb 	reg_cr = rtw_read8(rtwdev, REG_CR);
709*a0ccc12fSBjoern A. Zeeb 
710*a0ccc12fSBjoern A. Zeeb 	/* Already powered off */
711*a0ccc12fSBjoern A. Zeeb 	if (reg_cr == 0 || reg_cr == 0xEA)
712*a0ccc12fSBjoern A. Zeeb 		return;
713*a0ccc12fSBjoern A. Zeeb 
714*a0ccc12fSBjoern A. Zeeb 	rtw_hci_stop(rtwdev);
715*a0ccc12fSBjoern A. Zeeb 
716*a0ccc12fSBjoern A. Zeeb 	if (!rtwdev->efuse.btcoex)
717*a0ccc12fSBjoern A. Zeeb 		rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC);
718*a0ccc12fSBjoern A. Zeeb 
719*a0ccc12fSBjoern A. Zeeb 	/* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */
720*a0ccc12fSBjoern A. Zeeb 	if (speed == USB_SPEED_SUPER)
721*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_USB_MOD, 0x18);
722*a0ccc12fSBjoern A. Zeeb 
723*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_HISR0, 0xffffffff);
724*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_HISR1, 0xffffffff);
725*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_HIMR0, 0);
726*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_HIMR1, 0);
727*a0ccc12fSBjoern A. Zeeb 
728*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->efuse.btcoex)
729*a0ccc12fSBjoern A. Zeeb 		rtw_coex_power_off_setting(rtwdev);
730*a0ccc12fSBjoern A. Zeeb 
731*a0ccc12fSBjoern A. Zeeb 	ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO);
732*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN);
733*a0ccc12fSBjoern A. Zeeb 
734*a0ccc12fSBjoern A. Zeeb 	/* Stop Tx Report Timer. */
735*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1));
736*a0ccc12fSBjoern A. Zeeb 
737*a0ccc12fSBjoern A. Zeeb 	/* Stop Rx */
738*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_CR, 0);
739*a0ccc12fSBjoern A. Zeeb 
740*a0ccc12fSBjoern A. Zeeb 	rtw_pwr_seq_parser(rtwdev, enter_lps_flow);
741*a0ccc12fSBjoern A. Zeeb 
742*a0ccc12fSBjoern A. Zeeb 	if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)
743*a0ccc12fSBjoern A. Zeeb 		rtw88xxa_reset_8051(rtwdev);
744*a0ccc12fSBjoern A. Zeeb 
745*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2));
746*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_MCUFW_CTRL, 0);
747*a0ccc12fSBjoern A. Zeeb 
748*a0ccc12fSBjoern A. Zeeb 	rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq);
749*a0ccc12fSBjoern A. Zeeb 
750*a0ccc12fSBjoern A. Zeeb 	if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN)
751*a0ccc12fSBjoern A. Zeeb 		rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN);
752*a0ccc12fSBjoern A. Zeeb 
753*a0ccc12fSBjoern A. Zeeb 	clear_bit(RTW_FLAG_POWERON, rtwdev->flags);
754*a0ccc12fSBjoern A. Zeeb }
755*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_power_off);
756*a0ccc12fSBjoern A. Zeeb 
757*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band)
758*a0ccc12fSBjoern A. Zeeb {
759*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK,
760*a0ccc12fSBjoern A. Zeeb 			 rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_A));
761*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK,
762*a0ccc12fSBjoern A. Zeeb 			 rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_B));
763*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_pwrtrack_init(rtwdev);
764*a0ccc12fSBjoern A. Zeeb }
765*a0ccc12fSBjoern A. Zeeb 
766*a0ccc12fSBjoern A. Zeeb static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band)
767*a0ccc12fSBjoern A. Zeeb {
768*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0);
769*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1);
770*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7);
771*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7);
772*a0ccc12fSBjoern A. Zeeb 
773*a0ccc12fSBjoern A. Zeeb 	if (band == RTW_BAND_2G)
774*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1);
775*a0ccc12fSBjoern A. Zeeb 	else
776*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2);
777*a0ccc12fSBjoern A. Zeeb }
778*a0ccc12fSBjoern A. Zeeb 
779*a0ccc12fSBjoern A. Zeeb static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev)
780*a0ccc12fSBjoern A. Zeeb {
781*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
782*a0ccc12fSBjoern A. Zeeb 
783*a0ccc12fSBjoern A. Zeeb 	/* Turn off RF PA and LNA */
784*a0ccc12fSBjoern A. Zeeb 
785*a0ccc12fSBjoern A. Zeeb 	/* 0xCB0[15:12] = 0x7 (LNA_On)*/
786*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7);
787*a0ccc12fSBjoern A. Zeeb 	/* 0xCB0[7:4] = 0x7 (PAPE_A)*/
788*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7);
789*a0ccc12fSBjoern A. Zeeb 
790*a0ccc12fSBjoern A. Zeeb 	if (efuse->ext_lna_2g) {
791*a0ccc12fSBjoern A. Zeeb 		/* Turn on 2.4G External LNA */
792*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1);
793*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0);
794*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2);
795*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2);
796*a0ccc12fSBjoern A. Zeeb 	} else {
797*a0ccc12fSBjoern A. Zeeb 		/* Bypass 2.4G External LNA */
798*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0);
799*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0);
800*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7);
801*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7);
802*a0ccc12fSBjoern A. Zeeb 	}
803*a0ccc12fSBjoern A. Zeeb }
804*a0ccc12fSBjoern A. Zeeb 
805*a0ccc12fSBjoern A. Zeeb static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev)
806*a0ccc12fSBjoern A. Zeeb {
807*a0ccc12fSBjoern A. Zeeb 	/* Turn ON RF PA and LNA */
808*a0ccc12fSBjoern A. Zeeb 
809*a0ccc12fSBjoern A. Zeeb 	/* 0xCB0[15:12] = 0x7 (LNA_On)*/
810*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5);
811*a0ccc12fSBjoern A. Zeeb 	/* 0xCB0[7:4] = 0x7 (PAPE_A)*/
812*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4);
813*a0ccc12fSBjoern A. Zeeb 
814*a0ccc12fSBjoern A. Zeeb 	/* Bypass 2.4G External LNA */
815*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0);
816*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0);
817*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7);
818*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7);
819*a0ccc12fSBjoern A. Zeeb }
820*a0ccc12fSBjoern A. Zeeb 
821*a0ccc12fSBjoern A. Zeeb static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev)
822*a0ccc12fSBjoern A. Zeeb {
823*a0ccc12fSBjoern A. Zeeb 	switch (rtwdev->efuse.rfe_option) {
824*a0ccc12fSBjoern A. Zeeb 	case 0:
825*a0ccc12fSBjoern A. Zeeb 	case 2:
826*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777);
827*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
828*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000);
829*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
830*a0ccc12fSBjoern A. Zeeb 		break;
831*a0ccc12fSBjoern A. Zeeb 	case 1:
832*a0ccc12fSBjoern A. Zeeb 		if (rtwdev->efuse.btcoex) {
833*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777);
834*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
835*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000);
836*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
837*a0ccc12fSBjoern A. Zeeb 		} else {
838*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777);
839*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
840*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000);
841*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
842*a0ccc12fSBjoern A. Zeeb 		}
843*a0ccc12fSBjoern A. Zeeb 		break;
844*a0ccc12fSBjoern A. Zeeb 	case 3:
845*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770);
846*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770);
847*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
848*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
849*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1);
850*a0ccc12fSBjoern A. Zeeb 		break;
851*a0ccc12fSBjoern A. Zeeb 	case 4:
852*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777);
853*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
854*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001);
855*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001);
856*a0ccc12fSBjoern A. Zeeb 		break;
857*a0ccc12fSBjoern A. Zeeb 	case 5:
858*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77);
859*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777);
860*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0));
861*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
862*a0ccc12fSBjoern A. Zeeb 		break;
863*a0ccc12fSBjoern A. Zeeb 	case 6:
864*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770);
865*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770);
866*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077);
867*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077);
868*a0ccc12fSBjoern A. Zeeb 		break;
869*a0ccc12fSBjoern A. Zeeb 	default:
870*a0ccc12fSBjoern A. Zeeb 		break;
871*a0ccc12fSBjoern A. Zeeb 	}
872*a0ccc12fSBjoern A. Zeeb }
873*a0ccc12fSBjoern A. Zeeb 
874*a0ccc12fSBjoern A. Zeeb static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev)
875*a0ccc12fSBjoern A. Zeeb {
876*a0ccc12fSBjoern A. Zeeb 	switch (rtwdev->efuse.rfe_option) {
877*a0ccc12fSBjoern A. Zeeb 	case 0:
878*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717);
879*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717);
880*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
881*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
882*a0ccc12fSBjoern A. Zeeb 		break;
883*a0ccc12fSBjoern A. Zeeb 	case 1:
884*a0ccc12fSBjoern A. Zeeb 		if (rtwdev->efuse.btcoex) {
885*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717);
886*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717);
887*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000);
888*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
889*a0ccc12fSBjoern A. Zeeb 		} else {
890*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717);
891*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717);
892*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000);
893*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000);
894*a0ccc12fSBjoern A. Zeeb 		}
895*a0ccc12fSBjoern A. Zeeb 		break;
896*a0ccc12fSBjoern A. Zeeb 	case 2:
897*a0ccc12fSBjoern A. Zeeb 	case 4:
898*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777);
899*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777);
900*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
901*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
902*a0ccc12fSBjoern A. Zeeb 		break;
903*a0ccc12fSBjoern A. Zeeb 	case 3:
904*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717);
905*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717);
906*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010);
907*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
908*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1);
909*a0ccc12fSBjoern A. Zeeb 		break;
910*a0ccc12fSBjoern A. Zeeb 	case 5:
911*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33);
912*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777);
913*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0));
914*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010);
915*a0ccc12fSBjoern A. Zeeb 		break;
916*a0ccc12fSBjoern A. Zeeb 	case 6:
917*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717);
918*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717);
919*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077);
920*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077);
921*a0ccc12fSBjoern A. Zeeb 		break;
922*a0ccc12fSBjoern A. Zeeb 	default:
923*a0ccc12fSBjoern A. Zeeb 		break;
924*a0ccc12fSBjoern A. Zeeb 	}
925*a0ccc12fSBjoern A. Zeeb }
926*a0ccc12fSBjoern A. Zeeb 
927*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw)
928*a0ccc12fSBjoern A. Zeeb {
929*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
930*a0ccc12fSBjoern A. Zeeb 	u16 basic_rates, reg_41a;
931*a0ccc12fSBjoern A. Zeeb 
932*a0ccc12fSBjoern A. Zeeb 	/* 8811au one antenna module doesn't support antenna div, so driver must
933*a0ccc12fSBjoern A. Zeeb 	 * control antenna band, otherwise one of the band will have issue
934*a0ccc12fSBjoern A. Zeeb 	 */
935*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex &&
936*a0ccc12fSBjoern A. Zeeb 	    rtwdev->efuse.ant_div_cfg == 0)
937*a0ccc12fSBjoern A. Zeeb 		rtw8821a_set_ext_band_switch(rtwdev, new_band);
938*a0ccc12fSBjoern A. Zeeb 
939*a0ccc12fSBjoern A. Zeeb 	if (new_band == RTW_BAND_2G) {
940*a0ccc12fSBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
941*a0ccc12fSBjoern A. Zeeb 
942*a0ccc12fSBjoern A. Zeeb 		if (chip->id == RTW_CHIP_TYPE_8821A) {
943*a0ccc12fSBjoern A. Zeeb 			rtw8821a_phy_set_rfe_reg_24g(rtwdev);
944*a0ccc12fSBjoern A. Zeeb 
945*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0);
946*a0ccc12fSBjoern A. Zeeb 		} else {
947*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1);
948*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17);
949*a0ccc12fSBjoern A. Zeeb 
950*a0ccc12fSBjoern A. Zeeb 			if (bw == RTW_CHANNEL_WIDTH_20 &&
951*a0ccc12fSBjoern A. Zeeb 			    rtwdev->hal.rf_type == RF_1T1R &&
952*a0ccc12fSBjoern A. Zeeb 			    !rtwdev->efuse.ext_lna_2g)
953*a0ccc12fSBjoern A. Zeeb 				rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02);
954*a0ccc12fSBjoern A. Zeeb 			else
955*a0ccc12fSBjoern A. Zeeb 				rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04);
956*a0ccc12fSBjoern A. Zeeb 
957*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0);
958*a0ccc12fSBjoern A. Zeeb 
959*a0ccc12fSBjoern A. Zeeb 			rtw8812a_phy_set_rfe_reg_24g(rtwdev);
960*a0ccc12fSBjoern A. Zeeb 		}
961*a0ccc12fSBjoern A. Zeeb 
962*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1);
963*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1);
964*a0ccc12fSBjoern A. Zeeb 
965*a0ccc12fSBjoern A. Zeeb 		basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) |
966*a0ccc12fSBjoern A. Zeeb 			      BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) |
967*a0ccc12fSBjoern A. Zeeb 			      BIT(DESC_RATE6M) | BIT(DESC_RATE12M) |
968*a0ccc12fSBjoern A. Zeeb 			      BIT(DESC_RATE24M);
969*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates);
970*a0ccc12fSBjoern A. Zeeb 
971*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN);
972*a0ccc12fSBjoern A. Zeeb 	} else { /* RTW_BAND_5G */
973*a0ccc12fSBjoern A. Zeeb 		if (chip->id == RTW_CHIP_TYPE_8821A)
974*a0ccc12fSBjoern A. Zeeb 			rtw8821a_phy_set_rfe_reg_5g(rtwdev);
975*a0ccc12fSBjoern A. Zeeb 
976*a0ccc12fSBjoern A. Zeeb 		rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN);
977*a0ccc12fSBjoern A. Zeeb 
978*a0ccc12fSBjoern A. Zeeb 		read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30,
979*a0ccc12fSBjoern A. Zeeb 					 50, 2500, false, rtwdev, REG_TXPKT_EMPTY);
980*a0ccc12fSBjoern A. Zeeb 
981*a0ccc12fSBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
982*a0ccc12fSBjoern A. Zeeb 
983*a0ccc12fSBjoern A. Zeeb 		if (chip->id == RTW_CHIP_TYPE_8821A) {
984*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1);
985*a0ccc12fSBjoern A. Zeeb 		} else {
986*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2);
987*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15);
988*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04);
989*a0ccc12fSBjoern A. Zeeb 
990*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1);
991*a0ccc12fSBjoern A. Zeeb 
992*a0ccc12fSBjoern A. Zeeb 			rtw8812a_phy_set_rfe_reg_5g(rtwdev);
993*a0ccc12fSBjoern A. Zeeb 		}
994*a0ccc12fSBjoern A. Zeeb 
995*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0);
996*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf);
997*a0ccc12fSBjoern A. Zeeb 
998*a0ccc12fSBjoern A. Zeeb 		basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) |
999*a0ccc12fSBjoern A. Zeeb 			      BIT(DESC_RATE24M);
1000*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates);
1001*a0ccc12fSBjoern A. Zeeb 	}
1002*a0ccc12fSBjoern A. Zeeb 
1003*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_set_channel_bb_swing(rtwdev, new_band);
1004*a0ccc12fSBjoern A. Zeeb }
1005*a0ccc12fSBjoern A. Zeeb 
1006*a0ccc12fSBjoern A. Zeeb int rtw88xxa_power_on(struct rtw_dev *rtwdev)
1007*a0ccc12fSBjoern A. Zeeb {
1008*a0ccc12fSBjoern A. Zeeb 	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
1009*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
1010*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
1011*a0ccc12fSBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
1012*a0ccc12fSBjoern A. Zeeb 	int ret;
1013*a0ccc12fSBjoern A. Zeeb 
1014*a0ccc12fSBjoern A. Zeeb 	if (test_bit(RTW_FLAG_POWERON, rtwdev->flags))
1015*a0ccc12fSBjoern A. Zeeb 		return 0;
1016*a0ccc12fSBjoern A. Zeeb 
1017*a0ccc12fSBjoern A. Zeeb 	/* Override rtw_chip_efuse_info_setup() */
1018*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A)
1019*a0ccc12fSBjoern A. Zeeb 		efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL,
1020*a0ccc12fSBjoern A. Zeeb 						BIT_BT_FUNC_EN);
1021*a0ccc12fSBjoern A. Zeeb 
1022*a0ccc12fSBjoern A. Zeeb 	/* Override rtw_chip_efuse_info_setup() */
1023*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A)
1024*a0ccc12fSBjoern A. Zeeb 		rtw8812a_read_amplifier_type(rtwdev);
1025*a0ccc12fSBjoern A. Zeeb 
1026*a0ccc12fSBjoern A. Zeeb 	ret = rtw_hci_setup(rtwdev);
1027*a0ccc12fSBjoern A. Zeeb 	if (ret) {
1028*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "failed to setup hci\n");
1029*a0ccc12fSBjoern A. Zeeb 		goto err;
1030*a0ccc12fSBjoern A. Zeeb 	}
1031*a0ccc12fSBjoern A. Zeeb 
1032*a0ccc12fSBjoern A. Zeeb 	/* Revise for U2/U3 switch we can not update RF-A/B reset.
1033*a0ccc12fSBjoern A. Zeeb 	 * Reset after MAC power on to prevent RF R/W error.
1034*a0ccc12fSBjoern A. Zeeb 	 * Is it a right method?
1035*a0ccc12fSBjoern A. Zeeb 	 */
1036*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A) {
1037*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RF_CTRL, 5);
1038*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RF_CTRL, 7);
1039*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RF_B_CTRL, 5);
1040*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_RF_B_CTRL, 7);
1041*a0ccc12fSBjoern A. Zeeb 	}
1042*a0ccc12fSBjoern A. Zeeb 
1043*a0ccc12fSBjoern A. Zeeb 	/* If HW didn't go through a complete de-initial procedure,
1044*a0ccc12fSBjoern A. Zeeb 	 * it probably occurs some problem for double initial
1045*a0ccc12fSBjoern A. Zeeb 	 * procedure.
1046*a0ccc12fSBjoern A. Zeeb 	 */
1047*a0ccc12fSBjoern A. Zeeb 	rtw88xxau_hw_reset(rtwdev);
1048*a0ccc12fSBjoern A. Zeeb 
1049*a0ccc12fSBjoern A. Zeeb 	ret = rtw88xxau_init_power_on(rtwdev);
1050*a0ccc12fSBjoern A. Zeeb 	if (ret) {
1051*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "failed to power on\n");
1052*a0ccc12fSBjoern A. Zeeb 		goto err;
1053*a0ccc12fSBjoern A. Zeeb 	}
1054*a0ccc12fSBjoern A. Zeeb 
1055*a0ccc12fSBjoern A. Zeeb 	ret = rtw_set_trx_fifo_info(rtwdev);
1056*a0ccc12fSBjoern A. Zeeb 	if (ret) {
1057*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "failed to set trx fifo info\n");
1058*a0ccc12fSBjoern A. Zeeb 		goto err;
1059*a0ccc12fSBjoern A. Zeeb 	}
1060*a0ccc12fSBjoern A. Zeeb 
1061*a0ccc12fSBjoern A. Zeeb 	ret = rtw88xxa_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary);
1062*a0ccc12fSBjoern A. Zeeb 	if (ret) {
1063*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "failed to init llt\n");
1064*a0ccc12fSBjoern A. Zeeb 		goto err;
1065*a0ccc12fSBjoern A. Zeeb 	}
1066*a0ccc12fSBjoern A. Zeeb 
1067*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);
1068*a0ccc12fSBjoern A. Zeeb 
1069*a0ccc12fSBjoern A. Zeeb 	ret = rtw_wait_firmware_completion(rtwdev);
1070*a0ccc12fSBjoern A. Zeeb 	if (ret) {
1071*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "failed to wait firmware completion\n");
1072*a0ccc12fSBjoern A. Zeeb 		goto err_off;
1073*a0ccc12fSBjoern A. Zeeb 	}
1074*a0ccc12fSBjoern A. Zeeb 
1075*a0ccc12fSBjoern A. Zeeb 	ret = rtw_download_firmware(rtwdev, &rtwdev->fw);
1076*a0ccc12fSBjoern A. Zeeb 	if (ret) {
1077*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "failed to download firmware\n");
1078*a0ccc12fSBjoern A. Zeeb 		goto err_off;
1079*a0ccc12fSBjoern A. Zeeb 	}
1080*a0ccc12fSBjoern A. Zeeb 
1081*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_HMETFR, 0xf);
1082*a0ccc12fSBjoern A. Zeeb 
1083*a0ccc12fSBjoern A. Zeeb 	rtw_load_table(rtwdev, chip->mac_tbl);
1084*a0ccc12fSBjoern A. Zeeb 
1085*a0ccc12fSBjoern A. Zeeb 	rtw88xxau_init_queue_reserved_page(rtwdev);
1086*a0ccc12fSBjoern A. Zeeb 	rtw88xxau_init_tx_buffer_boundary(rtwdev);
1087*a0ccc12fSBjoern A. Zeeb 	rtw88xxau_init_queue_priority(rtwdev);
1088*a0ccc12fSBjoern A. Zeeb 
1089*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_TRXFF_BNDY + 2,
1090*a0ccc12fSBjoern A. Zeeb 		    chip->rxff_size - REPORT_BUF - 1);
1091*a0ccc12fSBjoern A. Zeeb 
1092*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A)
1093*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_PBP,
1094*a0ccc12fSBjoern A. Zeeb 			   u8_encode_bits(PBP_512, PBP_TX_MASK) |
1095*a0ccc12fSBjoern A. Zeeb 			   u8_encode_bits(PBP_64, PBP_RX_MASK));
1096*a0ccc12fSBjoern A. Zeeb 
1097*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE);
1098*a0ccc12fSBjoern A. Zeeb 
1099*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_HIMR0, 0);
1100*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_HIMR1, 0);
1101*a0ccc12fSBjoern A. Zeeb 
1102*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2);
1103*a0ccc12fSBjoern A. Zeeb 
1104*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_init_wmac_setting(rtwdev);
1105*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_init_adaptive_ctrl(rtwdev);
1106*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_init_edca(rtwdev);
1107*a0ccc12fSBjoern A. Zeeb 
1108*a0ccc12fSBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7));
1109*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_ACKTO, 0x80);
1110*a0ccc12fSBjoern A. Zeeb 
1111*a0ccc12fSBjoern A. Zeeb 	rtw88xxau_tx_aggregation(rtwdev);
1112*a0ccc12fSBjoern A. Zeeb 
1113*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_init_beacon_parameters(rtwdev);
1114*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff);
1115*a0ccc12fSBjoern A. Zeeb 
1116*a0ccc12fSBjoern A. Zeeb 	rtw_hci_interface_cfg(rtwdev);
1117*a0ccc12fSBjoern A. Zeeb 
1118*a0ccc12fSBjoern A. Zeeb 	/* usb3 rx interval */
1119*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USB3_RXITV, 0x01);
1120*a0ccc12fSBjoern A. Zeeb 
1121*a0ccc12fSBjoern A. Zeeb 	/* burst length=4, set 0x3400 for burst length=2 */
1122*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400);
1123*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5);
1124*a0ccc12fSBjoern A. Zeeb 
1125*a0ccc12fSBjoern A. Zeeb 	/* 0x456 = 0x70, sugguested by Zhilin */
1126*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A)
1127*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e);
1128*a0ccc12fSBjoern A. Zeeb 	else
1129*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70);
1130*a0ccc12fSBjoern A. Zeeb 
1131*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff);
1132*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USTIME_TSF, 0x50);
1133*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50);
1134*a0ccc12fSBjoern A. Zeeb 
1135*a0ccc12fSBjoern A. Zeeb 	if (rtwusb->udev->speed == USB_SPEED_SUPER)
1136*a0ccc12fSBjoern A. Zeeb 		/* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */
1137*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3));
1138*a0ccc12fSBjoern A. Zeeb 
1139*a0ccc12fSBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU);
1140*a0ccc12fSBjoern A. Zeeb 
1141*a0ccc12fSBjoern A. Zeeb 	/* for VHT packet length 11K */
1142*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18);
1143*a0ccc12fSBjoern A. Zeeb 
1144*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_PIFS, 0x00);
1145*a0ccc12fSBjoern A. Zeeb 
1146*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A) {
1147*a0ccc12fSBjoern A. Zeeb 		/* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */
1148*a0ccc12fSBjoern A. Zeeb 		rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f);
1149*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80);
1150*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777);
1151*a0ccc12fSBjoern A. Zeeb 	} else {
1152*a0ccc12fSBjoern A. Zeeb 		rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f);
1153*a0ccc12fSBjoern A. Zeeb 		rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7));
1154*a0ccc12fSBjoern A. Zeeb 	}
1155*a0ccc12fSBjoern A. Zeeb 
1156*a0ccc12fSBjoern A. Zeeb 	 /* to prevent mac is reseted by bus. */
1157*a0ccc12fSBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6));
1158*a0ccc12fSBjoern A. Zeeb 
1159*a0ccc12fSBjoern A. Zeeb 	/* ARFB table 9 for 11ac 5G 2SS */
1160*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR0, 0x00000010);
1161*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000);
1162*a0ccc12fSBjoern A. Zeeb 
1163*a0ccc12fSBjoern A. Zeeb 	/* ARFB table 10 for 11ac 5G 1SS */
1164*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010);
1165*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000);
1166*a0ccc12fSBjoern A. Zeeb 
1167*a0ccc12fSBjoern A. Zeeb 	/* ARFB table 11 for 11ac 24G 1SS */
1168*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015);
1169*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000);
1170*a0ccc12fSBjoern A. Zeeb 
1171*a0ccc12fSBjoern A. Zeeb 	/* ARFB table 12 for 11ac 24G 2SS */
1172*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015);
1173*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000);
1174*a0ccc12fSBjoern A. Zeeb 
1175*a0ccc12fSBjoern A. Zeeb 	rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN);
1176*a0ccc12fSBjoern A. Zeeb 
1177*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_phy_bb_config(rtwdev);
1178*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_phy_rf_config(rtwdev);
1179*a0ccc12fSBjoern A. Zeeb 
1180*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1)
1181*a0ccc12fSBjoern A. Zeeb 		rtw8812a_config_1t(rtwdev);
1182*a0ccc12fSBjoern A. Zeeb 
1183*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20);
1184*a0ccc12fSBjoern A. Zeeb 
1185*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30));
1186*a0ccc12fSBjoern A. Zeeb 
1187*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff);
1188*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff);
1189*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0);
1190*a0ccc12fSBjoern A. Zeeb 
1191*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5));
1192*a0ccc12fSBjoern A. Zeeb 
1193*a0ccc12fSBjoern A. Zeeb 	rtw_phy_init(rtwdev);
1194*a0ccc12fSBjoern A. Zeeb 
1195*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_pwrtrack_init(rtwdev);
1196*a0ccc12fSBjoern A. Zeeb 
1197*a0ccc12fSBjoern A. Zeeb 	/* 0x4c6[3] 1: RTS BW = Data BW
1198*a0ccc12fSBjoern A. Zeeb 	 * 0: RTS BW depends on CCA / secondary CCA result.
1199*a0ccc12fSBjoern A. Zeeb 	 */
1200*a0ccc12fSBjoern A. Zeeb 	rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3));
1201*a0ccc12fSBjoern A. Zeeb 
1202*a0ccc12fSBjoern A. Zeeb 	/* enable Tx report. */
1203*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f);
1204*a0ccc12fSBjoern A. Zeeb 
1205*a0ccc12fSBjoern A. Zeeb 	/* Pretx_en, for WEP/TKIP SEC */
1206*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01);
1207*a0ccc12fSBjoern A. Zeeb 
1208*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0);
1209*a0ccc12fSBjoern A. Zeeb 
1210*a0ccc12fSBjoern A. Zeeb 	/* Reset USB mode switch setting */
1211*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0);
1212*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_ACLK_MON, 0x0);
1213*a0ccc12fSBjoern A. Zeeb 
1214*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_USB_HRPWM, 0);
1215*a0ccc12fSBjoern A. Zeeb 
1216*a0ccc12fSBjoern A. Zeeb 	/* ack for xmit mgmt frames. */
1217*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12));
1218*a0ccc12fSBjoern A. Zeeb 
1219*a0ccc12fSBjoern A. Zeeb 	hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT,
1220*a0ccc12fSBjoern A. Zeeb 					      BIT_CCK_RPT_FORMAT);
1221*a0ccc12fSBjoern A. Zeeb 
1222*a0ccc12fSBjoern A. Zeeb 	ret = rtw_hci_start(rtwdev);
1223*a0ccc12fSBjoern A. Zeeb 	if (ret) {
1224*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "failed to start hci\n");
1225*a0ccc12fSBjoern A. Zeeb 		goto err_off;
1226*a0ccc12fSBjoern A. Zeeb 	}
1227*a0ccc12fSBjoern A. Zeeb 
1228*a0ccc12fSBjoern A. Zeeb 	if (efuse->btcoex) {
1229*a0ccc12fSBjoern A. Zeeb 		rtw_coex_power_on_setting(rtwdev);
1230*a0ccc12fSBjoern A. Zeeb 		rtw_coex_init_hw_config(rtwdev, false);
1231*a0ccc12fSBjoern A. Zeeb 	}
1232*a0ccc12fSBjoern A. Zeeb 
1233*a0ccc12fSBjoern A. Zeeb 	set_bit(RTW_FLAG_POWERON, rtwdev->flags);
1234*a0ccc12fSBjoern A. Zeeb 
1235*a0ccc12fSBjoern A. Zeeb 	return 0;
1236*a0ccc12fSBjoern A. Zeeb 
1237*a0ccc12fSBjoern A. Zeeb err_off:
1238*a0ccc12fSBjoern A. Zeeb 	chip->ops->power_off(rtwdev);
1239*a0ccc12fSBjoern A. Zeeb 
1240*a0ccc12fSBjoern A. Zeeb err:
1241*a0ccc12fSBjoern A. Zeeb 	return ret;
1242*a0ccc12fSBjoern A. Zeeb }
1243*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_power_on);
1244*a0ccc12fSBjoern A. Zeeb 
1245*a0ccc12fSBjoern A. Zeeb u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev,
1246*a0ccc12fSBjoern A. Zeeb 			 enum rtw_rf_path rf_path, u32 addr, u32 mask)
1247*a0ccc12fSBjoern A. Zeeb {
1248*a0ccc12fSBjoern A. Zeeb 	static const u32 pi_addr[2] = { REG_3WIRE_SWA, REG_3WIRE_SWB };
1249*a0ccc12fSBjoern A. Zeeb 	static const u32 read_addr[2][2] = {
1250*a0ccc12fSBjoern A. Zeeb 		{ REG_SI_READ_A, REG_SI_READ_B },
1251*a0ccc12fSBjoern A. Zeeb 		{ REG_PI_READ_A, REG_PI_READ_B }
1252*a0ccc12fSBjoern A. Zeeb 	};
1253*a0ccc12fSBjoern A. Zeeb 	const struct rtw_chip_info *chip = rtwdev->chip;
1254*a0ccc12fSBjoern A. Zeeb 	const struct rtw_hal *hal = &rtwdev->hal;
1255*a0ccc12fSBjoern A. Zeeb 	bool set_cca, pi_mode;
1256*a0ccc12fSBjoern A. Zeeb 	u32 val;
1257*a0ccc12fSBjoern A. Zeeb 
1258*a0ccc12fSBjoern A. Zeeb 	if (rf_path >= hal->rf_phy_num) {
1259*a0ccc12fSBjoern A. Zeeb 		rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
1260*a0ccc12fSBjoern A. Zeeb 		return INV_RF_DATA;
1261*a0ccc12fSBjoern A. Zeeb 	}
1262*a0ccc12fSBjoern A. Zeeb 
1263*a0ccc12fSBjoern A. Zeeb 	/* CCA off to avoid reading the wrong value.
1264*a0ccc12fSBjoern A. Zeeb 	 * Toggling CCA would affect RF 0x0, skip it.
1265*a0ccc12fSBjoern A. Zeeb 	 */
1266*a0ccc12fSBjoern A. Zeeb 	set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A &&
1267*a0ccc12fSBjoern A. Zeeb 		  hal->cut_version != RTW_CHIP_VER_CUT_C;
1268*a0ccc12fSBjoern A. Zeeb 
1269*a0ccc12fSBjoern A. Zeeb 	if (set_cca)
1270*a0ccc12fSBjoern A. Zeeb 		rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3));
1271*a0ccc12fSBjoern A. Zeeb 
1272*a0ccc12fSBjoern A. Zeeb 	addr &= 0xff;
1273*a0ccc12fSBjoern A. Zeeb 
1274*a0ccc12fSBjoern A. Zeeb 	pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4);
1275*a0ccc12fSBjoern A. Zeeb 
1276*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr);
1277*a0ccc12fSBjoern A. Zeeb 
1278*a0ccc12fSBjoern A. Zeeb 	if (chip->id == RTW_CHIP_TYPE_8821A ||
1279*a0ccc12fSBjoern A. Zeeb 	    hal->cut_version == RTW_CHIP_VER_CUT_C)
1280*a0ccc12fSBjoern A. Zeeb 		udelay(20);
1281*a0ccc12fSBjoern A. Zeeb 
1282*a0ccc12fSBjoern A. Zeeb 	val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask);
1283*a0ccc12fSBjoern A. Zeeb 
1284*a0ccc12fSBjoern A. Zeeb 	/* CCA on */
1285*a0ccc12fSBjoern A. Zeeb 	if (set_cca)
1286*a0ccc12fSBjoern A. Zeeb 		rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3));
1287*a0ccc12fSBjoern A. Zeeb 
1288*a0ccc12fSBjoern A. Zeeb 	return val;
1289*a0ccc12fSBjoern A. Zeeb }
1290*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_phy_read_rf);
1291*a0ccc12fSBjoern A. Zeeb 
1292*a0ccc12fSBjoern A. Zeeb static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw)
1293*a0ccc12fSBjoern A. Zeeb {
1294*a0ccc12fSBjoern A. Zeeb 	/* C cut Item12 ADC FIFO CLOCK */
1295*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) {
1296*a0ccc12fSBjoern A. Zeeb 		if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11)
1297*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3);
1298*a0ccc12fSBjoern A. Zeeb 		else
1299*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2);
1300*a0ccc12fSBjoern A. Zeeb 
1301*a0ccc12fSBjoern A. Zeeb 		/* A workaround to resolve 2480Mhz spur by setting ADC clock
1302*a0ccc12fSBjoern A. Zeeb 		 * as 160M.
1303*a0ccc12fSBjoern A. Zeeb 		 */
1304*a0ccc12fSBjoern A. Zeeb 		if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) {
1305*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3);
1306*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1);
1307*a0ccc12fSBjoern A. Zeeb 		} else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) {
1308*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1);
1309*a0ccc12fSBjoern A. Zeeb 		} else if (bw != RTW_CHANNEL_WIDTH_80) {
1310*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2);
1311*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0);
1312*a0ccc12fSBjoern A. Zeeb 		}
1313*a0ccc12fSBjoern A. Zeeb 	} else {
1314*a0ccc12fSBjoern A. Zeeb 		/* A workaround to resolve 2480Mhz spur by setting ADC clock
1315*a0ccc12fSBjoern A. Zeeb 		 * as 160M.
1316*a0ccc12fSBjoern A. Zeeb 		 */
1317*a0ccc12fSBjoern A. Zeeb 		if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14))
1318*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3);
1319*a0ccc12fSBjoern A. Zeeb 		else if (channel <= 14) /* 2.4G only */
1320*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2);
1321*a0ccc12fSBjoern A. Zeeb 	}
1322*a0ccc12fSBjoern A. Zeeb }
1323*a0ccc12fSBjoern A. Zeeb 
1324*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw)
1325*a0ccc12fSBjoern A. Zeeb {
1326*a0ccc12fSBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
1327*a0ccc12fSBjoern A. Zeeb 	u32 fc_area, rf_mod_ag;
1328*a0ccc12fSBjoern A. Zeeb 	u8 path;
1329*a0ccc12fSBjoern A. Zeeb 
1330*a0ccc12fSBjoern A. Zeeb 	switch (channel) {
1331*a0ccc12fSBjoern A. Zeeb 	case 36 ... 48:
1332*a0ccc12fSBjoern A. Zeeb 		fc_area = 0x494;
1333*a0ccc12fSBjoern A. Zeeb 		break;
1334*a0ccc12fSBjoern A. Zeeb 	case 50 ... 64:
1335*a0ccc12fSBjoern A. Zeeb 		fc_area = 0x453;
1336*a0ccc12fSBjoern A. Zeeb 		break;
1337*a0ccc12fSBjoern A. Zeeb 	case 100 ... 116:
1338*a0ccc12fSBjoern A. Zeeb 		fc_area = 0x452;
1339*a0ccc12fSBjoern A. Zeeb 		break;
1340*a0ccc12fSBjoern A. Zeeb 	default:
1341*a0ccc12fSBjoern A. Zeeb 		if (channel >= 118)
1342*a0ccc12fSBjoern A. Zeeb 			fc_area = 0x412;
1343*a0ccc12fSBjoern A. Zeeb 		else
1344*a0ccc12fSBjoern A. Zeeb 			fc_area = 0x96a;
1345*a0ccc12fSBjoern A. Zeeb 		break;
1346*a0ccc12fSBjoern A. Zeeb 	}
1347*a0ccc12fSBjoern A. Zeeb 
1348*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area);
1349*a0ccc12fSBjoern A. Zeeb 
1350*a0ccc12fSBjoern A. Zeeb 	for (path = 0; path < hal->rf_path_num; path++) {
1351*a0ccc12fSBjoern A. Zeeb 		switch (channel) {
1352*a0ccc12fSBjoern A. Zeeb 		case 36 ... 64:
1353*a0ccc12fSBjoern A. Zeeb 			rf_mod_ag = 0x101;
1354*a0ccc12fSBjoern A. Zeeb 			break;
1355*a0ccc12fSBjoern A. Zeeb 		case 100 ... 140:
1356*a0ccc12fSBjoern A. Zeeb 			rf_mod_ag = 0x301;
1357*a0ccc12fSBjoern A. Zeeb 			break;
1358*a0ccc12fSBjoern A. Zeeb 		default:
1359*a0ccc12fSBjoern A. Zeeb 			if (channel > 140)
1360*a0ccc12fSBjoern A. Zeeb 				rf_mod_ag = 0x501;
1361*a0ccc12fSBjoern A. Zeeb 			else
1362*a0ccc12fSBjoern A. Zeeb 				rf_mod_ag = 0x000;
1363*a0ccc12fSBjoern A. Zeeb 			break;
1364*a0ccc12fSBjoern A. Zeeb 		}
1365*a0ccc12fSBjoern A. Zeeb 
1366*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_CFGCH,
1367*a0ccc12fSBjoern A. Zeeb 			     RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag);
1368*a0ccc12fSBjoern A. Zeeb 
1369*a0ccc12fSBjoern A. Zeeb 		if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
1370*a0ccc12fSBjoern A. Zeeb 			rtw8812a_phy_fix_spur(rtwdev, channel, bw);
1371*a0ccc12fSBjoern A. Zeeb 
1372*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_CHANNEL_MASK, channel);
1373*a0ccc12fSBjoern A. Zeeb 	}
1374*a0ccc12fSBjoern A. Zeeb }
1375*a0ccc12fSBjoern A. Zeeb 
1376*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_set_reg_bw(struct rtw_dev *rtwdev, u8 bw)
1377*a0ccc12fSBjoern A. Zeeb {
1378*a0ccc12fSBjoern A. Zeeb 	u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL);
1379*a0ccc12fSBjoern A. Zeeb 
1380*a0ccc12fSBjoern A. Zeeb 	val16 &= ~BIT_RFMOD;
1381*a0ccc12fSBjoern A. Zeeb 	if (bw == RTW_CHANNEL_WIDTH_80)
1382*a0ccc12fSBjoern A. Zeeb 		val16 |= BIT_RFMOD_80M;
1383*a0ccc12fSBjoern A. Zeeb 	else if (bw == RTW_CHANNEL_WIDTH_40)
1384*a0ccc12fSBjoern A. Zeeb 		val16 |= BIT_RFMOD_40M;
1385*a0ccc12fSBjoern A. Zeeb 
1386*a0ccc12fSBjoern A. Zeeb 	rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16);
1387*a0ccc12fSBjoern A. Zeeb }
1388*a0ccc12fSBjoern A. Zeeb 
1389*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel,
1390*a0ccc12fSBjoern A. Zeeb 				      u8 bw, u8 primary_chan_idx)
1391*a0ccc12fSBjoern A. Zeeb {
1392*a0ccc12fSBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
1393*a0ccc12fSBjoern A. Zeeb 	u8 txsc40 = 0, txsc20, txsc;
1394*a0ccc12fSBjoern A. Zeeb 	u8 reg_837, l1pkval;
1395*a0ccc12fSBjoern A. Zeeb 
1396*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_set_reg_bw(rtwdev, bw);
1397*a0ccc12fSBjoern A. Zeeb 
1398*a0ccc12fSBjoern A. Zeeb 	txsc20 = primary_chan_idx;
1399*a0ccc12fSBjoern A. Zeeb 	if (bw == RTW_CHANNEL_WIDTH_80) {
1400*a0ccc12fSBjoern A. Zeeb 		if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST)
1401*a0ccc12fSBjoern A. Zeeb 			txsc40 = RTW_SC_40_UPPER;
1402*a0ccc12fSBjoern A. Zeeb 		else
1403*a0ccc12fSBjoern A. Zeeb 			txsc40 = RTW_SC_40_LOWER;
1404*a0ccc12fSBjoern A. Zeeb 	}
1405*a0ccc12fSBjoern A. Zeeb 
1406*a0ccc12fSBjoern A. Zeeb 	txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40);
1407*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_DATA_SC, txsc);
1408*a0ccc12fSBjoern A. Zeeb 
1409*a0ccc12fSBjoern A. Zeeb 	reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3);
1410*a0ccc12fSBjoern A. Zeeb 
1411*a0ccc12fSBjoern A. Zeeb 	switch (bw) {
1412*a0ccc12fSBjoern A. Zeeb 	default:
1413*a0ccc12fSBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_20:
1414*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200);
1415*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0);
1416*a0ccc12fSBjoern A. Zeeb 
1417*a0ccc12fSBjoern A. Zeeb 		if (hal->rf_type == RF_2T2R)
1418*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7);
1419*a0ccc12fSBjoern A. Zeeb 		else
1420*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8);
1421*a0ccc12fSBjoern A. Zeeb 
1422*a0ccc12fSBjoern A. Zeeb 		break;
1423*a0ccc12fSBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_40:
1424*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201);
1425*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0);
1426*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc);
1427*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc);
1428*a0ccc12fSBjoern A. Zeeb 
1429*a0ccc12fSBjoern A. Zeeb 		if (reg_837 & BIT(2)) {
1430*a0ccc12fSBjoern A. Zeeb 			l1pkval = 6;
1431*a0ccc12fSBjoern A. Zeeb 		} else {
1432*a0ccc12fSBjoern A. Zeeb 			if (hal->rf_type == RF_2T2R)
1433*a0ccc12fSBjoern A. Zeeb 				l1pkval = 7;
1434*a0ccc12fSBjoern A. Zeeb 			else
1435*a0ccc12fSBjoern A. Zeeb 				l1pkval = 8;
1436*a0ccc12fSBjoern A. Zeeb 		}
1437*a0ccc12fSBjoern A. Zeeb 
1438*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval);
1439*a0ccc12fSBjoern A. Zeeb 
1440*a0ccc12fSBjoern A. Zeeb 		if (txsc == RTW_SC_20_UPPER)
1441*a0ccc12fSBjoern A. Zeeb 			rtw_write32_set(rtwdev, REG_RXSB, BIT(4));
1442*a0ccc12fSBjoern A. Zeeb 		else
1443*a0ccc12fSBjoern A. Zeeb 			rtw_write32_clr(rtwdev, REG_RXSB, BIT(4));
1444*a0ccc12fSBjoern A. Zeeb 
1445*a0ccc12fSBjoern A. Zeeb 		break;
1446*a0ccc12fSBjoern A. Zeeb 	case RTW_CHANNEL_WIDTH_80:
1447*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202);
1448*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1);
1449*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc);
1450*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc);
1451*a0ccc12fSBjoern A. Zeeb 
1452*a0ccc12fSBjoern A. Zeeb 		if (reg_837 & BIT(2)) {
1453*a0ccc12fSBjoern A. Zeeb 			l1pkval = 5;
1454*a0ccc12fSBjoern A. Zeeb 		} else {
1455*a0ccc12fSBjoern A. Zeeb 			if (hal->rf_type == RF_2T2R)
1456*a0ccc12fSBjoern A. Zeeb 				l1pkval = 6;
1457*a0ccc12fSBjoern A. Zeeb 			else
1458*a0ccc12fSBjoern A. Zeeb 				l1pkval = 7;
1459*a0ccc12fSBjoern A. Zeeb 		}
1460*a0ccc12fSBjoern A. Zeeb 
1461*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval);
1462*a0ccc12fSBjoern A. Zeeb 
1463*a0ccc12fSBjoern A. Zeeb 		break;
1464*a0ccc12fSBjoern A. Zeeb 	}
1465*a0ccc12fSBjoern A. Zeeb }
1466*a0ccc12fSBjoern A. Zeeb 
1467*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
1468*a0ccc12fSBjoern A. Zeeb {
1469*a0ccc12fSBjoern A. Zeeb 	u8 path;
1470*a0ccc12fSBjoern A. Zeeb 
1471*a0ccc12fSBjoern A. Zeeb 	for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
1472*a0ccc12fSBjoern A. Zeeb 		switch (bw) {
1473*a0ccc12fSBjoern A. Zeeb 		case RTW_CHANNEL_WIDTH_5:
1474*a0ccc12fSBjoern A. Zeeb 		case RTW_CHANNEL_WIDTH_10:
1475*a0ccc12fSBjoern A. Zeeb 		case RTW_CHANNEL_WIDTH_20:
1476*a0ccc12fSBjoern A. Zeeb 		default:
1477*a0ccc12fSBjoern A. Zeeb 			rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3);
1478*a0ccc12fSBjoern A. Zeeb 			break;
1479*a0ccc12fSBjoern A. Zeeb 		case RTW_CHANNEL_WIDTH_40:
1480*a0ccc12fSBjoern A. Zeeb 			rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1);
1481*a0ccc12fSBjoern A. Zeeb 			break;
1482*a0ccc12fSBjoern A. Zeeb 		case RTW_CHANNEL_WIDTH_80:
1483*a0ccc12fSBjoern A. Zeeb 			rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0);
1484*a0ccc12fSBjoern A. Zeeb 			break;
1485*a0ccc12fSBjoern A. Zeeb 		}
1486*a0ccc12fSBjoern A. Zeeb 	}
1487*a0ccc12fSBjoern A. Zeeb }
1488*a0ccc12fSBjoern A. Zeeb 
1489*a0ccc12fSBjoern A. Zeeb void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
1490*a0ccc12fSBjoern A. Zeeb 			  u8 primary_chan_idx)
1491*a0ccc12fSBjoern A. Zeeb {
1492*a0ccc12fSBjoern A. Zeeb 	u8 old_band, new_band;
1493*a0ccc12fSBjoern A. Zeeb 
1494*a0ccc12fSBjoern A. Zeeb 	if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN)
1495*a0ccc12fSBjoern A. Zeeb 		old_band = RTW_BAND_5G;
1496*a0ccc12fSBjoern A. Zeeb 	else
1497*a0ccc12fSBjoern A. Zeeb 		old_band = RTW_BAND_2G;
1498*a0ccc12fSBjoern A. Zeeb 
1499*a0ccc12fSBjoern A. Zeeb 	if (channel > 14)
1500*a0ccc12fSBjoern A. Zeeb 		new_band = RTW_BAND_5G;
1501*a0ccc12fSBjoern A. Zeeb 	else
1502*a0ccc12fSBjoern A. Zeeb 		new_band = RTW_BAND_2G;
1503*a0ccc12fSBjoern A. Zeeb 
1504*a0ccc12fSBjoern A. Zeeb 	if (new_band != old_band)
1505*a0ccc12fSBjoern A. Zeeb 		rtw88xxa_switch_band(rtwdev, new_band, bw);
1506*a0ccc12fSBjoern A. Zeeb 
1507*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_switch_channel(rtwdev, channel, bw);
1508*a0ccc12fSBjoern A. Zeeb 
1509*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx);
1510*a0ccc12fSBjoern A. Zeeb 
1511*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A)
1512*a0ccc12fSBjoern A. Zeeb 		rtw8812a_phy_fix_spur(rtwdev, channel, bw);
1513*a0ccc12fSBjoern A. Zeeb 
1514*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_set_channel_rf(rtwdev, channel, bw);
1515*a0ccc12fSBjoern A. Zeeb }
1516*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_set_channel);
1517*a0ccc12fSBjoern A. Zeeb 
1518*a0ccc12fSBjoern A. Zeeb void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
1519*a0ccc12fSBjoern A. Zeeb 			       struct rtw_rx_pkt_stat *pkt_stat,
1520*a0ccc12fSBjoern A. Zeeb 			       s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx))
1521*a0ccc12fSBjoern A. Zeeb {
1522*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1523*a0ccc12fSBjoern A. Zeeb 	struct rtw_jaguar_phy_status_rpt *rpt;
1524*a0ccc12fSBjoern A. Zeeb 	u8 gain[RTW_RF_PATH_MAX], rssi, i;
1525*a0ccc12fSBjoern A. Zeeb 	s8 rx_pwr_db, power_a, power_b;
1526*a0ccc12fSBjoern A. Zeeb 	const s8 min_rx_power = -120;
1527*a0ccc12fSBjoern A. Zeeb 	u8 lna_idx, vga_idx;
1528*a0ccc12fSBjoern A. Zeeb 
1529*a0ccc12fSBjoern A. Zeeb 	rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status;
1530*a0ccc12fSBjoern A. Zeeb 
1531*a0ccc12fSBjoern A. Zeeb 	if (pkt_stat->rate <= DESC_RATE11M) {
1532*a0ccc12fSBjoern A. Zeeb 		lna_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX);
1533*a0ccc12fSBjoern A. Zeeb 		vga_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX);
1534*a0ccc12fSBjoern A. Zeeb 
1535*a0ccc12fSBjoern A. Zeeb 		rx_pwr_db = cck_rx_pwr(lna_idx, vga_idx);
1536*a0ccc12fSBjoern A. Zeeb 
1537*a0ccc12fSBjoern A. Zeeb 		pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db;
1538*a0ccc12fSBjoern A. Zeeb 		pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
1539*a0ccc12fSBjoern A. Zeeb 		dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
1540*a0ccc12fSBjoern A. Zeeb 		pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
1541*a0ccc12fSBjoern A. Zeeb 		pkt_stat->signal_power = rx_pwr_db;
1542*a0ccc12fSBjoern A. Zeeb 	} else { /* OFDM rate */
1543*a0ccc12fSBjoern A. Zeeb 		gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A);
1544*a0ccc12fSBjoern A. Zeeb 		gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B);
1545*a0ccc12fSBjoern A. Zeeb 
1546*a0ccc12fSBjoern A. Zeeb 		for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) {
1547*a0ccc12fSBjoern A. Zeeb 			pkt_stat->rx_power[i] = gain[i] - 110;
1548*a0ccc12fSBjoern A. Zeeb 			rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1);
1549*a0ccc12fSBjoern A. Zeeb 			dm_info->rssi[i] = rssi;
1550*a0ccc12fSBjoern A. Zeeb 		}
1551*a0ccc12fSBjoern A. Zeeb 
1552*a0ccc12fSBjoern A. Zeeb 		pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power,
1553*a0ccc12fSBjoern A. Zeeb 							 rtwdev->hal.rf_path_num);
1554*a0ccc12fSBjoern A. Zeeb 
1555*a0ccc12fSBjoern A. Zeeb 		power_a = pkt_stat->rx_power[RF_PATH_A];
1556*a0ccc12fSBjoern A. Zeeb 		power_b = pkt_stat->rx_power[RF_PATH_B];
1557*a0ccc12fSBjoern A. Zeeb 		if (rtwdev->hal.rf_path_num == 1)
1558*a0ccc12fSBjoern A. Zeeb 			power_b = power_a;
1559*a0ccc12fSBjoern A. Zeeb 
1560*a0ccc12fSBjoern A. Zeeb 		pkt_stat->signal_power = max3(power_a, power_b, min_rx_power);
1561*a0ccc12fSBjoern A. Zeeb 	}
1562*a0ccc12fSBjoern A. Zeeb }
1563*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_query_phy_status);
1564*a0ccc12fSBjoern A. Zeeb 
1565*a0ccc12fSBjoern A. Zeeb static void
1566*a0ccc12fSBjoern A. Zeeb rtw88xxa_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path,
1567*a0ccc12fSBjoern A. Zeeb 				    u8 rs, u32 *phy_pwr_idx)
1568*a0ccc12fSBjoern A. Zeeb {
1569*a0ccc12fSBjoern A. Zeeb 	static const u32 offset_txagc[2] = {
1570*a0ccc12fSBjoern A. Zeeb 		REG_TX_AGC_A_CCK_11_CCK_1, REG_TX_AGC_B_CCK_11_CCK_1
1571*a0ccc12fSBjoern A. Zeeb 	};
1572*a0ccc12fSBjoern A. Zeeb 	u8 rate, rate_idx, pwr_index, shift;
1573*a0ccc12fSBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
1574*a0ccc12fSBjoern A. Zeeb 	bool write_1ss_mcs9;
1575*a0ccc12fSBjoern A. Zeeb 	u32 mask;
1576*a0ccc12fSBjoern A. Zeeb 	int j;
1577*a0ccc12fSBjoern A. Zeeb 
1578*a0ccc12fSBjoern A. Zeeb 	for (j = 0; j < rtw_rate_size[rs]; j++) {
1579*a0ccc12fSBjoern A. Zeeb 		rate = rtw_rate_section[rs][j];
1580*a0ccc12fSBjoern A. Zeeb 
1581*a0ccc12fSBjoern A. Zeeb 		pwr_index = hal->tx_pwr_tbl[path][rate];
1582*a0ccc12fSBjoern A. Zeeb 
1583*a0ccc12fSBjoern A. Zeeb 		shift = rate & 0x3;
1584*a0ccc12fSBjoern A. Zeeb 		*phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
1585*a0ccc12fSBjoern A. Zeeb 
1586*a0ccc12fSBjoern A. Zeeb 		write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 &&
1587*a0ccc12fSBjoern A. Zeeb 				 hal->rf_path_num == 1;
1588*a0ccc12fSBjoern A. Zeeb 
1589*a0ccc12fSBjoern A. Zeeb 		if (write_1ss_mcs9)
1590*a0ccc12fSBjoern A. Zeeb 			mask = MASKLWORD;
1591*a0ccc12fSBjoern A. Zeeb 		else
1592*a0ccc12fSBjoern A. Zeeb 			mask = MASKDWORD;
1593*a0ccc12fSBjoern A. Zeeb 
1594*a0ccc12fSBjoern A. Zeeb 		if (shift == 0x3 || write_1ss_mcs9) {
1595*a0ccc12fSBjoern A. Zeeb 			rate_idx = rate & 0xfc;
1596*a0ccc12fSBjoern A. Zeeb 			if (rate >= DESC_RATEVHT1SS_MCS0)
1597*a0ccc12fSBjoern A. Zeeb 				rate_idx -= 0x10;
1598*a0ccc12fSBjoern A. Zeeb 
1599*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx,
1600*a0ccc12fSBjoern A. Zeeb 					 mask, *phy_pwr_idx);
1601*a0ccc12fSBjoern A. Zeeb 
1602*a0ccc12fSBjoern A. Zeeb 			*phy_pwr_idx = 0;
1603*a0ccc12fSBjoern A. Zeeb 		}
1604*a0ccc12fSBjoern A. Zeeb 	}
1605*a0ccc12fSBjoern A. Zeeb }
1606*a0ccc12fSBjoern A. Zeeb 
1607*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_tx_power_training(struct rtw_dev *rtwdev, u8 bw,
1608*a0ccc12fSBjoern A. Zeeb 				       u8 channel, u8 path)
1609*a0ccc12fSBjoern A. Zeeb {
1610*a0ccc12fSBjoern A. Zeeb 	static const u32 write_offset[] = {
1611*a0ccc12fSBjoern A. Zeeb 		REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B,
1612*a0ccc12fSBjoern A. Zeeb 	};
1613*a0ccc12fSBjoern A. Zeeb 	u32 power_level, write_data;
1614*a0ccc12fSBjoern A. Zeeb 	u8 i;
1615*a0ccc12fSBjoern A. Zeeb 
1616*a0ccc12fSBjoern A. Zeeb 	power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7];
1617*a0ccc12fSBjoern A. Zeeb 	write_data = 0;
1618*a0ccc12fSBjoern A. Zeeb 
1619*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < 3; i++) {
1620*a0ccc12fSBjoern A. Zeeb 		if (i == 0)
1621*a0ccc12fSBjoern A. Zeeb 			power_level -= 10;
1622*a0ccc12fSBjoern A. Zeeb 		else if (i == 1)
1623*a0ccc12fSBjoern A. Zeeb 			power_level -= 8;
1624*a0ccc12fSBjoern A. Zeeb 		else
1625*a0ccc12fSBjoern A. Zeeb 			power_level -= 6;
1626*a0ccc12fSBjoern A. Zeeb 
1627*a0ccc12fSBjoern A. Zeeb 		write_data |= max_t(u32, power_level, 2) << (i * 8);
1628*a0ccc12fSBjoern A. Zeeb 	}
1629*a0ccc12fSBjoern A. Zeeb 
1630*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data);
1631*a0ccc12fSBjoern A. Zeeb }
1632*a0ccc12fSBjoern A. Zeeb 
1633*a0ccc12fSBjoern A. Zeeb void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev)
1634*a0ccc12fSBjoern A. Zeeb {
1635*a0ccc12fSBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
1636*a0ccc12fSBjoern A. Zeeb 	u32 phy_pwr_idx = 0;
1637*a0ccc12fSBjoern A. Zeeb 	int rs, path;
1638*a0ccc12fSBjoern A. Zeeb 
1639*a0ccc12fSBjoern A. Zeeb 	for (path = 0; path < hal->rf_path_num; path++) {
1640*a0ccc12fSBjoern A. Zeeb 		for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
1641*a0ccc12fSBjoern A. Zeeb 			if (hal->rf_path_num == 1 &&
1642*a0ccc12fSBjoern A. Zeeb 			    (rs == RTW_RATE_SECTION_HT_2S ||
1643*a0ccc12fSBjoern A. Zeeb 			     rs == RTW_RATE_SECTION_VHT_2S))
1644*a0ccc12fSBjoern A. Zeeb 				continue;
1645*a0ccc12fSBjoern A. Zeeb 
1646*a0ccc12fSBjoern A. Zeeb 			if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) &&
1647*a0ccc12fSBjoern A. Zeeb 			    rs > RTW_RATE_SECTION_OFDM)
1648*a0ccc12fSBjoern A. Zeeb 				continue;
1649*a0ccc12fSBjoern A. Zeeb 
1650*a0ccc12fSBjoern A. Zeeb 			if (hal->current_band_type == RTW_BAND_5G &&
1651*a0ccc12fSBjoern A. Zeeb 			    rs == RTW_RATE_SECTION_CCK)
1652*a0ccc12fSBjoern A. Zeeb 				continue;
1653*a0ccc12fSBjoern A. Zeeb 
1654*a0ccc12fSBjoern A. Zeeb 			rtw88xxa_set_tx_power_index_by_rate(rtwdev, path, rs,
1655*a0ccc12fSBjoern A. Zeeb 							    &phy_pwr_idx);
1656*a0ccc12fSBjoern A. Zeeb 		}
1657*a0ccc12fSBjoern A. Zeeb 
1658*a0ccc12fSBjoern A. Zeeb 		rtw88xxa_tx_power_training(rtwdev, hal->current_band_width,
1659*a0ccc12fSBjoern A. Zeeb 					   hal->current_channel, path);
1660*a0ccc12fSBjoern A. Zeeb 	}
1661*a0ccc12fSBjoern A. Zeeb }
1662*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_set_tx_power_index);
1663*a0ccc12fSBjoern A. Zeeb 
1664*a0ccc12fSBjoern A. Zeeb void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev)
1665*a0ccc12fSBjoern A. Zeeb {
1666*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1667*a0ccc12fSBjoern A. Zeeb 	u32 cck_fa_cnt, ofdm_fa_cnt;
1668*a0ccc12fSBjoern A. Zeeb 	u32 crc32_cnt, cca32_cnt;
1669*a0ccc12fSBjoern A. Zeeb 	u32 cck_enable;
1670*a0ccc12fSBjoern A. Zeeb 
1671*a0ccc12fSBjoern A. Zeeb 	cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28);
1672*a0ccc12fSBjoern A. Zeeb 	cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK);
1673*a0ccc12fSBjoern A. Zeeb 	ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM);
1674*a0ccc12fSBjoern A. Zeeb 
1675*a0ccc12fSBjoern A. Zeeb 	dm_info->cck_fa_cnt = cck_fa_cnt;
1676*a0ccc12fSBjoern A. Zeeb 	dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
1677*a0ccc12fSBjoern A. Zeeb 	dm_info->total_fa_cnt = ofdm_fa_cnt;
1678*a0ccc12fSBjoern A. Zeeb 	if (cck_enable)
1679*a0ccc12fSBjoern A. Zeeb 		dm_info->total_fa_cnt += cck_fa_cnt;
1680*a0ccc12fSBjoern A. Zeeb 
1681*a0ccc12fSBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK);
1682*a0ccc12fSBjoern A. Zeeb 	dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
1683*a0ccc12fSBjoern A. Zeeb 	dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
1684*a0ccc12fSBjoern A. Zeeb 
1685*a0ccc12fSBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM);
1686*a0ccc12fSBjoern A. Zeeb 	dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
1687*a0ccc12fSBjoern A. Zeeb 	dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
1688*a0ccc12fSBjoern A. Zeeb 
1689*a0ccc12fSBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT);
1690*a0ccc12fSBjoern A. Zeeb 	dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
1691*a0ccc12fSBjoern A. Zeeb 	dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
1692*a0ccc12fSBjoern A. Zeeb 
1693*a0ccc12fSBjoern A. Zeeb 	crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT);
1694*a0ccc12fSBjoern A. Zeeb 	dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD);
1695*a0ccc12fSBjoern A. Zeeb 	dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD);
1696*a0ccc12fSBjoern A. Zeeb 
1697*a0ccc12fSBjoern A. Zeeb 	cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM);
1698*a0ccc12fSBjoern A. Zeeb 	dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD);
1699*a0ccc12fSBjoern A. Zeeb 	dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
1700*a0ccc12fSBjoern A. Zeeb 	if (cck_enable) {
1701*a0ccc12fSBjoern A. Zeeb 		cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK);
1702*a0ccc12fSBjoern A. Zeeb 		dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD);
1703*a0ccc12fSBjoern A. Zeeb 		dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
1704*a0ccc12fSBjoern A. Zeeb 	}
1705*a0ccc12fSBjoern A. Zeeb 
1706*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_FAS, BIT(17));
1707*a0ccc12fSBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_FAS, BIT(17));
1708*a0ccc12fSBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15));
1709*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15));
1710*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_CNTRST, BIT(0));
1711*a0ccc12fSBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0));
1712*a0ccc12fSBjoern A. Zeeb }
1713*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_false_alarm_statistics);
1714*a0ccc12fSBjoern A. Zeeb 
1715*a0ccc12fSBjoern A. Zeeb void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev,
1716*a0ccc12fSBjoern A. Zeeb 				u32 *macbb_backup,
1717*a0ccc12fSBjoern A. Zeeb 				const u32 *backup_macbb_reg,
1718*a0ccc12fSBjoern A. Zeeb 				u32 macbb_num)
1719*a0ccc12fSBjoern A. Zeeb {
1720*a0ccc12fSBjoern A. Zeeb 	u32 i;
1721*a0ccc12fSBjoern A. Zeeb 
1722*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
1723*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
1724*a0ccc12fSBjoern A. Zeeb 
1725*a0ccc12fSBjoern A. Zeeb 	/* save MACBB default value */
1726*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < macbb_num; i++)
1727*a0ccc12fSBjoern A. Zeeb 		macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]);
1728*a0ccc12fSBjoern A. Zeeb }
1729*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_iqk_backup_mac_bb);
1730*a0ccc12fSBjoern A. Zeeb 
1731*a0ccc12fSBjoern A. Zeeb void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
1732*a0ccc12fSBjoern A. Zeeb 			     const u32 *backup_afe_reg, u32 afe_num)
1733*a0ccc12fSBjoern A. Zeeb {
1734*a0ccc12fSBjoern A. Zeeb 	u32 i;
1735*a0ccc12fSBjoern A. Zeeb 
1736*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
1737*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
1738*a0ccc12fSBjoern A. Zeeb 
1739*a0ccc12fSBjoern A. Zeeb 	/* Save AFE Parameters */
1740*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < afe_num; i++)
1741*a0ccc12fSBjoern A. Zeeb 		afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]);
1742*a0ccc12fSBjoern A. Zeeb }
1743*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_iqk_backup_afe);
1744*a0ccc12fSBjoern A. Zeeb 
1745*a0ccc12fSBjoern A. Zeeb void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev,
1746*a0ccc12fSBjoern A. Zeeb 				 u32 *macbb_backup,
1747*a0ccc12fSBjoern A. Zeeb 				 const u32 *backup_macbb_reg,
1748*a0ccc12fSBjoern A. Zeeb 				 u32 macbb_num)
1749*a0ccc12fSBjoern A. Zeeb {
1750*a0ccc12fSBjoern A. Zeeb 	u32 i;
1751*a0ccc12fSBjoern A. Zeeb 
1752*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
1753*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
1754*a0ccc12fSBjoern A. Zeeb 
1755*a0ccc12fSBjoern A. Zeeb 	/* Reload MacBB Parameters */
1756*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < macbb_num; i++)
1757*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]);
1758*a0ccc12fSBjoern A. Zeeb }
1759*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_iqk_restore_mac_bb);
1760*a0ccc12fSBjoern A. Zeeb 
1761*a0ccc12fSBjoern A. Zeeb void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev)
1762*a0ccc12fSBjoern A. Zeeb {
1763*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
1764*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
1765*a0ccc12fSBjoern A. Zeeb 
1766*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_TXPAUSE, 0x3f);
1767*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_BCN_CTRL,
1768*a0ccc12fSBjoern A. Zeeb 			 (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0);
1769*a0ccc12fSBjoern A. Zeeb 
1770*a0ccc12fSBjoern A. Zeeb 	/* RX ante off */
1771*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_RXPSEL, 0x00);
1772*a0ccc12fSBjoern A. Zeeb 
1773*a0ccc12fSBjoern A. Zeeb 	/* CCA off */
1774*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc);
1775*a0ccc12fSBjoern A. Zeeb 
1776*a0ccc12fSBjoern A. Zeeb 	/* CCK RX path off */
1777*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf);
1778*a0ccc12fSBjoern A. Zeeb }
1779*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_iqk_configure_mac);
1780*a0ccc12fSBjoern A. Zeeb 
1781*a0ccc12fSBjoern A. Zeeb bool rtw88xxa_iqk_finish(int average, int threshold,
1782*a0ccc12fSBjoern A. Zeeb 			 int *x_temp, int *y_temp, int *x, int *y,
1783*a0ccc12fSBjoern A. Zeeb 			 bool break_inner, bool break_outer)
1784*a0ccc12fSBjoern A. Zeeb {
1785*a0ccc12fSBjoern A. Zeeb 	bool finish = false;
1786*a0ccc12fSBjoern A. Zeeb 	int i, ii, dx, dy;
1787*a0ccc12fSBjoern A. Zeeb 
1788*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < average; i++) {
1789*a0ccc12fSBjoern A. Zeeb 		for (ii = i + 1; ii < average; ii++) {
1790*a0ccc12fSBjoern A. Zeeb 			dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21);
1791*a0ccc12fSBjoern A. Zeeb 			dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21);
1792*a0ccc12fSBjoern A. Zeeb 
1793*a0ccc12fSBjoern A. Zeeb 			if (dx < threshold && dy < threshold) {
1794*a0ccc12fSBjoern A. Zeeb 				*x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21));
1795*a0ccc12fSBjoern A. Zeeb 				*y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21));
1796*a0ccc12fSBjoern A. Zeeb 
1797*a0ccc12fSBjoern A. Zeeb 				*x /= 2;
1798*a0ccc12fSBjoern A. Zeeb 				*y /= 2;
1799*a0ccc12fSBjoern A. Zeeb 
1800*a0ccc12fSBjoern A. Zeeb 				finish = true;
1801*a0ccc12fSBjoern A. Zeeb 
1802*a0ccc12fSBjoern A. Zeeb 				if (break_inner)
1803*a0ccc12fSBjoern A. Zeeb 					break;
1804*a0ccc12fSBjoern A. Zeeb 			}
1805*a0ccc12fSBjoern A. Zeeb 		}
1806*a0ccc12fSBjoern A. Zeeb 
1807*a0ccc12fSBjoern A. Zeeb 		if (finish && break_outer)
1808*a0ccc12fSBjoern A. Zeeb 			break;
1809*a0ccc12fSBjoern A. Zeeb 	}
1810*a0ccc12fSBjoern A. Zeeb 
1811*a0ccc12fSBjoern A. Zeeb 	return finish;
1812*a0ccc12fSBjoern A. Zeeb }
1813*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_iqk_finish);
1814*a0ccc12fSBjoern A. Zeeb 
1815*a0ccc12fSBjoern A. Zeeb static void rtw88xxa_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path)
1816*a0ccc12fSBjoern A. Zeeb {
1817*a0ccc12fSBjoern A. Zeeb 	static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B };
1818*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1819*a0ccc12fSBjoern A. Zeeb 	u8 cck_swing_idx, ofdm_swing_idx;
1820*a0ccc12fSBjoern A. Zeeb 	u8 pwr_tracking_limit;
1821*a0ccc12fSBjoern A. Zeeb 
1822*a0ccc12fSBjoern A. Zeeb 	switch (tx_rate) {
1823*a0ccc12fSBjoern A. Zeeb 	case DESC_RATE1M ... DESC_RATE11M:
1824*a0ccc12fSBjoern A. Zeeb 		pwr_tracking_limit = 32;
1825*a0ccc12fSBjoern A. Zeeb 		break;
1826*a0ccc12fSBjoern A. Zeeb 	case DESC_RATE6M ... DESC_RATE48M:
1827*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEMCS3 ... DESC_RATEMCS4:
1828*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEMCS11 ... DESC_RATEMCS12:
1829*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4:
1830*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4:
1831*a0ccc12fSBjoern A. Zeeb 		pwr_tracking_limit = 30;
1832*a0ccc12fSBjoern A. Zeeb 		break;
1833*a0ccc12fSBjoern A. Zeeb 	case DESC_RATE54M:
1834*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEMCS5 ... DESC_RATEMCS7:
1835*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEMCS13 ... DESC_RATEMCS15:
1836*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6:
1837*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6:
1838*a0ccc12fSBjoern A. Zeeb 		pwr_tracking_limit = 28;
1839*a0ccc12fSBjoern A. Zeeb 		break;
1840*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEMCS0 ... DESC_RATEMCS2:
1841*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEMCS8 ... DESC_RATEMCS10:
1842*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2:
1843*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2:
1844*a0ccc12fSBjoern A. Zeeb 		pwr_tracking_limit = 34;
1845*a0ccc12fSBjoern A. Zeeb 		break;
1846*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT1SS_MCS7:
1847*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT2SS_MCS7:
1848*a0ccc12fSBjoern A. Zeeb 		pwr_tracking_limit = 26;
1849*a0ccc12fSBjoern A. Zeeb 		break;
1850*a0ccc12fSBjoern A. Zeeb 	default:
1851*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT1SS_MCS8:
1852*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT2SS_MCS8:
1853*a0ccc12fSBjoern A. Zeeb 		pwr_tracking_limit = 24;
1854*a0ccc12fSBjoern A. Zeeb 		break;
1855*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT1SS_MCS9:
1856*a0ccc12fSBjoern A. Zeeb 	case DESC_RATEVHT2SS_MCS9:
1857*a0ccc12fSBjoern A. Zeeb 		pwr_tracking_limit = 22;
1858*a0ccc12fSBjoern A. Zeeb 		break;
1859*a0ccc12fSBjoern A. Zeeb 	}
1860*a0ccc12fSBjoern A. Zeeb 
1861*a0ccc12fSBjoern A. Zeeb 	cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index;
1862*a0ccc12fSBjoern A. Zeeb 	ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index;
1863*a0ccc12fSBjoern A. Zeeb 
1864*a0ccc12fSBjoern A. Zeeb 	if (ofdm_swing_idx > pwr_tracking_limit) {
1865*a0ccc12fSBjoern A. Zeeb 		if (path == RF_PATH_A)
1866*a0ccc12fSBjoern A. Zeeb 			dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit;
1867*a0ccc12fSBjoern A. Zeeb 		dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit;
1868*a0ccc12fSBjoern A. Zeeb 
1869*a0ccc12fSBjoern A. Zeeb 		ofdm_swing_idx = pwr_tracking_limit;
1870*a0ccc12fSBjoern A. Zeeb 	} else if (ofdm_swing_idx == 0) {
1871*a0ccc12fSBjoern A. Zeeb 		if (path == RF_PATH_A)
1872*a0ccc12fSBjoern A. Zeeb 			dm_info->txagc_remnant_cck = cck_swing_idx;
1873*a0ccc12fSBjoern A. Zeeb 		dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx;
1874*a0ccc12fSBjoern A. Zeeb 	} else {
1875*a0ccc12fSBjoern A. Zeeb 		if (path == RF_PATH_A)
1876*a0ccc12fSBjoern A. Zeeb 			dm_info->txagc_remnant_cck = 0;
1877*a0ccc12fSBjoern A. Zeeb 		dm_info->txagc_remnant_ofdm[path] = 0;
1878*a0ccc12fSBjoern A. Zeeb 	}
1879*a0ccc12fSBjoern A. Zeeb 
1880*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21),
1881*a0ccc12fSBjoern A. Zeeb 			 rtw88xxa_txscale_tbl[ofdm_swing_idx]);
1882*a0ccc12fSBjoern A. Zeeb }
1883*a0ccc12fSBjoern A. Zeeb 
1884*a0ccc12fSBjoern A. Zeeb void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
1885*a0ccc12fSBjoern A. Zeeb 			   void (*do_lck)(struct rtw_dev *rtwdev),
1886*a0ccc12fSBjoern A. Zeeb 			   void (*do_iqk)(struct rtw_dev *rtwdev))
1887*a0ccc12fSBjoern A. Zeeb {
1888*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1889*a0ccc12fSBjoern A. Zeeb 	struct rtw_hal *hal = &rtwdev->hal;
1890*a0ccc12fSBjoern A. Zeeb 	struct rtw_swing_table swing_table;
1891*a0ccc12fSBjoern A. Zeeb 	s8 remnant_pre[RTW_RF_PATH_MAX];
1892*a0ccc12fSBjoern A. Zeeb 	u8 thermal_value, delta, path;
1893*a0ccc12fSBjoern A. Zeeb 	bool need_iqk;
1894*a0ccc12fSBjoern A. Zeeb 
1895*a0ccc12fSBjoern A. Zeeb 	rtw_phy_config_swing_table(rtwdev, &swing_table);
1896*a0ccc12fSBjoern A. Zeeb 
1897*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->efuse.thermal_meter[0] == 0xff) {
1898*a0ccc12fSBjoern A. Zeeb 		pr_err_once("efuse thermal meter is 0xff\n");
1899*a0ccc12fSBjoern A. Zeeb 		return;
1900*a0ccc12fSBjoern A. Zeeb 	}
1901*a0ccc12fSBjoern A. Zeeb 
1902*a0ccc12fSBjoern A. Zeeb 	thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
1903*a0ccc12fSBjoern A. Zeeb 
1904*a0ccc12fSBjoern A. Zeeb 	rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
1905*a0ccc12fSBjoern A. Zeeb 
1906*a0ccc12fSBjoern A. Zeeb 	need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev);
1907*a0ccc12fSBjoern A. Zeeb 
1908*a0ccc12fSBjoern A. Zeeb 	if (need_iqk && do_lck)
1909*a0ccc12fSBjoern A. Zeeb 		do_lck(rtwdev);
1910*a0ccc12fSBjoern A. Zeeb 
1911*a0ccc12fSBjoern A. Zeeb 	if (dm_info->pwr_trk_init_trigger)
1912*a0ccc12fSBjoern A. Zeeb 		dm_info->pwr_trk_init_trigger = false;
1913*a0ccc12fSBjoern A. Zeeb 	else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
1914*a0ccc12fSBjoern A. Zeeb 						   RF_PATH_A))
1915*a0ccc12fSBjoern A. Zeeb 		goto iqk;
1916*a0ccc12fSBjoern A. Zeeb 
1917*a0ccc12fSBjoern A. Zeeb 	delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
1918*a0ccc12fSBjoern A. Zeeb 
1919*a0ccc12fSBjoern A. Zeeb 	for (path = RF_PATH_A; path < hal->rf_path_num; path++) {
1920*a0ccc12fSBjoern A. Zeeb 		remnant_pre[path] = dm_info->txagc_remnant_ofdm[path];
1921*a0ccc12fSBjoern A. Zeeb 
1922*a0ccc12fSBjoern A. Zeeb 		dm_info->delta_power_index[path] =
1923*a0ccc12fSBjoern A. Zeeb 			rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path,
1924*a0ccc12fSBjoern A. Zeeb 						    RF_PATH_A, delta);
1925*a0ccc12fSBjoern A. Zeeb 
1926*a0ccc12fSBjoern A. Zeeb 		if (dm_info->delta_power_index[path] !=
1927*a0ccc12fSBjoern A. Zeeb 		    dm_info->delta_power_index_last[path]) {
1928*a0ccc12fSBjoern A. Zeeb 			dm_info->delta_power_index_last[path] =
1929*a0ccc12fSBjoern A. Zeeb 				dm_info->delta_power_index[path];
1930*a0ccc12fSBjoern A. Zeeb 
1931*a0ccc12fSBjoern A. Zeeb 			rtw88xxa_pwrtrack_set(rtwdev, dm_info->tx_rate, path);
1932*a0ccc12fSBjoern A. Zeeb 		}
1933*a0ccc12fSBjoern A. Zeeb 	}
1934*a0ccc12fSBjoern A. Zeeb 
1935*a0ccc12fSBjoern A. Zeeb 	for (path = RF_PATH_A; path < hal->rf_path_num; path++) {
1936*a0ccc12fSBjoern A. Zeeb 		if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) {
1937*a0ccc12fSBjoern A. Zeeb 			rtw_phy_set_tx_power_level(rtwdev,
1938*a0ccc12fSBjoern A. Zeeb 						   hal->current_channel);
1939*a0ccc12fSBjoern A. Zeeb 			break;
1940*a0ccc12fSBjoern A. Zeeb 		}
1941*a0ccc12fSBjoern A. Zeeb 	}
1942*a0ccc12fSBjoern A. Zeeb 
1943*a0ccc12fSBjoern A. Zeeb iqk:
1944*a0ccc12fSBjoern A. Zeeb 	if (need_iqk)
1945*a0ccc12fSBjoern A. Zeeb 		do_iqk(rtwdev);
1946*a0ccc12fSBjoern A. Zeeb }
1947*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack);
1948*a0ccc12fSBjoern A. Zeeb 
1949*a0ccc12fSBjoern A. Zeeb void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
1950*a0ccc12fSBjoern A. Zeeb {
1951*a0ccc12fSBjoern A. Zeeb 	static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed};
1952*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1953*a0ccc12fSBjoern A. Zeeb 
1954*a0ccc12fSBjoern A. Zeeb 	/* Override rtw_phy_cck_pd_lv_link(). It implements something
1955*a0ccc12fSBjoern A. Zeeb 	 * like type 2/3/4. We need type 1 here.
1956*a0ccc12fSBjoern A. Zeeb 	 */
1957*a0ccc12fSBjoern A. Zeeb 	if (rtw_is_assoc(rtwdev)) {
1958*a0ccc12fSBjoern A. Zeeb 		if (dm_info->min_rssi > 60) {
1959*a0ccc12fSBjoern A. Zeeb 			new_lvl = CCK_PD_LV3;
1960*a0ccc12fSBjoern A. Zeeb 		} else if (dm_info->min_rssi > 35) {
1961*a0ccc12fSBjoern A. Zeeb 			new_lvl = CCK_PD_LV2;
1962*a0ccc12fSBjoern A. Zeeb 		} else if (dm_info->min_rssi > 20) {
1963*a0ccc12fSBjoern A. Zeeb 			if (dm_info->cck_fa_avg > 500)
1964*a0ccc12fSBjoern A. Zeeb 				new_lvl = CCK_PD_LV2;
1965*a0ccc12fSBjoern A. Zeeb 			else if (dm_info->cck_fa_avg < 250)
1966*a0ccc12fSBjoern A. Zeeb 				new_lvl = CCK_PD_LV1;
1967*a0ccc12fSBjoern A. Zeeb 			else
1968*a0ccc12fSBjoern A. Zeeb 				return;
1969*a0ccc12fSBjoern A. Zeeb 		} else {
1970*a0ccc12fSBjoern A. Zeeb 			new_lvl = CCK_PD_LV1;
1971*a0ccc12fSBjoern A. Zeeb 		}
1972*a0ccc12fSBjoern A. Zeeb 	}
1973*a0ccc12fSBjoern A. Zeeb 
1974*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n",
1975*a0ccc12fSBjoern A. Zeeb 		dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl);
1976*a0ccc12fSBjoern A. Zeeb 
1977*a0ccc12fSBjoern A. Zeeb 	if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl)
1978*a0ccc12fSBjoern A. Zeeb 		return;
1979*a0ccc12fSBjoern A. Zeeb 
1980*a0ccc12fSBjoern A. Zeeb 	dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
1981*a0ccc12fSBjoern A. Zeeb 	dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl;
1982*a0ccc12fSBjoern A. Zeeb 
1983*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]);
1984*a0ccc12fSBjoern A. Zeeb }
1985*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw88xxa_phy_cck_pd_set);
1986*a0ccc12fSBjoern A. Zeeb 
1987*a0ccc12fSBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation");
1988*a0ccc12fSBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code");
1989*a0ccc12fSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL");
1990