1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
36 #include "../btcoexist/halbt_precomp.h"
40 #define READ_NEXT_PAIR(array_table, v1, v2, i) \
43 v1 = array_table[i]; \
44 v2 = array_table[i+1]; \
47 static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
48 enum radio_path rfpath, u32 offset);
49 static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
50 enum radio_path rfpath, u32 offset,
52 static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask);
53 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw);
54 /*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/
55 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
56 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
58 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
60 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
62 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
63 enum wireless_mode wirelessmode,
65 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw);
66 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw);
68 static void rtl8812ae_fixspur(struct ieee80211_hw *hw,
69 enum ht_channel_width band_width, u8 channel)
71 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
73 /*C cut Item12 ADC FIFO CLOCK*/
74 if (IS_VENDOR_8812A_C_CUT(rtlhal->version)) {
75 if (band_width == HT_CHANNEL_WIDTH_20_40 && channel == 11)
76 rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x3);
77 /* 0x8AC[11:10] = 2'b11*/
79 rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2);
80 /* 0x8AC[11:10] = 2'b10*/
82 /* <20120914, Kordan> A workarould to resolve
83 * 2480Mhz spur by setting ADC clock as 160M. (Asked by Binson)
85 if (band_width == HT_CHANNEL_WIDTH_20 &&
86 (channel == 13 || channel == 14)) {
87 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
88 /*0x8AC[9:8] = 2'b11*/
89 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
91 } else if (band_width == HT_CHANNEL_WIDTH_20_40 &&
93 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
95 } else if (band_width != HT_CHANNEL_WIDTH_80) {
96 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
97 /*0x8AC[9:8] = 2'b10*/
98 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
101 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
102 /* <20120914, Kordan> A workarould to resolve
103 * 2480Mhz spur by setting ADC clock as 160M.
105 if (band_width == HT_CHANNEL_WIDTH_20 &&
106 (channel == 13 || channel == 14))
107 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
109 else if (channel <= 14) /*2.4G only*/
110 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
115 u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
118 struct rtl_priv *rtlpriv = rtl_priv(hw);
119 u32 returnvalue, originalvalue, bitshift;
121 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
122 "regaddr(%#x), bitmask(%#x)\n",
124 originalvalue = rtl_read_dword(rtlpriv, regaddr);
125 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
126 returnvalue = (originalvalue & bitmask) >> bitshift;
128 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
129 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
130 bitmask, regaddr, originalvalue);
134 void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw,
135 u32 regaddr, u32 bitmask, u32 data)
137 struct rtl_priv *rtlpriv = rtl_priv(hw);
138 u32 originalvalue, bitshift;
140 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
141 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
142 regaddr, bitmask, data);
144 if (bitmask != MASKDWORD) {
145 originalvalue = rtl_read_dword(rtlpriv, regaddr);
146 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
147 data = ((originalvalue & (~bitmask)) |
148 ((data << bitshift) & bitmask));
151 rtl_write_dword(rtlpriv, regaddr, data);
153 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
154 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
155 regaddr, bitmask, data);
158 u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw,
159 enum radio_path rfpath, u32 regaddr,
162 struct rtl_priv *rtlpriv = rtl_priv(hw);
163 u32 original_value, readback_value, bitshift;
166 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
167 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
168 regaddr, rfpath, bitmask);
170 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
172 original_value = _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
173 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
174 readback_value = (original_value & bitmask) >> bitshift;
176 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
178 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
179 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
180 regaddr, rfpath, bitmask, original_value);
182 return readback_value;
185 void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw,
186 enum radio_path rfpath,
187 u32 regaddr, u32 bitmask, u32 data)
189 struct rtl_priv *rtlpriv = rtl_priv(hw);
190 u32 original_value, bitshift;
193 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
194 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
195 regaddr, bitmask, data, rfpath);
197 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
199 if (bitmask != RFREG_OFFSET_MASK) {
201 _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
202 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
203 data = ((original_value & (~bitmask)) | (data << bitshift));
206 _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data);
208 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
210 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
211 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
212 regaddr, bitmask, data, rfpath);
215 static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
216 enum radio_path rfpath, u32 offset)
218 struct rtl_priv *rtlpriv = rtl_priv(hw);
219 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
220 bool is_pi_mode = false;
223 /* 2009/06/17 MH We can not execute IO for power
224 save or other accident mode.*/
225 if (RT_CANNOT_IO(hw)) {
226 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
229 /* <20120809, Kordan> CCA OFF(when entering),
230 asked by James to avoid reading the wrong value.
231 <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
233 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
234 (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
235 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1);
238 if (rfpath == RF90_PATH_A)
239 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4);
240 else if (rfpath == RF90_PATH_B)
241 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4);
243 rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset);
245 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
246 (IS_VENDOR_8812A_C_CUT(rtlhal->version)))
250 if (rfpath == RF90_PATH_A)
252 rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA);
253 else if (rfpath == RF90_PATH_B)
255 rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA);
257 if (rfpath == RF90_PATH_A)
259 rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA);
260 else if (rfpath == RF90_PATH_B)
262 rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA);
265 /*<20120809, Kordan> CCA ON(when exiting),
266 * asked by James to avoid reading the wrong value.
267 * <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!
270 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
271 (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
272 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0);
276 static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
277 enum radio_path rfpath, u32 offset,
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 struct rtl_phy *rtlphy = &rtlpriv->phy;
282 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
286 if (RT_CANNOT_IO(hw)) {
287 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
292 data_and_addr = ((newoffset << 20) |
293 (data & 0x000fffff)) & 0x0fffffff;
294 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
295 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
296 "RFW-%d Addr[0x%x]=0x%x\n",
297 rfpath, pphyreg->rf3wire_offset, data_and_addr);
300 static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
304 for (i = 0; i <= 31; i++) {
305 if (((bitmask >> i) & 0x1) == 1)
311 bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw)
315 rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw);
320 bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw)
322 bool rtstatus = true;
323 struct rtl_priv *rtlpriv = rtl_priv(hw);
324 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
325 struct rtl_phy *rtlphy = &rtlpriv->phy;
326 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
330 phy_init_bb_rf_register_definition(hw);
332 regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
334 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval);
335 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
336 regval | FEN_BB_GLB_RSTN | FEN_BBRSTB);
338 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7);
339 rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7);
341 rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw);
343 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
344 crystal_cap = rtlefuse->crystalcap & 0x3F;
345 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000,
346 (crystal_cap | (crystal_cap << 6)));
348 crystal_cap = rtlefuse->crystalcap & 0x3F;
349 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
350 (crystal_cap | (crystal_cap << 6)));
352 rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);
357 bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
359 return rtl8821ae_phy_rf6052_config(hw);
362 u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band,
365 struct rtl_priv *rtlpriv = rtl_priv(hw);
366 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
367 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
368 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
369 char reg_swing_2g = -1;/* 0xff; */
370 char reg_swing_5g = -1;/* 0xff; */
371 char swing_2g = -1 * reg_swing_2g;
372 char swing_5g = -1 * reg_swing_5g;
374 const char auto_temp = -1;
376 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
377 "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
378 (int)swing_2g, (int)swing_5g,
379 (int)rtlefuse->autoload_failflag);
381 if (rtlefuse->autoload_failflag) {
382 if (band == BAND_ON_2_4G) {
383 rtldm->swing_diff_2g = swing_2g;
385 out = 0x200; /* 0 dB */
386 } else if (swing_2g == -3) {
387 out = 0x16A; /* -3 dB */
388 } else if (swing_2g == -6) {
389 out = 0x101; /* -6 dB */
390 } else if (swing_2g == -9) {
391 out = 0x0B6; /* -9 dB */
393 rtldm->swing_diff_2g = 0;
396 } else if (band == BAND_ON_5G) {
397 rtldm->swing_diff_5g = swing_5g;
399 out = 0x200; /* 0 dB */
400 } else if (swing_5g == -3) {
401 out = 0x16A; /* -3 dB */
402 } else if (swing_5g == -6) {
403 out = 0x101; /* -6 dB */
404 } else if (swing_5g == -9) {
405 out = 0x0B6; /* -9 dB */
407 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
408 rtldm->swing_diff_5g = -3;
411 rtldm->swing_diff_5g = 0;
416 rtldm->swing_diff_2g = -3;
417 rtldm->swing_diff_5g = -3;
418 out = 0x16A; /* -3 dB */
421 u32 swing = 0, swing_a = 0, swing_b = 0;
423 if (band == BAND_ON_2_4G) {
424 if (reg_swing_2g == auto_temp) {
425 efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
426 swing = (swing == 0xFF) ? 0x00 : swing;
427 } else if (swing_2g == 0) {
428 swing = 0x00; /* 0 dB */
429 } else if (swing_2g == -3) {
430 swing = 0x05; /* -3 dB */
431 } else if (swing_2g == -6) {
432 swing = 0x0A; /* -6 dB */
433 } else if (swing_2g == -9) {
434 swing = 0xFF; /* -9 dB */
439 if (reg_swing_5g == auto_temp) {
440 efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
441 swing = (swing == 0xFF) ? 0x00 : swing;
442 } else if (swing_5g == 0) {
443 swing = 0x00; /* 0 dB */
444 } else if (swing_5g == -3) {
445 swing = 0x05; /* -3 dB */
446 } else if (swing_5g == -6) {
447 swing = 0x0A; /* -6 dB */
448 } else if (swing_5g == -9) {
449 swing = 0xFF; /* -9 dB */
455 swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
456 swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
457 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
458 "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
462 if (swing_a == 0x0) {
463 if (band == BAND_ON_2_4G)
464 rtldm->swing_diff_2g = 0;
466 rtldm->swing_diff_5g = 0;
467 out = 0x200; /* 0 dB */
468 } else if (swing_a == 0x1) {
469 if (band == BAND_ON_2_4G)
470 rtldm->swing_diff_2g = -3;
472 rtldm->swing_diff_5g = -3;
473 out = 0x16A; /* -3 dB */
474 } else if (swing_a == 0x2) {
475 if (band == BAND_ON_2_4G)
476 rtldm->swing_diff_2g = -6;
478 rtldm->swing_diff_5g = -6;
479 out = 0x101; /* -6 dB */
480 } else if (swing_a == 0x3) {
481 if (band == BAND_ON_2_4G)
482 rtldm->swing_diff_2g = -9;
484 rtldm->swing_diff_5g = -9;
485 out = 0x0B6; /* -9 dB */
488 if (swing_b == 0x0) {
489 if (band == BAND_ON_2_4G)
490 rtldm->swing_diff_2g = 0;
492 rtldm->swing_diff_5g = 0;
493 out = 0x200; /* 0 dB */
494 } else if (swing_b == 0x1) {
495 if (band == BAND_ON_2_4G)
496 rtldm->swing_diff_2g = -3;
498 rtldm->swing_diff_5g = -3;
499 out = 0x16A; /* -3 dB */
500 } else if (swing_b == 0x2) {
501 if (band == BAND_ON_2_4G)
502 rtldm->swing_diff_2g = -6;
504 rtldm->swing_diff_5g = -6;
505 out = 0x101; /* -6 dB */
506 } else if (swing_b == 0x3) {
507 if (band == BAND_ON_2_4G)
508 rtldm->swing_diff_2g = -9;
510 rtldm->swing_diff_5g = -9;
511 out = 0x0B6; /* -9 dB */
515 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
516 "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out);
520 void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
522 struct rtl_priv *rtlpriv = rtl_priv(hw);
523 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
524 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
525 u8 current_band = rtlhal->current_bandtype;
527 char bb_diff_between_band;
529 txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
530 rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
531 rtlhal->current_bandtype = (enum band_type) band;
532 /* reconfig BB/RF according to wireless mode */
533 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
535 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
537 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
538 /* 0xCB0[15:12] = 0x7 (LNA_On)*/
539 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
540 /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
541 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
544 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
546 rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
549 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
550 /* 0xC1C[11:8] = 0 */
551 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
553 /* 0x82C[1:0] = 2b'00 */
554 rtl_set_bbreg(hw, 0x82c, 0x3, 0);
556 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
557 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
559 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
561 rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x000);
562 rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x000);
565 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
566 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
568 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
569 } else {/* 5G band */
572 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
573 /*0xCB0[15:12] = 0x5 (LNA_On)*/
574 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
575 /*0xCB0[7:4] = 0x4 (PAPE_A)*/
576 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
579 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
582 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
583 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
584 "Reg41A value %d", reg_41a);
586 while ((reg_41a != 0x30) && (count < 50)) {
588 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
590 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
593 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
594 "Reg41A value %d", reg_41a);
597 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
598 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
601 /* 2012/02/01, Sinda add registry to switch workaround
602 without long-run verification for scan issue. */
603 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
605 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
607 rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
610 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
611 /* AGC table select */
613 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
615 /* 0x82C[1:0] = 2'b00 */
616 rtl_set_bbreg(hw, 0x82c, 0x3, 1);
618 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
619 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
621 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
623 rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x010);
624 rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x010);
627 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
628 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
630 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
631 "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
632 rtlpriv->dm.ofdm_index[RF90_PATH_A]);
635 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
636 (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
638 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
639 phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
641 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
642 phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
644 /* <20121005, Kordan> When TxPowerTrack is ON,
645 * we should take care of the change of BB swing.
646 * That is, reset all info to trigger Tx power tracking.
648 if (band != current_band) {
649 bb_diff_between_band =
650 (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
651 bb_diff_between_band = (band == BAND_ON_2_4G) ?
652 bb_diff_between_band :
653 (-1 * bb_diff_between_band);
654 rtldm->default_ofdm_index += bb_diff_between_band * 2;
656 rtl8821ae_dm_clear_txpower_tracking_state(hw);
659 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
660 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
664 static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
667 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
668 u32 _board = rtlefuse->board_type; /*need efuse define*/
669 u32 _interface = 0x01; /* ODM_ITRF_PCIE */
670 u32 _platform = 0x08;/* ODM_WIN */
671 u32 cond = condition;
673 if (condition == 0xCDCDCDCD)
676 cond = condition & 0xFF;
677 if ((_board != cond) && cond != 0xFF)
680 cond = condition & 0xFF00;
682 if ((_interface & cond) == 0 && cond != 0x07)
685 cond = condition & 0xFF0000;
687 if ((_platform & cond) == 0 && cond != 0x0F)
692 static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
694 enum radio_path rfpath, u32 regaddr)
696 if (addr == 0xfe || addr == 0xffe) {
697 /* In order not to disturb BT music when
698 * wifi init.(1ant NIC only)
702 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
707 static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
710 u32 content = 0x1000; /*RF Content: radio_a_txt*/
711 u32 maskforphyset = (u32)(content & 0xE000);
713 _rtl8821ae_config_rf_reg(hw, addr, data,
714 RF90_PATH_A, addr | maskforphyset);
717 static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
720 u32 content = 0x1001; /*RF Content: radio_b_txt*/
721 u32 maskforphyset = (u32)(content & 0xE000);
723 _rtl8821ae_config_rf_reg(hw, addr, data,
724 RF90_PATH_B, addr | maskforphyset);
727 static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
732 else if (addr == 0xfd)
734 else if (addr == 0xfc)
736 else if (addr == 0xfb)
738 else if (addr == 0xfa)
740 else if (addr == 0xf9)
743 rtl_set_bbreg(hw, addr, MASKDWORD, data);
748 static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
750 struct rtl_priv *rtlpriv = rtl_priv(hw);
751 struct rtl_phy *rtlphy = &rtlpriv->phy;
752 u8 band, rfpath, txnum, rate_section;
754 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
755 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
756 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
757 for (rate_section = 0;
758 rate_section < TX_PWR_BY_RATE_NUM_SECTION;
760 rtlphy->tx_power_by_rate_offset[band]
761 [rfpath][txnum][rate_section] = 0;
764 static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
769 struct rtl_priv *rtlpriv = rtl_priv(hw);
770 struct rtl_phy *rtlphy = &rtlpriv->phy;
772 if (path > RF90_PATH_D) {
773 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
774 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
778 if (band == BAND_ON_2_4G) {
779 switch (rate_section) {
781 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
784 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
787 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
790 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
792 case VHT_1SSMCS0_1SSMCS9:
793 rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
795 case VHT_2SSMCS0_2SSMCS9:
796 rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
799 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
800 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
801 rate_section, path, txnum);
804 } else if (band == BAND_ON_5G) {
805 switch (rate_section) {
807 rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
810 rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
813 rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
815 case VHT_1SSMCS0_1SSMCS9:
816 rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
818 case VHT_2SSMCS0_2SSMCS9:
819 rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
822 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
823 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
824 rate_section, path, txnum);
828 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
829 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
833 static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
835 u8 txnum, u8 rate_section)
837 struct rtl_priv *rtlpriv = rtl_priv(hw);
838 struct rtl_phy *rtlphy = &rtlpriv->phy;
841 if (path > RF90_PATH_D) {
842 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
843 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
848 if (band == BAND_ON_2_4G) {
849 switch (rate_section) {
851 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
854 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
857 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
860 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
862 case VHT_1SSMCS0_1SSMCS9:
863 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
865 case VHT_2SSMCS0_2SSMCS9:
866 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
869 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
870 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
871 rate_section, path, txnum);
874 } else if (band == BAND_ON_5G) {
875 switch (rate_section) {
877 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
880 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
883 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
885 case VHT_1SSMCS0_1SSMCS9:
886 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
888 case VHT_2SSMCS0_2SSMCS9:
889 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
892 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
893 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
894 rate_section, path, txnum);
898 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
899 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
905 static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
907 struct rtl_priv *rtlpriv = rtl_priv(hw);
908 struct rtl_phy *rtlphy = &rtlpriv->phy;
910 u8 base = 0, path = 0;
912 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
913 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
914 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
915 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
917 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
918 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
919 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
921 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
922 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
923 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
925 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
926 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
927 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
929 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
930 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
931 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
933 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
934 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
935 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
937 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
938 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
939 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
941 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
942 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
943 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
945 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
946 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
947 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
949 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
950 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
951 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
953 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
954 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
955 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
959 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
966 for (i = 3; i >= 0; --i) {
967 if (i >= start && i <= end) {
968 /* Get the exact value */
969 temp_value = (u8)(*data >> (i * 8)) & 0xF;
970 temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
972 /* Change the value to a relative value */
973 temp_value = (temp_value > base_val) ? temp_value -
974 base_val : base_val - temp_value;
976 temp_value = (u8)(*data >> (i * 8)) & 0xFF;
979 temp_data |= temp_value;
984 static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
986 struct rtl_priv *rtlpriv = rtl_priv(hw);
987 struct rtl_phy *rtlphy = &rtlpriv->phy;
988 u8 regulation, bw, channel, rate_section;
989 char temp_pwrlmt = 0;
991 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
992 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
993 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
994 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
995 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
996 [bw][rate_section][channel][RF90_PATH_A];
997 if (temp_pwrlmt == MAX_POWER_INDEX) {
998 if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
999 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1000 "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1001 1, bw, rate_section, channel, RF90_PATH_A);
1002 if (rate_section == 2) {
1003 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1004 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1005 } else if (rate_section == 4) {
1006 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1007 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1008 } else if (rate_section == 3) {
1009 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1010 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1011 } else if (rate_section == 5) {
1012 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1013 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1016 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d", temp_pwrlmt);
1025 static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1026 enum band_type band, u8 rate)
1028 struct rtl_priv *rtlpriv = rtl_priv(hw);
1030 if (band == BAND_ON_2_4G) {
1073 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1074 "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1078 } else if (band == BAND_ON_5G) {
1113 case MGN_VHT1SS_MCS0:
1114 case MGN_VHT1SS_MCS1:
1115 case MGN_VHT1SS_MCS2:
1116 case MGN_VHT1SS_MCS3:
1117 case MGN_VHT1SS_MCS4:
1118 case MGN_VHT1SS_MCS5:
1119 case MGN_VHT1SS_MCS6:
1120 case MGN_VHT1SS_MCS7:
1121 case MGN_VHT1SS_MCS8:
1122 case MGN_VHT1SS_MCS9:
1126 case MGN_VHT2SS_MCS0:
1127 case MGN_VHT2SS_MCS1:
1128 case MGN_VHT2SS_MCS2:
1129 case MGN_VHT2SS_MCS3:
1130 case MGN_VHT2SS_MCS4:
1131 case MGN_VHT2SS_MCS5:
1132 case MGN_VHT2SS_MCS6:
1133 case MGN_VHT2SS_MCS7:
1134 case MGN_VHT2SS_MCS8:
1135 case MGN_VHT2SS_MCS9:
1140 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1141 "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1150 static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1152 struct rtl_priv *rtlpriv = rtl_priv(hw);
1153 struct rtl_phy *rtlphy = &rtlpriv->phy;
1154 u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1155 u8 regulation, bw, channel, rate_section;
1156 u8 base_index2_4G = 0;
1157 u8 base_index5G = 0;
1158 char temp_value = 0, temp_pwrlmt = 0;
1161 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1162 "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1164 _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1166 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1167 for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) {
1168 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1169 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1170 /* obtain the base dBm values in 2.4G band
1171 CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1172 if (rate_section == 0) { /*CCK*/
1174 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1175 BAND_ON_2_4G, MGN_11M);
1176 } else if (rate_section == 1) { /*OFDM*/
1178 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1179 BAND_ON_2_4G, MGN_54M);
1180 } else if (rate_section == 2) { /*HT IT*/
1182 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1183 BAND_ON_2_4G, MGN_MCS7);
1184 } else if (rate_section == 3) { /*HT 2T*/
1186 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1187 BAND_ON_2_4G, MGN_MCS15);
1190 temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1191 [bw][rate_section][channel][RF90_PATH_A];
1193 for (rf_path = RF90_PATH_A;
1194 rf_path < MAX_RF_PATH_NUM;
1196 if (rate_section == 3)
1197 bw40_pwr_base_dbm2_4G =
1198 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1200 bw40_pwr_base_dbm2_4G =
1201 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1203 if (temp_pwrlmt != MAX_POWER_INDEX) {
1204 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1205 rtlphy->txpwr_limit_2_4g[regulation]
1206 [bw][rate_section][channel][rf_path] =
1210 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1211 "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n",
1212 regulation, bw, rate_section, channel,
1213 rtlphy->txpwr_limit_2_4g[regulation][bw]
1214 [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1215 ? 0 : temp_pwrlmt/2, channel, rf_path,
1216 bw40_pwr_base_dbm2_4G);
1222 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1223 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
1224 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1225 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1226 /* obtain the base dBm values in 5G band
1227 OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1228 VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1229 if (rate_section == 1) { /*OFDM*/
1231 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1232 BAND_ON_5G, MGN_54M);
1233 } else if (rate_section == 2) { /*HT 1T*/
1235 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1236 BAND_ON_5G, MGN_MCS7);
1237 } else if (rate_section == 3) { /*HT 2T*/
1239 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1240 BAND_ON_5G, MGN_MCS15);
1241 } else if (rate_section == 4) { /*VHT 1T*/
1243 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1244 BAND_ON_5G, MGN_VHT1SS_MCS7);
1245 } else if (rate_section == 5) { /*VHT 2T*/
1247 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1248 BAND_ON_5G, MGN_VHT2SS_MCS7);
1251 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1252 [bw][rate_section][channel]
1255 for (rf_path = RF90_PATH_A;
1256 rf_path < MAX_RF_PATH_NUM;
1258 if (rate_section == 3 || rate_section == 5)
1259 bw40_pwr_base_dbm5G =
1260 rtlphy->txpwr_by_rate_base_5g[rf_path]
1261 [RF_2TX][base_index5G];
1263 bw40_pwr_base_dbm5G =
1264 rtlphy->txpwr_by_rate_base_5g[rf_path]
1265 [RF_1TX][base_index5G];
1267 if (temp_pwrlmt != MAX_POWER_INDEX) {
1269 temp_pwrlmt - bw40_pwr_base_dbm5G;
1270 rtlphy->txpwr_limit_5g[regulation]
1271 [bw][rate_section][channel]
1272 [rf_path] = temp_value;
1275 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1276 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
1277 regulation, bw, rate_section,
1278 channel, rtlphy->txpwr_limit_5g[regulation]
1279 [bw][rate_section][channel][rf_path],
1280 temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1286 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1287 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1290 static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1292 struct rtl_priv *rtlpriv = rtl_priv(hw);
1293 struct rtl_phy *rtlphy = &rtlpriv->phy;
1296 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1297 "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1299 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1300 for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j)
1301 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1302 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1303 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1304 rtlphy->txpwr_limit_2_4g
1308 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1309 for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j)
1310 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1311 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1312 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1313 rtlphy->txpwr_limit_5g
1318 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1319 "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1322 static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1324 struct rtl_priv *rtlpriv = rtl_priv(hw);
1325 struct rtl_phy *rtlphy = &rtlpriv->phy;
1326 u8 base = 0, rfPath = 0;
1328 for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
1329 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1330 _phy_convert_txpower_dbm_to_relative_value(
1331 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0],
1334 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1335 _phy_convert_txpower_dbm_to_relative_value(
1336 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1],
1338 _phy_convert_txpower_dbm_to_relative_value(
1339 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2],
1342 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1343 _phy_convert_txpower_dbm_to_relative_value(
1344 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3],
1346 _phy_convert_txpower_dbm_to_relative_value(
1347 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4],
1350 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1352 _phy_convert_txpower_dbm_to_relative_value(
1353 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5],
1356 _phy_convert_txpower_dbm_to_relative_value(
1357 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6],
1360 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1361 _phy_convert_txpower_dbm_to_relative_value(
1362 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7],
1364 _phy_convert_txpower_dbm_to_relative_value(
1365 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8],
1367 _phy_convert_txpower_dbm_to_relative_value(
1368 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1371 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1372 _phy_convert_txpower_dbm_to_relative_value(
1373 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1375 _phy_convert_txpower_dbm_to_relative_value(
1376 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10],
1378 _phy_convert_txpower_dbm_to_relative_value(
1379 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11],
1382 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM);
1383 _phy_convert_txpower_dbm_to_relative_value(
1384 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1],
1386 _phy_convert_txpower_dbm_to_relative_value(
1387 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2],
1390 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7);
1391 _phy_convert_txpower_dbm_to_relative_value(
1392 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3],
1394 _phy_convert_txpower_dbm_to_relative_value(
1395 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4],
1398 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15);
1399 _phy_convert_txpower_dbm_to_relative_value(
1400 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5],
1402 _phy_convert_txpower_dbm_to_relative_value(
1403 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6],
1406 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1407 _phy_convert_txpower_dbm_to_relative_value(
1408 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7],
1410 _phy_convert_txpower_dbm_to_relative_value(
1411 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8],
1413 _phy_convert_txpower_dbm_to_relative_value(
1414 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1417 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1418 _phy_convert_txpower_dbm_to_relative_value(
1419 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1421 _phy_convert_txpower_dbm_to_relative_value(
1422 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10],
1424 _phy_convert_txpower_dbm_to_relative_value(
1425 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11],
1429 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1430 "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1433 static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1435 _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1436 _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1439 /* string is in decimal */
1440 static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
1445 while (str[i] != '\0') {
1446 if (str[i] >= '0' && str[i] <= '9') {
1448 *pint += (str[i] - '0');
1458 static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
1464 if (str1[num] != str2[num])
1470 static char _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1471 u8 band, u8 channel)
1473 struct rtl_priv *rtlpriv = rtl_priv(hw);
1474 char channel_index = -1;
1475 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
1476 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
1477 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
1478 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149,
1479 151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171,
1482 if (band == BAND_ON_2_4G)
1483 channel_index = channel - 1;
1484 else if (band == BAND_ON_5G) {
1485 for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) {
1486 if (channel_5g[i] == channel)
1490 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
1493 if (channel_index == -1)
1494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1495 "Invalid Channel %d of Band %d in %s", channel,
1498 return channel_index;
1501 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1502 u8 *pband, u8 *pbandwidth,
1503 u8 *prate_section, u8 *prf_path,
1504 u8 *pchannel, u8 *ppower_limit)
1506 struct rtl_priv *rtlpriv = rtl_priv(hw);
1507 struct rtl_phy *rtlphy = &rtlpriv->phy;
1508 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1510 char power_limit = 0, prev_power_limit, ret;
1512 if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1513 !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1515 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1516 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1517 channel, power_limit);
1520 power_limit = power_limit > MAX_POWER_INDEX ?
1521 MAX_POWER_INDEX : power_limit;
1523 if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1525 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1527 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1529 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1532 if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1534 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1536 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1537 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1539 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1540 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1542 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1543 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1545 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1546 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1549 if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1551 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1553 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1555 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1558 if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1559 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1566 channel_index = ret;
1568 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1569 [bandwidth][rate_section]
1570 [channel_index][RF90_PATH_A];
1572 if (power_limit < prev_power_limit)
1573 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1574 [rate_section][channel_index][RF90_PATH_A] =
1577 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1578 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1579 regulation, bandwidth, rate_section, channel_index,
1580 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1581 [rate_section][channel_index][RF90_PATH_A]);
1582 } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1583 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1590 channel_index = ret;
1592 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1593 [rate_section][channel_index]
1596 if (power_limit < prev_power_limit)
1597 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1598 [rate_section][channel_index][RF90_PATH_A] = power_limit;
1600 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1601 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1602 regulation, bandwidth, rate_section, channel,
1603 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1604 [rate_section][channel_index][RF90_PATH_A]);
1606 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1607 "Cannot recognize the band info in %s\n", pband);
1612 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1613 u8 *regulation, u8 *band,
1614 u8 *bandwidth, u8 *rate_section,
1615 u8 *rf_path, u8 *channel,
1618 _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1619 rate_section, rf_path, channel,
1623 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1625 struct rtl_priv *rtlpriv = rtl_priv(hw);
1626 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1631 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1632 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1633 array = RTL8812AE_TXPWR_LMT;
1635 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1636 array = RTL8821AE_TXPWR_LMT;
1639 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1642 for (i = 0; i < array_len; i += 7) {
1643 u8 *regulation = array[i];
1644 u8 *band = array[i+1];
1645 u8 *bandwidth = array[i+2];
1646 u8 *rate = array[i+3];
1647 u8 *rf_path = array[i+4];
1648 u8 *chnl = array[i+5];
1649 u8 *val = array[i+6];
1651 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1652 bandwidth, rate, rf_path,
1657 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1659 struct rtl_priv *rtlpriv = rtl_priv(hw);
1660 struct rtl_phy *rtlphy = &rtlpriv->phy;
1661 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1664 _rtl8821ae_phy_init_txpower_limit(hw);
1666 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1667 if (rtlefuse->eeprom_regulatory != 2)
1668 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1670 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1671 BASEBAND_CONFIG_PHY_REG);
1672 if (rtstatus != true) {
1673 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
1676 _rtl8821ae_phy_init_tx_power_by_rate(hw);
1677 if (rtlefuse->autoload_failflag == false) {
1678 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1679 BASEBAND_CONFIG_PHY_REG);
1681 if (rtstatus != true) {
1682 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
1686 _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1688 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1689 if (rtlefuse->eeprom_regulatory != 2)
1690 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1692 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1693 BASEBAND_CONFIG_AGC_TAB);
1695 if (rtstatus != true) {
1696 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1699 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1700 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1704 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1706 struct rtl_priv *rtlpriv = rtl_priv(hw);
1707 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1712 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1713 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1714 arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1715 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1717 arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1718 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1720 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1721 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1722 for (i = 0; i < arraylength; i += 2) {
1724 v2 = (u8)ptrarray[i + 1];
1725 if (v1 < 0xCDCDCDCD) {
1726 rtl_write_byte(rtlpriv, v1, (u8)v2);
1729 if (!_rtl8821ae_check_condition(hw, v1)) {
1730 /*Discard the following (offset, data) pairs*/
1731 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1732 while (v2 != 0xDEAD &&
1734 v2 != 0xCDCD && i < arraylength - 2) {
1735 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1737 i -= 2; /* prevent from for-loop += 2*/
1738 } else {/*Configure matched pairs and skip to end of if-else.*/
1739 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1740 while (v2 != 0xDEAD &&
1742 v2 != 0xCDCD && i < arraylength - 2) {
1743 rtl_write_byte(rtlpriv, v1, v2);
1744 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1747 while (v2 != 0xDEAD && i < arraylength - 2)
1748 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1755 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1758 struct rtl_priv *rtlpriv = rtl_priv(hw);
1759 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1765 if (configtype == BASEBAND_CONFIG_PHY_REG) {
1766 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1767 arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1768 array_table = RTL8812AE_PHY_REG_ARRAY;
1770 arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1771 array_table = RTL8821AE_PHY_REG_ARRAY;
1774 for (i = 0; i < arraylen; i += 2) {
1775 v1 = array_table[i];
1776 v2 = array_table[i + 1];
1777 if (v1 < 0xCDCDCDCD) {
1778 _rtl8821ae_config_bb_reg(hw, v1, v2);
1780 } else {/*This line is the start line of branch.*/
1781 if (!_rtl8821ae_check_condition(hw, v1)) {
1782 /*Discard the following (offset, data) pairs*/
1783 READ_NEXT_PAIR(array_table, v1, v2, i);
1784 while (v2 != 0xDEAD &&
1788 READ_NEXT_PAIR(array_table, v1,
1792 i -= 2; /* prevent from for-loop += 2*/
1793 } else {/*Configure matched pairs and skip to end of if-else.*/
1794 READ_NEXT_PAIR(array_table, v1, v2, i);
1795 while (v2 != 0xDEAD &&
1799 _rtl8821ae_config_bb_reg(hw, v1,
1801 READ_NEXT_PAIR(array_table, v1,
1805 while (v2 != 0xDEAD &&
1807 READ_NEXT_PAIR(array_table, v1,
1813 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1814 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1815 arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1816 array_table = RTL8812AE_AGC_TAB_ARRAY;
1818 arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1819 array_table = RTL8821AE_AGC_TAB_ARRAY;
1822 for (i = 0; i < arraylen; i = i + 2) {
1823 v1 = array_table[i];
1824 v2 = array_table[i+1];
1825 if (v1 < 0xCDCDCDCD) {
1826 rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1829 } else {/*This line is the start line of branch.*/
1830 if (!_rtl8821ae_check_condition(hw, v1)) {
1831 /*Discard the following (offset, data) pairs*/
1832 READ_NEXT_PAIR(array_table, v1, v2, i);
1833 while (v2 != 0xDEAD &&
1837 READ_NEXT_PAIR(array_table, v1,
1840 i -= 2; /* prevent from for-loop += 2*/
1841 } else {/*Configure matched pairs and skip to end of if-else.*/
1842 READ_NEXT_PAIR(array_table, v1, v2, i);
1843 while (v2 != 0xDEAD &&
1847 rtl_set_bbreg(hw, v1, MASKDWORD,
1850 READ_NEXT_PAIR(array_table, v1,
1854 while (v2 != 0xDEAD &&
1856 READ_NEXT_PAIR(array_table, v1,
1860 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1861 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1862 array_table[i], array_table[i + 1]);
1869 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1873 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1874 index = (u8)((regaddr - 0xC20) / 4);
1875 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1876 index = (u8)((regaddr - 0xE20) / 4);
1878 RT_ASSERT(!COMP_INIT,
1879 "Invalid RegAddr 0x%x\n", regaddr);
1883 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1884 u32 band, u32 rfpath,
1885 u32 txnum, u32 regaddr,
1886 u32 bitmask, u32 data)
1888 struct rtl_priv *rtlpriv = rtl_priv(hw);
1889 struct rtl_phy *rtlphy = &rtlpriv->phy;
1890 u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1892 if (band != BAND_ON_2_4G && band != BAND_ON_5G)
1893 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1895 if (rfpath >= MAX_RF_PATH)
1896 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1898 if (txnum >= MAX_RF_PATH)
1899 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1901 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1902 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1903 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1904 band, rfpath, txnum, rate_section,
1905 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1908 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
1911 struct rtl_priv *rtlpriv = rtl_priv(hw);
1912 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1916 u32 v1, v2, v3, v4, v5, v6;
1918 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1919 arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
1920 array = RTL8812AE_PHY_REG_ARRAY_PG;
1922 arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
1923 array = RTL8821AE_PHY_REG_ARRAY_PG;
1926 if (configtype != BASEBAND_CONFIG_PHY_REG) {
1927 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
1928 "configtype != BaseBand_Config_PHY_REG\n");
1931 for (i = 0; i < arraylen; i += 6) {
1939 if (v1 < 0xCDCDCDCD) {
1940 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
1941 (v4 == 0xfe || v4 == 0xffe)) {
1946 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1949 else if (v4 == 0xfd)
1951 else if (v4 == 0xfc)
1953 else if (v4 == 0xfb)
1955 else if (v4 == 0xfa)
1957 else if (v4 == 0xf9)
1960 _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
1964 /*don't need the hw_body*/
1965 if (!_rtl8821ae_check_condition(hw, v1)) {
1966 i += 2; /* skip the pair of expression*/
1970 while (v2 != 0xDEAD) {
1983 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
1984 enum radio_path rfpath)
1987 bool rtstatus = true;
1988 u32 *radioa_array_table_a, *radioa_array_table_b;
1989 u16 radioa_arraylen_a, radioa_arraylen_b;
1990 struct rtl_priv *rtlpriv = rtl_priv(hw);
1993 radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
1994 radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
1995 radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
1996 radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
1997 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1998 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
1999 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2003 for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2004 v1 = radioa_array_table_a[i];
2005 v2 = radioa_array_table_a[i+1];
2006 if (v1 < 0xcdcdcdcd) {
2007 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2009 } else{/*This line is the start line of branch.*/
2010 if (!_rtl8821ae_check_condition(hw, v1)) {
2011 /*Discard the following (offset, data) pairs*/
2012 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2013 while (v2 != 0xDEAD &&
2015 v2 != 0xCDCD && i < radioa_arraylen_a-2)
2016 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2018 i -= 2; /* prevent from for-loop += 2*/
2019 } else {/*Configure matched pairs and skip to end of if-else.*/
2020 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2021 while (v2 != 0xDEAD &&
2023 v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2024 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2025 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2028 while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2029 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2036 for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2037 v1 = radioa_array_table_b[i];
2038 v2 = radioa_array_table_b[i+1];
2039 if (v1 < 0xcdcdcdcd) {
2040 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2042 } else{/*This line is the start line of branch.*/
2043 if (!_rtl8821ae_check_condition(hw, v1)) {
2044 /*Discard the following (offset, data) pairs*/
2045 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2046 while (v2 != 0xDEAD &&
2048 v2 != 0xCDCD && i < radioa_arraylen_b-2)
2049 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2051 i -= 2; /* prevent from for-loop += 2*/
2052 } else {/*Configure matched pairs and skip to end of if-else.*/
2053 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2054 while (v2 != 0xDEAD &&
2056 v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2057 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2058 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2061 while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2062 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2068 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2069 "switch case not process\n");
2072 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2073 "switch case not process\n");
2079 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2080 enum radio_path rfpath)
2082 #define READ_NEXT_RF_PAIR(v1, v2, i) \
2085 v1 = radioa_array_table[i]; \
2086 v2 = radioa_array_table[i+1]; \
2091 bool rtstatus = true;
2092 u32 *radioa_array_table;
2093 u16 radioa_arraylen;
2094 struct rtl_priv *rtlpriv = rtl_priv(hw);
2095 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2098 radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2099 radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2100 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2101 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2102 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2106 for (i = 0; i < radioa_arraylen; i = i + 2) {
2107 v1 = radioa_array_table[i];
2108 v2 = radioa_array_table[i+1];
2109 if (v1 < 0xcdcdcdcd)
2110 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2111 else{/*This line is the start line of branch.*/
2112 if (!_rtl8821ae_check_condition(hw, v1)) {
2113 /*Discard the following (offset, data) pairs*/
2114 READ_NEXT_RF_PAIR(v1, v2, i);
2115 while (v2 != 0xDEAD &&
2117 v2 != 0xCDCD && i < radioa_arraylen - 2)
2118 READ_NEXT_RF_PAIR(v1, v2, i);
2120 i -= 2; /* prevent from for-loop += 2*/
2121 } else {/*Configure matched pairs and skip to end of if-else.*/
2122 READ_NEXT_RF_PAIR(v1, v2, i);
2123 while (v2 != 0xDEAD &&
2125 v2 != 0xCDCD && i < radioa_arraylen - 2) {
2126 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2127 READ_NEXT_RF_PAIR(v1, v2, i);
2130 while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2131 READ_NEXT_RF_PAIR(v1, v2, i);
2138 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2139 "switch case not process\n");
2142 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2143 "switch case not process\n");
2146 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2147 "switch case not process\n");
2153 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2155 struct rtl_priv *rtlpriv = rtl_priv(hw);
2156 struct rtl_phy *rtlphy = &rtlpriv->phy;
2158 rtlphy->default_initialgain[0] =
2159 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2160 rtlphy->default_initialgain[1] =
2161 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2162 rtlphy->default_initialgain[2] =
2163 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2164 rtlphy->default_initialgain[3] =
2165 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2167 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2168 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2169 rtlphy->default_initialgain[0],
2170 rtlphy->default_initialgain[1],
2171 rtlphy->default_initialgain[2],
2172 rtlphy->default_initialgain[3]);
2174 rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2175 ROFDM0_RXDETECTOR3, MASKBYTE0);
2176 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2177 ROFDM0_RXDETECTOR2, MASKDWORD);
2179 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2180 "Default framesync (0x%x) = 0x%x\n",
2181 ROFDM0_RXDETECTOR3, rtlphy->framesync);
2184 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2186 struct rtl_priv *rtlpriv = rtl_priv(hw);
2187 struct rtl_phy *rtlphy = &rtlpriv->phy;
2189 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2190 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2192 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2193 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2195 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2196 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2198 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2199 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2201 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2202 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2204 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2205 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2207 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2208 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2211 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2213 struct rtl_priv *rtlpriv = rtl_priv(hw);
2214 struct rtl_phy *rtlphy = &rtlpriv->phy;
2218 txpwr_level = rtlphy->cur_cck_txpwridx;
2219 txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2220 WIRELESS_MODE_B, txpwr_level);
2221 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2222 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2224 txpwr_level) > txpwr_dbm)
2226 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2228 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2229 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2230 WIRELESS_MODE_N_24G,
2231 txpwr_level) > txpwr_dbm)
2233 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2235 *powerlevel = txpwr_dbm;
2238 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2240 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
2241 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
2242 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
2243 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140,
2244 142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165,
2245 167, 168, 169, 171, 173, 175, 177
2250 if (channel <= 14) {
2252 *chnl_index = channel - 1;
2256 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2257 if (channel_5g[i] == channel) {
2266 static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2268 char rate_section = 0;
2302 case DESC_RATEMCS10:
2303 case DESC_RATEMCS11:
2306 case DESC_RATEMCS12:
2307 case DESC_RATEMCS13:
2308 case DESC_RATEMCS14:
2309 case DESC_RATEMCS15:
2312 case DESC_RATEVHT1SS_MCS0:
2313 case DESC_RATEVHT1SS_MCS1:
2314 case DESC_RATEVHT1SS_MCS2:
2315 case DESC_RATEVHT1SS_MCS3:
2318 case DESC_RATEVHT1SS_MCS4:
2319 case DESC_RATEVHT1SS_MCS5:
2320 case DESC_RATEVHT1SS_MCS6:
2321 case DESC_RATEVHT1SS_MCS7:
2324 case DESC_RATEVHT1SS_MCS8:
2325 case DESC_RATEVHT1SS_MCS9:
2326 case DESC_RATEVHT2SS_MCS0:
2327 case DESC_RATEVHT2SS_MCS1:
2330 case DESC_RATEVHT2SS_MCS2:
2331 case DESC_RATEVHT2SS_MCS3:
2332 case DESC_RATEVHT2SS_MCS4:
2333 case DESC_RATEVHT2SS_MCS5:
2336 case DESC_RATEVHT2SS_MCS6:
2337 case DESC_RATEVHT2SS_MCS7:
2338 case DESC_RATEVHT2SS_MCS8:
2339 case DESC_RATEVHT2SS_MCS9:
2343 RT_ASSERT(true, "Rate_Section is Illegal\n");
2347 return rate_section;
2350 static char _rtl8812ae_phy_get_world_wide_limit(char *limit_table)
2352 char min = limit_table[0];
2355 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2356 if (limit_table[i] < min)
2357 min = limit_table[i];
2362 static char _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2364 enum ht_channel_width bandwidth,
2365 enum radio_path rf_path,
2366 u8 rate, u8 channel)
2368 struct rtl_priv *rtlpriv = rtl_priv(hw);
2369 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2370 struct rtl_phy *rtlphy = &rtlpriv->phy;
2371 short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2372 rate_section = -1, channel_temp = -1;
2373 u16 bd, regu, bdwidth, sec, chnl;
2374 char power_limit = MAX_POWER_INDEX;
2376 if (rtlefuse->eeprom_regulatory == 2)
2377 return MAX_POWER_INDEX;
2379 regulation = TXPWR_LMT_WW;
2381 if (band == BAND_ON_2_4G)
2383 else if (band == BAND_ON_5G)
2386 if (bandwidth == HT_CHANNEL_WIDTH_20)
2388 else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2390 else if (bandwidth == HT_CHANNEL_WIDTH_80)
2422 case DESC_RATEMCS10:
2423 case DESC_RATEMCS11:
2424 case DESC_RATEMCS12:
2425 case DESC_RATEMCS13:
2426 case DESC_RATEMCS14:
2427 case DESC_RATEMCS15:
2430 case DESC_RATEVHT1SS_MCS0:
2431 case DESC_RATEVHT1SS_MCS1:
2432 case DESC_RATEVHT1SS_MCS2:
2433 case DESC_RATEVHT1SS_MCS3:
2434 case DESC_RATEVHT1SS_MCS4:
2435 case DESC_RATEVHT1SS_MCS5:
2436 case DESC_RATEVHT1SS_MCS6:
2437 case DESC_RATEVHT1SS_MCS7:
2438 case DESC_RATEVHT1SS_MCS8:
2439 case DESC_RATEVHT1SS_MCS9:
2442 case DESC_RATEVHT2SS_MCS0:
2443 case DESC_RATEVHT2SS_MCS1:
2444 case DESC_RATEVHT2SS_MCS2:
2445 case DESC_RATEVHT2SS_MCS3:
2446 case DESC_RATEVHT2SS_MCS4:
2447 case DESC_RATEVHT2SS_MCS5:
2448 case DESC_RATEVHT2SS_MCS6:
2449 case DESC_RATEVHT2SS_MCS7:
2450 case DESC_RATEVHT2SS_MCS8:
2451 case DESC_RATEVHT2SS_MCS9:
2455 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2456 "Wrong rate 0x%x\n", rate);
2460 if (band_temp == BAND_ON_5G && rate_section == 0)
2461 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2462 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2464 /*workaround for wrong index combination to obtain tx power limit,
2465 OFDM only exists in BW 20M*/
2466 if (rate_section == 1)
2469 /*workaround for wrong index combination to obtain tx power limit,
2470 *HT on 80M will reference to HT on 40M
2472 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2473 bandwidth_temp == 2)
2476 if (band == BAND_ON_2_4G)
2477 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2478 BAND_ON_2_4G, channel);
2479 else if (band == BAND_ON_5G)
2480 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2481 BAND_ON_5G, channel);
2482 else if (band == BAND_ON_BOTH)
2483 ;/* BAND_ON_BOTH don't care temporarily */
2485 if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2486 rate_section == -1 || channel_temp == -1) {
2487 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2488 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2489 band_temp, regulation, bandwidth_temp, rf_path,
2490 rate_section, channel_temp);
2491 return MAX_POWER_INDEX;
2496 bdwidth = bandwidth_temp;
2498 chnl = channel_temp;
2500 if (band == BAND_ON_2_4G) {
2501 char limits[10] = {0};
2504 for (i = 0; i < 4; ++i)
2505 limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2506 [sec][chnl][rf_path];
2508 power_limit = (regulation == TXPWR_LMT_WW) ?
2509 _rtl8812ae_phy_get_world_wide_limit(limits) :
2510 rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2511 [sec][chnl][rf_path];
2512 } else if (band == BAND_ON_5G) {
2513 char limits[10] = {0};
2516 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2517 limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2518 [sec][chnl][rf_path];
2520 power_limit = (regulation == TXPWR_LMT_WW) ?
2521 _rtl8812ae_phy_get_world_wide_limit(limits) :
2522 rtlphy->txpwr_limit_5g[regu][chnl]
2523 [sec][chnl][rf_path];
2525 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2526 "No power limit table of the specified band\n");
2531 static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2532 u8 band, u8 path, u8 rate)
2534 struct rtl_priv *rtlpriv = rtl_priv(hw);
2535 struct rtl_phy *rtlphy = &rtlpriv->phy;
2536 u8 shift = 0, rate_section, tx_num;
2537 char tx_pwr_diff = 0;
2540 rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2541 tx_num = RF_TX_NUM_NONIMPLEMENT;
2543 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2544 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2545 (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2558 case DESC_RATEMCS12:
2559 case DESC_RATEVHT1SS_MCS0:
2560 case DESC_RATEVHT1SS_MCS4:
2561 case DESC_RATEVHT1SS_MCS8:
2562 case DESC_RATEVHT2SS_MCS2:
2563 case DESC_RATEVHT2SS_MCS6:
2572 case DESC_RATEMCS13:
2573 case DESC_RATEVHT1SS_MCS1:
2574 case DESC_RATEVHT1SS_MCS5:
2575 case DESC_RATEVHT1SS_MCS9:
2576 case DESC_RATEVHT2SS_MCS3:
2577 case DESC_RATEVHT2SS_MCS7:
2585 case DESC_RATEMCS10:
2586 case DESC_RATEMCS14:
2587 case DESC_RATEVHT1SS_MCS2:
2588 case DESC_RATEVHT1SS_MCS6:
2589 case DESC_RATEVHT2SS_MCS0:
2590 case DESC_RATEVHT2SS_MCS4:
2591 case DESC_RATEVHT2SS_MCS8:
2599 case DESC_RATEMCS11:
2600 case DESC_RATEMCS15:
2601 case DESC_RATEVHT1SS_MCS3:
2602 case DESC_RATEVHT1SS_MCS7:
2603 case DESC_RATEVHT2SS_MCS1:
2604 case DESC_RATEVHT2SS_MCS5:
2605 case DESC_RATEVHT2SS_MCS9:
2609 RT_ASSERT(true, "Rate_Section is Illegal\n");
2613 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2614 [tx_num][rate_section] >> shift) & 0xff;
2616 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2617 if (rtlpriv->efuse.eeprom_regulatory != 2) {
2618 limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2619 rtlphy->current_chan_bw, path, rate,
2620 rtlphy->current_channel);
2622 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2623 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2625 if (tx_pwr_diff < (-limit))
2626 tx_pwr_diff = -limit;
2630 tx_pwr_diff = limit;
2632 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2634 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2635 "Maximum power by rate %d, final power by rate %d\n",
2636 limit, tx_pwr_diff);
2642 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2643 u8 rate, u8 bandwidth, u8 channel)
2645 struct rtl_priv *rtlpriv = rtl_priv(hw);
2646 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2647 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2648 u8 index = (channel - 1);
2650 bool in_24g = false;
2651 char powerdiff_byrate = 0;
2653 if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2654 (channel > 14 || channel < 1)) ||
2655 ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2657 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2658 "Illegal channel!!\n");
2661 in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2663 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2664 txpower = rtlefuse->txpwrlevel_cck[path][index];
2665 else if (DESC_RATE6M <= rate)
2666 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2668 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2670 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2671 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2672 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2674 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2675 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2676 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2677 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2678 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2679 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2680 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2681 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2682 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2683 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2684 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2685 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2686 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2687 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2688 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2689 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2690 (DESC_RATEVHT1SS_MCS0 <= rate &&
2691 rate <= DESC_RATEVHT2SS_MCS9))
2692 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2693 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2694 (DESC_RATEVHT2SS_MCS0 <= rate &&
2695 rate <= DESC_RATEVHT2SS_MCS9))
2696 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2699 if (DESC_RATE6M <= rate)
2700 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2702 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2705 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2706 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2707 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2709 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2710 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2711 (DESC_RATEVHT1SS_MCS0 <= rate &&
2712 rate <= DESC_RATEVHT2SS_MCS9))
2713 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2714 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2715 (DESC_RATEVHT2SS_MCS0 <= rate &&
2716 rate <= DESC_RATEVHT2SS_MCS9))
2717 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2718 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2719 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2720 (DESC_RATEVHT1SS_MCS0 <= rate &&
2721 rate <= DESC_RATEVHT2SS_MCS9))
2722 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2723 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2724 (DESC_RATEVHT2SS_MCS0 <= rate &&
2725 rate <= DESC_RATEVHT2SS_MCS9))
2726 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2727 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2728 u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2729 42, 58, 106, 122, 138, 155, 171
2733 for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i)
2734 if (channel_5g_80m[i] == channel)
2737 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2738 (DESC_RATEVHT1SS_MCS0 <= rate &&
2739 rate <= DESC_RATEVHT2SS_MCS9))
2740 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2741 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2742 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2743 (DESC_RATEVHT2SS_MCS0 <= rate &&
2744 rate <= DESC_RATEVHT2SS_MCS9))
2745 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2746 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2747 + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2750 if (rtlefuse->eeprom_regulatory != 2)
2752 _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2755 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2756 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2757 txpower -= powerdiff_byrate;
2759 txpower += powerdiff_byrate;
2761 if (rate > DESC_RATE11M)
2762 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2764 txpower += rtlpriv->dm.remnant_cck_idx;
2766 if (txpower > MAX_POWER_INDEX)
2767 txpower = MAX_POWER_INDEX;
2772 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2773 u8 power_index, u8 path, u8 rate)
2775 struct rtl_priv *rtlpriv = rtl_priv(hw);
2777 if (path == RF90_PATH_A) {
2780 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2781 MASKBYTE0, power_index);
2784 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2785 MASKBYTE1, power_index);
2788 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2789 MASKBYTE2, power_index);
2792 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2793 MASKBYTE3, power_index);
2796 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2797 MASKBYTE0, power_index);
2800 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2801 MASKBYTE1, power_index);
2804 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2805 MASKBYTE2, power_index);
2808 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2809 MASKBYTE3, power_index);
2812 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2813 MASKBYTE0, power_index);
2816 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2817 MASKBYTE1, power_index);
2820 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2821 MASKBYTE2, power_index);
2824 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2825 MASKBYTE3, power_index);
2828 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2829 MASKBYTE0, power_index);
2832 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2833 MASKBYTE1, power_index);
2836 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2837 MASKBYTE2, power_index);
2840 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2841 MASKBYTE3, power_index);
2844 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2845 MASKBYTE0, power_index);
2848 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2849 MASKBYTE1, power_index);
2852 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2853 MASKBYTE2, power_index);
2856 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2857 MASKBYTE3, power_index);
2860 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2861 MASKBYTE0, power_index);
2864 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2865 MASKBYTE1, power_index);
2867 case DESC_RATEMCS10:
2868 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2869 MASKBYTE2, power_index);
2871 case DESC_RATEMCS11:
2872 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2873 MASKBYTE3, power_index);
2875 case DESC_RATEMCS12:
2876 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2877 MASKBYTE0, power_index);
2879 case DESC_RATEMCS13:
2880 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2881 MASKBYTE1, power_index);
2883 case DESC_RATEMCS14:
2884 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2885 MASKBYTE2, power_index);
2887 case DESC_RATEMCS15:
2888 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2889 MASKBYTE3, power_index);
2891 case DESC_RATEVHT1SS_MCS0:
2892 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2893 MASKBYTE0, power_index);
2895 case DESC_RATEVHT1SS_MCS1:
2896 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2897 MASKBYTE1, power_index);
2899 case DESC_RATEVHT1SS_MCS2:
2900 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2901 MASKBYTE2, power_index);
2903 case DESC_RATEVHT1SS_MCS3:
2904 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2905 MASKBYTE3, power_index);
2907 case DESC_RATEVHT1SS_MCS4:
2908 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2909 MASKBYTE0, power_index);
2911 case DESC_RATEVHT1SS_MCS5:
2912 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2913 MASKBYTE1, power_index);
2915 case DESC_RATEVHT1SS_MCS6:
2916 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2917 MASKBYTE2, power_index);
2919 case DESC_RATEVHT1SS_MCS7:
2920 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2921 MASKBYTE3, power_index);
2923 case DESC_RATEVHT1SS_MCS8:
2924 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2925 MASKBYTE0, power_index);
2927 case DESC_RATEVHT1SS_MCS9:
2928 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2929 MASKBYTE1, power_index);
2931 case DESC_RATEVHT2SS_MCS0:
2932 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2933 MASKBYTE2, power_index);
2935 case DESC_RATEVHT2SS_MCS1:
2936 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2937 MASKBYTE3, power_index);
2939 case DESC_RATEVHT2SS_MCS2:
2940 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2941 MASKBYTE0, power_index);
2943 case DESC_RATEVHT2SS_MCS3:
2944 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2945 MASKBYTE1, power_index);
2947 case DESC_RATEVHT2SS_MCS4:
2948 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2949 MASKBYTE2, power_index);
2951 case DESC_RATEVHT2SS_MCS5:
2952 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2953 MASKBYTE3, power_index);
2955 case DESC_RATEVHT2SS_MCS6:
2956 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2957 MASKBYTE0, power_index);
2959 case DESC_RATEVHT2SS_MCS7:
2960 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2961 MASKBYTE1, power_index);
2963 case DESC_RATEVHT2SS_MCS8:
2964 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2965 MASKBYTE2, power_index);
2967 case DESC_RATEVHT2SS_MCS9:
2968 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2969 MASKBYTE3, power_index);
2972 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2973 "Invalid Rate!!\n");
2976 } else if (path == RF90_PATH_B) {
2979 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2980 MASKBYTE0, power_index);
2983 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2984 MASKBYTE1, power_index);
2987 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2988 MASKBYTE2, power_index);
2991 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2992 MASKBYTE3, power_index);
2995 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2996 MASKBYTE0, power_index);
2999 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3000 MASKBYTE1, power_index);
3003 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3004 MASKBYTE2, power_index);
3007 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3008 MASKBYTE3, power_index);
3011 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3012 MASKBYTE0, power_index);
3015 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3016 MASKBYTE1, power_index);
3019 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3020 MASKBYTE2, power_index);
3023 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3024 MASKBYTE3, power_index);
3027 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3028 MASKBYTE0, power_index);
3031 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3032 MASKBYTE1, power_index);
3035 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3036 MASKBYTE2, power_index);
3039 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3040 MASKBYTE3, power_index);
3043 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3044 MASKBYTE0, power_index);
3047 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3048 MASKBYTE1, power_index);
3051 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3052 MASKBYTE2, power_index);
3055 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3056 MASKBYTE3, power_index);
3059 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3060 MASKBYTE0, power_index);
3063 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3064 MASKBYTE1, power_index);
3066 case DESC_RATEMCS10:
3067 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3068 MASKBYTE2, power_index);
3070 case DESC_RATEMCS11:
3071 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3072 MASKBYTE3, power_index);
3074 case DESC_RATEMCS12:
3075 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3076 MASKBYTE0, power_index);
3078 case DESC_RATEMCS13:
3079 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3080 MASKBYTE1, power_index);
3082 case DESC_RATEMCS14:
3083 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3084 MASKBYTE2, power_index);
3086 case DESC_RATEMCS15:
3087 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3088 MASKBYTE3, power_index);
3090 case DESC_RATEVHT1SS_MCS0:
3091 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3092 MASKBYTE0, power_index);
3094 case DESC_RATEVHT1SS_MCS1:
3095 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3096 MASKBYTE1, power_index);
3098 case DESC_RATEVHT1SS_MCS2:
3099 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3100 MASKBYTE2, power_index);
3102 case DESC_RATEVHT1SS_MCS3:
3103 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3104 MASKBYTE3, power_index);
3106 case DESC_RATEVHT1SS_MCS4:
3107 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3108 MASKBYTE0, power_index);
3110 case DESC_RATEVHT1SS_MCS5:
3111 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3112 MASKBYTE1, power_index);
3114 case DESC_RATEVHT1SS_MCS6:
3115 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3116 MASKBYTE2, power_index);
3118 case DESC_RATEVHT1SS_MCS7:
3119 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3120 MASKBYTE3, power_index);
3122 case DESC_RATEVHT1SS_MCS8:
3123 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3124 MASKBYTE0, power_index);
3126 case DESC_RATEVHT1SS_MCS9:
3127 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3128 MASKBYTE1, power_index);
3130 case DESC_RATEVHT2SS_MCS0:
3131 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3132 MASKBYTE2, power_index);
3134 case DESC_RATEVHT2SS_MCS1:
3135 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3136 MASKBYTE3, power_index);
3138 case DESC_RATEVHT2SS_MCS2:
3139 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3140 MASKBYTE0, power_index);
3142 case DESC_RATEVHT2SS_MCS3:
3143 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3144 MASKBYTE1, power_index);
3146 case DESC_RATEVHT2SS_MCS4:
3147 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3148 MASKBYTE2, power_index);
3150 case DESC_RATEVHT2SS_MCS5:
3151 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3152 MASKBYTE3, power_index);
3154 case DESC_RATEVHT2SS_MCS6:
3155 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3156 MASKBYTE0, power_index);
3158 case DESC_RATEVHT2SS_MCS7:
3159 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3160 MASKBYTE1, power_index);
3162 case DESC_RATEVHT2SS_MCS8:
3163 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3164 MASKBYTE2, power_index);
3166 case DESC_RATEVHT2SS_MCS9:
3167 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3168 MASKBYTE3, power_index);
3171 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3172 "Invalid Rate!!\n");
3176 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3177 "Invalid RFPath!!\n");
3181 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3183 u8 channel, u8 size)
3185 struct rtl_priv *rtlpriv = rtl_priv(hw);
3186 struct rtl_phy *rtlphy = &rtlpriv->phy;
3190 for (i = 0; i < size; i++) {
3192 _rtl8821ae_get_txpower_index(hw, path, array[i],
3193 rtlphy->current_chan_bw,
3195 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3200 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3201 u8 bw, u8 channel, u8 path)
3203 struct rtl_priv *rtlpriv = rtl_priv(hw);
3204 struct rtl_phy *rtlphy = &rtlpriv->phy;
3207 u32 power_level, data, offset;
3209 if (path >= rtlphy->num_total_rfpath)
3213 if (path == RF90_PATH_A) {
3215 _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3216 DESC_RATEMCS7, bw, channel);
3217 offset = RA_TXPWRTRAING;
3220 _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3221 DESC_RATEMCS7, bw, channel);
3222 offset = RB_TXPWRTRAING;
3225 for (i = 0; i < 3; i++) {
3227 power_level = power_level - 10;
3229 power_level = power_level - 8;
3231 power_level = power_level - 6;
3233 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3235 rtl_set_bbreg(hw, offset, 0xffffff, data);
3238 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3239 u8 channel, u8 path)
3241 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3242 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3243 struct rtl_priv *rtlpriv = rtl_priv(hw);
3244 struct rtl_phy *rtlphy = &rtlpriv->phy;
3245 u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3247 u8 sizes_of_cck_retes = 4;
3248 u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3249 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3250 DESC_RATE48M, DESC_RATE54M};
3251 u8 sizes_of_ofdm_retes = 8;
3252 u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3253 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3254 DESC_RATEMCS6, DESC_RATEMCS7};
3255 u8 sizes_of_ht_retes_1t = 8;
3256 u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9,
3257 DESC_RATEMCS10, DESC_RATEMCS11,
3258 DESC_RATEMCS12, DESC_RATEMCS13,
3259 DESC_RATEMCS14, DESC_RATEMCS15};
3260 u8 sizes_of_ht_retes_2t = 8;
3261 u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3262 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3263 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3264 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3265 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3266 u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3267 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3268 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3269 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3270 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3271 u8 sizes_of_vht_retes = 10;
3273 if (rtlhal->current_bandtype == BAND_ON_2_4G)
3274 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3275 sizes_of_cck_retes);
3277 _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3278 sizes_of_ofdm_retes);
3279 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3280 sizes_of_ht_retes_1t);
3281 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3282 sizes_of_vht_retes);
3284 if (rtlphy->num_total_rfpath >= 2) {
3285 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3287 sizes_of_ht_retes_2t);
3288 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3290 sizes_of_vht_retes);
3293 _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3297 /*just in case, write txpower in DW, to reduce time*/
3298 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3300 struct rtl_priv *rtlpriv = rtl_priv(hw);
3301 struct rtl_phy *rtlphy = &rtlpriv->phy;
3304 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3305 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3308 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3309 enum wireless_mode wirelessmode,
3315 switch (wirelessmode) {
3316 case WIRELESS_MODE_B:
3319 case WIRELESS_MODE_G:
3320 case WIRELESS_MODE_N_24G:
3327 pwrout_dbm = txpwridx / 2 + offset;
3331 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3333 struct rtl_priv *rtlpriv = rtl_priv(hw);
3334 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3335 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3337 if (!is_hal_stop(rtlhal)) {
3338 switch (operation) {
3339 case SCAN_OPT_BACKUP_BAND0:
3340 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3341 rtlpriv->cfg->ops->set_hw_reg(hw,
3346 case SCAN_OPT_BACKUP_BAND1:
3347 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3348 rtlpriv->cfg->ops->set_hw_reg(hw,
3353 case SCAN_OPT_RESTORE:
3354 iotype = IO_CMD_RESUME_DM_BY_SCAN;
3355 rtlpriv->cfg->ops->set_hw_reg(hw,
3360 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3361 "Unknown Scan Backup operation.\n");
3367 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3369 u16 reg_rf_mode_bw, tmp = 0;
3371 reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3373 case HT_CHANNEL_WIDTH_20:
3374 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3376 case HT_CHANNEL_WIDTH_20_40:
3377 tmp = reg_rf_mode_bw | BIT(7);
3378 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3380 case HT_CHANNEL_WIDTH_80:
3381 tmp = reg_rf_mode_bw | BIT(8);
3382 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3385 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3390 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3392 struct rtl_phy *rtlphy = &rtlpriv->phy;
3393 struct rtl_mac *mac = rtl_mac(rtlpriv);
3394 u8 sc_set_40 = 0, sc_set_20 = 0;
3396 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3397 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3398 sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3399 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3400 sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3402 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3403 "SCMapping: Not Correct Primary40MHz Setting\n");
3405 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3406 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3407 sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3408 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3409 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3410 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3411 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3412 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3413 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3414 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3415 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3416 sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3418 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3419 "SCMapping: Not Correct Primary40MHz Setting\n");
3420 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3421 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3422 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3423 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3424 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3426 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3427 "SCMapping: Not Correct Primary40MHz Setting\n");
3429 return (sc_set_40 << 4) | sc_set_20;
3432 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3434 struct rtl_priv *rtlpriv = rtl_priv(hw);
3435 struct rtl_phy *rtlphy = &rtlpriv->phy;
3439 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3440 "Switch to %s bandwidth\n",
3441 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3443 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3444 "40MHz" : "80MHz")));
3446 _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3447 sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3448 rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3450 switch (rtlphy->current_chan_bw) {
3451 case HT_CHANNEL_WIDTH_20:
3452 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3453 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3455 if (rtlphy->rf_type == RF_2T2R)
3456 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3458 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3460 case HT_CHANNEL_WIDTH_20_40:
3461 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3462 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3463 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3464 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3466 if (rtlphy->reg_837 & BIT(2))
3469 if (rtlphy->rf_type == RF_2T2R)
3474 /* 0x848[25:22] = 0x6 */
3475 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3477 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3478 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3480 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3483 case HT_CHANNEL_WIDTH_80:
3484 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3485 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3487 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3488 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3489 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3491 if (rtlphy->reg_837 & BIT(2))
3494 if (rtlphy->rf_type == RF_2T2R)
3499 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3503 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3504 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3508 rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3510 rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3511 rtlphy->set_bwmode_inprogress = false;
3513 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3516 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3517 enum nl80211_channel_type ch_type)
3519 struct rtl_priv *rtlpriv = rtl_priv(hw);
3520 struct rtl_phy *rtlphy = &rtlpriv->phy;
3521 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3522 u8 tmp_bw = rtlphy->current_chan_bw;
3524 if (rtlphy->set_bwmode_inprogress)
3526 rtlphy->set_bwmode_inprogress = true;
3527 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3528 rtl8821ae_phy_set_bw_mode_callback(hw);
3530 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3531 "FALSE driver sleep or unload\n");
3532 rtlphy->set_bwmode_inprogress = false;
3533 rtlphy->current_chan_bw = tmp_bw;
3537 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3539 struct rtl_priv *rtlpriv = rtl_priv(hw);
3540 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3541 struct rtl_phy *rtlphy = &rtlpriv->phy;
3542 u8 channel = rtlphy->current_channel;
3546 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3547 "switch to channel%d\n", rtlphy->current_channel);
3548 if (is_hal_stop(rtlhal))
3551 if (36 <= channel && channel <= 48)
3553 else if (50 <= channel && channel <= 64)
3555 else if (100 <= channel && channel <= 116)
3557 else if (118 <= channel)
3561 rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3563 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3564 if (36 <= channel && channel <= 64)
3566 else if (100 <= channel && channel <= 140)
3568 else if (140 < channel)
3572 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3573 BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3575 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3576 BMASKBYTE0, channel);
3579 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3580 if (36 <= channel && channel <= 64)
3582 else if (100 <= channel && channel <= 140)
3586 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3587 BRFREGOFFSETMASK, data);
3591 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3594 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3596 struct rtl_priv *rtlpriv = rtl_priv(hw);
3597 struct rtl_phy *rtlphy = &rtlpriv->phy;
3598 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3599 u32 timeout = 1000, timecount = 0;
3600 u8 channel = rtlphy->current_channel;
3602 if (rtlphy->sw_chnl_inprogress)
3604 if (rtlphy->set_bwmode_inprogress)
3607 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3608 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3609 "sw_chnl_inprogress false driver sleep or unload\n");
3612 while (rtlphy->lck_inprogress && timecount < timeout) {
3617 if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3618 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3619 else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3620 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3622 rtlphy->sw_chnl_inprogress = true;
3626 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3627 "switch to channel%d, band type is %d\n",
3628 rtlphy->current_channel, rtlhal->current_bandtype);
3630 rtl8821ae_phy_sw_chnl_callback(hw);
3632 rtl8821ae_dm_clear_txpower_tracking_state(hw);
3633 rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3635 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3636 rtlphy->sw_chnl_inprogress = false;
3640 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3642 u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3643 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3644 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3645 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3646 110, 112, 114, 116, 118, 120, 122, 124, 126,
3647 128, 130, 132, 134, 136, 138, 140, 149, 151,
3648 153, 155, 157, 159, 161, 163, 165};
3652 for (place = 14; place < sizeof(channel_all); place++)
3653 if (channel_all[place] == chnl)
3660 #define MACBB_REG_NUM 10
3661 #define AFE_REG_NUM 14
3662 #define RF_REG_NUM 3
3664 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3666 u32 *backup_macbb_reg, u32 mac_bb_num)
3668 struct rtl_priv *rtlpriv = rtl_priv(hw);
3671 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3672 /*save MACBB default value*/
3673 for (i = 0; i < mac_bb_num; i++)
3674 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3676 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3679 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3680 u32 *backup_afe_REG, u32 afe_num)
3682 struct rtl_priv *rtlpriv = rtl_priv(hw);
3685 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3686 /*Save AFE Parameters */
3687 for (i = 0; i < afe_num; i++)
3688 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3689 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3692 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3693 u32 *rfb_backup, u32 *backup_rf_reg,
3696 struct rtl_priv *rtlpriv = rtl_priv(hw);
3699 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3700 /*Save RF Parameters*/
3701 for (i = 0; i < rf_num; i++) {
3702 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3704 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3707 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3710 static void _rtl8821ae_iqk_configure_mac(
3711 struct ieee80211_hw *hw
3714 struct rtl_priv *rtlpriv = rtl_priv(hw);
3715 /* ========MAC register setting========*/
3716 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3717 rtl_write_byte(rtlpriv, 0x522, 0x3f);
3718 rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3719 rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/
3720 rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/
3723 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3724 enum radio_path path, u32 tx_x, u32 tx_y)
3726 struct rtl_priv *rtlpriv = rtl_priv(hw);
3729 /* [31] = 1 --> Page C1 */
3730 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3731 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3732 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3733 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3734 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3735 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3736 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3737 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3739 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3740 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3741 rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3742 rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3749 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3750 enum radio_path path, u32 rx_x, u32 rx_y)
3752 struct rtl_priv *rtlpriv = rtl_priv(hw);
3755 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3756 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3757 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3758 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3759 "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3761 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3762 "0xc10 = %x ====>fill to IQC\n",
3763 rtl_read_dword(rtlpriv, 0xc10));
3772 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3774 struct rtl_priv *rtlpriv = rtl_priv(hw);
3775 struct rtl_phy *rtlphy = &rtlpriv->phy;
3776 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3778 u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3779 int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3780 int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3781 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3782 bool tx0iqkok = false, rx0iqkok = false;
3783 bool vdf_enable = false;
3784 int i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3785 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3787 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3788 "BandWidth = %d.\n",
3789 rtlphy->current_chan_bw);
3790 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3793 while (cal < cal_num) {
3796 temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3798 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3799 /*========Path-A AFE all on========*/
3800 /*Port 0 DAC/ADC on*/
3801 rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3802 rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3803 rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3804 rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3805 rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3806 rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3807 rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3808 rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3809 rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3810 rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3812 rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3815 /* ====== LOK ====== */
3816 /*DAC/ADC sampling rate (160 MHz)*/
3817 rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3819 /* 2. LoK RF Setting (at BW = 20M) */
3820 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3821 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */
3822 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3823 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3824 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3825 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3826 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3827 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3828 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3829 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3830 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3831 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3832 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3833 rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3835 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3836 rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3838 if (rtlhal->current_bandtype)
3839 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3841 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3843 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3844 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3845 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3846 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3847 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3849 mdelay(10); /* Delay 10ms */
3850 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3852 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3853 rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3855 switch (rtlphy->current_chan_bw) {
3857 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3860 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3866 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3868 /* 3. TX RF Setting */
3869 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3870 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3871 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3872 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3873 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3874 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3875 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3876 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3877 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3878 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3879 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3880 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3881 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3882 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3883 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3885 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3886 rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3887 if (rtlhal->current_bandtype)
3888 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3890 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3892 if (vdf_enable == 1) {
3893 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3894 for (k = 0; k <= 2; k++) {
3897 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3898 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3899 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3902 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3903 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3904 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3907 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3908 "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3909 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3910 "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3911 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3912 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3913 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3914 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3915 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3916 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3917 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3922 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3926 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3927 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3929 mdelay(10); /* Delay 10ms */
3930 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3933 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3934 if ((~iqk_ready) || (delay_count > 20))
3942 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3943 /* ============TXIQK Check============== */
3944 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3947 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3948 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3949 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3950 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3954 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3955 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3958 if (cal_retry == 10)
3964 if (cal_retry == 10)
3970 tx_x0[cal] = vdf_x[k-1];
3971 tx_y0[cal] = vdf_y[k-1];
3974 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3975 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3976 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3980 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3981 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3983 mdelay(10); /* Delay 10ms */
3984 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3987 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3988 if ((~iqk_ready) || (delay_count > 20))
3996 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3997 /* ============TXIQK Check============== */
3998 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4001 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4002 tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4003 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4004 tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4008 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4009 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4012 if (cal_retry == 10)
4018 if (cal_retry == 10)
4024 if (tx0iqkok == false)
4025 break; /* TXK fail, Don't do RXK */
4027 if (vdf_enable == 1) {
4028 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */
4029 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4030 for (k = 0; k <= 2; k++) {
4031 /* ====== RX mode TXK (RXK Step 1) ====== */
4032 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4033 /* 1. TX RF Setting */
4034 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4035 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4036 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4037 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4038 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4039 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4040 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4042 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4043 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4044 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4045 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4046 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4047 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4048 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4052 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4053 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4054 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4059 rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4060 rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4061 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4066 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4067 "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4068 vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4069 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4070 "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4071 vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4072 rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4073 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4074 rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4075 rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4076 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4077 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4078 rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4084 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4085 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4086 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4090 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4091 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4093 mdelay(10); /* Delay 10ms */
4094 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4097 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4098 if ((~iqk_ready) || (delay_count > 20))
4106 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4107 /* ============TXIQK Check============== */
4108 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4111 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4112 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4113 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4114 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4120 if (cal_retry == 10)
4126 if (cal_retry == 10)
4131 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4132 tx_x0_rxk[cal] = tx_x0[cal];
4133 tx_y0_rxk[cal] = tx_y0[cal];
4138 "RXK Step 1 fail\n");
4141 /* ====== RX IQK ====== */
4142 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4143 /* 1. RX RF Setting */
4144 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4145 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4146 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4147 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4148 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4149 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4150 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4152 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4153 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4154 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4155 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4156 rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4157 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4158 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4160 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4161 rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4162 rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4163 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4165 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4168 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */
4169 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4174 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4175 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4177 mdelay(10); /* Delay 10ms */
4178 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4181 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4182 if ((~iqk_ready) || (delay_count > 20))
4190 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4191 /* ============RXIQK Check============== */
4192 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4194 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4195 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4196 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4197 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4201 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4202 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4205 if (cal_retry == 10)
4212 if (cal_retry == 10)
4219 rx_x0[cal] = vdf_x[k-1];
4220 rx_y0[cal] = vdf_y[k-1];
4222 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */
4226 /* ====== RX mode TXK (RXK Step 1) ====== */
4227 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4228 /* 1. TX RF Setting */
4229 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4230 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4231 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4232 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4233 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4234 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4235 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4236 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4237 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4238 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4240 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4241 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4242 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4243 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4244 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4245 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4249 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4250 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4252 mdelay(10); /* Delay 10ms */
4253 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4256 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4257 if ((~iqk_ready) || (delay_count > 20))
4265 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4266 /* ============TXIQK Check============== */
4267 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4270 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4271 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4272 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4273 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4279 if (cal_retry == 10)
4285 if (cal_retry == 10)
4290 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4291 tx_x0_rxk[cal] = tx_x0[cal];
4292 tx_y0_rxk[cal] = tx_y0[cal];
4294 RT_TRACE(rtlpriv, COMP_IQK,
4298 /* ====== RX IQK ====== */
4299 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4300 /* 1. RX RF Setting */
4301 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4302 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4303 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4304 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4305 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4306 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4307 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4309 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4310 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4311 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4312 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4313 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4314 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4315 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4317 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4318 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4319 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4320 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4322 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4324 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4329 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4330 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4332 mdelay(10); /* Delay 10ms */
4333 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4336 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4337 if ((~iqk_ready) || (delay_count > 20))
4345 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4346 /* ============RXIQK Check============== */
4347 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4349 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4350 rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4351 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4352 rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4356 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4357 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4360 if (cal_retry == 10)
4367 if (cal_retry == 10)
4377 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4378 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4386 /* FillIQK Result */
4389 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4390 "========Path_A =======\n");
4391 if (tx_average == 0)
4394 for (i = 0; i < tx_average; i++) {
4395 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4396 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4397 (tx_x0_rxk[i])>>21&0x000007ff, i,
4398 (tx_y0_rxk[i])>>21&0x000007ff);
4399 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4400 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4401 (tx_x0[i])>>21&0x000007ff, i,
4402 (tx_y0[i])>>21&0x000007ff);
4404 for (i = 0; i < tx_average; i++) {
4405 for (ii = i+1; ii < tx_average; ii++) {
4406 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4407 if (dx < 3 && dx > -3) {
4408 dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4409 if (dy < 3 && dy > -3) {
4410 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4411 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4422 _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4424 _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4426 if (rx_average == 0)
4429 for (i = 0; i < rx_average; i++)
4430 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4431 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4432 (rx_x0[i])>>21&0x000007ff, i,
4433 (rx_y0[i])>>21&0x000007ff);
4434 for (i = 0; i < rx_average; i++) {
4435 for (ii = i+1; ii < rx_average; ii++) {
4436 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4437 if (dx < 4 && dx > -4) {
4438 dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4439 if (dy < 4 && dy > -4) {
4440 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4441 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4452 _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4454 _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4461 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4462 enum radio_path path,
4464 u32 *rf_backup, u32 rf_reg_num)
4466 struct rtl_priv *rtlpriv = rtl_priv(hw);
4469 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4470 for (i = 0; i < RF_REG_NUM; i++)
4471 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4476 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4477 "RestoreRF Path A Success!!!!\n");
4484 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4485 u32 *afe_backup, u32 *backup_afe_reg,
4489 struct rtl_priv *rtlpriv = rtl_priv(hw);
4491 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4492 /* Reload AFE Parameters */
4493 for (i = 0; i < afe_num; i++)
4494 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4495 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4496 rtl_write_dword(rtlpriv, 0xc80, 0x0);
4497 rtl_write_dword(rtlpriv, 0xc84, 0x0);
4498 rtl_write_dword(rtlpriv, 0xc88, 0x0);
4499 rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4500 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4501 rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4502 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4503 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4504 rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4505 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4508 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4510 u32 *backup_macbb_reg,
4514 struct rtl_priv *rtlpriv = rtl_priv(hw);
4516 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4517 /* Reload MacBB Parameters */
4518 for (i = 0; i < macbb_num; i++)
4519 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4520 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4523 #undef MACBB_REG_NUM
4527 #define MACBB_REG_NUM 11
4528 #define AFE_REG_NUM 12
4529 #define RF_REG_NUM 3
4531 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4533 u32 macbb_backup[MACBB_REG_NUM];
4534 u32 afe_backup[AFE_REG_NUM];
4535 u32 rfa_backup[RF_REG_NUM];
4536 u32 rfb_backup[RF_REG_NUM];
4537 u32 backup_macbb_reg[MACBB_REG_NUM] = {
4538 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4539 0xe00, 0xe50, 0x838, 0x82c
4541 u32 backup_afe_reg[AFE_REG_NUM] = {
4542 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4543 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4545 u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4547 _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4549 _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4550 _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4553 _rtl8821ae_iqk_configure_mac(hw);
4554 _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4555 _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4558 _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4559 _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4563 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4565 struct rtl_priv *rtlpriv = rtl_priv(hw);
4566 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4567 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4568 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4571 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4573 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4576 #undef IQK_ADDA_REG_NUM
4577 #undef IQK_DELAY_TIME
4579 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4583 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4584 u8 thermal_value, u8 threshold)
4586 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4588 rtldm->thermalvalue_iqk = thermal_value;
4589 rtl8812ae_phy_iq_calibrate(hw, false);
4592 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4594 struct rtl_priv *rtlpriv = rtl_priv(hw);
4595 struct rtl_phy *rtlphy = &rtlpriv->phy;
4597 if (!rtlphy->lck_inprogress) {
4598 spin_lock(&rtlpriv->locks.iqk_lock);
4599 rtlphy->lck_inprogress = true;
4600 spin_unlock(&rtlpriv->locks.iqk_lock);
4602 _rtl8821ae_phy_iq_calibrate(hw);
4604 spin_lock(&rtlpriv->locks.iqk_lock);
4605 rtlphy->lck_inprogress = false;
4606 spin_unlock(&rtlpriv->locks.iqk_lock);
4610 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4612 struct rtl_priv *rtlpriv = rtl_priv(hw);
4613 struct rtl_phy *rtlphy = &rtlpriv->phy;
4616 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4617 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4618 (int)(sizeof(rtlphy->iqk_matrix) /
4619 sizeof(struct iqk_matrix_regs)),
4620 IQK_MATRIX_SETTINGS_NUM);
4622 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4623 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4624 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4625 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4626 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4628 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4629 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4630 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4631 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4633 rtlphy->iqk_matrix[i].iqk_done = false;
4637 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4638 u8 thermal_value, u8 threshold)
4640 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4642 rtl8821ae_reset_iqk_result(hw);
4644 rtldm->thermalvalue_iqk = thermal_value;
4645 rtl8821ae_phy_iq_calibrate(hw, false);
4648 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4652 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
4656 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4658 _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4661 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4663 struct rtl_priv *rtlpriv = rtl_priv(hw);
4664 struct rtl_phy *rtlphy = &rtlpriv->phy;
4665 bool postprocessing = false;
4667 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4668 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4669 iotype, rtlphy->set_io_inprogress);
4672 case IO_CMD_RESUME_DM_BY_SCAN:
4673 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4674 "[IO CMD] Resume DM after scan.\n");
4675 postprocessing = true;
4677 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4678 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4679 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4680 "[IO CMD] Pause DM before scan.\n");
4681 postprocessing = true;
4684 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4685 "switch case not process\n");
4689 if (postprocessing && !rtlphy->set_io_inprogress) {
4690 rtlphy->set_io_inprogress = true;
4691 rtlphy->current_io_type = iotype;
4695 rtl8821ae_phy_set_io(hw);
4696 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4700 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4702 struct rtl_priv *rtlpriv = rtl_priv(hw);
4703 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4704 struct rtl_phy *rtlphy = &rtlpriv->phy;
4706 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4707 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4708 rtlphy->current_io_type, rtlphy->set_io_inprogress);
4709 switch (rtlphy->current_io_type) {
4710 case IO_CMD_RESUME_DM_BY_SCAN:
4711 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4712 _rtl8821ae_resume_tx_beacon(hw);
4713 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4714 rtl8821ae_dm_write_cck_cca_thres(hw,
4715 rtlphy->initgain_backup.cca);
4717 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4718 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4719 _rtl8821ae_stop_tx_beacon(hw);
4720 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4721 rtl8821ae_dm_write_dig(hw, 0x17);
4722 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4723 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4725 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4728 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4729 "switch case not process\n");
4732 rtlphy->set_io_inprogress = false;
4733 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4734 "(%#x)\n", rtlphy->current_io_type);
4737 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4739 struct rtl_priv *rtlpriv = rtl_priv(hw);
4741 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4742 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4743 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4744 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4745 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4748 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4749 enum rf_pwrstate rfpwr_state)
4751 struct rtl_priv *rtlpriv = rtl_priv(hw);
4752 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4753 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4754 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4755 bool bresult = true;
4757 struct rtl8192_tx_ring *ring = NULL;
4759 switch (rfpwr_state) {
4761 if ((ppsc->rfpwr_state == ERFOFF) &&
4762 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4763 bool rtstatus = false;
4764 u32 initializecount = 0;
4768 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4769 "IPS Set eRf nic enable\n");
4770 rtstatus = rtl_ps_enable_nic(hw);
4771 } while (!rtstatus && (initializecount < 10));
4772 RT_CLEAR_PS_LEVEL(ppsc,
4773 RT_RF_OFF_LEVL_HALT_NIC);
4775 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4776 "Set ERFON sleeped:%d ms\n",
4777 jiffies_to_msecs(jiffies -
4779 last_sleep_jiffies));
4780 ppsc->last_awake_jiffies = jiffies;
4781 rtl8821ae_phy_set_rf_on(hw);
4783 if (mac->link_state == MAC80211_LINKED) {
4784 rtlpriv->cfg->ops->led_control(hw,
4787 rtlpriv->cfg->ops->led_control(hw,
4792 for (queue_id = 0, i = 0;
4793 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4794 ring = &pcipriv->dev.tx_ring[queue_id];
4795 if (queue_id == BEACON_QUEUE ||
4796 skb_queue_len(&ring->queue) == 0) {
4800 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4801 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4803 skb_queue_len(&ring->queue));
4808 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4809 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4810 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4811 MAX_DOZE_WAITING_TIMES_9x,
4813 skb_queue_len(&ring->queue));
4818 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4819 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4820 "IPS Set eRf nic disable\n");
4821 rtl_ps_disable_nic(hw);
4822 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4824 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4825 rtlpriv->cfg->ops->led_control(hw,
4828 rtlpriv->cfg->ops->led_control(hw,
4834 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4835 "switch case not process\n");
4840 ppsc->rfpwr_state = rfpwr_state;
4844 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4845 enum rf_pwrstate rfpwr_state)
4847 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4849 bool bresult = false;
4851 if (rfpwr_state == ppsc->rfpwr_state)
4853 bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);