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