1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019 Realtek Corporation
12 #include "rtw8821c_table.h"
19 static const s8 lna_gain_table_0[8] = {22, 8, -6, -22, -31, -40, -46, -52};
20 static const s8 lna_gain_table_1[16] = {10, 6, 2, -2, -6, -10, -14, -17,
21 -20, -24, -28, -31, -34, -37, -40, -44};
23 static void rtw8821ce_efuse_parsing(struct rtw_efuse *efuse,
24 struct rtw8821c_efuse *map)
26 ether_addr_copy(efuse->addr, map->e.mac_addr);
29 enum rtw8821ce_rf_set {
36 static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
38 struct rtw_efuse *efuse = &rtwdev->efuse;
39 struct rtw8821c_efuse *map;
42 map = (struct rtw8821c_efuse *)log_map;
44 efuse->rfe_option = map->rfe_option;
45 efuse->rf_board_option = map->rf_board_option;
46 efuse->crystal_cap = map->xtal_k;
47 efuse->pa_type_2g = map->pa_type;
48 efuse->pa_type_5g = map->pa_type;
49 efuse->lna_type_2g = map->lna_type_2g[0];
50 efuse->lna_type_5g = map->lna_type_5g[0];
51 efuse->channel_plan = map->channel_plan;
52 efuse->country_code[0] = map->country_code[0];
53 efuse->country_code[1] = map->country_code[1];
54 efuse->bt_setting = map->rf_bt_setting;
55 efuse->regd = map->rf_board_option & 0x7;
56 efuse->thermal_meter[0] = map->thermal_meter;
57 efuse->thermal_meter_k = map->thermal_meter;
58 efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g;
59 efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g;
61 for (i = 0; i < 4; i++)
62 efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
64 if (rtwdev->efuse.rfe_option == 2 || rtwdev->efuse.rfe_option == 4)
65 efuse->txpwr_idx_table[0].pwr_idx_2g = map->txpwr_idx_table[1].pwr_idx_2g;
67 switch (rtw_hci_type(rtwdev)) {
68 case RTW_HCI_TYPE_PCIE:
69 rtw8821ce_efuse_parsing(efuse, map);
79 static const u32 rtw8821c_txscale_tbl[] = {
80 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8,
81 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180,
82 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab,
83 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe
86 static u8 rtw8821c_get_swing_index(struct rtw_dev *rtwdev)
89 u32 swing, table_value;
91 swing = rtw_read32_mask(rtwdev, REG_TXSCALE_A, 0xffe00000);
92 for (i = 0; i < ARRAY_SIZE(rtw8821c_txscale_tbl); i++) {
93 table_value = rtw8821c_txscale_tbl[i];
94 if (swing == table_value)
101 static void rtw8821c_pwrtrack_init(struct rtw_dev *rtwdev)
103 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
104 u8 swing_idx = rtw8821c_get_swing_index(rtwdev);
106 if (swing_idx >= ARRAY_SIZE(rtw8821c_txscale_tbl))
107 dm_info->default_ofdm_index = 24;
109 dm_info->default_ofdm_index = swing_idx;
111 ewma_thermal_init(&dm_info->avg_thermal[RF_PATH_A]);
112 dm_info->delta_power_index[RF_PATH_A] = 0;
113 dm_info->delta_power_index_last[RF_PATH_A] = 0;
114 dm_info->pwr_trk_triggered = false;
115 dm_info->pwr_trk_init_trigger = true;
116 dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
119 static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev)
121 rtw_bf_phy_init(rtwdev);
122 /* Grouping bitmap parameters */
123 rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF);
126 static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev)
130 /* power on BB/RF domain */
131 val = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
132 val |= BIT_FEN_PCIEA;
133 rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
135 /* toggle BB reset */
136 val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST;
137 rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
138 val &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
139 rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
140 val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST;
141 rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
143 rtw_write8(rtwdev, REG_RF_CTRL,
144 BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
145 usleep_range(10, 11);
146 rtw_write8(rtwdev, REG_WLRF1 + 3,
147 BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
148 usleep_range(10, 11);
150 /* pre init before header files config */
151 rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
153 rtw_phy_load_tables(rtwdev);
155 crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
156 rtw_write32_mask(rtwdev, REG_AFE_XTAL_CTRL, 0x7e000000, crystal_cap);
157 rtw_write32_mask(rtwdev, REG_AFE_PLL_CTRL, 0x7e, crystal_cap);
158 rtw_write32_mask(rtwdev, REG_CCK0_FAREPORT, BIT(18) | BIT(22), 0);
160 /* post init after header files config */
161 rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
162 rtwdev->chip->ch_param[0] = rtw_read32_mask(rtwdev, REG_TXSF2, MASKDWORD);
163 rtwdev->chip->ch_param[1] = rtw_read32_mask(rtwdev, REG_TXSF6, MASKDWORD);
164 rtwdev->chip->ch_param[2] = rtw_read32_mask(rtwdev, REG_TXFILTER, MASKDWORD);
166 rtw_phy_init(rtwdev);
167 rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f;
169 rtw8821c_pwrtrack_init(rtwdev);
171 rtw8821c_phy_bf_init(rtwdev);
174 static int rtw8821c_mac_init(struct rtw_dev *rtwdev)
179 /* protocol configuration */
180 rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME);
181 rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
182 pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT;
183 rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF));
184 rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8));
185 value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) |
186 (WLAN_MAX_AGG_PKT_LIMIT << 16) |
187 (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24);
188 rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32);
189 rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2,
190 WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8);
191 rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH);
192 rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH);
193 rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH);
194 rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH);
195 rtw_write8_set(rtwdev, REG_INIRTS_RATE_SEL, BIT(5));
197 /* EDCA configuration */
198 rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0);
199 rtw_write16(rtwdev, REG_TXPAUSE, 0);
200 rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
201 rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME);
202 rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG);
203 rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT);
204 rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT);
205 rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG);
206 rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG);
208 /* Set beacon cotnrol - enable TSF and other related functions */
209 rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
211 /* Set send beacon related registers */
212 rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME);
213 rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT);
214 rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
215 rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8);
217 /* WMAC configuration */
218 rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
219 rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
220 rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
221 rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512);
222 rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2);
223 rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
224 rtw_write8(rtwdev, REG_ACKTO_CCK, 0x40);
225 rtw_write8_set(rtwdev, REG_WMAC_TRXPTCL_CTL_H, BIT(1));
226 rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL,
227 BIT_DIS_CHK_VHTSIGB_CRC);
228 rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
229 rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1);
234 static void rtw8821c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
238 ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
239 ldo_pwr = enable ? ldo_pwr | BIT(7) : ldo_pwr & ~BIT(7);
240 rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
243 static void rtw8821c_switch_rf_set(struct rtw_dev *rtwdev, u8 rf_set)
247 rtw_write32_set(rtwdev, REG_DMEM_CTRL, BIT_WL_RST);
248 rtw_write32_set(rtwdev, REG_SYS_CTRL, BIT_FEN_EN);
250 reg = rtw_read32(rtwdev, REG_RFECTL);
254 reg &= ~(B_CTRL_SWITCH | B_WL_SWITCH | B_WLG_SWITCH |
256 rtw_write32_mask(rtwdev, REG_ENRXCCA, MASKBYTE2, BTG_CCA);
257 rtw_write32_mask(rtwdev, REG_ENTXCCK, MASKLWORD, BTG_LNA);
260 reg |= B_WL_SWITCH | B_WLG_SWITCH;
261 reg &= ~(B_BTG_SWITCH | B_CTRL_SWITCH | B_WLA_SWITCH);
262 rtw_write32_mask(rtwdev, REG_ENRXCCA, MASKBYTE2, WLG_CCA);
263 rtw_write32_mask(rtwdev, REG_ENTXCCK, MASKLWORD, WLG_LNA);
266 reg |= B_WL_SWITCH | B_WLA_SWITCH;
267 reg &= ~(B_BTG_SWITCH | B_CTRL_SWITCH | B_WLG_SWITCH);
274 rtw_write32(rtwdev, REG_RFECTL, reg);
277 static void rtw8821c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
281 rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK);
283 rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK |
286 rf_reg18 |= (channel <= 14 ? RF18_BAND_2G : RF18_BAND_5G);
287 rf_reg18 |= (channel & RF18_CHANNEL_MASK);
289 if (channel >= 100 && channel <= 140)
290 rf_reg18 |= RF18_RFSI_GE;
291 else if (channel > 140)
292 rf_reg18 |= RF18_RFSI_GT;
295 case RTW_CHANNEL_WIDTH_5:
296 case RTW_CHANNEL_WIDTH_10:
297 case RTW_CHANNEL_WIDTH_20:
299 rf_reg18 |= RF18_BW_20M;
301 case RTW_CHANNEL_WIDTH_40:
302 rf_reg18 |= RF18_BW_40M;
304 case RTW_CHANNEL_WIDTH_80:
305 rf_reg18 |= RF18_BW_80M;
310 if (rtwdev->efuse.rfe_option == 0)
311 rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLG);
312 else if (rtwdev->efuse.rfe_option == 2 ||
313 rtwdev->efuse.rfe_option == 4)
314 rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_BTG);
315 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x1);
316 rtw_write_rf(rtwdev, RF_PATH_A, 0x64, 0xf, 0xf);
318 rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLA);
319 rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x0);
322 rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18);
324 rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0);
325 rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1);
328 static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw)
330 if (bw == RTW_CHANNEL_WIDTH_40) {
331 /* RX DFIR for BW40 */
332 rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
333 rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2);
334 rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
335 rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0);
336 } else if (bw == RTW_CHANNEL_WIDTH_80) {
337 /* RX DFIR for BW80 */
338 rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
339 rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1);
340 rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
341 rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x1);
343 /* RX DFIR for BW20, BW10 and BW5 */
344 rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
345 rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2);
346 rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1);
347 rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0);
351 static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
357 rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1);
358 rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0);
359 rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0);
360 rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15);
362 rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x0);
363 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a);
365 rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c);
366 rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000);
367 rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667);
369 rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD,
370 rtwdev->chip->ch_param[0]);
371 rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD,
372 rtwdev->chip->ch_param[1] & MASKLWORD);
373 rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD,
374 rtwdev->chip->ch_param[2]);
376 } else if (channel > 35) {
377 rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1);
378 rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1);
379 rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0);
380 rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15);
382 if (channel >= 36 && channel <= 64)
383 rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x1);
384 else if (channel >= 100 && channel <= 144)
385 rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x2);
386 else if (channel >= 149)
387 rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x3);
389 if (channel >= 36 && channel <= 48)
390 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494);
391 else if (channel >= 52 && channel <= 64)
392 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453);
393 else if (channel >= 100 && channel <= 116)
394 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452);
395 else if (channel >= 118 && channel <= 177)
396 rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412);
400 case RTW_CHANNEL_WIDTH_20:
402 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
405 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
407 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
409 case RTW_CHANNEL_WIDTH_40:
410 if (primary_ch_idx == 1)
411 rtw_write32_set(rtwdev, REG_RXSB, BIT(4));
413 rtw_write32_clr(rtwdev, REG_RXSB, BIT(4));
415 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
417 val32 |= 0x20020000 | ((primary_ch_idx & 0xf) << 2) |
418 RTW_CHANNEL_WIDTH_40;
419 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
421 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
423 case RTW_CHANNEL_WIDTH_80:
424 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
426 val32 |= 0x40040000 | ((primary_ch_idx & 0xf) << 2) |
427 RTW_CHANNEL_WIDTH_80;
428 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
430 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
432 case RTW_CHANNEL_WIDTH_5:
433 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
436 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
438 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
439 rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
441 case RTW_CHANNEL_WIDTH_10:
442 val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
445 rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
447 rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
448 rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
453 static u32 rtw8821c_get_bb_swing(struct rtw_dev *rtwdev, u8 channel)
455 struct rtw_efuse efuse = rtwdev->efuse;
457 u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6};
459 tx_bb_swing = channel <= 14 ? efuse.tx_bb_swing_setting_2g :
460 efuse.tx_bb_swing_setting_5g;
464 return swing2setting[(tx_bb_swing / 3)];
467 static void rtw8821c_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 channel,
468 u8 bw, u8 primary_ch_idx)
470 rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21),
471 rtw8821c_get_bb_swing(rtwdev, channel));
472 rtw8821c_pwrtrack_init(rtwdev);
475 static void rtw8821c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
478 rtw8821c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
479 rtw8821c_set_channel_bb_swing(rtwdev, channel, bw, primary_chan_idx);
480 rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
481 rtw8821c_set_channel_rf(rtwdev, channel, bw);
482 rtw8821c_set_channel_rxdfir(rtwdev, bw);
485 static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx)
487 struct rtw_efuse *efuse = &rtwdev->efuse;
488 const s8 *lna_gain_table;
489 int lna_gain_table_size;
493 if (efuse->rfe_option == 0) {
494 lna_gain_table = lna_gain_table_0;
495 lna_gain_table_size = ARRAY_SIZE(lna_gain_table_0);
497 lna_gain_table = lna_gain_table_1;
498 lna_gain_table_size = ARRAY_SIZE(lna_gain_table_1);
501 if (lna_idx >= lna_gain_table_size) {
502 rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx);
506 lna_gain = lna_gain_table[lna_idx];
507 rx_pwr_all = lna_gain - 2 * vga_idx;
512 static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
513 struct rtw_rx_pkt_stat *pkt_stat)
515 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
520 vga_idx = GET_PHY_STAT_P0_VGA(phy_status);
521 lna_idx = FIELD_PREP(BIT_LNA_H_MASK, GET_PHY_STAT_P0_LNA_H(phy_status)) |
522 FIELD_PREP(BIT_LNA_L_MASK, GET_PHY_STAT_P0_LNA_L(phy_status));
523 rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx);
525 pkt_stat->rx_power[RF_PATH_A] = rx_power;
526 pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
527 dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
528 pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
529 pkt_stat->signal_power = rx_power;
532 static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
533 struct rtw_rx_pkt_stat *pkt_stat)
535 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
537 s8 min_rx_power = -120;
539 if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
540 rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
542 rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
544 if (rxsc >= 1 && rxsc <= 8)
545 bw = RTW_CHANNEL_WIDTH_20;
546 else if (rxsc >= 9 && rxsc <= 12)
547 bw = RTW_CHANNEL_WIDTH_40;
549 bw = RTW_CHANNEL_WIDTH_80;
551 bw = GET_PHY_STAT_P1_RF_MODE(phy_status);
553 pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
554 pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
555 dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
557 pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
561 static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
562 struct rtw_rx_pkt_stat *pkt_stat)
566 page = *phy_status & 0xf;
570 query_phy_status_page0(rtwdev, phy_status, pkt_stat);
573 query_phy_status_page1(rtwdev, phy_status, pkt_stat);
576 rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
581 static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
582 struct rtw_rx_pkt_stat *pkt_stat,
583 struct ieee80211_rx_status *rx_status)
585 struct ieee80211_hdr *hdr;
586 u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
587 u8 *phy_status = NULL;
589 memset(pkt_stat, 0, sizeof(*pkt_stat));
591 pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
592 pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
593 pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
594 pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
595 GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
596 pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
597 pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
598 pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
599 pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
600 pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
601 pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
602 pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
603 pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
605 /* drv_info_sz is in unit of 8-bytes */
606 pkt_stat->drv_info_sz *= 8;
608 /* c2h cmd pkt's rx/phy status is not interested */
609 if (pkt_stat->is_c2h)
612 hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
613 pkt_stat->drv_info_sz);
614 if (pkt_stat->phy_status) {
615 phy_status = rx_desc + desc_sz + pkt_stat->shift;
616 query_phy_status(rtwdev, phy_status, pkt_stat);
619 rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
623 rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
625 struct rtw_hal *hal = &rtwdev->hal;
626 static const u32 offset_txagc[2] = {0x1d00, 0x1d80};
627 static u32 phy_pwr_idx;
628 u8 rate, rate_idx, pwr_index, shift;
631 for (j = 0; j < rtw_rate_size[rs]; j++) {
632 rate = rtw_rate_section[rs][j];
633 pwr_index = hal->tx_pwr_tbl[path][rate];
635 phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
636 if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) {
637 rate_idx = rate & 0xfc;
638 rtw_write32(rtwdev, offset_txagc[path] + rate_idx,
645 static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev)
647 struct rtw_hal *hal = &rtwdev->hal;
650 for (path = 0; path < hal->rf_path_num; path++) {
651 for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
652 if (rs == RTW_RATE_SECTION_HT_2S ||
653 rs == RTW_RATE_SECTION_VHT_2S)
655 rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs);
660 static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev)
662 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
669 cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28);
670 cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK);
671 ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM);
673 dm_info->cck_fa_cnt = cck_fa_cnt;
674 dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
676 dm_info->total_fa_cnt += cck_fa_cnt;
677 dm_info->total_fa_cnt = ofdm_fa_cnt;
679 crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK);
680 dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
681 dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
683 crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM);
684 dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
685 dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
687 crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT);
688 dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
689 dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
691 crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT);
692 dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
693 dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
695 cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM);
696 dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt);
697 dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
699 cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK);
700 dm_info->cck_cca_cnt = FIELD_GET(GENMASK(15, 0), cca32_cnt);
701 dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
704 rtw_write32_set(rtwdev, REG_FAS, BIT(17));
705 rtw_write32_clr(rtwdev, REG_FAS, BIT(17));
706 rtw_write32_clr(rtwdev, REG_RXDESC, BIT(15));
707 rtw_write32_set(rtwdev, REG_RXDESC, BIT(15));
708 rtw_write32_set(rtwdev, REG_CNTRST, BIT(0));
709 rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0));
712 static void rtw8821c_do_iqk(struct rtw_dev *rtwdev)
714 static int do_iqk_cnt;
715 struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
716 u32 rf_reg, iqk_fail_mask;
720 if (rtw_is_assoc(rtwdev))
721 para.segment_iqk = 1;
723 rtw_fw_do_iqk(rtwdev, ¶);
725 for (counter = 0; counter < 300; counter++) {
726 rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK);
727 if (rf_reg == 0xabcde)
731 rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
733 reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
734 iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
735 rtw_dbg(rtwdev, RTW_DBG_PHY,
736 "iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
737 counter, reload, ++do_iqk_cnt, iqk_fail_mask);
740 static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev)
742 rtw8821c_do_iqk(rtwdev);
746 static void rtw8821c_coex_cfg_init(struct rtw_dev *rtwdev)
748 /* enable TBTT nterrupt */
749 rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
751 /* BT report packet sample rate */
752 rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
754 /* enable BT counter statistics */
755 rtw_write8(rtwdev, REG_BT_STAT_CTRL, BT_CNT_ENABLE);
757 /* enable PTA (3-wire function form BT side) */
758 rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
759 rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
761 /* enable PTA (tx/rx signal form WiFi side) */
762 rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
763 /* wl tx signal to PTA not case EDCCA */
764 rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN);
765 /* GNT_BT=1 while select both */
766 rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY);
768 /* beacon queue always hi-pri */
769 rtw_write8_mask(rtwdev, REG_BT_COEX_TABLE_H + 3, BIT_BCN_QUEUE,
773 static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type,
776 struct rtw_coex *coex = &rtwdev->coex;
777 struct rtw_coex_dm *coex_dm = &coex->dm;
778 struct rtw_coex_rfe *coex_rfe = &coex->rfe;
779 u32 switch_status = FIELD_PREP(CTRL_TYPE_MASK, ctrl_type) | pos_type;
780 bool polarity_inverse;
783 if (switch_status == coex_dm->cur_switch_status)
786 if (coex_rfe->wlg_at_btg) {
787 ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
789 if (coex_rfe->ant_switch_polarity)
790 pos_type = COEX_SWITCH_TO_WLA;
792 pos_type = COEX_SWITCH_TO_WLG_BT;
795 coex_dm->cur_switch_status = switch_status;
797 if (coex_rfe->ant_switch_diversity &&
798 ctrl_type == COEX_SWITCH_CTRL_BY_BBSW)
799 ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV;
801 polarity_inverse = (coex_rfe->ant_switch_polarity == 1);
805 case COEX_SWITCH_CTRL_BY_BBSW:
806 rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
807 rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
808 /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
809 rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
812 if (pos_type == COEX_SWITCH_TO_WLG_BT) {
813 if (coex_rfe->rfe_module_type != 0x4 &&
814 coex_rfe->rfe_module_type != 0x2)
817 regval = (!polarity_inverse ? 0x2 : 0x1);
818 } else if (pos_type == COEX_SWITCH_TO_WLG) {
819 regval = (!polarity_inverse ? 0x2 : 0x1);
821 regval = (!polarity_inverse ? 0x1 : 0x2);
824 rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15,
827 case COEX_SWITCH_CTRL_BY_PTA:
828 rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
829 rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
830 /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
831 rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
834 regval = (!polarity_inverse ? 0x2 : 0x1);
835 rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15,
838 case COEX_SWITCH_CTRL_BY_ANTDIV:
839 rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
840 rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
841 rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
844 case COEX_SWITCH_CTRL_BY_MAC:
845 rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
847 regval = (!polarity_inverse ? 0x0 : 0x1);
848 rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA,
851 case COEX_SWITCH_CTRL_BY_FW:
852 rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
853 rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
855 case COEX_SWITCH_CTRL_BY_BT:
856 rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
857 rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
861 if (ctrl_type == COEX_SWITCH_CTRL_BY_BT) {
862 rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1);
863 rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2);
865 rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1);
866 rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2);
870 static void rtw8821c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
873 static void rtw8821c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
875 rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_SPI_EN);
876 rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_JTAG_EN);
877 rtw_write32_clr(rtwdev, REG_GPIO_MUXCFG, BIT_FSPI_EN);
878 rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_LED1DIS);
879 rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_SDIO_INT);
880 rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_DBG_GNT_WL_BT);
883 static void rtw8821c_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
885 struct rtw_coex *coex = &rtwdev->coex;
886 struct rtw_coex_rfe *coex_rfe = &coex->rfe;
887 struct rtw_efuse *efuse = &rtwdev->efuse;
889 coex_rfe->rfe_module_type = efuse->rfe_option;
890 coex_rfe->ant_switch_polarity = 0;
891 coex_rfe->ant_switch_exist = true;
892 coex_rfe->wlg_at_btg = false;
894 switch (coex_rfe->rfe_module_type) {
898 case 9: /* 1-Ant, Main, WLG */
899 default: /* 2-Ant, DPDT, WLG */
902 case 10: /* 1-Ant, Main, BTG */
904 case 15: /* 2-Ant, DPDT, BTG */
905 coex_rfe->wlg_at_btg = true;
908 case 11: /* 1-Ant, Aux, WLG */
909 coex_rfe->ant_switch_polarity = 1;
912 case 12: /* 1-Ant, Aux, BTG */
913 coex_rfe->wlg_at_btg = true;
914 coex_rfe->ant_switch_polarity = 1;
917 case 13: /* 2-Ant, no switch, WLG */
919 case 14: /* 2-Ant, no antenna switch, WLG */
920 coex_rfe->ant_switch_exist = false;
925 static void rtw8821c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
927 struct rtw_coex *coex = &rtwdev->coex;
928 struct rtw_coex_dm *coex_dm = &coex->dm;
929 struct rtw_efuse *efuse = &rtwdev->efuse;
930 bool share_ant = efuse->share_ant;
935 if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
938 coex_dm->cur_wl_pwr_lvl = wl_pwr;
941 static void rtw8821c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
945 rtw8821c_txagc_swing_offset(struct rtw_dev *rtwdev, u8 pwr_idx_offset,
946 s8 pwr_idx_offset_lower,
947 s8 *txagc_idx, u8 *swing_idx)
949 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
950 s8 delta_pwr_idx = dm_info->delta_power_index[RF_PATH_A];
951 u8 swing_upper_bound = dm_info->default_ofdm_index + 10;
952 u8 swing_lower_bound = 0;
953 u8 max_pwr_idx_offset = 0xf;
955 u8 swing_index = dm_info->default_ofdm_index;
957 pwr_idx_offset = min_t(u8, pwr_idx_offset, max_pwr_idx_offset);
958 pwr_idx_offset_lower = max_t(s8, pwr_idx_offset_lower, -15);
960 if (delta_pwr_idx >= 0) {
961 if (delta_pwr_idx <= pwr_idx_offset) {
962 agc_index = delta_pwr_idx;
963 swing_index = dm_info->default_ofdm_index;
964 } else if (delta_pwr_idx > pwr_idx_offset) {
965 agc_index = pwr_idx_offset;
966 swing_index = dm_info->default_ofdm_index +
967 delta_pwr_idx - pwr_idx_offset;
968 swing_index = min_t(u8, swing_index, swing_upper_bound);
970 } else if (delta_pwr_idx < 0) {
971 if (delta_pwr_idx >= pwr_idx_offset_lower) {
972 agc_index = delta_pwr_idx;
973 swing_index = dm_info->default_ofdm_index;
974 } else if (delta_pwr_idx < pwr_idx_offset_lower) {
975 if (dm_info->default_ofdm_index >
976 (pwr_idx_offset_lower - delta_pwr_idx))
977 swing_index = dm_info->default_ofdm_index +
978 delta_pwr_idx - pwr_idx_offset_lower;
980 swing_index = swing_lower_bound;
982 agc_index = pwr_idx_offset_lower;
986 if (swing_index >= ARRAY_SIZE(rtw8821c_txscale_tbl)) {
987 rtw_warn(rtwdev, "swing index overflow\n");
988 swing_index = ARRAY_SIZE(rtw8821c_txscale_tbl) - 1;
991 *txagc_idx = agc_index;
992 *swing_idx = swing_index;
995 static void rtw8821c_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 pwr_idx_offset,
996 s8 pwr_idx_offset_lower)
1001 rtw8821c_txagc_swing_offset(rtwdev, pwr_idx_offset, pwr_idx_offset_lower,
1002 &txagc_idx, &swing_idx);
1003 rtw_write32_mask(rtwdev, REG_TXAGCIDX, GENMASK(6, 1), txagc_idx);
1004 rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21),
1005 rtw8821c_txscale_tbl[swing_idx]);
1008 static void rtw8821c_pwrtrack_set(struct rtw_dev *rtwdev)
1010 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1011 u8 pwr_idx_offset, tx_pwr_idx;
1012 s8 pwr_idx_offset_lower;
1013 u8 channel = rtwdev->hal.current_channel;
1014 u8 band_width = rtwdev->hal.current_band_width;
1015 u8 regd = rtw_regd_get(rtwdev);
1016 u8 tx_rate = dm_info->tx_rate;
1017 u8 max_pwr_idx = rtwdev->chip->max_power_index;
1019 tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, RF_PATH_A, tx_rate,
1020 band_width, channel, regd);
1022 tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx);
1024 pwr_idx_offset = max_pwr_idx - tx_pwr_idx;
1025 pwr_idx_offset_lower = 0 - tx_pwr_idx;
1027 rtw8821c_pwrtrack_set_pwr(rtwdev, pwr_idx_offset, pwr_idx_offset_lower);
1030 static void rtw8821c_phy_pwrtrack(struct rtw_dev *rtwdev)
1032 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1033 struct rtw_swing_table swing_table;
1034 u8 thermal_value, delta;
1036 rtw_phy_config_swing_table(rtwdev, &swing_table);
1038 if (rtwdev->efuse.thermal_meter[0] == 0xff)
1041 thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
1043 rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
1045 if (dm_info->pwr_trk_init_trigger)
1046 dm_info->pwr_trk_init_trigger = false;
1047 else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
1051 delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
1053 delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1);
1055 dm_info->delta_power_index[RF_PATH_A] =
1056 rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, RF_PATH_A,
1058 if (dm_info->delta_power_index[RF_PATH_A] ==
1059 dm_info->delta_power_index_last[RF_PATH_A])
1062 dm_info->delta_power_index_last[RF_PATH_A] =
1063 dm_info->delta_power_index[RF_PATH_A];
1064 rtw8821c_pwrtrack_set(rtwdev);
1067 if (rtw_phy_pwrtrack_need_iqk(rtwdev))
1068 rtw8821c_do_iqk(rtwdev);
1071 static void rtw8821c_pwr_track(struct rtw_dev *rtwdev)
1073 struct rtw_efuse *efuse = &rtwdev->efuse;
1074 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1076 if (efuse->power_track_type != 0)
1079 if (!dm_info->pwr_trk_triggered) {
1080 rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
1081 GENMASK(17, 16), 0x03);
1082 dm_info->pwr_trk_triggered = true;
1086 rtw8821c_phy_pwrtrack(rtwdev);
1087 dm_info->pwr_trk_triggered = false;
1090 static void rtw8821c_bf_config_bfee_su(struct rtw_dev *rtwdev,
1091 struct rtw_vif *vif,
1092 struct rtw_bfee *bfee, bool enable)
1095 rtw_bf_enable_bfee_su(rtwdev, vif, bfee);
1097 rtw_bf_remove_bfee_su(rtwdev, bfee);
1100 static void rtw8821c_bf_config_bfee_mu(struct rtw_dev *rtwdev,
1101 struct rtw_vif *vif,
1102 struct rtw_bfee *bfee, bool enable)
1105 rtw_bf_enable_bfee_mu(rtwdev, vif, bfee);
1107 rtw_bf_remove_bfee_mu(rtwdev, bfee);
1110 static void rtw8821c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
1111 struct rtw_bfee *bfee, bool enable)
1113 if (bfee->role == RTW_BFEE_SU)
1114 rtw8821c_bf_config_bfee_su(rtwdev, vif, bfee, enable);
1115 else if (bfee->role == RTW_BFEE_MU)
1116 rtw8821c_bf_config_bfee_mu(rtwdev, vif, bfee, enable);
1118 rtw_warn(rtwdev, "wrong bfee role\n");
1121 static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
1123 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1124 u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13};
1127 rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n",
1128 dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl);
1130 if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl)
1133 cck_n_rx = (rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_2RX) &&
1134 rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_MRC)) ? 2 : 1;
1135 rtw_dbg(rtwdev, RTW_DBG_PHY,
1136 "is_linked=%d, lv=%d, n_rx=%d, cs_ratio=0x%x, pd_th=0x%x, cck_fa_avg=%d\n",
1137 rtw_is_assoc(rtwdev), new_lvl, cck_n_rx,
1138 dm_info->cck_pd_default + new_lvl * 2,
1139 pd[new_lvl], dm_info->cck_fa_avg);
1141 dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
1143 dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl;
1144 rtw_write32_mask(rtwdev, REG_PWRTH, 0x3f0000, pd[new_lvl]);
1145 rtw_write32_mask(rtwdev, REG_PWRTH2, 0x1f0000,
1146 dm_info->cck_pd_default + new_lvl * 2);
1149 static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
1151 RTW_PWR_CUT_ALL_MSK,
1152 RTW_PWR_INTF_SDIO_MSK,
1154 RTW_PWR_CMD_WRITE, BIT(0), 0},
1156 RTW_PWR_CUT_ALL_MSK,
1157 RTW_PWR_INTF_SDIO_MSK,
1159 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
1161 RTW_PWR_CUT_ALL_MSK,
1162 RTW_PWR_INTF_USB_MSK,
1164 RTW_PWR_CMD_WRITE, BIT(0), 0},
1166 RTW_PWR_CUT_ALL_MSK,
1167 RTW_PWR_INTF_ALL_MSK,
1169 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
1171 RTW_PWR_CUT_ALL_MSK,
1172 RTW_PWR_INTF_PCI_MSK,
1174 RTW_PWR_CMD_WRITE, 0xFF, 0},
1176 RTW_PWR_CUT_ALL_MSK,
1177 RTW_PWR_INTF_PCI_MSK,
1179 RTW_PWR_CMD_WRITE, 0xFF, 0},
1181 RTW_PWR_CUT_ALL_MSK,
1182 RTW_PWR_INTF_ALL_MSK,
1184 RTW_PWR_CMD_END, 0, 0},
1187 static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
1189 RTW_PWR_CUT_ALL_MSK,
1190 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1192 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1194 RTW_PWR_CUT_ALL_MSK,
1195 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1197 RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
1199 RTW_PWR_CUT_ALL_MSK,
1200 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1202 RTW_PWR_CMD_WRITE, BIT(5), 0},
1204 RTW_PWR_CUT_ALL_MSK,
1205 RTW_PWR_INTF_ALL_MSK,
1207 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
1209 RTW_PWR_CUT_ALL_MSK,
1210 RTW_PWR_INTF_PCI_MSK,
1212 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1214 RTW_PWR_CUT_ALL_MSK,
1215 RTW_PWR_INTF_ALL_MSK,
1217 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
1219 RTW_PWR_CUT_ALL_MSK,
1220 RTW_PWR_INTF_PCI_MSK,
1222 RTW_PWR_CMD_WRITE, BIT(0), 0},
1224 RTW_PWR_CUT_ALL_MSK,
1225 RTW_PWR_INTF_ALL_MSK,
1227 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1229 RTW_PWR_CUT_ALL_MSK,
1230 RTW_PWR_INTF_ALL_MSK,
1232 RTW_PWR_CMD_WRITE, BIT(7), 0},
1234 RTW_PWR_CUT_ALL_MSK,
1235 RTW_PWR_INTF_ALL_MSK,
1237 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
1239 RTW_PWR_CUT_ALL_MSK,
1240 RTW_PWR_INTF_USB_MSK,
1242 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1244 RTW_PWR_CUT_ALL_MSK,
1245 RTW_PWR_INTF_ALL_MSK,
1247 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1249 RTW_PWR_CUT_ALL_MSK,
1250 RTW_PWR_INTF_ALL_MSK,
1252 RTW_PWR_CMD_POLLING, BIT(0), 0},
1254 RTW_PWR_CUT_ALL_MSK,
1255 RTW_PWR_INTF_ALL_MSK,
1257 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
1259 RTW_PWR_CUT_ALL_MSK,
1260 RTW_PWR_INTF_PCI_MSK,
1262 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1264 RTW_PWR_CUT_ALL_MSK,
1265 RTW_PWR_INTF_PCI_MSK,
1267 RTW_PWR_CMD_WRITE, BIT(1), 0},
1269 RTW_PWR_CUT_ALL_MSK,
1270 RTW_PWR_INTF_PCI_MSK,
1272 RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)),
1273 (BIT(7) | BIT(6) | BIT(5))},
1275 RTW_PWR_CUT_ALL_MSK,
1276 RTW_PWR_INTF_PCI_MSK,
1278 RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0},
1280 RTW_PWR_CUT_ALL_MSK,
1281 RTW_PWR_INTF_ALL_MSK,
1283 RTW_PWR_CMD_WRITE, BIT(1), 0},
1285 RTW_PWR_CUT_ALL_MSK,
1286 RTW_PWR_INTF_ALL_MSK,
1288 RTW_PWR_CMD_END, 0, 0},
1291 static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
1293 RTW_PWR_CUT_ALL_MSK,
1294 RTW_PWR_INTF_ALL_MSK,
1296 RTW_PWR_CMD_WRITE, BIT(3), 0},
1298 RTW_PWR_CUT_ALL_MSK,
1299 RTW_PWR_INTF_ALL_MSK,
1301 RTW_PWR_CMD_WRITE, 0xFF, 0},
1303 RTW_PWR_CUT_ALL_MSK,
1304 RTW_PWR_INTF_ALL_MSK,
1306 RTW_PWR_CMD_WRITE, BIT(1), 0},
1308 RTW_PWR_CUT_ALL_MSK,
1309 RTW_PWR_INTF_ALL_MSK,
1311 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1313 RTW_PWR_CUT_ALL_MSK,
1314 RTW_PWR_INTF_ALL_MSK,
1316 RTW_PWR_CMD_WRITE, BIT(1), 0},
1318 RTW_PWR_CUT_ALL_MSK,
1319 RTW_PWR_INTF_USB_MSK,
1321 RTW_PWR_CMD_WRITE, BIT(0), 0},
1323 RTW_PWR_CUT_ALL_MSK,
1324 RTW_PWR_INTF_ALL_MSK,
1326 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
1328 RTW_PWR_CUT_ALL_MSK,
1329 RTW_PWR_INTF_ALL_MSK,
1331 RTW_PWR_CMD_POLLING, BIT(1), 0},
1333 RTW_PWR_CUT_ALL_MSK,
1334 RTW_PWR_INTF_ALL_MSK,
1336 RTW_PWR_CMD_WRITE, BIT(3), 0},
1338 RTW_PWR_CUT_ALL_MSK,
1339 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1341 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
1343 RTW_PWR_CUT_ALL_MSK,
1344 RTW_PWR_INTF_ALL_MSK,
1346 RTW_PWR_CMD_END, 0, 0},
1349 static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
1351 RTW_PWR_CUT_ALL_MSK,
1352 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1354 RTW_PWR_CMD_WRITE, 0xFF, 0x20},
1356 RTW_PWR_CUT_ALL_MSK,
1357 RTW_PWR_INTF_ALL_MSK,
1359 RTW_PWR_CMD_WRITE, BIT(5), 0},
1361 RTW_PWR_CUT_ALL_MSK,
1362 RTW_PWR_INTF_PCI_MSK,
1364 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
1366 RTW_PWR_CUT_ALL_MSK,
1367 RTW_PWR_INTF_USB_MSK,
1369 RTW_PWR_CMD_WRITE, BIT(0), 0},
1371 RTW_PWR_CUT_ALL_MSK,
1372 RTW_PWR_INTF_SDIO_MSK,
1374 RTW_PWR_CMD_WRITE, BIT(5), 0},
1376 RTW_PWR_CUT_ALL_MSK,
1377 RTW_PWR_INTF_SDIO_MSK,
1379 RTW_PWR_CMD_WRITE, BIT(4), 0},
1381 RTW_PWR_CUT_ALL_MSK,
1382 RTW_PWR_INTF_SDIO_MSK,
1384 RTW_PWR_CMD_WRITE, BIT(0), 0},
1386 RTW_PWR_CUT_ALL_MSK,
1387 RTW_PWR_INTF_SDIO_MSK,
1389 RTW_PWR_CMD_WRITE, BIT(1), 0},
1391 RTW_PWR_CUT_ALL_MSK,
1392 RTW_PWR_INTF_SDIO_MSK,
1394 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
1396 RTW_PWR_CUT_ALL_MSK,
1397 RTW_PWR_INTF_SDIO_MSK,
1399 RTW_PWR_CMD_WRITE, BIT(2), 0},
1401 RTW_PWR_CUT_ALL_MSK,
1402 RTW_PWR_INTF_SDIO_MSK,
1404 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
1406 RTW_PWR_CUT_ALL_MSK,
1407 RTW_PWR_INTF_SDIO_MSK,
1409 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
1411 RTW_PWR_CUT_ALL_MSK,
1412 RTW_PWR_INTF_ALL_MSK,
1414 RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0},
1416 RTW_PWR_CUT_ALL_MSK,
1417 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
1419 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
1421 RTW_PWR_CUT_ALL_MSK,
1422 RTW_PWR_INTF_SDIO_MSK,
1424 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
1426 RTW_PWR_CUT_ALL_MSK,
1427 RTW_PWR_INTF_SDIO_MSK,
1429 RTW_PWR_CMD_POLLING, BIT(1), 0},
1431 RTW_PWR_CUT_ALL_MSK,
1432 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK,
1434 RTW_PWR_CMD_WRITE, BIT(1), 0},
1436 RTW_PWR_CUT_ALL_MSK,
1437 RTW_PWR_INTF_SDIO_MSK,
1439 RTW_PWR_CMD_WRITE, 0xFF, 0},
1441 RTW_PWR_CUT_ALL_MSK,
1442 RTW_PWR_INTF_SDIO_MSK,
1444 RTW_PWR_CMD_WRITE, 0xFF, 0x90},
1446 RTW_PWR_CUT_ALL_MSK,
1447 RTW_PWR_INTF_SDIO_MSK,
1449 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
1451 RTW_PWR_CUT_ALL_MSK,
1452 RTW_PWR_INTF_SDIO_MSK,
1454 RTW_PWR_CMD_WRITE, 0xFF, 0x04},
1456 RTW_PWR_CUT_ALL_MSK,
1457 RTW_PWR_INTF_ALL_MSK,
1459 RTW_PWR_CMD_END, 0, 0},
1462 static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = {
1463 trans_carddis_to_cardemu_8821c,
1464 trans_cardemu_to_act_8821c,
1468 static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = {
1469 trans_act_to_cardemu_8821c,
1470 trans_cardemu_to_carddis_8821c,
1474 static const struct rtw_intf_phy_para usb2_param_8821c[] = {
1477 RTW_INTF_PHY_CUT_ALL,
1478 RTW_INTF_PHY_PLATFORM_ALL},
1481 static const struct rtw_intf_phy_para usb3_param_8821c[] = {
1484 RTW_INTF_PHY_CUT_ALL,
1485 RTW_INTF_PHY_PLATFORM_ALL},
1488 static const struct rtw_intf_phy_para pcie_gen1_param_8821c[] = {
1491 RTW_INTF_PHY_CUT_ALL,
1492 RTW_INTF_PHY_PLATFORM_ALL},
1495 RTW_INTF_PHY_CUT_ALL,
1496 RTW_INTF_PHY_PLATFORM_ALL},
1499 static const struct rtw_intf_phy_para pcie_gen2_param_8821c[] = {
1502 RTW_INTF_PHY_CUT_ALL,
1503 RTW_INTF_PHY_PLATFORM_ALL},
1506 static const struct rtw_intf_phy_para_table phy_para_table_8821c = {
1507 .usb2_para = usb2_param_8821c,
1508 .usb3_para = usb3_param_8821c,
1509 .gen1_para = pcie_gen1_param_8821c,
1510 .gen2_para = pcie_gen2_param_8821c,
1511 .n_usb2_para = ARRAY_SIZE(usb2_param_8821c),
1512 .n_usb3_para = ARRAY_SIZE(usb2_param_8821c),
1513 .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8821c),
1514 .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c),
1517 static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
1518 [0] = RTW_DEF_RFE(8821c, 0, 0),
1519 [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
1520 [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
1521 [6] = RTW_DEF_RFE(8821c, 0, 0),
1524 static struct rtw_hw_reg rtw8821c_dig[] = {
1525 [0] = { .addr = 0xc50, .mask = 0x7f },
1528 static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = {
1529 .ctrl = LTECOEX_ACCESS_CTRL,
1530 .wdata = LTECOEX_WRITE_DATA,
1531 .rdata = LTECOEX_READ_DATA,
1534 static struct rtw_page_table page_table_8821c[] = {
1535 /* not sure what [0] stands for */
1536 {16, 16, 16, 14, 1},
1537 {16, 16, 16, 14, 1},
1540 {16, 16, 16, 14, 1},
1543 static struct rtw_rqpn rqpn_table_8821c[] = {
1544 /* not sure what [0] stands for */
1545 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1546 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1547 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
1548 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1549 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1550 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
1551 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1552 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
1553 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
1554 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1555 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1556 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
1557 {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
1558 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
1559 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
1562 static struct rtw_prioq_addrs prioq_addrs_8821c = {
1563 .prio[RTW_DMA_MAPPING_EXTRA] = {
1564 .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
1566 .prio[RTW_DMA_MAPPING_LOW] = {
1567 .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2,
1569 .prio[RTW_DMA_MAPPING_NORMAL] = {
1570 .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2,
1572 .prio[RTW_DMA_MAPPING_HIGH] = {
1573 .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2,
1578 static struct rtw_chip_ops rtw8821c_ops = {
1579 .phy_set_param = rtw8821c_phy_set_param,
1580 .read_efuse = rtw8821c_read_efuse,
1581 .query_rx_desc = rtw8821c_query_rx_desc,
1582 .set_channel = rtw8821c_set_channel,
1583 .mac_init = rtw8821c_mac_init,
1584 .read_rf = rtw_phy_read_rf,
1585 .write_rf = rtw_phy_write_rf_reg_sipi,
1586 .set_antenna = NULL,
1587 .set_tx_power_index = rtw8821c_set_tx_power_index,
1588 .cfg_ldo25 = rtw8821c_cfg_ldo25,
1589 .false_alarm_statistics = rtw8821c_false_alarm_statistics,
1590 .phy_calibration = rtw8821c_phy_calibration,
1591 .cck_pd_set = rtw8821c_phy_cck_pd_set,
1592 .pwr_track = rtw8821c_pwr_track,
1593 .config_bfee = rtw8821c_bf_config_bfee,
1594 .set_gid_table = rtw_bf_set_gid_table,
1595 .cfg_csi_rate = rtw_bf_cfg_csi_rate,
1597 .coex_set_init = rtw8821c_coex_cfg_init,
1598 .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch,
1599 .coex_set_gnt_fix = rtw8821c_coex_cfg_gnt_fix,
1600 .coex_set_gnt_debug = rtw8821c_coex_cfg_gnt_debug,
1601 .coex_set_rfe_type = rtw8821c_coex_cfg_rfe_type,
1602 .coex_set_wl_tx_power = rtw8821c_coex_cfg_wl_tx_power,
1603 .coex_set_wl_rx_gain = rtw8821c_coex_cfg_wl_rx_gain,
1606 /* rssi in percentage % (dbm = % - 100) */
1607 static const u8 wl_rssi_step_8821c[] = {101, 45, 101, 40};
1608 static const u8 bt_rssi_step_8821c[] = {101, 101, 101, 101};
1610 /* Shared-Antenna Coex Table */
1611 static const struct coex_table_para table_sant_8821c[] = {
1612 {0x55555555, 0x55555555}, /* case-0 */
1613 {0x55555555, 0x55555555},
1614 {0x66555555, 0x66555555},
1615 {0xaaaaaaaa, 0xaaaaaaaa},
1616 {0x5a5a5a5a, 0x5a5a5a5a},
1617 {0xfafafafa, 0xfafafafa}, /* case-5 */
1618 {0x6a5a5555, 0xaaaaaaaa},
1619 {0x6a5a56aa, 0x6a5a56aa},
1620 {0x6a5a5a5a, 0x6a5a5a5a},
1621 {0x66555555, 0x5a5a5a5a},
1622 {0x66555555, 0x6a5a5a5a}, /* case-10 */
1623 {0x66555555, 0xaaaaaaaa},
1624 {0x66555555, 0x6a5a5aaa},
1625 {0x66555555, 0x6aaa6aaa},
1626 {0x66555555, 0x6a5a5aaa},
1627 {0x66555555, 0xaaaaaaaa}, /* case-15 */
1628 {0xffff55ff, 0xfafafafa},
1629 {0xffff55ff, 0x6afa5afa},
1630 {0xaaffffaa, 0xfafafafa},
1631 {0xaa5555aa, 0x5a5a5a5a},
1632 {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
1633 {0xaa5555aa, 0xaaaaaaaa},
1634 {0xffffffff, 0x55555555},
1635 {0xffffffff, 0x5a5a5a5a},
1636 {0xffffffff, 0x5a5a5a5a},
1637 {0xffffffff, 0x5a5a5aaa}, /* case-25 */
1638 {0x55555555, 0x5a5a5a5a},
1639 {0x55555555, 0xaaaaaaaa},
1640 {0x66555555, 0x6a5a6a5a},
1641 {0x66556655, 0x66556655},
1642 {0x66556aaa, 0x6a5a6aaa}, /* case-30 */
1643 {0xffffffff, 0x5aaa5aaa},
1644 {0x56555555, 0x5a5a5aaa}
1647 /* Non-Shared-Antenna Coex Table */
1648 static const struct coex_table_para table_nsant_8821c[] = {
1649 {0xffffffff, 0xffffffff}, /* case-100 */
1650 {0xffff55ff, 0xfafafafa},
1651 {0x66555555, 0x66555555},
1652 {0xaaaaaaaa, 0xaaaaaaaa},
1653 {0x5a5a5a5a, 0x5a5a5a5a},
1654 {0xffffffff, 0xffffffff}, /* case-105 */
1655 {0x5afa5afa, 0x5afa5afa},
1656 {0x55555555, 0xfafafafa},
1657 {0x66555555, 0xfafafafa},
1658 {0x66555555, 0x5a5a5a5a},
1659 {0x66555555, 0x6a5a5a5a}, /* case-110 */
1660 {0x66555555, 0xaaaaaaaa},
1661 {0xffff55ff, 0xfafafafa},
1662 {0xffff55ff, 0x5afa5afa},
1663 {0xffff55ff, 0xaaaaaaaa},
1664 {0xffff55ff, 0xffff55ff}, /* case-115 */
1665 {0xaaffffaa, 0x5afa5afa},
1666 {0xaaffffaa, 0xaaaaaaaa},
1667 {0xffffffff, 0xfafafafa},
1668 {0xffff55ff, 0xfafafafa},
1669 {0xffffffff, 0xaaaaaaaa}, /* case-120 */
1670 {0xffff55ff, 0x5afa5afa},
1671 {0xffff55ff, 0x5afa5afa},
1672 {0x55ff55ff, 0x55ff55ff}
1675 /* Shared-Antenna TDMA */
1676 static const struct coex_tdma_para tdma_sant_8821c[] = {
1677 { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
1678 { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */
1679 { {0x61, 0x3a, 0x03, 0x11, 0x11} },
1680 { {0x61, 0x35, 0x03, 0x11, 0x11} },
1681 { {0x61, 0x20, 0x03, 0x11, 0x11} },
1682 { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */
1683 { {0x61, 0x45, 0x03, 0x11, 0x10} },
1684 { {0x61, 0x35, 0x03, 0x11, 0x10} },
1685 { {0x61, 0x30, 0x03, 0x11, 0x10} },
1686 { {0x61, 0x20, 0x03, 0x11, 0x10} },
1687 { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
1688 { {0x61, 0x08, 0x03, 0x11, 0x15} },
1689 { {0x61, 0x08, 0x03, 0x10, 0x14} },
1690 { {0x51, 0x08, 0x03, 0x10, 0x54} },
1691 { {0x51, 0x08, 0x03, 0x10, 0x55} },
1692 { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
1693 { {0x51, 0x45, 0x03, 0x10, 0x50} },
1694 { {0x51, 0x3a, 0x03, 0x11, 0x50} },
1695 { {0x51, 0x30, 0x03, 0x10, 0x50} },
1696 { {0x51, 0x21, 0x03, 0x10, 0x50} },
1697 { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
1698 { {0x51, 0x4a, 0x03, 0x10, 0x50} },
1699 { {0x51, 0x08, 0x03, 0x30, 0x54} },
1700 { {0x55, 0x08, 0x03, 0x10, 0x54} },
1701 { {0x65, 0x10, 0x03, 0x11, 0x10} },
1702 { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
1703 { {0x51, 0x21, 0x03, 0x10, 0x50} },
1704 { {0x61, 0x08, 0x03, 0x11, 0x11} }
1707 /* Non-Shared-Antenna TDMA */
1708 static const struct coex_tdma_para tdma_nsant_8821c[] = {
1709 { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */
1710 { {0x61, 0x45, 0x03, 0x11, 0x11} },
1711 { {0x61, 0x25, 0x03, 0x11, 0x11} },
1712 { {0x61, 0x35, 0x03, 0x11, 0x11} },
1713 { {0x61, 0x20, 0x03, 0x11, 0x11} },
1714 { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
1715 { {0x61, 0x45, 0x03, 0x11, 0x10} },
1716 { {0x61, 0x30, 0x03, 0x11, 0x10} },
1717 { {0x61, 0x30, 0x03, 0x11, 0x10} },
1718 { {0x61, 0x20, 0x03, 0x11, 0x10} },
1719 { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
1720 { {0x61, 0x10, 0x03, 0x11, 0x11} },
1721 { {0x61, 0x08, 0x03, 0x10, 0x14} },
1722 { {0x51, 0x08, 0x03, 0x10, 0x54} },
1723 { {0x51, 0x08, 0x03, 0x10, 0x55} },
1724 { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
1725 { {0x51, 0x45, 0x03, 0x10, 0x50} },
1726 { {0x51, 0x3a, 0x03, 0x10, 0x50} },
1727 { {0x51, 0x30, 0x03, 0x10, 0x50} },
1728 { {0x51, 0x21, 0x03, 0x10, 0x50} },
1729 { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */
1730 { {0x51, 0x10, 0x03, 0x10, 0x50} }
1733 static const struct coex_5g_afh_map afh_5g_8821c[] = { {0, 0, 0} };
1735 /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
1736 static const struct coex_rf_para rf_para_tx_8821c[] = {
1737 {0, 0, false, 7}, /* for normal */
1738 {0, 20, false, 7}, /* for WL-CPT */
1745 static const struct coex_rf_para rf_para_rx_8821c[] = {
1746 {0, 0, false, 7}, /* for normal */
1747 {0, 20, false, 7}, /* for WL-CPT */
1754 static_assert(ARRAY_SIZE(rf_para_tx_8821c) == ARRAY_SIZE(rf_para_rx_8821c));
1756 static const u8 rtw8821c_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = {
1757 {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10,
1758 11, 11, 12, 12, 12, 12, 12},
1759 {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11,
1760 11, 12, 12, 12, 12, 12, 12, 12},
1761 {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11,
1762 11, 12, 12, 12, 12, 12, 12},
1765 static const u8 rtw8821c_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = {
1766 {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11,
1767 12, 12, 12, 12, 12, 12, 12},
1768 {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11,
1769 12, 12, 12, 12, 12, 12, 12, 12},
1770 {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11,
1771 11, 12, 12, 12, 12, 12, 12, 12},
1774 static const u8 rtw8821c_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = {
1775 {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10,
1776 11, 11, 12, 12, 12, 12, 12},
1777 {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11,
1778 11, 12, 12, 12, 12, 12, 12, 12},
1779 {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11,
1780 11, 12, 12, 12, 12, 12, 12},
1783 static const u8 rtw8821c_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = {
1784 {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11,
1785 12, 12, 12, 12, 12, 12, 12},
1786 {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11,
1787 12, 12, 12, 12, 12, 12, 12, 12},
1788 {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11,
1789 11, 12, 12, 12, 12, 12, 12, 12},
1792 static const u8 rtw8821c_pwrtrk_2gb_n[] = {
1793 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
1794 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9
1797 static const u8 rtw8821c_pwrtrk_2gb_p[] = {
1798 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5,
1799 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9
1802 static const u8 rtw8821c_pwrtrk_2ga_n[] = {
1803 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
1804 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9
1807 static const u8 rtw8821c_pwrtrk_2ga_p[] = {
1808 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5,
1809 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9
1812 static const u8 rtw8821c_pwrtrk_2g_cck_b_n[] = {
1813 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
1814 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9
1817 static const u8 rtw8821c_pwrtrk_2g_cck_b_p[] = {
1818 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
1819 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9
1822 static const u8 rtw8821c_pwrtrk_2g_cck_a_n[] = {
1823 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
1824 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9
1827 static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = {
1828 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
1829 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9
1832 static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
1833 .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0],
1834 .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1],
1835 .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2],
1836 .pwrtrk_5gb_p[0] = rtw8821c_pwrtrk_5gb_p[0],
1837 .pwrtrk_5gb_p[1] = rtw8821c_pwrtrk_5gb_p[1],
1838 .pwrtrk_5gb_p[2] = rtw8821c_pwrtrk_5gb_p[2],
1839 .pwrtrk_5ga_n[0] = rtw8821c_pwrtrk_5ga_n[0],
1840 .pwrtrk_5ga_n[1] = rtw8821c_pwrtrk_5ga_n[1],
1841 .pwrtrk_5ga_n[2] = rtw8821c_pwrtrk_5ga_n[2],
1842 .pwrtrk_5ga_p[0] = rtw8821c_pwrtrk_5ga_p[0],
1843 .pwrtrk_5ga_p[1] = rtw8821c_pwrtrk_5ga_p[1],
1844 .pwrtrk_5ga_p[2] = rtw8821c_pwrtrk_5ga_p[2],
1845 .pwrtrk_2gb_n = rtw8821c_pwrtrk_2gb_n,
1846 .pwrtrk_2gb_p = rtw8821c_pwrtrk_2gb_p,
1847 .pwrtrk_2ga_n = rtw8821c_pwrtrk_2ga_n,
1848 .pwrtrk_2ga_p = rtw8821c_pwrtrk_2ga_p,
1849 .pwrtrk_2g_cckb_n = rtw8821c_pwrtrk_2g_cck_b_n,
1850 .pwrtrk_2g_cckb_p = rtw8821c_pwrtrk_2g_cck_b_p,
1851 .pwrtrk_2g_ccka_n = rtw8821c_pwrtrk_2g_cck_a_n,
1852 .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p,
1855 static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = {
1856 {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1857 {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1858 {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1859 {0, 0, RTW_REG_DOMAIN_NL},
1860 {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1861 {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1862 {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
1863 {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1864 {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
1865 {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
1866 {0, 0, RTW_REG_DOMAIN_NL},
1867 {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
1868 {0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
1869 {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
1870 {0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
1871 {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A},
1872 {0, 0, RTW_REG_DOMAIN_NL},
1873 {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
1874 {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1875 {0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
1876 {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1877 {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
1880 struct rtw_chip_info rtw8821c_hw_spec = {
1881 .ops = &rtw8821c_ops,
1882 .id = RTW_CHIP_TYPE_8821C,
1883 .fw_name = "rtw88/rtw8821c_fw.bin",
1884 .wlan_cpu = RTW_WCPU_11AC,
1885 .tx_pkt_desc_sz = 48,
1886 .tx_buf_desc_sz = 16,
1887 .rx_pkt_desc_sz = 24,
1888 .rx_buf_desc_sz = 8,
1889 .phy_efuse_size = 512,
1890 .log_efuse_size = 512,
1891 .ptct_efuse_size = 96,
1895 .is_pwr_by_rate_dec = true,
1896 .max_power_index = 0x3f,
1897 .csi_buf_pg_num = 0,
1898 .band = RTW_BAND_2G | RTW_BAND_5G,
1901 .ht_supported = true,
1902 .vht_supported = true,
1903 .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
1904 .sys_func_en = 0xD8,
1905 .pwr_on_seq = card_enable_flow_8821c,
1906 .pwr_off_seq = card_disable_flow_8821c,
1907 .page_table = page_table_8821c,
1908 .rqpn_table = rqpn_table_8821c,
1909 .prioq_addrs = &prioq_addrs_8821c,
1910 .intf_table = &phy_para_table_8821c,
1911 .dig = rtw8821c_dig,
1912 .rf_base_addr = {0x2800, 0x2c00},
1913 .rf_sipi_addr = {0xc90, 0xe90},
1914 .ltecoex_addr = &rtw8821c_ltecoex_addr,
1915 .mac_tbl = &rtw8821c_mac_tbl,
1916 .agc_tbl = &rtw8821c_agc_tbl,
1917 .bb_tbl = &rtw8821c_bb_tbl,
1918 .rf_tbl = {&rtw8821c_rf_a_tbl},
1919 .rfe_defs = rtw8821c_rfe_defs,
1920 .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs),
1922 .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl,
1924 .bfer_su_max_num = 2,
1925 .bfer_mu_max_num = 1,
1926 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2,
1928 .coex_para_ver = 0x19092746,
1929 .bt_desired_ver = 0x46,
1930 .scbd_support = true,
1931 .new_scbd10_def = false,
1932 .ble_hid_profile_support = false,
1933 .wl_mimo_ps_support = false,
1934 .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
1935 .bt_rssi_type = COEX_BTRSSI_RATIO,
1936 .ant_isolation = 15,
1937 .rssi_tolerance = 2,
1938 .wl_rssi_step = wl_rssi_step_8821c,
1939 .bt_rssi_step = bt_rssi_step_8821c,
1940 .table_sant_num = ARRAY_SIZE(table_sant_8821c),
1941 .table_sant = table_sant_8821c,
1942 .table_nsant_num = ARRAY_SIZE(table_nsant_8821c),
1943 .table_nsant = table_nsant_8821c,
1944 .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821c),
1945 .tdma_sant = tdma_sant_8821c,
1946 .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821c),
1947 .tdma_nsant = tdma_nsant_8821c,
1948 .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821c),
1949 .wl_rf_para_tx = rf_para_tx_8821c,
1950 .wl_rf_para_rx = rf_para_rx_8821c,
1951 .bt_afh_span_bw20 = 0x24,
1952 .bt_afh_span_bw40 = 0x36,
1953 .afh_5g_num = ARRAY_SIZE(afh_5g_8821c),
1954 .afh_5g = afh_5g_8821c,
1956 .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821c),
1957 .coex_info_hw_regs = coex_info_hw_regs_8821c,
1959 EXPORT_SYMBOL(rtw8821c_hw_spec);
1961 MODULE_FIRMWARE("rtw88/rtw8821c_fw.bin");
1963 MODULE_AUTHOR("Realtek Corporation");
1964 MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821c driver");
1965 MODULE_LICENSE("Dual BSD/GPL");