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