Merge tag 'block-5.11-2021-01-10' of git://git.kernel.dk/linux-block
[linux/fpc-iii.git] / drivers / net / wireless / realtek / rtw88 / rtw8822b.c
blobf1789155e901601fb5a4062a65a50ed44800059d
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019 Realtek Corporation
3 */
5 #include <linux/module.h>
6 #include "main.h"
7 #include "coex.h"
8 #include "fw.h"
9 #include "tx.h"
10 #include "rx.h"
11 #include "phy.h"
12 #include "rtw8822b.h"
13 #include "rtw8822b_table.h"
14 #include "mac.h"
15 #include "reg.h"
16 #include "debug.h"
17 #include "bf.h"
19 static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
20 u8 rx_path, bool is_tx2_path);
22 static void rtw8822be_efuse_parsing(struct rtw_efuse *efuse,
23 struct rtw8822b_efuse *map)
25 ether_addr_copy(efuse->addr, map->e.mac_addr);
28 static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
30 struct rtw_efuse *efuse = &rtwdev->efuse;
31 struct rtw8822b_efuse *map;
32 int i;
34 map = (struct rtw8822b_efuse *)log_map;
36 efuse->rfe_option = map->rfe_option;
37 efuse->rf_board_option = map->rf_board_option;
38 efuse->crystal_cap = map->xtal_k;
39 efuse->pa_type_2g = map->pa_type;
40 efuse->pa_type_5g = map->pa_type;
41 efuse->lna_type_2g = map->lna_type_2g[0];
42 efuse->lna_type_5g = map->lna_type_5g[0];
43 efuse->channel_plan = map->channel_plan;
44 efuse->country_code[0] = map->country_code[0];
45 efuse->country_code[1] = map->country_code[1];
46 efuse->bt_setting = map->rf_bt_setting;
47 efuse->regd = map->rf_board_option & 0x7;
48 efuse->thermal_meter[RF_PATH_A] = map->thermal_meter;
49 efuse->thermal_meter_k = map->thermal_meter;
51 for (i = 0; i < 4; i++)
52 efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
54 switch (rtw_hci_type(rtwdev)) {
55 case RTW_HCI_TYPE_PCIE:
56 rtw8822be_efuse_parsing(efuse, map);
57 break;
58 default:
59 /* unsupported now */
60 return -ENOTSUPP;
63 return 0;
66 static void rtw8822b_phy_rfe_init(struct rtw_dev *rtwdev)
68 /* chip top mux */
69 rtw_write32_mask(rtwdev, 0x64, BIT(29) | BIT(28), 0x3);
70 rtw_write32_mask(rtwdev, 0x4c, BIT(26) | BIT(25), 0x0);
71 rtw_write32_mask(rtwdev, 0x40, BIT(2), 0x1);
73 /* from s0 or s1 */
74 rtw_write32_mask(rtwdev, 0x1990, 0x3f, 0x30);
75 rtw_write32_mask(rtwdev, 0x1990, (BIT(11) | BIT(10)), 0x3);
77 /* input or output */
78 rtw_write32_mask(rtwdev, 0x974, 0x3f, 0x3f);
79 rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3);
82 #define RTW_TXSCALE_SIZE 37
83 static const u32 rtw8822b_txscale_tbl[RTW_TXSCALE_SIZE] = {
84 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8,
85 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180,
86 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab,
87 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe
90 static u8 rtw8822b_get_swing_index(struct rtw_dev *rtwdev)
92 u8 i = 0;
93 u32 swing, table_value;
95 swing = rtw_read32_mask(rtwdev, 0xc1c, 0xffe00000);
96 for (i = 0; i < RTW_TXSCALE_SIZE; i++) {
97 table_value = rtw8822b_txscale_tbl[i];
98 if (swing == table_value)
99 break;
102 return i;
105 static void rtw8822b_pwrtrack_init(struct rtw_dev *rtwdev)
107 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
108 u8 swing_idx = rtw8822b_get_swing_index(rtwdev);
109 u8 path;
111 if (swing_idx >= RTW_TXSCALE_SIZE)
112 dm_info->default_ofdm_index = 24;
113 else
114 dm_info->default_ofdm_index = swing_idx;
116 for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
117 ewma_thermal_init(&dm_info->avg_thermal[path]);
118 dm_info->delta_power_index[path] = 0;
120 dm_info->pwr_trk_triggered = false;
121 dm_info->pwr_trk_init_trigger = true;
122 dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
125 static void rtw8822b_phy_bf_init(struct rtw_dev *rtwdev)
127 rtw_bf_phy_init(rtwdev);
128 /* Grouping bitmap parameters */
129 rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF);
132 static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev)
134 struct rtw_hal *hal = &rtwdev->hal;
135 u8 crystal_cap;
136 bool is_tx2_path;
138 /* power on BB/RF domain */
139 rtw_write8_set(rtwdev, REG_SYS_FUNC_EN,
140 BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
141 rtw_write8_set(rtwdev, REG_RF_CTRL,
142 BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
143 rtw_write32_set(rtwdev, REG_WLRF1, BIT_WLRF1_BBRF_EN);
145 /* pre init before header files config */
146 rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
148 rtw_phy_load_tables(rtwdev);
150 crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
151 rtw_write32_mask(rtwdev, 0x24, 0x7e000000, crystal_cap);
152 rtw_write32_mask(rtwdev, 0x28, 0x7e, crystal_cap);
154 /* post init after header files config */
155 rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
157 is_tx2_path = false;
158 rtw8822b_config_trx_mode(rtwdev, hal->antenna_tx, hal->antenna_rx,
159 is_tx2_path);
160 rtw_phy_init(rtwdev);
162 rtw8822b_phy_rfe_init(rtwdev);
163 rtw8822b_pwrtrack_init(rtwdev);
165 rtw8822b_phy_bf_init(rtwdev);
168 #define WLAN_SLOT_TIME 0x09
169 #define WLAN_PIFS_TIME 0x19
170 #define WLAN_SIFS_CCK_CONT_TX 0xA
171 #define WLAN_SIFS_OFDM_CONT_TX 0xE
172 #define WLAN_SIFS_CCK_TRX 0x10
173 #define WLAN_SIFS_OFDM_TRX 0x10
174 #define WLAN_VO_TXOP_LIMIT 0x186 /* unit : 32us */
175 #define WLAN_VI_TXOP_LIMIT 0x3BC /* unit : 32us */
176 #define WLAN_RDG_NAV 0x05
177 #define WLAN_TXOP_NAV 0x1B
178 #define WLAN_CCK_RX_TSF 0x30
179 #define WLAN_OFDM_RX_TSF 0x30
180 #define WLAN_TBTT_PROHIBIT 0x04 /* unit : 32us */
181 #define WLAN_TBTT_HOLD_TIME 0x064 /* unit : 32us */
182 #define WLAN_DRV_EARLY_INT 0x04
183 #define WLAN_BCN_DMA_TIME 0x02
185 #define WLAN_RX_FILTER0 0x0FFFFFFF
186 #define WLAN_RX_FILTER2 0xFFFF
187 #define WLAN_RCR_CFG 0xE400220E
188 #define WLAN_RXPKT_MAX_SZ 12288
189 #define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9)
191 #define WLAN_AMPDU_MAX_TIME 0x70
192 #define WLAN_RTS_LEN_TH 0xFF
193 #define WLAN_RTS_TX_TIME_TH 0x08
194 #define WLAN_MAX_AGG_PKT_LIMIT 0x20
195 #define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20
196 #define FAST_EDCA_VO_TH 0x06
197 #define FAST_EDCA_VI_TH 0x06
198 #define FAST_EDCA_BE_TH 0x06
199 #define FAST_EDCA_BK_TH 0x06
200 #define WLAN_BAR_RETRY_LIMIT 0x01
201 #define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08
203 #define WLAN_TX_FUNC_CFG1 0x30
204 #define WLAN_TX_FUNC_CFG2 0x30
205 #define WLAN_MAC_OPT_NORM_FUNC1 0x98
206 #define WLAN_MAC_OPT_LB_FUNC1 0x80
207 #define WLAN_MAC_OPT_FUNC2 0x30810041
209 #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \
210 (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
211 (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
212 (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
214 #define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
215 (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
217 #define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
218 #define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
220 static int rtw8822b_mac_init(struct rtw_dev *rtwdev)
222 u32 value32;
224 /* protocol configuration */
225 rtw_write8_clr(rtwdev, REG_SW_AMPDU_BURST_MODE_CTRL, BIT_PRE_TX_CMD);
226 rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME);
227 rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
228 value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) |
229 (WLAN_MAX_AGG_PKT_LIMIT << 16) |
230 (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24);
231 rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32);
232 rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2,
233 WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8);
234 rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH);
235 rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH);
236 rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH);
237 rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH);
238 /* EDCA configuration */
239 rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0);
240 rtw_write16(rtwdev, REG_TXPAUSE, 0x0000);
241 rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
242 rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME);
243 rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG);
244 rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT);
245 rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT);
246 rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG);
247 rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG);
248 /* Set beacon cotnrol - enable TSF and other related functions */
249 rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
250 /* Set send beacon related registers */
251 rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME);
252 rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT);
253 rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
254 rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8);
255 /* WMAC configuration */
256 rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
257 rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
258 rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
259 rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512);
260 rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2);
261 rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
262 rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
263 rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1);
265 return 0;
268 static void rtw8822b_set_channel_rfe_efem(struct rtw_dev *rtwdev, u8 channel)
270 struct rtw_hal *hal = &rtwdev->hal;
272 if (IS_CH_2G_BAND(channel)) {
273 rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x705770);
274 rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57);
275 rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(4), 0);
276 } else {
277 rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x177517);
278 rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75);
279 rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(5), 0);
282 rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0);
284 if (hal->antenna_rx == BB_PATH_AB ||
285 hal->antenna_tx == BB_PATH_AB) {
286 /* 2TX or 2RX */
287 rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501);
288 } else if (hal->antenna_rx == hal->antenna_tx) {
289 /* TXA+RXA or TXB+RXB */
290 rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500);
291 } else {
292 /* TXB+RXA or TXA+RXB */
293 rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005);
297 static void rtw8822b_set_channel_rfe_ifem(struct rtw_dev *rtwdev, u8 channel)
299 struct rtw_hal *hal = &rtwdev->hal;
301 if (IS_CH_2G_BAND(channel)) {
302 /* signal source */
303 rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x745774);
304 rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57);
305 } else {
306 /* signal source */
307 rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x477547);
308 rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x75);
311 rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0);
313 if (IS_CH_2G_BAND(channel)) {
314 if (hal->antenna_rx == BB_PATH_AB ||
315 hal->antenna_tx == BB_PATH_AB) {
316 /* 2TX or 2RX */
317 rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa501);
318 } else if (hal->antenna_rx == hal->antenna_tx) {
319 /* TXA+RXA or TXB+RXB */
320 rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa500);
321 } else {
322 /* TXB+RXA or TXA+RXB */
323 rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa005);
325 } else {
326 rtw_write32s_mask(rtwdev, REG_TRSW, MASKLWORD, 0xa5a5);
330 enum {
331 CCUT_IDX_1R_2G,
332 CCUT_IDX_2R_2G,
333 CCUT_IDX_1R_5G,
334 CCUT_IDX_2R_5G,
335 CCUT_IDX_NR,
338 struct cca_ccut {
339 u32 reg82c[CCUT_IDX_NR];
340 u32 reg830[CCUT_IDX_NR];
341 u32 reg838[CCUT_IDX_NR];
344 static const struct cca_ccut cca_ifem_ccut = {
345 {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/
346 {0x79a0eaaa, 0x79A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/
347 {0x87765541, 0x87746341, 0x87765541, 0x87746341}, /*Reg838*/
350 static const struct cca_ccut cca_efem_ccut = {
351 {0x75B86010, 0x75B76010, 0x75B86010, 0x75B76010}, /*Reg82C*/
352 {0x79A0EAA8, 0x79A0EAAC, 0x79A0EAA8, 0x79a0eaaa}, /*Reg830*/
353 {0x87766451, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/
356 static const struct cca_ccut cca_ifem_ccut_ext = {
357 {0x75da8010, 0x75da8010, 0x75da8010, 0x75da8010}, /*Reg82C*/
358 {0x79a0eaaa, 0x97A0EAAC, 0x79a0eaaa, 0x79a0eaaa}, /*Reg830*/
359 {0x87765541, 0x86666341, 0x87765561, 0x86666361}, /*Reg838*/
362 static void rtw8822b_get_cca_val(const struct cca_ccut *cca_ccut, u8 col,
363 u32 *reg82c, u32 *reg830, u32 *reg838)
365 *reg82c = cca_ccut->reg82c[col];
366 *reg830 = cca_ccut->reg830[col];
367 *reg838 = cca_ccut->reg838[col];
370 struct rtw8822b_rfe_info {
371 const struct cca_ccut *cca_ccut_2g;
372 const struct cca_ccut *cca_ccut_5g;
373 enum rtw_rfe_fem fem;
374 bool ifem_ext;
375 void (*rtw_set_channel_rfe)(struct rtw_dev *rtwdev, u8 channel);
378 #define I2GE5G_CCUT(set_ch) { \
379 .cca_ccut_2g = &cca_ifem_ccut, \
380 .cca_ccut_5g = &cca_efem_ccut, \
381 .fem = RTW_RFE_IFEM2G_EFEM5G, \
382 .ifem_ext = false, \
383 .rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch, \
385 #define IFEM_EXT_CCUT(set_ch) { \
386 .cca_ccut_2g = &cca_ifem_ccut_ext, \
387 .cca_ccut_5g = &cca_ifem_ccut_ext, \
388 .fem = RTW_RFE_IFEM, \
389 .ifem_ext = true, \
390 .rtw_set_channel_rfe = &rtw8822b_set_channel_rfe_ ## set_ch, \
393 static const struct rtw8822b_rfe_info rtw8822b_rfe_info[] = {
394 [2] = I2GE5G_CCUT(efem),
395 [3] = IFEM_EXT_CCUT(ifem),
396 [5] = IFEM_EXT_CCUT(ifem),
399 static void rtw8822b_set_channel_cca(struct rtw_dev *rtwdev, u8 channel, u8 bw,
400 const struct rtw8822b_rfe_info *rfe_info)
402 struct rtw_hal *hal = &rtwdev->hal;
403 struct rtw_efuse *efuse = &rtwdev->efuse;
404 const struct cca_ccut *cca_ccut;
405 u8 col;
406 u32 reg82c, reg830, reg838;
407 bool is_efem_cca = false, is_ifem_cca = false, is_rfe_type = false;
409 if (IS_CH_2G_BAND(channel)) {
410 cca_ccut = rfe_info->cca_ccut_2g;
412 if (hal->antenna_rx == BB_PATH_A ||
413 hal->antenna_rx == BB_PATH_B)
414 col = CCUT_IDX_1R_2G;
415 else
416 col = CCUT_IDX_2R_2G;
417 } else {
418 cca_ccut = rfe_info->cca_ccut_5g;
420 if (hal->antenna_rx == BB_PATH_A ||
421 hal->antenna_rx == BB_PATH_B)
422 col = CCUT_IDX_1R_5G;
423 else
424 col = CCUT_IDX_2R_5G;
427 rtw8822b_get_cca_val(cca_ccut, col, &reg82c, &reg830, &reg838);
429 switch (rfe_info->fem) {
430 case RTW_RFE_IFEM:
431 default:
432 is_ifem_cca = true;
433 if (rfe_info->ifem_ext)
434 is_rfe_type = true;
435 break;
436 case RTW_RFE_EFEM:
437 is_efem_cca = true;
438 break;
439 case RTW_RFE_IFEM2G_EFEM5G:
440 if (IS_CH_2G_BAND(channel))
441 is_ifem_cca = true;
442 else
443 is_efem_cca = true;
444 break;
447 if (is_ifem_cca) {
448 if ((hal->cut_version == RTW_CHIP_VER_CUT_B &&
449 (col == CCUT_IDX_2R_2G || col == CCUT_IDX_2R_5G) &&
450 bw == RTW_CHANNEL_WIDTH_40) ||
451 (!is_rfe_type && col == CCUT_IDX_2R_5G &&
452 bw == RTW_CHANNEL_WIDTH_40) ||
453 (efuse->rfe_option == 5 && col == CCUT_IDX_2R_5G))
454 reg830 = 0x79a0ea28;
457 rtw_write32_mask(rtwdev, REG_CCASEL, MASKDWORD, reg82c);
458 rtw_write32_mask(rtwdev, REG_PDMFTH, MASKDWORD, reg830);
459 rtw_write32_mask(rtwdev, REG_CCA2ND, MASKDWORD, reg838);
461 if (is_efem_cca && !(hal->cut_version == RTW_CHIP_VER_CUT_B))
462 rtw_write32_mask(rtwdev, REG_L1WT, MASKDWORD, 0x9194b2b9);
464 if (bw == RTW_CHANNEL_WIDTH_20 && IS_CH_5G_BAND_MID(channel))
465 rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0, 0x4);
468 static const u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff, 0x6,
469 0x5, 0x0, 0x0, 0x7, 0x6, 0x6};
470 static const u8 middle_band[23] = {0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6, 0xff, 0x0,
471 0x0, 0x7, 0x6, 0x6, 0x5, 0x0, 0xff, 0x7, 0x6,
472 0x6, 0x5, 0x0, 0x0, 0x7};
473 static const u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff, 0x0,
474 0x7, 0x7, 0x6, 0x5, 0x5, 0x0};
476 static void rtw8822b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
478 #define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8))
479 #define RF18_BAND_2G (0)
480 #define RF18_BAND_5G (BIT(16) | BIT(8))
481 #define RF18_CHANNEL_MASK (MASKBYTE0)
482 #define RF18_RFSI_MASK (BIT(18) | BIT(17))
483 #define RF18_RFSI_GE_CH80 (BIT(17))
484 #define RF18_RFSI_GT_CH144 (BIT(18))
485 #define RF18_BW_MASK (BIT(11) | BIT(10))
486 #define RF18_BW_20M (BIT(11) | BIT(10))
487 #define RF18_BW_40M (BIT(11))
488 #define RF18_BW_80M (BIT(10))
489 #define RFBE_MASK (BIT(17) | BIT(16) | BIT(15))
491 struct rtw_hal *hal = &rtwdev->hal;
492 u32 rf_reg18, rf_reg_be;
494 rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK);
496 rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK |
497 RF18_BW_MASK);
499 rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G);
500 rf_reg18 |= (channel & RF18_CHANNEL_MASK);
501 if (channel > 144)
502 rf_reg18 |= RF18_RFSI_GT_CH144;
503 else if (channel >= 80)
504 rf_reg18 |= RF18_RFSI_GE_CH80;
506 switch (bw) {
507 case RTW_CHANNEL_WIDTH_5:
508 case RTW_CHANNEL_WIDTH_10:
509 case RTW_CHANNEL_WIDTH_20:
510 default:
511 rf_reg18 |= RF18_BW_20M;
512 break;
513 case RTW_CHANNEL_WIDTH_40:
514 rf_reg18 |= RF18_BW_40M;
515 break;
516 case RTW_CHANNEL_WIDTH_80:
517 rf_reg18 |= RF18_BW_80M;
518 break;
521 if (IS_CH_2G_BAND(channel))
522 rf_reg_be = 0x0;
523 else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel))
524 rf_reg_be = low_band[(channel - 36) >> 1];
525 else if (IS_CH_5G_BAND_3(channel))
526 rf_reg_be = middle_band[(channel - 100) >> 1];
527 else if (IS_CH_5G_BAND_4(channel))
528 rf_reg_be = high_band[(channel - 149) >> 1];
529 else
530 goto err;
532 rtw_write_rf(rtwdev, RF_PATH_A, RF_MALSEL, RFBE_MASK, rf_reg_be);
534 /* need to set 0xdf[18]=1 before writing RF18 when channel 144 */
535 if (channel == 144)
536 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x1);
537 else
538 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(18), 0x0);
540 rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18);
541 if (hal->rf_type > RF_1T1R)
542 rtw_write_rf(rtwdev, RF_PATH_B, 0x18, RFREG_MASK, rf_reg18);
544 rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0);
545 rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1);
547 return;
549 err:
550 WARN_ON(1);
553 static void rtw8822b_toggle_igi(struct rtw_dev *rtwdev)
555 struct rtw_hal *hal = &rtwdev->hal;
556 u32 igi;
558 igi = rtw_read32_mask(rtwdev, REG_RXIGI_A, 0x7f);
559 rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi - 2);
560 rtw_write32_mask(rtwdev, REG_RXIGI_A, 0x7f, igi);
561 rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi - 2);
562 rtw_write32_mask(rtwdev, REG_RXIGI_B, 0x7f, igi);
564 rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, 0x0);
565 rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0,
566 hal->antenna_rx | (hal->antenna_rx << 4));
569 static void rtw8822b_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw)
571 if (bw == RTW_CHANNEL_WIDTH_40) {
572 /* RX DFIR for BW40 */
573 rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x1);
574 rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x0);
575 rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
576 } else if (bw == RTW_CHANNEL_WIDTH_80) {
577 /* RX DFIR for BW80 */
578 rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
579 rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1);
580 rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
581 } else {
582 /* RX DFIR for BW20, BW10 and BW5*/
583 rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
584 rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2);
585 rtw_write32s_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1);
589 static void rtw8822b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
590 u8 primary_ch_idx)
592 struct rtw_efuse *efuse = &rtwdev->efuse;
593 u8 rfe_option = efuse->rfe_option;
594 u32 val32;
596 if (IS_CH_2G_BAND(channel)) {
597 rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1);
598 rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0);
599 rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0);
600 rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15);
602 rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x0);
603 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a);
604 if (channel == 14) {
605 rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x00006577);
606 rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000);
607 } else {
608 rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x384f6577);
609 rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x1525);
612 rtw_write32_mask(rtwdev, REG_RFEINV, 0x300, 0x2);
613 } else if (IS_CH_5G_BAND(channel)) {
614 rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1);
615 rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1);
616 rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0);
617 rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 34);
619 if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel))
620 rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x1);
621 else if (IS_CH_5G_BAND_3(channel))
622 rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x2);
623 else if (IS_CH_5G_BAND_4(channel))
624 rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x3);
626 if (IS_CH_5G_BAND_1(channel))
627 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494);
628 else if (IS_CH_5G_BAND_2(channel))
629 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453);
630 else if (channel >= 100 && channel <= 116)
631 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452);
632 else if (channel >= 118 && channel <= 177)
633 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412);
635 rtw_write32_mask(rtwdev, 0xcbc, 0x300, 0x1);
638 switch (bw) {
639 case RTW_CHANNEL_WIDTH_20:
640 default:
641 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
642 val32 &= 0xFFCFFC00;
643 val32 |= (RTW_CHANNEL_WIDTH_20);
644 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
646 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
647 break;
648 case RTW_CHANNEL_WIDTH_40:
649 if (primary_ch_idx == RTW_SC_20_UPPER)
650 rtw_write32_set(rtwdev, REG_RXSB, BIT(4));
651 else
652 rtw_write32_clr(rtwdev, REG_RXSB, BIT(4));
654 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
655 val32 &= 0xFF3FF300;
656 val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_40);
657 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
659 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
660 break;
661 case RTW_CHANNEL_WIDTH_80:
662 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
663 val32 &= 0xFCEFCF00;
664 val32 |= (((primary_ch_idx & 0xf) << 2) | RTW_CHANNEL_WIDTH_80);
665 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
667 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
669 if (rfe_option == 2 || rfe_option == 3) {
670 rtw_write32_mask(rtwdev, REG_L1PKWT, 0x0000f000, 0x6);
671 rtw_write32_mask(rtwdev, REG_ADC40, BIT(10), 0x1);
673 break;
674 case RTW_CHANNEL_WIDTH_5:
675 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
676 val32 &= 0xEFEEFE00;
677 val32 |= ((BIT(6) | RTW_CHANNEL_WIDTH_20));
678 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
680 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
681 rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
682 break;
683 case RTW_CHANNEL_WIDTH_10:
684 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
685 val32 &= 0xEFFEFF00;
686 val32 |= ((BIT(7) | RTW_CHANNEL_WIDTH_20));
687 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
689 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
690 rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
691 break;
695 static void rtw8822b_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
696 u8 primary_chan_idx)
698 struct rtw_efuse *efuse = &rtwdev->efuse;
699 const struct rtw8822b_rfe_info *rfe_info;
701 if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info),
702 "rfe_option %d is out of boundary\n", efuse->rfe_option))
703 return;
705 rfe_info = &rtw8822b_rfe_info[efuse->rfe_option];
707 rtw8822b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
708 rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
709 rtw8822b_set_channel_rf(rtwdev, channel, bw);
710 rtw8822b_set_channel_rxdfir(rtwdev, bw);
711 rtw8822b_toggle_igi(rtwdev);
712 rtw8822b_set_channel_cca(rtwdev, channel, bw, rfe_info);
713 (*rfe_info->rtw_set_channel_rfe)(rtwdev, channel);
716 static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,
717 u8 rx_path, bool is_tx2_path)
719 struct rtw_efuse *efuse = &rtwdev->efuse;
720 const struct rtw8822b_rfe_info *rfe_info;
721 u8 ch = rtwdev->hal.current_channel;
722 u8 tx_path_sel, rx_path_sel;
723 int counter;
725 if (WARN(efuse->rfe_option >= ARRAY_SIZE(rtw8822b_rfe_info),
726 "rfe_option %d is out of boundary\n", efuse->rfe_option))
727 return;
729 rfe_info = &rtw8822b_rfe_info[efuse->rfe_option];
731 if ((tx_path | rx_path) & BB_PATH_A)
732 rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x3231);
733 else
734 rtw_write32_mask(rtwdev, REG_AGCTR_A, MASKLWORD, 0x1111);
736 if ((tx_path | rx_path) & BB_PATH_B)
737 rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x3231);
738 else
739 rtw_write32_mask(rtwdev, REG_AGCTR_B, MASKLWORD, 0x1111);
741 rtw_write32_mask(rtwdev, REG_CDDTXP, (BIT(19) | BIT(18)), 0x3);
742 rtw_write32_mask(rtwdev, REG_TXPSEL, (BIT(29) | BIT(28)), 0x1);
743 rtw_write32_mask(rtwdev, REG_TXPSEL, BIT(30), 0x1);
745 if (tx_path & BB_PATH_A) {
746 rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x001);
747 rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x8);
748 } else if (tx_path & BB_PATH_B) {
749 rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x002);
750 rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0x4);
753 if (tx_path == BB_PATH_A || tx_path == BB_PATH_B)
754 rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x01);
755 else
756 rtw_write32_mask(rtwdev, REG_TXPSEL1, 0xfff0, 0x43);
758 tx_path_sel = (tx_path << 4) | tx_path;
759 rtw_write32_mask(rtwdev, REG_TXPSEL, MASKBYTE0, tx_path_sel);
761 if (tx_path != BB_PATH_A && tx_path != BB_PATH_B) {
762 if (is_tx2_path || rtwdev->mp_mode) {
763 rtw_write32_mask(rtwdev, REG_CDDTXP, 0xfff00000, 0x043);
764 rtw_write32_mask(rtwdev, REG_ADCINI, 0xf0000000, 0xc);
768 rtw_write32_mask(rtwdev, REG_RXDESC, BIT(22), 0x0);
769 rtw_write32_mask(rtwdev, REG_RXDESC, BIT(18), 0x0);
771 if (rx_path & BB_PATH_A)
772 rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x0);
773 else if (rx_path & BB_PATH_B)
774 rtw_write32_mask(rtwdev, REG_ADCINI, 0x0f000000, 0x5);
776 rx_path_sel = (rx_path << 4) | rx_path;
777 rtw_write32_mask(rtwdev, REG_RXPSEL, MASKBYTE0, rx_path_sel);
779 if (rx_path == BB_PATH_A || rx_path == BB_PATH_B) {
780 rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x0);
781 rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x0);
782 rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x0);
783 } else {
784 rtw_write32_mask(rtwdev, REG_ANTWT, BIT(16), 0x1);
785 rtw_write32_mask(rtwdev, REG_HTSTFWT, BIT(28), 0x1);
786 rtw_write32_mask(rtwdev, REG_MRC, BIT(23), 0x1);
789 for (counter = 100; counter > 0; counter--) {
790 u32 rf_reg33;
792 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
793 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001);
795 udelay(2);
796 rf_reg33 = rtw_read_rf(rtwdev, RF_PATH_A, 0x33, RFREG_MASK);
798 if (rf_reg33 == 0x00001)
799 break;
802 if (WARN(counter <= 0, "write RF mode table fail\n"))
803 return;
805 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
806 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00001);
807 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x00034);
808 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x4080c);
809 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
810 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
812 rtw8822b_toggle_igi(rtwdev);
813 rtw8822b_set_channel_cca(rtwdev, 1, RTW_CHANNEL_WIDTH_20, rfe_info);
814 (*rfe_info->rtw_set_channel_rfe)(rtwdev, ch);
817 static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
818 struct rtw_rx_pkt_stat *pkt_stat)
820 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
821 s8 min_rx_power = -120;
822 u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status);
824 /* 8822B uses only 1 antenna to RX CCK rates */
825 pkt_stat->rx_power[RF_PATH_A] = pwdb - 110;
826 pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
827 pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
828 pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
829 min_rx_power);
830 dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
833 static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
834 struct rtw_rx_pkt_stat *pkt_stat)
836 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
837 u8 rxsc, bw;
838 s8 min_rx_power = -120;
839 s8 rx_evm;
840 u8 evm_dbm = 0;
841 u8 rssi;
842 int path;
844 if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
845 rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
846 else
847 rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
849 if (rxsc >= 1 && rxsc <= 8)
850 bw = RTW_CHANNEL_WIDTH_20;
851 else if (rxsc >= 9 && rxsc <= 12)
852 bw = RTW_CHANNEL_WIDTH_40;
853 else if (rxsc >= 13)
854 bw = RTW_CHANNEL_WIDTH_80;
855 else
856 bw = GET_PHY_STAT_P1_RF_MODE(phy_status);
858 pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
859 pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110;
860 pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 2);
861 pkt_stat->bw = bw;
862 pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A],
863 pkt_stat->rx_power[RF_PATH_B],
864 min_rx_power);
866 dm_info->curr_rx_rate = pkt_stat->rate;
868 pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status);
869 pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status);
871 pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status);
872 pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status);
874 pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status);
875 pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status);
877 for (path = 0; path <= rtwdev->hal.rf_path_num; path++) {
878 rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1);
879 dm_info->rssi[path] = rssi;
880 dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1;
881 dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1;
883 rx_evm = pkt_stat->rx_evm[path];
885 if (rx_evm < 0) {
886 if (rx_evm == S8_MIN)
887 evm_dbm = 0;
888 else
889 evm_dbm = ((u8)-rx_evm >> 1);
891 dm_info->rx_evm_dbm[path] = evm_dbm;
895 static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
896 struct rtw_rx_pkt_stat *pkt_stat)
898 u8 page;
900 page = *phy_status & 0xf;
902 switch (page) {
903 case 0:
904 query_phy_status_page0(rtwdev, phy_status, pkt_stat);
905 break;
906 case 1:
907 query_phy_status_page1(rtwdev, phy_status, pkt_stat);
908 break;
909 default:
910 rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
911 return;
915 static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
916 struct rtw_rx_pkt_stat *pkt_stat,
917 struct ieee80211_rx_status *rx_status)
919 struct ieee80211_hdr *hdr;
920 u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
921 u8 *phy_status = NULL;
923 memset(pkt_stat, 0, sizeof(*pkt_stat));
925 pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
926 pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
927 pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
928 pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
929 GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
930 pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
931 pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
932 pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
933 pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
934 pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
935 pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
936 pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
937 pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
939 /* drv_info_sz is in unit of 8-bytes */
940 pkt_stat->drv_info_sz *= 8;
942 /* c2h cmd pkt's rx/phy status is not interested */
943 if (pkt_stat->is_c2h)
944 return;
946 hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
947 pkt_stat->drv_info_sz);
948 if (pkt_stat->phy_status) {
949 phy_status = rx_desc + desc_sz + pkt_stat->shift;
950 query_phy_status(rtwdev, phy_status, pkt_stat);
953 rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
956 static void
957 rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
959 struct rtw_hal *hal = &rtwdev->hal;
960 static const u32 offset_txagc[2] = {0x1d00, 0x1d80};
961 static u32 phy_pwr_idx;
962 u8 rate, rate_idx, pwr_index, shift;
963 int j;
965 for (j = 0; j < rtw_rate_size[rs]; j++) {
966 rate = rtw_rate_section[rs][j];
967 pwr_index = hal->tx_pwr_tbl[path][rate];
968 shift = rate & 0x3;
969 phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
970 if (shift == 0x3) {
971 rate_idx = rate & 0xfc;
972 rtw_write32(rtwdev, offset_txagc[path] + rate_idx,
973 phy_pwr_idx);
974 phy_pwr_idx = 0;
979 static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev)
981 struct rtw_hal *hal = &rtwdev->hal;
982 int rs, path;
984 for (path = 0; path < hal->rf_path_num; path++) {
985 for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
986 rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs);
990 static bool rtw8822b_check_rf_path(u8 antenna)
992 switch (antenna) {
993 case BB_PATH_A:
994 case BB_PATH_B:
995 case BB_PATH_AB:
996 return true;
997 default:
998 return false;
1002 static int rtw8822b_set_antenna(struct rtw_dev *rtwdev,
1003 u32 antenna_tx,
1004 u32 antenna_rx)
1006 struct rtw_hal *hal = &rtwdev->hal;
1008 rtw_dbg(rtwdev, RTW_DBG_PHY, "config RF path, tx=0x%x rx=0x%x\n",
1009 antenna_tx, antenna_rx);
1011 if (!rtw8822b_check_rf_path(antenna_tx)) {
1012 rtw_info(rtwdev, "unsupported tx path 0x%x\n", antenna_tx);
1013 return -EINVAL;
1016 if (!rtw8822b_check_rf_path(antenna_rx)) {
1017 rtw_info(rtwdev, "unsupported rx path 0x%x\n", antenna_rx);
1018 return -EINVAL;
1021 hal->antenna_tx = antenna_tx;
1022 hal->antenna_rx = antenna_rx;
1024 rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
1026 return 0;
1029 static void rtw8822b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
1031 u8 ldo_pwr;
1033 ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
1034 ldo_pwr = enable ? ldo_pwr | BIT_LDO25_EN : ldo_pwr & ~BIT_LDO25_EN;
1035 rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
1038 static void rtw8822b_false_alarm_statistics(struct rtw_dev *rtwdev)
1040 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1041 u32 cck_enable;
1042 u32 cck_fa_cnt;
1043 u32 ofdm_fa_cnt;
1044 u32 crc32_cnt;
1045 u32 cca32_cnt;
1047 cck_enable = rtw_read32(rtwdev, 0x808) & BIT(28);
1048 cck_fa_cnt = rtw_read16(rtwdev, 0xa5c);
1049 ofdm_fa_cnt = rtw_read16(rtwdev, 0xf48);
1051 dm_info->cck_fa_cnt = cck_fa_cnt;
1052 dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
1053 dm_info->total_fa_cnt = ofdm_fa_cnt;
1054 dm_info->total_fa_cnt += cck_enable ? cck_fa_cnt : 0;
1056 crc32_cnt = rtw_read32(rtwdev, 0xf04);
1057 dm_info->cck_ok_cnt = crc32_cnt & 0xffff;
1058 dm_info->cck_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1059 crc32_cnt = rtw_read32(rtwdev, 0xf14);
1060 dm_info->ofdm_ok_cnt = crc32_cnt & 0xffff;
1061 dm_info->ofdm_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1062 crc32_cnt = rtw_read32(rtwdev, 0xf10);
1063 dm_info->ht_ok_cnt = crc32_cnt & 0xffff;
1064 dm_info->ht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1065 crc32_cnt = rtw_read32(rtwdev, 0xf0c);
1066 dm_info->vht_ok_cnt = crc32_cnt & 0xffff;
1067 dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16;
1069 cca32_cnt = rtw_read32(rtwdev, 0xf08);
1070 dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16);
1071 dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
1072 if (cck_enable) {
1073 cca32_cnt = rtw_read32(rtwdev, 0xfcc);
1074 dm_info->cck_cca_cnt = cca32_cnt & 0xffff;
1075 dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
1078 rtw_write32_set(rtwdev, 0x9a4, BIT(17));
1079 rtw_write32_clr(rtwdev, 0x9a4, BIT(17));
1080 rtw_write32_clr(rtwdev, 0xa2c, BIT(15));
1081 rtw_write32_set(rtwdev, 0xa2c, BIT(15));
1082 rtw_write32_set(rtwdev, 0xb58, BIT(0));
1083 rtw_write32_clr(rtwdev, 0xb58, BIT(0));
1086 static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)
1088 static int do_iqk_cnt;
1089 struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
1090 u32 rf_reg, iqk_fail_mask;
1091 int counter;
1092 bool reload;
1094 rtw_fw_do_iqk(rtwdev, &para);
1096 for (counter = 0; counter < 300; counter++) {
1097 rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK);
1098 if (rf_reg == 0xabcde)
1099 break;
1100 msleep(20);
1102 rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
1104 reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
1105 iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
1106 rtw_dbg(rtwdev, RTW_DBG_PHY,
1107 "iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
1108 counter, reload, ++do_iqk_cnt, iqk_fail_mask);
1111 static void rtw8822b_phy_calibration(struct rtw_dev *rtwdev)
1113 rtw8822b_do_iqk(rtwdev);
1116 static void rtw8822b_coex_cfg_init(struct rtw_dev *rtwdev)
1118 /* enable TBTT nterrupt */
1119 rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
1121 /* BT report packet sample rate */
1122 /* 0x790[5:0]=0x5 */
1123 rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
1125 /* enable BT counter statistics */
1126 rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
1128 /* enable PTA (3-wire function form BT side) */
1129 rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
1130 rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
1132 /* enable PTA (tx/rx signal form WiFi side) */
1133 rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
1134 /* wl tx signal to PTA not case EDCCA */
1135 rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN);
1136 /* GNT_BT=1 while select both */
1137 rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY);
1140 static void rtw8822b_coex_cfg_ant_switch(struct rtw_dev *rtwdev,
1141 u8 ctrl_type, u8 pos_type)
1143 struct rtw_coex *coex = &rtwdev->coex;
1144 struct rtw_coex_dm *coex_dm = &coex->dm;
1145 struct rtw_coex_rfe *coex_rfe = &coex->rfe;
1146 bool polarity_inverse;
1147 u8 regval = 0;
1149 if (((ctrl_type << 8) + pos_type) == coex_dm->cur_switch_status)
1150 return;
1152 coex_dm->cur_switch_status = (ctrl_type << 8) + pos_type;
1154 if (coex_rfe->ant_switch_diversity &&
1155 ctrl_type == COEX_SWITCH_CTRL_BY_BBSW)
1156 ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV;
1158 polarity_inverse = (coex_rfe->ant_switch_polarity == 1);
1160 switch (ctrl_type) {
1161 default:
1162 case COEX_SWITCH_CTRL_BY_BBSW:
1163 /* 0x4c[23] = 0 */
1164 rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1165 /* 0x4c[24] = 1 */
1166 rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1167 /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
1168 rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x77);
1170 if (pos_type == COEX_SWITCH_TO_WLG_BT) {
1171 if (coex_rfe->rfe_module_type != 0x4 &&
1172 coex_rfe->rfe_module_type != 0x2)
1173 regval = 0x3;
1174 else
1175 regval = (!polarity_inverse ? 0x2 : 0x1);
1176 } else if (pos_type == COEX_SWITCH_TO_WLG) {
1177 regval = (!polarity_inverse ? 0x2 : 0x1);
1178 } else {
1179 regval = (!polarity_inverse ? 0x1 : 0x2);
1182 rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval);
1183 break;
1184 case COEX_SWITCH_CTRL_BY_PTA:
1185 /* 0x4c[23] = 0 */
1186 rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1187 /* 0x4c[24] = 1 */
1188 rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1189 /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
1190 rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x66);
1192 regval = (!polarity_inverse ? 0x2 : 0x1);
1193 rtw_write8_mask(rtwdev, REG_RFE_INV8, BIT_MASK_RFE_INV89, regval);
1194 break;
1195 case COEX_SWITCH_CTRL_BY_ANTDIV:
1196 /* 0x4c[23] = 0 */
1197 rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1198 /* 0x4c[24] = 1 */
1199 rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1200 rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 0x88);
1201 break;
1202 case COEX_SWITCH_CTRL_BY_MAC:
1203 /* 0x4c[23] = 1 */
1204 rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x1);
1206 regval = (!polarity_inverse ? 0x0 : 0x1);
1207 rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA, regval);
1208 break;
1209 case COEX_SWITCH_CTRL_BY_FW:
1210 /* 0x4c[23] = 0 */
1211 rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1212 /* 0x4c[24] = 1 */
1213 rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x1);
1214 break;
1215 case COEX_SWITCH_CTRL_BY_BT:
1216 /* 0x4c[23] = 0 */
1217 rtw_write8_mask(rtwdev, REG_LED_CFG + 2, BIT_DPDT_SEL_EN >> 16, 0x0);
1218 /* 0x4c[24] = 0 */
1219 rtw_write8_mask(rtwdev, REG_LED_CFG + 3, BIT_DPDT_WL_SEL >> 24, 0x0);
1220 break;
1224 static void rtw8822b_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
1228 static void rtw8822b_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
1230 rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT_BTGP_SPI_EN >> 16, 0);
1231 rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT_BTGP_JTAG_EN >> 24, 0);
1232 rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT_FSPI_EN >> 16, 0);
1233 rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 1, BIT_LED1DIS >> 8, 0);
1234 rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT_DBG_GNT_WL_BT >> 24, 0);
1237 static void rtw8822b_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
1239 struct rtw_coex *coex = &rtwdev->coex;
1240 struct rtw_coex_rfe *coex_rfe = &coex->rfe;
1241 struct rtw_efuse *efuse = &rtwdev->efuse;
1242 bool is_ext_fem = false;
1244 coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;
1245 coex_rfe->ant_switch_polarity = 0;
1246 coex_rfe->ant_switch_diversity = false;
1247 if (coex_rfe->rfe_module_type == 0x12 ||
1248 coex_rfe->rfe_module_type == 0x15 ||
1249 coex_rfe->rfe_module_type == 0x16)
1250 coex_rfe->ant_switch_exist = false;
1251 else
1252 coex_rfe->ant_switch_exist = true;
1254 if (coex_rfe->rfe_module_type == 2 ||
1255 coex_rfe->rfe_module_type == 4) {
1256 rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, true);
1257 is_ext_fem = true;
1258 } else {
1259 rtw_coex_write_scbd(rtwdev, COEX_SCBD_EXTFEM, false);
1262 coex_rfe->wlg_at_btg = false;
1264 if (efuse->share_ant &&
1265 coex_rfe->ant_switch_exist && !is_ext_fem)
1266 coex_rfe->ant_switch_with_bt = true;
1267 else
1268 coex_rfe->ant_switch_with_bt = false;
1270 /* Ext switch buffer mux */
1271 rtw_write8(rtwdev, REG_RFE_CTRL_E, 0xff);
1272 rtw_write8_mask(rtwdev, REG_RFESEL_CTRL + 1, 0x3, 0x0);
1273 rtw_write8_mask(rtwdev, REG_RFE_INV16, BIT_RFE_BUF_EN, 0x0);
1275 /* Disable LTE Coex Function in WiFi side */
1276 rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0);
1278 /* BTC_CTT_WL_VS_LTE */
1279 rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff);
1281 /* BTC_CTT_BT_VS_LTE */
1282 rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff);
1285 static void rtw8822b_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
1287 struct rtw_coex *coex = &rtwdev->coex;
1288 struct rtw_coex_dm *coex_dm = &coex->dm;
1289 static const u16 reg_addr[] = {0xc58, 0xe58};
1290 static const u8 wl_tx_power[] = {0xd8, 0xd4, 0xd0, 0xcc, 0xc8};
1291 u8 i, pwr;
1293 if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
1294 return;
1296 coex_dm->cur_wl_pwr_lvl = wl_pwr;
1298 if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power))
1299 coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1;
1301 pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl];
1303 for (i = 0; i < ARRAY_SIZE(reg_addr); i++)
1304 rtw_write8_mask(rtwdev, reg_addr[i], 0xff, pwr);
1307 static void rtw8822b_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
1309 struct rtw_coex *coex = &rtwdev->coex;
1310 struct rtw_coex_dm *coex_dm = &coex->dm;
1311 /* WL Rx Low gain on */
1312 static const u32 wl_rx_low_gain_on[] = {
1313 0xff000003, 0xbd120003, 0xbe100003, 0xbf080003, 0xbf060003,
1314 0xbf050003, 0xbc140003, 0xbb160003, 0xba180003, 0xb91a0003,
1315 0xb81c0003, 0xb71e0003, 0xb4200003, 0xb5220003, 0xb4240003,
1316 0xb3260003, 0xb2280003, 0xb12a0003, 0xb02c0003, 0xaf2e0003,
1317 0xae300003, 0xad320003, 0xac340003, 0xab360003, 0x8d380003,
1318 0x8c3a0003, 0x8b3c0003, 0x8a3e0003, 0x6e400003, 0x6d420003,
1319 0x6c440003, 0x6b460003, 0x6a480003, 0x694a0003, 0x684c0003,
1320 0x674e0003, 0x66500003, 0x65520003, 0x64540003, 0x64560003,
1321 0x007e0403
1324 /* WL Rx Low gain off */
1325 static const u32 wl_rx_low_gain_off[] = {
1326 0xff000003, 0xf4120003, 0xf5100003, 0xf60e0003, 0xf70c0003,
1327 0xf80a0003, 0xf3140003, 0xf2160003, 0xf1180003, 0xf01a0003,
1328 0xef1c0003, 0xee1e0003, 0xed200003, 0xec220003, 0xeb240003,
1329 0xea260003, 0xe9280003, 0xe82a0003, 0xe72c0003, 0xe62e0003,
1330 0xe5300003, 0xc8320003, 0xc7340003, 0xc6360003, 0xc5380003,
1331 0xc43a0003, 0xc33c0003, 0xc23e0003, 0xc1400003, 0xc0420003,
1332 0xa5440003, 0xa4460003, 0xa3480003, 0xa24a0003, 0xa14c0003,
1333 0x834e0003, 0x82500003, 0x81520003, 0x80540003, 0x65560003,
1334 0x007e0403
1336 u8 i;
1338 if (low_gain == coex_dm->cur_wl_rx_low_gain_en)
1339 return;
1341 coex_dm->cur_wl_rx_low_gain_en = low_gain;
1343 if (coex_dm->cur_wl_rx_low_gain_en) {
1344 rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table On!\n");
1345 for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++)
1346 rtw_write32(rtwdev, REG_RX_GAIN_EN, wl_rx_low_gain_on[i]);
1348 /* set Rx filter corner RCK offset */
1349 rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x1);
1350 rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x3f);
1351 rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x1);
1352 rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x3f);
1353 } else {
1354 rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], Hi-Li Table Off!\n");
1355 for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++)
1356 rtw_write32(rtwdev, 0x81c, wl_rx_low_gain_off[i]);
1358 /* set Rx filter corner RCK offset */
1359 rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK, 0x3f, 0x4);
1360 rtw_write_rf(rtwdev, RF_PATH_A, RF_RCKD, 0x2, 0x0);
1361 rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK, 0x3f, 0x4);
1362 rtw_write_rf(rtwdev, RF_PATH_B, RF_RCKD, 0x2, 0x0);
1366 static void rtw8822b_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path,
1367 u8 tx_pwr_idx_offset,
1368 s8 *txagc_idx, u8 *swing_idx)
1370 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1371 s8 delta_pwr_idx = dm_info->delta_power_index[path];
1372 u8 swing_upper_bound = dm_info->default_ofdm_index + 10;
1373 u8 swing_lower_bound = 0;
1374 u8 max_tx_pwr_idx_offset = 0xf;
1375 s8 agc_index = 0;
1376 u8 swing_index = dm_info->default_ofdm_index;
1378 tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset);
1380 if (delta_pwr_idx >= 0) {
1381 if (delta_pwr_idx <= tx_pwr_idx_offset) {
1382 agc_index = delta_pwr_idx;
1383 swing_index = dm_info->default_ofdm_index;
1384 } else if (delta_pwr_idx > tx_pwr_idx_offset) {
1385 agc_index = tx_pwr_idx_offset;
1386 swing_index = dm_info->default_ofdm_index +
1387 delta_pwr_idx - tx_pwr_idx_offset;
1388 swing_index = min_t(u8, swing_index, swing_upper_bound);
1390 } else {
1391 if (dm_info->default_ofdm_index > abs(delta_pwr_idx))
1392 swing_index =
1393 dm_info->default_ofdm_index + delta_pwr_idx;
1394 else
1395 swing_index = swing_lower_bound;
1396 swing_index = max_t(u8, swing_index, swing_lower_bound);
1398 agc_index = 0;
1401 if (swing_index >= RTW_TXSCALE_SIZE) {
1402 rtw_warn(rtwdev, "swing index overflow\n");
1403 swing_index = RTW_TXSCALE_SIZE - 1;
1405 *txagc_idx = agc_index;
1406 *swing_idx = swing_index;
1409 static void rtw8822b_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path,
1410 u8 pwr_idx_offset)
1412 s8 txagc_idx;
1413 u8 swing_idx;
1414 u32 reg1, reg2;
1416 if (path == RF_PATH_A) {
1417 reg1 = 0xc94;
1418 reg2 = 0xc1c;
1419 } else if (path == RF_PATH_B) {
1420 reg1 = 0xe94;
1421 reg2 = 0xe1c;
1422 } else {
1423 return;
1426 rtw8822b_txagc_swing_offset(rtwdev, path, pwr_idx_offset,
1427 &txagc_idx, &swing_idx);
1428 rtw_write32_mask(rtwdev, reg1, GENMASK(29, 25), txagc_idx);
1429 rtw_write32_mask(rtwdev, reg2, GENMASK(31, 21),
1430 rtw8822b_txscale_tbl[swing_idx]);
1433 static void rtw8822b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
1435 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1436 u8 pwr_idx_offset, tx_pwr_idx;
1437 u8 channel = rtwdev->hal.current_channel;
1438 u8 band_width = rtwdev->hal.current_band_width;
1439 u8 regd = rtwdev->regd.txpwr_regd;
1440 u8 tx_rate = dm_info->tx_rate;
1441 u8 max_pwr_idx = rtwdev->chip->max_power_index;
1443 tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate,
1444 band_width, channel, regd);
1446 tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx);
1448 pwr_idx_offset = max_pwr_idx - tx_pwr_idx;
1450 rtw8822b_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset);
1453 static void rtw8822b_phy_pwrtrack_path(struct rtw_dev *rtwdev,
1454 struct rtw_swing_table *swing_table,
1455 u8 path)
1457 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1458 u8 power_idx_cur, power_idx_last;
1459 u8 delta;
1461 /* 8822B only has one thermal meter at PATH A */
1462 delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
1464 power_idx_last = dm_info->delta_power_index[path];
1465 power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table,
1466 path, RF_PATH_A, delta);
1468 /* if delta of power indexes are the same, just skip */
1469 if (power_idx_cur == power_idx_last)
1470 return;
1472 dm_info->delta_power_index[path] = power_idx_cur;
1473 rtw8822b_pwrtrack_set(rtwdev, path);
1476 static void rtw8822b_phy_pwrtrack(struct rtw_dev *rtwdev)
1478 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1479 struct rtw_swing_table swing_table;
1480 u8 thermal_value, path;
1482 rtw_phy_config_swing_table(rtwdev, &swing_table);
1484 if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff)
1485 return;
1487 thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
1489 rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
1491 if (dm_info->pwr_trk_init_trigger)
1492 dm_info->pwr_trk_init_trigger = false;
1493 else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
1494 RF_PATH_A))
1495 goto iqk;
1497 for (path = 0; path < rtwdev->hal.rf_path_num; path++)
1498 rtw8822b_phy_pwrtrack_path(rtwdev, &swing_table, path);
1500 iqk:
1501 if (rtw_phy_pwrtrack_need_iqk(rtwdev))
1502 rtw8822b_do_iqk(rtwdev);
1505 static void rtw8822b_pwr_track(struct rtw_dev *rtwdev)
1507 struct rtw_efuse *efuse = &rtwdev->efuse;
1508 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1510 if (efuse->power_track_type != 0)
1511 return;
1513 if (!dm_info->pwr_trk_triggered) {
1514 rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
1515 GENMASK(17, 16), 0x03);
1516 dm_info->pwr_trk_triggered = true;
1517 return;
1520 rtw8822b_phy_pwrtrack(rtwdev);
1521 dm_info->pwr_trk_triggered = false;
1524 static void rtw8822b_bf_config_bfee_su(struct rtw_dev *rtwdev,
1525 struct rtw_vif *vif,
1526 struct rtw_bfee *bfee, bool enable)
1528 if (enable)
1529 rtw_bf_enable_bfee_su(rtwdev, vif, bfee);
1530 else
1531 rtw_bf_remove_bfee_su(rtwdev, bfee);
1534 static void rtw8822b_bf_config_bfee_mu(struct rtw_dev *rtwdev,
1535 struct rtw_vif *vif,
1536 struct rtw_bfee *bfee, bool enable)
1538 if (enable)
1539 rtw_bf_enable_bfee_mu(rtwdev, vif, bfee);
1540 else
1541 rtw_bf_remove_bfee_mu(rtwdev, bfee);
1544 static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
1545 struct rtw_bfee *bfee, bool enable)
1547 if (bfee->role == RTW_BFEE_SU)
1548 rtw8822b_bf_config_bfee_su(rtwdev, vif, bfee, enable);
1549 else if (bfee->role == RTW_BFEE_MU)
1550 rtw8822b_bf_config_bfee_mu(rtwdev, vif, bfee, enable);
1551 else
1552 rtw_warn(rtwdev, "wrong bfee role\n");
1555 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
1556 {0x0086,
1557 RTW_PWR_CUT_ALL_MSK,
1558 RTW_PWR_INTF_SDIO_MSK,
1559 RTW_PWR_ADDR_SDIO,
1560 RTW_PWR_CMD_WRITE, BIT(0), 0},
1561 {0x0086,
1562 RTW_PWR_CUT_ALL_MSK,
1563 RTW_PWR_INTF_SDIO_MSK,
1564 RTW_PWR_ADDR_SDIO,
1565 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
1566 {0x004A,
1567 RTW_PWR_CUT_ALL_MSK,
1568 RTW_PWR_INTF_USB_MSK,
1569 RTW_PWR_ADDR_MAC,
1570 RTW_PWR_CMD_WRITE, BIT(0), 0},
1571 {0x0005,
1572 RTW_PWR_CUT_ALL_MSK,
1573 RTW_PWR_INTF_ALL_MSK,
1574 RTW_PWR_ADDR_MAC,
1575 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
1576 {0x0300,
1577 RTW_PWR_CUT_ALL_MSK,
1578 RTW_PWR_INTF_PCI_MSK,
1579 RTW_PWR_ADDR_MAC,
1580 RTW_PWR_CMD_WRITE, 0xFF, 0},
1581 {0x0301,
1582 RTW_PWR_CUT_ALL_MSK,
1583 RTW_PWR_INTF_PCI_MSK,
1584 RTW_PWR_ADDR_MAC,
1585 RTW_PWR_CMD_WRITE, 0xFF, 0},
1586 {0xFFFF,
1587 RTW_PWR_CUT_ALL_MSK,
1588 RTW_PWR_INTF_ALL_MSK,
1590 RTW_PWR_CMD_END, 0, 0},
1593 static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8822b[] = {
1594 {0x0012,
1595 RTW_PWR_CUT_ALL_MSK,
1596 RTW_PWR_INTF_ALL_MSK,
1597 RTW_PWR_ADDR_MAC,
1598 RTW_PWR_CMD_WRITE, BIT(1), 0},
1599 {0x0012,
1600 RTW_PWR_CUT_ALL_MSK,
1601 RTW_PWR_INTF_ALL_MSK,
1602 RTW_PWR_ADDR_MAC,
1603 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1604 {0x0020,
1605 RTW_PWR_CUT_ALL_MSK,
1606 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1607 RTW_PWR_ADDR_MAC,
1608 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1609 {0x0001,
1610 RTW_PWR_CUT_ALL_MSK,
1611 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1612 RTW_PWR_ADDR_MAC,
1613 RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
1614 {0x0000,
1615 RTW_PWR_CUT_ALL_MSK,
1616 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1617 RTW_PWR_ADDR_MAC,
1618 RTW_PWR_CMD_WRITE, BIT(5), 0},
1619 {0x0005,
1620 RTW_PWR_CUT_ALL_MSK,
1621 RTW_PWR_INTF_ALL_MSK,
1622 RTW_PWR_ADDR_MAC,
1623 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
1624 {0x0075,
1625 RTW_PWR_CUT_ALL_MSK,
1626 RTW_PWR_INTF_PCI_MSK,
1627 RTW_PWR_ADDR_MAC,
1628 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1629 {0x0006,
1630 RTW_PWR_CUT_ALL_MSK,
1631 RTW_PWR_INTF_ALL_MSK,
1632 RTW_PWR_ADDR_MAC,
1633 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
1634 {0x0075,
1635 RTW_PWR_CUT_ALL_MSK,
1636 RTW_PWR_INTF_PCI_MSK,
1637 RTW_PWR_ADDR_MAC,
1638 RTW_PWR_CMD_WRITE, BIT(0), 0},
1639 {0xFF1A,
1640 RTW_PWR_CUT_ALL_MSK,
1641 RTW_PWR_INTF_USB_MSK,
1642 RTW_PWR_ADDR_MAC,
1643 RTW_PWR_CMD_WRITE, 0xFF, 0},
1644 {0x0006,
1645 RTW_PWR_CUT_ALL_MSK,
1646 RTW_PWR_INTF_ALL_MSK,
1647 RTW_PWR_ADDR_MAC,
1648 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1649 {0x0005,
1650 RTW_PWR_CUT_ALL_MSK,
1651 RTW_PWR_INTF_ALL_MSK,
1652 RTW_PWR_ADDR_MAC,
1653 RTW_PWR_CMD_WRITE, BIT(7), 0},
1654 {0x0005,
1655 RTW_PWR_CUT_ALL_MSK,
1656 RTW_PWR_INTF_ALL_MSK,
1657 RTW_PWR_ADDR_MAC,
1658 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
1659 {0x10C3,
1660 RTW_PWR_CUT_ALL_MSK,
1661 RTW_PWR_INTF_USB_MSK,
1662 RTW_PWR_ADDR_MAC,
1663 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1664 {0x0005,
1665 RTW_PWR_CUT_ALL_MSK,
1666 RTW_PWR_INTF_ALL_MSK,
1667 RTW_PWR_ADDR_MAC,
1668 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1669 {0x0005,
1670 RTW_PWR_CUT_ALL_MSK,
1671 RTW_PWR_INTF_ALL_MSK,
1672 RTW_PWR_ADDR_MAC,
1673 RTW_PWR_CMD_POLLING, BIT(0), 0},
1674 {0x0020,
1675 RTW_PWR_CUT_ALL_MSK,
1676 RTW_PWR_INTF_ALL_MSK,
1677 RTW_PWR_ADDR_MAC,
1678 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
1679 {0x10A8,
1680 RTW_PWR_CUT_C_MSK,
1681 RTW_PWR_INTF_ALL_MSK,
1682 RTW_PWR_ADDR_MAC,
1683 RTW_PWR_CMD_WRITE, 0xFF, 0},
1684 {0x10A9,
1685 RTW_PWR_CUT_C_MSK,
1686 RTW_PWR_INTF_ALL_MSK,
1687 RTW_PWR_ADDR_MAC,
1688 RTW_PWR_CMD_WRITE, 0xFF, 0xef},
1689 {0x10AA,
1690 RTW_PWR_CUT_C_MSK,
1691 RTW_PWR_INTF_ALL_MSK,
1692 RTW_PWR_ADDR_MAC,
1693 RTW_PWR_CMD_WRITE, 0xFF, 0x0c},
1694 {0x0068,
1695 RTW_PWR_CUT_C_MSK,
1696 RTW_PWR_INTF_SDIO_MSK,
1697 RTW_PWR_ADDR_MAC,
1698 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
1699 {0x0029,
1700 RTW_PWR_CUT_ALL_MSK,
1701 RTW_PWR_INTF_ALL_MSK,
1702 RTW_PWR_ADDR_MAC,
1703 RTW_PWR_CMD_WRITE, 0xFF, 0xF9},
1704 {0x0024,
1705 RTW_PWR_CUT_ALL_MSK,
1706 RTW_PWR_INTF_ALL_MSK,
1707 RTW_PWR_ADDR_MAC,
1708 RTW_PWR_CMD_WRITE, BIT(2), 0},
1709 {0x0074,
1710 RTW_PWR_CUT_ALL_MSK,
1711 RTW_PWR_INTF_PCI_MSK,
1712 RTW_PWR_ADDR_MAC,
1713 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1714 {0x00AF,
1715 RTW_PWR_CUT_ALL_MSK,
1716 RTW_PWR_INTF_ALL_MSK,
1717 RTW_PWR_ADDR_MAC,
1718 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1719 {0xFFFF,
1720 RTW_PWR_CUT_ALL_MSK,
1721 RTW_PWR_INTF_ALL_MSK,
1723 RTW_PWR_CMD_END, 0, 0},
1726 static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8822b[] = {
1727 {0x0003,
1728 RTW_PWR_CUT_ALL_MSK,
1729 RTW_PWR_INTF_SDIO_MSK,
1730 RTW_PWR_ADDR_MAC,
1731 RTW_PWR_CMD_WRITE, BIT(2), 0},
1732 {0x0093,
1733 RTW_PWR_CUT_ALL_MSK,
1734 RTW_PWR_INTF_ALL_MSK,
1735 RTW_PWR_ADDR_MAC,
1736 RTW_PWR_CMD_WRITE, BIT(3), 0},
1737 {0x001F,
1738 RTW_PWR_CUT_ALL_MSK,
1739 RTW_PWR_INTF_ALL_MSK,
1740 RTW_PWR_ADDR_MAC,
1741 RTW_PWR_CMD_WRITE, 0xFF, 0},
1742 {0x00EF,
1743 RTW_PWR_CUT_ALL_MSK,
1744 RTW_PWR_INTF_ALL_MSK,
1745 RTW_PWR_ADDR_MAC,
1746 RTW_PWR_CMD_WRITE, 0xFF, 0},
1747 {0xFF1A,
1748 RTW_PWR_CUT_ALL_MSK,
1749 RTW_PWR_INTF_USB_MSK,
1750 RTW_PWR_ADDR_MAC,
1751 RTW_PWR_CMD_WRITE, 0xFF, 0x30},
1752 {0x0049,
1753 RTW_PWR_CUT_ALL_MSK,
1754 RTW_PWR_INTF_ALL_MSK,
1755 RTW_PWR_ADDR_MAC,
1756 RTW_PWR_CMD_WRITE, BIT(1), 0},
1757 {0x0006,
1758 RTW_PWR_CUT_ALL_MSK,
1759 RTW_PWR_INTF_ALL_MSK,
1760 RTW_PWR_ADDR_MAC,
1761 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1762 {0x0002,
1763 RTW_PWR_CUT_ALL_MSK,
1764 RTW_PWR_INTF_ALL_MSK,
1765 RTW_PWR_ADDR_MAC,
1766 RTW_PWR_CMD_WRITE, BIT(1), 0},
1767 {0x10C3,
1768 RTW_PWR_CUT_ALL_MSK,
1769 RTW_PWR_INTF_USB_MSK,
1770 RTW_PWR_ADDR_MAC,
1771 RTW_PWR_CMD_WRITE, BIT(0), 0},
1772 {0x0005,
1773 RTW_PWR_CUT_ALL_MSK,
1774 RTW_PWR_INTF_ALL_MSK,
1775 RTW_PWR_ADDR_MAC,
1776 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
1777 {0x0005,
1778 RTW_PWR_CUT_ALL_MSK,
1779 RTW_PWR_INTF_ALL_MSK,
1780 RTW_PWR_ADDR_MAC,
1781 RTW_PWR_CMD_POLLING, BIT(1), 0},
1782 {0x0020,
1783 RTW_PWR_CUT_ALL_MSK,
1784 RTW_PWR_INTF_ALL_MSK,
1785 RTW_PWR_ADDR_MAC,
1786 RTW_PWR_CMD_WRITE, BIT(3), 0},
1787 {0x0000,
1788 RTW_PWR_CUT_ALL_MSK,
1789 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1790 RTW_PWR_ADDR_MAC,
1791 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1792 {0xFFFF,
1793 RTW_PWR_CUT_ALL_MSK,
1794 RTW_PWR_INTF_ALL_MSK,
1796 RTW_PWR_CMD_END, 0, 0},
1799 static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
1800 {0x0005,
1801 RTW_PWR_CUT_ALL_MSK,
1802 RTW_PWR_INTF_SDIO_MSK,
1803 RTW_PWR_ADDR_MAC,
1804 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
1805 {0x0007,
1806 RTW_PWR_CUT_ALL_MSK,
1807 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1808 RTW_PWR_ADDR_MAC,
1809 RTW_PWR_CMD_WRITE, 0xFF, 0x20},
1810 {0x0067,
1811 RTW_PWR_CUT_ALL_MSK,
1812 RTW_PWR_INTF_ALL_MSK,
1813 RTW_PWR_ADDR_MAC,
1814 RTW_PWR_CMD_WRITE, BIT(5), 0},
1815 {0x0005,
1816 RTW_PWR_CUT_ALL_MSK,
1817 RTW_PWR_INTF_PCI_MSK,
1818 RTW_PWR_ADDR_MAC,
1819 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
1820 {0x004A,
1821 RTW_PWR_CUT_ALL_MSK,
1822 RTW_PWR_INTF_USB_MSK,
1823 RTW_PWR_ADDR_MAC,
1824 RTW_PWR_CMD_WRITE, BIT(0), 0},
1825 {0x0067,
1826 RTW_PWR_CUT_ALL_MSK,
1827 RTW_PWR_INTF_SDIO_MSK,
1828 RTW_PWR_ADDR_MAC,
1829 RTW_PWR_CMD_WRITE, BIT(5), 0},
1830 {0x0067,
1831 RTW_PWR_CUT_ALL_MSK,
1832 RTW_PWR_INTF_SDIO_MSK,
1833 RTW_PWR_ADDR_MAC,
1834 RTW_PWR_CMD_WRITE, BIT(4), 0},
1835 {0x004F,
1836 RTW_PWR_CUT_ALL_MSK,
1837 RTW_PWR_INTF_SDIO_MSK,
1838 RTW_PWR_ADDR_MAC,
1839 RTW_PWR_CMD_WRITE, BIT(0), 0},
1840 {0x0067,
1841 RTW_PWR_CUT_ALL_MSK,
1842 RTW_PWR_INTF_SDIO_MSK,
1843 RTW_PWR_ADDR_MAC,
1844 RTW_PWR_CMD_WRITE, BIT(1), 0},
1845 {0x0046,
1846 RTW_PWR_CUT_ALL_MSK,
1847 RTW_PWR_INTF_SDIO_MSK,
1848 RTW_PWR_ADDR_MAC,
1849 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
1850 {0x0067,
1851 RTW_PWR_CUT_ALL_MSK,
1852 RTW_PWR_INTF_SDIO_MSK,
1853 RTW_PWR_ADDR_MAC,
1854 RTW_PWR_CMD_WRITE, BIT(2), 0},
1855 {0x0046,
1856 RTW_PWR_CUT_ALL_MSK,
1857 RTW_PWR_INTF_SDIO_MSK,
1858 RTW_PWR_ADDR_MAC,
1859 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
1860 {0x0062,
1861 RTW_PWR_CUT_ALL_MSK,
1862 RTW_PWR_INTF_SDIO_MSK,
1863 RTW_PWR_ADDR_MAC,
1864 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
1865 {0x0081,
1866 RTW_PWR_CUT_ALL_MSK,
1867 RTW_PWR_INTF_ALL_MSK,
1868 RTW_PWR_ADDR_MAC,
1869 RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0},
1870 {0x0005,
1871 RTW_PWR_CUT_ALL_MSK,
1872 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1873 RTW_PWR_ADDR_MAC,
1874 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
1875 {0x0086,
1876 RTW_PWR_CUT_ALL_MSK,
1877 RTW_PWR_INTF_SDIO_MSK,
1878 RTW_PWR_ADDR_SDIO,
1879 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1880 {0x0086,
1881 RTW_PWR_CUT_ALL_MSK,
1882 RTW_PWR_INTF_SDIO_MSK,
1883 RTW_PWR_ADDR_SDIO,
1884 RTW_PWR_CMD_POLLING, BIT(1), 0},
1885 {0x0090,
1886 RTW_PWR_CUT_ALL_MSK,
1887 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK,
1888 RTW_PWR_ADDR_MAC,
1889 RTW_PWR_CMD_WRITE, BIT(1), 0},
1890 {0x0044,
1891 RTW_PWR_CUT_ALL_MSK,
1892 RTW_PWR_INTF_SDIO_MSK,
1893 RTW_PWR_ADDR_SDIO,
1894 RTW_PWR_CMD_WRITE, 0xFF, 0},
1895 {0x0040,
1896 RTW_PWR_CUT_ALL_MSK,
1897 RTW_PWR_INTF_SDIO_MSK,
1898 RTW_PWR_ADDR_SDIO,
1899 RTW_PWR_CMD_WRITE, 0xFF, 0x90},
1900 {0x0041,
1901 RTW_PWR_CUT_ALL_MSK,
1902 RTW_PWR_INTF_SDIO_MSK,
1903 RTW_PWR_ADDR_SDIO,
1904 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
1905 {0x0042,
1906 RTW_PWR_CUT_ALL_MSK,
1907 RTW_PWR_INTF_SDIO_MSK,
1908 RTW_PWR_ADDR_SDIO,
1909 RTW_PWR_CMD_WRITE, 0xFF, 0x04},
1910 {0xFFFF,
1911 RTW_PWR_CUT_ALL_MSK,
1912 RTW_PWR_INTF_ALL_MSK,
1914 RTW_PWR_CMD_END, 0, 0},
1917 static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
1918 trans_carddis_to_cardemu_8822b,
1919 trans_cardemu_to_act_8822b,
1920 NULL
1923 static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
1924 trans_act_to_cardemu_8822b,
1925 trans_cardemu_to_carddis_8822b,
1926 NULL
1929 static const struct rtw_intf_phy_para usb2_param_8822b[] = {
1930 {0xFFFF, 0x00,
1931 RTW_IP_SEL_PHY,
1932 RTW_INTF_PHY_CUT_ALL,
1933 RTW_INTF_PHY_PLATFORM_ALL},
1936 static const struct rtw_intf_phy_para usb3_param_8822b[] = {
1937 {0x0001, 0xA841,
1938 RTW_IP_SEL_PHY,
1939 RTW_INTF_PHY_CUT_D,
1940 RTW_INTF_PHY_PLATFORM_ALL},
1941 {0xFFFF, 0x0000,
1942 RTW_IP_SEL_PHY,
1943 RTW_INTF_PHY_CUT_ALL,
1944 RTW_INTF_PHY_PLATFORM_ALL},
1947 static const struct rtw_intf_phy_para pcie_gen1_param_8822b[] = {
1948 {0x0001, 0xA841,
1949 RTW_IP_SEL_PHY,
1950 RTW_INTF_PHY_CUT_C,
1951 RTW_INTF_PHY_PLATFORM_ALL},
1952 {0x0002, 0x60C6,
1953 RTW_IP_SEL_PHY,
1954 RTW_INTF_PHY_CUT_C,
1955 RTW_INTF_PHY_PLATFORM_ALL},
1956 {0x0008, 0x3596,
1957 RTW_IP_SEL_PHY,
1958 RTW_INTF_PHY_CUT_C,
1959 RTW_INTF_PHY_PLATFORM_ALL},
1960 {0x0009, 0x321C,
1961 RTW_IP_SEL_PHY,
1962 RTW_INTF_PHY_CUT_C,
1963 RTW_INTF_PHY_PLATFORM_ALL},
1964 {0x000A, 0x9623,
1965 RTW_IP_SEL_PHY,
1966 RTW_INTF_PHY_CUT_C,
1967 RTW_INTF_PHY_PLATFORM_ALL},
1968 {0x0020, 0x94FF,
1969 RTW_IP_SEL_PHY,
1970 RTW_INTF_PHY_CUT_C,
1971 RTW_INTF_PHY_PLATFORM_ALL},
1972 {0x0021, 0xFFCF,
1973 RTW_IP_SEL_PHY,
1974 RTW_INTF_PHY_CUT_C,
1975 RTW_INTF_PHY_PLATFORM_ALL},
1976 {0x0026, 0xC006,
1977 RTW_IP_SEL_PHY,
1978 RTW_INTF_PHY_CUT_C,
1979 RTW_INTF_PHY_PLATFORM_ALL},
1980 {0x0029, 0xFF0E,
1981 RTW_IP_SEL_PHY,
1982 RTW_INTF_PHY_CUT_C,
1983 RTW_INTF_PHY_PLATFORM_ALL},
1984 {0x002A, 0x1840,
1985 RTW_IP_SEL_PHY,
1986 RTW_INTF_PHY_CUT_C,
1987 RTW_INTF_PHY_PLATFORM_ALL},
1988 {0xFFFF, 0x0000,
1989 RTW_IP_SEL_PHY,
1990 RTW_INTF_PHY_CUT_ALL,
1991 RTW_INTF_PHY_PLATFORM_ALL},
1994 static const struct rtw_intf_phy_para pcie_gen2_param_8822b[] = {
1995 {0x0001, 0xA841,
1996 RTW_IP_SEL_PHY,
1997 RTW_INTF_PHY_CUT_C,
1998 RTW_INTF_PHY_PLATFORM_ALL},
1999 {0x0002, 0x60C6,
2000 RTW_IP_SEL_PHY,
2001 RTW_INTF_PHY_CUT_C,
2002 RTW_INTF_PHY_PLATFORM_ALL},
2003 {0x0008, 0x3597,
2004 RTW_IP_SEL_PHY,
2005 RTW_INTF_PHY_CUT_C,
2006 RTW_INTF_PHY_PLATFORM_ALL},
2007 {0x0009, 0x321C,
2008 RTW_IP_SEL_PHY,
2009 RTW_INTF_PHY_CUT_C,
2010 RTW_INTF_PHY_PLATFORM_ALL},
2011 {0x000A, 0x9623,
2012 RTW_IP_SEL_PHY,
2013 RTW_INTF_PHY_CUT_C,
2014 RTW_INTF_PHY_PLATFORM_ALL},
2015 {0x0020, 0x94FF,
2016 RTW_IP_SEL_PHY,
2017 RTW_INTF_PHY_CUT_C,
2018 RTW_INTF_PHY_PLATFORM_ALL},
2019 {0x0021, 0xFFCF,
2020 RTW_IP_SEL_PHY,
2021 RTW_INTF_PHY_CUT_C,
2022 RTW_INTF_PHY_PLATFORM_ALL},
2023 {0x0026, 0xC006,
2024 RTW_IP_SEL_PHY,
2025 RTW_INTF_PHY_CUT_C,
2026 RTW_INTF_PHY_PLATFORM_ALL},
2027 {0x0029, 0xFF0E,
2028 RTW_IP_SEL_PHY,
2029 RTW_INTF_PHY_CUT_C,
2030 RTW_INTF_PHY_PLATFORM_ALL},
2031 {0x002A, 0x3040,
2032 RTW_IP_SEL_PHY,
2033 RTW_INTF_PHY_CUT_C,
2034 RTW_INTF_PHY_PLATFORM_ALL},
2035 {0xFFFF, 0x0000,
2036 RTW_IP_SEL_PHY,
2037 RTW_INTF_PHY_CUT_ALL,
2038 RTW_INTF_PHY_PLATFORM_ALL},
2041 static const struct rtw_intf_phy_para_table phy_para_table_8822b = {
2042 .usb2_para = usb2_param_8822b,
2043 .usb3_para = usb3_param_8822b,
2044 .gen1_para = pcie_gen1_param_8822b,
2045 .gen2_para = pcie_gen2_param_8822b,
2046 .n_usb2_para = ARRAY_SIZE(usb2_param_8822b),
2047 .n_usb3_para = ARRAY_SIZE(usb2_param_8822b),
2048 .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8822b),
2049 .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b),
2052 static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
2053 [2] = RTW_DEF_RFE(8822b, 2, 2),
2054 [3] = RTW_DEF_RFE(8822b, 3, 0),
2055 [5] = RTW_DEF_RFE(8822b, 5, 5),
2058 static const struct rtw_hw_reg rtw8822b_dig[] = {
2059 [0] = { .addr = 0xc50, .mask = 0x7f },
2060 [1] = { .addr = 0xe50, .mask = 0x7f },
2063 static const struct rtw_ltecoex_addr rtw8822b_ltecoex_addr = {
2064 .ctrl = LTECOEX_ACCESS_CTRL,
2065 .wdata = LTECOEX_WRITE_DATA,
2066 .rdata = LTECOEX_READ_DATA,
2069 static const struct rtw_page_table page_table_8822b[] = {
2070 {64, 64, 64, 64, 1},
2071 {64, 64, 64, 64, 1},
2072 {64, 64, 0, 0, 1},
2073 {64, 64, 64, 0, 1},
2074 {64, 64, 64, 64, 1},
2077 static const struct rtw_rqpn rqpn_table_8822b[] = {
2078 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2079 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2080 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2081 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2082 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2083 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2084 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2085 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
2086 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
2087 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2088 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2089 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
2090 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2091 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2092 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2095 static struct rtw_prioq_addrs prioq_addrs_8822b = {
2096 .prio[RTW_DMA_MAPPING_EXTRA] = {
2097 .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
2099 .prio[RTW_DMA_MAPPING_LOW] = {
2100 .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2,
2102 .prio[RTW_DMA_MAPPING_NORMAL] = {
2103 .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2,
2105 .prio[RTW_DMA_MAPPING_HIGH] = {
2106 .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2,
2108 .wsize = true,
2111 static struct rtw_chip_ops rtw8822b_ops = {
2112 .phy_set_param = rtw8822b_phy_set_param,
2113 .read_efuse = rtw8822b_read_efuse,
2114 .query_rx_desc = rtw8822b_query_rx_desc,
2115 .set_channel = rtw8822b_set_channel,
2116 .mac_init = rtw8822b_mac_init,
2117 .read_rf = rtw_phy_read_rf,
2118 .write_rf = rtw_phy_write_rf_reg_sipi,
2119 .set_tx_power_index = rtw8822b_set_tx_power_index,
2120 .set_antenna = rtw8822b_set_antenna,
2121 .cfg_ldo25 = rtw8822b_cfg_ldo25,
2122 .false_alarm_statistics = rtw8822b_false_alarm_statistics,
2123 .phy_calibration = rtw8822b_phy_calibration,
2124 .pwr_track = rtw8822b_pwr_track,
2125 .config_bfee = rtw8822b_bf_config_bfee,
2126 .set_gid_table = rtw_bf_set_gid_table,
2127 .cfg_csi_rate = rtw_bf_cfg_csi_rate,
2129 .coex_set_init = rtw8822b_coex_cfg_init,
2130 .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch,
2131 .coex_set_gnt_fix = rtw8822b_coex_cfg_gnt_fix,
2132 .coex_set_gnt_debug = rtw8822b_coex_cfg_gnt_debug,
2133 .coex_set_rfe_type = rtw8822b_coex_cfg_rfe_type,
2134 .coex_set_wl_tx_power = rtw8822b_coex_cfg_wl_tx_power,
2135 .coex_set_wl_rx_gain = rtw8822b_coex_cfg_wl_rx_gain,
2138 /* Shared-Antenna Coex Table */
2139 static const struct coex_table_para table_sant_8822b[] = {
2140 {0xffffffff, 0xffffffff}, /* case-0 */
2141 {0x55555555, 0x55555555},
2142 {0x66555555, 0x66555555},
2143 {0xaaaaaaaa, 0xaaaaaaaa},
2144 {0x5a5a5a5a, 0x5a5a5a5a},
2145 {0xfafafafa, 0xfafafafa}, /* case-5 */
2146 {0x6a5a5555, 0xaaaaaaaa},
2147 {0x6a5a56aa, 0x6a5a56aa},
2148 {0x6a5a5a5a, 0x6a5a5a5a},
2149 {0x66555555, 0x5a5a5a5a},
2150 {0x66555555, 0x6a5a5a5a}, /* case-10 */
2151 {0x66555555, 0xfafafafa},
2152 {0x66555555, 0x5a5a5aaa},
2153 {0x66555555, 0x6aaa5aaa},
2154 {0x66555555, 0xaaaa5aaa},
2155 {0x66555555, 0xaaaaaaaa}, /* case-15 */
2156 {0xffff55ff, 0xfafafafa},
2157 {0xffff55ff, 0x6afa5afa},
2158 {0xaaffffaa, 0xfafafafa},
2159 {0xaa5555aa, 0x5a5a5a5a},
2160 {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
2161 {0xaa5555aa, 0xaaaaaaaa},
2162 {0xffffffff, 0x5a5a5a5a},
2163 {0xffffffff, 0x5a5a5a5a},
2164 {0xffffffff, 0x55555555},
2165 {0xffffffff, 0x6a5a5aaa}, /* case-25 */
2166 {0x55555555, 0x5a5a5a5a},
2167 {0x55555555, 0xaaaaaaaa},
2168 {0x55555555, 0x6a5a6a5a},
2169 {0x66556655, 0x66556655},
2170 {0x66556aaa, 0x6a5a6aaa}, /* case-30 */
2171 {0xffffffff, 0x5aaa5aaa},
2172 {0x56555555, 0x5a5a5aaa},
2175 /* Non-Shared-Antenna Coex Table */
2176 static const struct coex_table_para table_nsant_8822b[] = {
2177 {0xffffffff, 0xffffffff}, /* case-100 */
2178 {0x55555555, 0x55555555},
2179 {0x66555555, 0x66555555},
2180 {0xaaaaaaaa, 0xaaaaaaaa},
2181 {0x5a5a5a5a, 0x5a5a5a5a},
2182 {0xfafafafa, 0xfafafafa}, /* case-105 */
2183 {0x5afa5afa, 0x5afa5afa},
2184 {0x55555555, 0xfafafafa},
2185 {0x66555555, 0xfafafafa},
2186 {0x66555555, 0x5a5a5a5a},
2187 {0x66555555, 0x6a5a5a5a}, /* case-110 */
2188 {0x66555555, 0xaaaaaaaa},
2189 {0xffff55ff, 0xfafafafa},
2190 {0xffff55ff, 0x5afa5afa},
2191 {0xffff55ff, 0xaaaaaaaa},
2192 {0xffff55ff, 0xffff55ff}, /* case-115 */
2193 {0xaaffffaa, 0x5afa5afa},
2194 {0xaaffffaa, 0xaaaaaaaa},
2195 {0xffffffff, 0xfafafafa},
2196 {0xffffffff, 0x5afa5afa},
2197 {0xffffffff, 0xaaaaaaaa}, /* case-120 */
2198 {0x55ff55ff, 0x5afa5afa},
2199 {0x55ff55ff, 0xaaaaaaaa},
2200 {0x55ff55ff, 0x55ff55ff}
2203 /* Shared-Antenna TDMA */
2204 static const struct coex_tdma_para tdma_sant_8822b[] = {
2205 { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
2206 { {0x61, 0x45, 0x03, 0x11, 0x11} },
2207 { {0x61, 0x3a, 0x03, 0x11, 0x11} },
2208 { {0x61, 0x30, 0x03, 0x11, 0x11} },
2209 { {0x61, 0x20, 0x03, 0x11, 0x11} },
2210 { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */
2211 { {0x61, 0x45, 0x03, 0x11, 0x10} },
2212 { {0x61, 0x3a, 0x03, 0x11, 0x10} },
2213 { {0x61, 0x30, 0x03, 0x11, 0x10} },
2214 { {0x61, 0x20, 0x03, 0x11, 0x10} },
2215 { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
2216 { {0x61, 0x08, 0x03, 0x11, 0x14} },
2217 { {0x61, 0x08, 0x03, 0x10, 0x14} },
2218 { {0x51, 0x08, 0x03, 0x10, 0x54} },
2219 { {0x51, 0x08, 0x03, 0x10, 0x55} },
2220 { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
2221 { {0x51, 0x45, 0x03, 0x10, 0x50} },
2222 { {0x51, 0x3a, 0x03, 0x10, 0x50} },
2223 { {0x51, 0x30, 0x03, 0x10, 0x50} },
2224 { {0x51, 0x20, 0x03, 0x10, 0x50} },
2225 { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
2226 { {0x51, 0x4a, 0x03, 0x10, 0x50} },
2227 { {0x51, 0x0c, 0x03, 0x10, 0x54} },
2228 { {0x55, 0x08, 0x03, 0x10, 0x54} },
2229 { {0x65, 0x10, 0x03, 0x11, 0x10} },
2230 { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
2231 { {0x51, 0x08, 0x03, 0x10, 0x50} },
2232 { {0x61, 0x08, 0x03, 0x11, 0x11} }
2235 /* Non-Shared-Antenna TDMA */
2236 static const struct coex_tdma_para tdma_nsant_8822b[] = {
2237 { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-100 */
2238 { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */
2239 { {0x61, 0x3a, 0x03, 0x11, 0x11} },
2240 { {0x61, 0x30, 0x03, 0x11, 0x11} },
2241 { {0x61, 0x20, 0x03, 0x11, 0x11} },
2242 { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
2243 { {0x61, 0x45, 0x03, 0x11, 0x10} },
2244 { {0x61, 0x3a, 0x03, 0x11, 0x10} },
2245 { {0x61, 0x30, 0x03, 0x11, 0x10} },
2246 { {0x61, 0x20, 0x03, 0x11, 0x10} },
2247 { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
2248 { {0x61, 0x08, 0x03, 0x11, 0x14} },
2249 { {0x61, 0x08, 0x03, 0x10, 0x14} },
2250 { {0x51, 0x08, 0x03, 0x10, 0x54} },
2251 { {0x51, 0x08, 0x03, 0x10, 0x55} },
2252 { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
2253 { {0x51, 0x45, 0x03, 0x10, 0x50} },
2254 { {0x51, 0x3a, 0x03, 0x10, 0x50} },
2255 { {0x51, 0x30, 0x03, 0x10, 0x50} },
2256 { {0x51, 0x20, 0x03, 0x10, 0x50} },
2257 { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */
2258 { {0x51, 0x08, 0x03, 0x10, 0x50} }
2261 /* rssi in percentage % (dbm = % - 100) */
2262 static const u8 wl_rssi_step_8822b[] = {60, 50, 44, 30};
2263 static const u8 bt_rssi_step_8822b[] = {30, 30, 30, 30};
2265 /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
2266 static const struct coex_rf_para rf_para_tx_8822b[] = {
2267 {0, 0, false, 7}, /* for normal */
2268 {0, 16, false, 7}, /* for WL-CPT */
2269 {4, 0, true, 1},
2270 {3, 6, true, 1},
2271 {2, 9, true, 1},
2272 {1, 13, true, 1}
2275 static const struct coex_rf_para rf_para_rx_8822b[] = {
2276 {0, 0, false, 7}, /* for normal */
2277 {0, 16, false, 7}, /* for WL-CPT */
2278 {4, 0, true, 1},
2279 {3, 6, true, 1},
2280 {2, 9, true, 1},
2281 {1, 13, true, 1}
2284 static const struct coex_5g_afh_map afh_5g_8822b[] = {
2285 {120, 2, 4},
2286 {124, 8, 8},
2287 {128, 17, 8},
2288 {132, 26, 10},
2289 {136, 34, 8},
2290 {140, 42, 10},
2291 {144, 51, 8},
2292 {149, 62, 8},
2293 {153, 71, 10},
2294 {157, 77, 4},
2295 {118, 2, 4},
2296 {126, 12, 16},
2297 {134, 29, 16},
2298 {142, 46, 16},
2299 {151, 66, 16},
2300 {159, 76, 4},
2301 {122, 10, 20},
2302 {138, 37, 34},
2303 {155, 68, 20}
2305 static_assert(ARRAY_SIZE(rf_para_tx_8822b) == ARRAY_SIZE(rf_para_rx_8822b));
2307 static const u8
2308 rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2309 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2310 8, 8, 9, 10, 11, 11, 12, 13, 14, 14,
2311 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2312 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2313 8, 8, 9, 10, 11, 11, 12, 13, 14, 14,
2314 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2315 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2316 8, 8, 9, 10, 11, 11, 12, 13, 14, 14,
2317 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2320 static const u8
2321 rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2322 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2323 8, 9, 9, 10, 11, 12, 13, 14, 14, 15,
2324 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2325 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2326 8, 9, 9, 10, 11, 12, 13, 14, 14, 15,
2327 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2328 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2329 8, 9, 9, 10, 11, 12, 13, 14, 14, 15,
2330 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 },
2333 static const u8
2334 rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2335 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2336 8, 8, 9, 10, 11, 11, 12, 13, 14, 14,
2337 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2338 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2339 8, 8, 9, 10, 11, 11, 12, 13, 14, 14,
2340 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2341 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2342 8, 8, 9, 10, 11, 11, 12, 13, 14, 14,
2343 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 },
2346 static const u8
2347 rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = {
2348 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2349 8, 9, 9, 10, 11, 12, 13, 14, 14, 15,
2350 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2351 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2352 8, 9, 9, 10, 11, 12, 13, 14, 14, 15,
2353 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2354 { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7,
2355 8, 9, 9, 10, 11, 12, 13, 14, 14, 15,
2356 16, 17, 18, 19, 19, 20, 21, 22, 22, 23},
2359 static const u8 rtw8822b_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = {
2360 0, 1, 1, 1, 2, 2, 3, 3, 3, 4,
2361 4, 5, 5, 5, 6, 6, 7, 7, 7, 8,
2362 8, 9, 9, 9, 10, 10, 11, 11, 11, 12
2365 static const u8 rtw8822b_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = {
2366 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
2367 5, 5, 6, 6, 6, 7, 7, 8, 8, 9,
2368 9, 10, 10, 11, 11, 12, 12, 12, 13, 13
2371 static const u8 rtw8822b_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = {
2372 0, 1, 1, 1, 2, 2, 3, 3, 3, 4,
2373 4, 5, 5, 5, 6, 6, 7, 7, 7, 8,
2374 8, 9, 9, 9, 10, 10, 11, 11, 11, 12
2377 static const u8 rtw8822b_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = {
2378 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
2379 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
2380 10, 11, 11, 12, 12, 13, 13, 14, 14, 15
2383 static const u8 rtw8822b_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = {
2384 0, 1, 1, 1, 2, 2, 3, 3, 3, 4,
2385 4, 5, 5, 5, 6, 6, 7, 7, 7, 8,
2386 8, 9, 9, 9, 10, 10, 11, 11, 11, 12
2389 static const u8 rtw8822b_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = {
2390 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
2391 5, 5, 6, 6, 6, 7, 7, 8, 8, 9,
2392 9, 10, 10, 11, 11, 12, 12, 12, 13, 13
2395 static const u8 rtw8822b_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = {
2396 0, 1, 1, 1, 2, 2, 3, 3, 3, 4,
2397 4, 5, 5, 5, 6, 6, 7, 7, 7, 8,
2398 8, 9, 9, 9, 10, 10, 11, 11, 11, 12
2401 static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
2402 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
2403 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
2404 10, 11, 11, 12, 12, 13, 13, 14, 14, 15
2407 static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
2408 .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
2409 .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
2410 .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
2411 .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1],
2412 .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2],
2413 .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3],
2414 .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1],
2415 .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2],
2416 .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3],
2417 .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1],
2418 .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2],
2419 .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3],
2420 .pwrtrk_2gb_n = rtw8822b_pwrtrk_2gb_n,
2421 .pwrtrk_2gb_p = rtw8822b_pwrtrk_2gb_p,
2422 .pwrtrk_2ga_n = rtw8822b_pwrtrk_2ga_n,
2423 .pwrtrk_2ga_p = rtw8822b_pwrtrk_2ga_p,
2424 .pwrtrk_2g_cckb_n = rtw8822b_pwrtrk_2g_cck_b_n,
2425 .pwrtrk_2g_cckb_p = rtw8822b_pwrtrk_2g_cck_b_p,
2426 .pwrtrk_2g_ccka_n = rtw8822b_pwrtrk_2g_cck_a_n,
2427 .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
2430 static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
2431 {0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2432 {0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2433 {0xcba, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2434 {0xcbd, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2435 {0xc58, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2436 {0xcbd, BIT(0), RTW_REG_DOMAIN_MAC8},
2437 {0, 0, RTW_REG_DOMAIN_NL},
2438 {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2439 {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2440 {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
2441 {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2442 {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
2443 {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
2444 {0, 0, RTW_REG_DOMAIN_NL},
2445 {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
2446 {0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
2447 {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
2448 {0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
2449 {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B},
2450 {0, 0, RTW_REG_DOMAIN_NL},
2451 {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2452 {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2453 {0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
2454 {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2457 struct rtw_chip_info rtw8822b_hw_spec = {
2458 .ops = &rtw8822b_ops,
2459 .id = RTW_CHIP_TYPE_8822B,
2460 .fw_name = "rtw88/rtw8822b_fw.bin",
2461 .wlan_cpu = RTW_WCPU_11AC,
2462 .tx_pkt_desc_sz = 48,
2463 .tx_buf_desc_sz = 16,
2464 .rx_pkt_desc_sz = 24,
2465 .rx_buf_desc_sz = 8,
2466 .phy_efuse_size = 1024,
2467 .log_efuse_size = 768,
2468 .ptct_efuse_size = 96,
2469 .txff_size = 262144,
2470 .rxff_size = 24576,
2471 .fw_rxff_size = 12288,
2472 .txgi_factor = 1,
2473 .is_pwr_by_rate_dec = true,
2474 .max_power_index = 0x3f,
2475 .csi_buf_pg_num = 0,
2476 .band = RTW_BAND_2G | RTW_BAND_5G,
2477 .page_size = 128,
2478 .dig_min = 0x1c,
2479 .ht_supported = true,
2480 .vht_supported = true,
2481 .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
2482 .sys_func_en = 0xDC,
2483 .pwr_on_seq = card_enable_flow_8822b,
2484 .pwr_off_seq = card_disable_flow_8822b,
2485 .page_table = page_table_8822b,
2486 .rqpn_table = rqpn_table_8822b,
2487 .prioq_addrs = &prioq_addrs_8822b,
2488 .intf_table = &phy_para_table_8822b,
2489 .dig = rtw8822b_dig,
2490 .dig_cck = NULL,
2491 .rf_base_addr = {0x2800, 0x2c00},
2492 .rf_sipi_addr = {0xc90, 0xe90},
2493 .ltecoex_addr = &rtw8822b_ltecoex_addr,
2494 .mac_tbl = &rtw8822b_mac_tbl,
2495 .agc_tbl = &rtw8822b_agc_tbl,
2496 .bb_tbl = &rtw8822b_bb_tbl,
2497 .rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl},
2498 .rfe_defs = rtw8822b_rfe_defs,
2499 .rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs),
2500 .pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl,
2501 .iqk_threshold = 8,
2502 .bfer_su_max_num = 2,
2503 .bfer_mu_max_num = 1,
2504 .rx_ldpc = true,
2506 .coex_para_ver = 0x20070206,
2507 .bt_desired_ver = 0x6,
2508 .scbd_support = true,
2509 .new_scbd10_def = false,
2510 .ble_hid_profile_support = false,
2511 .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
2512 .bt_rssi_type = COEX_BTRSSI_RATIO,
2513 .ant_isolation = 15,
2514 .rssi_tolerance = 2,
2515 .wl_rssi_step = wl_rssi_step_8822b,
2516 .bt_rssi_step = bt_rssi_step_8822b,
2517 .table_sant_num = ARRAY_SIZE(table_sant_8822b),
2518 .table_sant = table_sant_8822b,
2519 .table_nsant_num = ARRAY_SIZE(table_nsant_8822b),
2520 .table_nsant = table_nsant_8822b,
2521 .tdma_sant_num = ARRAY_SIZE(tdma_sant_8822b),
2522 .tdma_sant = tdma_sant_8822b,
2523 .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8822b),
2524 .tdma_nsant = tdma_nsant_8822b,
2525 .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8822b),
2526 .wl_rf_para_tx = rf_para_tx_8822b,
2527 .wl_rf_para_rx = rf_para_rx_8822b,
2528 .bt_afh_span_bw20 = 0x24,
2529 .bt_afh_span_bw40 = 0x36,
2530 .afh_5g_num = ARRAY_SIZE(afh_5g_8822b),
2531 .afh_5g = afh_5g_8822b,
2533 .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b),
2534 .coex_info_hw_regs = coex_info_hw_regs_8822b,
2536 .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680},
2538 EXPORT_SYMBOL(rtw8822b_hw_spec);
2540 MODULE_FIRMWARE("rtw88/rtw8822b_fw.bin");
2542 MODULE_AUTHOR("Realtek Corporation");
2543 MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822b driver");
2544 MODULE_LICENSE("Dual BSD/GPL");