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