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 static void _rtl8812ae_phy_set_rfe_reg_24g(struct ieee80211_hw *hw)
364 struct rtl_priv *rtlpriv = rtl_priv(hw);
365 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
368 switch (rtlhal->rfe_type) {
370 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337770);
371 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337770);
372 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
373 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
374 rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1);
377 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
378 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
379 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x001);
380 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x001);
383 rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x77);
384 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
385 tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3);
386 rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp & ~0x1);
387 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
390 if (rtlpriv->btcoexist.bt_coexistence) {
391 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x777777);
392 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
394 rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000);
395 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
401 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
402 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
403 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
404 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
409 static void _rtl8812ae_phy_set_rfe_reg_5g(struct ieee80211_hw *hw)
411 struct rtl_priv *rtlpriv = rtl_priv(hw);
412 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
415 switch (rtlhal->rfe_type) {
417 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337717);
418 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337717);
419 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
420 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
423 if (rtlpriv->btcoexist.bt_coexistence) {
424 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x337717);
425 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
427 rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000);
428 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
430 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
432 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
434 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
435 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
439 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337717);
440 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337717);
441 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
442 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
443 rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1);
446 rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x33);
447 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
448 tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3);
449 rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp | 0x1);
450 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
455 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337777);
456 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
457 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
458 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
463 u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band,
466 struct rtl_priv *rtlpriv = rtl_priv(hw);
467 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
468 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
469 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
470 char reg_swing_2g = -1;/* 0xff; */
471 char reg_swing_5g = -1;/* 0xff; */
472 char swing_2g = -1 * reg_swing_2g;
473 char swing_5g = -1 * reg_swing_5g;
475 const char auto_temp = -1;
477 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
478 "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
479 (int)swing_2g, (int)swing_5g,
480 (int)rtlefuse->autoload_failflag);
482 if (rtlefuse->autoload_failflag) {
483 if (band == BAND_ON_2_4G) {
484 rtldm->swing_diff_2g = swing_2g;
486 out = 0x200; /* 0 dB */
487 } else if (swing_2g == -3) {
488 out = 0x16A; /* -3 dB */
489 } else if (swing_2g == -6) {
490 out = 0x101; /* -6 dB */
491 } else if (swing_2g == -9) {
492 out = 0x0B6; /* -9 dB */
494 rtldm->swing_diff_2g = 0;
497 } else if (band == BAND_ON_5G) {
498 rtldm->swing_diff_5g = swing_5g;
500 out = 0x200; /* 0 dB */
501 } else if (swing_5g == -3) {
502 out = 0x16A; /* -3 dB */
503 } else if (swing_5g == -6) {
504 out = 0x101; /* -6 dB */
505 } else if (swing_5g == -9) {
506 out = 0x0B6; /* -9 dB */
508 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
509 rtldm->swing_diff_5g = -3;
512 rtldm->swing_diff_5g = 0;
517 rtldm->swing_diff_2g = -3;
518 rtldm->swing_diff_5g = -3;
519 out = 0x16A; /* -3 dB */
522 u32 swing = 0, swing_a = 0, swing_b = 0;
524 if (band == BAND_ON_2_4G) {
525 if (reg_swing_2g == auto_temp) {
526 efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
527 swing = (swing == 0xFF) ? 0x00 : swing;
528 } else if (swing_2g == 0) {
529 swing = 0x00; /* 0 dB */
530 } else if (swing_2g == -3) {
531 swing = 0x05; /* -3 dB */
532 } else if (swing_2g == -6) {
533 swing = 0x0A; /* -6 dB */
534 } else if (swing_2g == -9) {
535 swing = 0xFF; /* -9 dB */
540 if (reg_swing_5g == auto_temp) {
541 efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
542 swing = (swing == 0xFF) ? 0x00 : swing;
543 } else if (swing_5g == 0) {
544 swing = 0x00; /* 0 dB */
545 } else if (swing_5g == -3) {
546 swing = 0x05; /* -3 dB */
547 } else if (swing_5g == -6) {
548 swing = 0x0A; /* -6 dB */
549 } else if (swing_5g == -9) {
550 swing = 0xFF; /* -9 dB */
556 swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
557 swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
558 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
559 "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
563 if (swing_a == 0x0) {
564 if (band == BAND_ON_2_4G)
565 rtldm->swing_diff_2g = 0;
567 rtldm->swing_diff_5g = 0;
568 out = 0x200; /* 0 dB */
569 } else if (swing_a == 0x1) {
570 if (band == BAND_ON_2_4G)
571 rtldm->swing_diff_2g = -3;
573 rtldm->swing_diff_5g = -3;
574 out = 0x16A; /* -3 dB */
575 } else if (swing_a == 0x2) {
576 if (band == BAND_ON_2_4G)
577 rtldm->swing_diff_2g = -6;
579 rtldm->swing_diff_5g = -6;
580 out = 0x101; /* -6 dB */
581 } else if (swing_a == 0x3) {
582 if (band == BAND_ON_2_4G)
583 rtldm->swing_diff_2g = -9;
585 rtldm->swing_diff_5g = -9;
586 out = 0x0B6; /* -9 dB */
589 if (swing_b == 0x0) {
590 if (band == BAND_ON_2_4G)
591 rtldm->swing_diff_2g = 0;
593 rtldm->swing_diff_5g = 0;
594 out = 0x200; /* 0 dB */
595 } else if (swing_b == 0x1) {
596 if (band == BAND_ON_2_4G)
597 rtldm->swing_diff_2g = -3;
599 rtldm->swing_diff_5g = -3;
600 out = 0x16A; /* -3 dB */
601 } else if (swing_b == 0x2) {
602 if (band == BAND_ON_2_4G)
603 rtldm->swing_diff_2g = -6;
605 rtldm->swing_diff_5g = -6;
606 out = 0x101; /* -6 dB */
607 } else if (swing_b == 0x3) {
608 if (band == BAND_ON_2_4G)
609 rtldm->swing_diff_2g = -9;
611 rtldm->swing_diff_5g = -9;
612 out = 0x0B6; /* -9 dB */
616 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
617 "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out);
621 void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
623 struct rtl_priv *rtlpriv = rtl_priv(hw);
624 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
625 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
626 u8 current_band = rtlhal->current_bandtype;
628 char bb_diff_between_band;
630 txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
631 rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
632 rtlhal->current_bandtype = (enum band_type) band;
633 /* reconfig BB/RF according to wireless mode */
634 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
636 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
638 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
639 /* 0xCB0[15:12] = 0x7 (LNA_On)*/
640 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
641 /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
642 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
645 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
647 rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
650 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
651 /* 0xC1C[11:8] = 0 */
652 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
654 /* 0x82C[1:0] = 2b'00 */
655 rtl_set_bbreg(hw, 0x82c, 0x3, 0);
658 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
659 _rtl8812ae_phy_set_rfe_reg_24g(hw);
661 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
662 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
664 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
665 } else {/* 5G band */
668 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
669 /*0xCB0[15:12] = 0x5 (LNA_On)*/
670 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
671 /*0xCB0[7:4] = 0x4 (PAPE_A)*/
672 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
675 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
678 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
679 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
680 "Reg41A value %d", reg_41a);
682 while ((reg_41a != 0x30) && (count < 50)) {
684 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
686 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
689 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
690 "Reg41A value %d", reg_41a);
693 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
694 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
697 /* 2012/02/01, Sinda add registry to switch workaround
698 without long-run verification for scan issue. */
699 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
701 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
703 rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
706 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
707 /* AGC table select */
709 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
711 /* 0x82C[1:0] = 2'b00 */
712 rtl_set_bbreg(hw, 0x82c, 0x3, 1);
714 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
715 _rtl8812ae_phy_set_rfe_reg_5g(hw);
717 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
718 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
720 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
721 "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
722 rtlpriv->dm.ofdm_index[RF90_PATH_A]);
725 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
726 (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
728 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
729 phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
731 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
732 phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
734 /* <20121005, Kordan> When TxPowerTrack is ON,
735 * we should take care of the change of BB swing.
736 * That is, reset all info to trigger Tx power tracking.
738 if (band != current_band) {
739 bb_diff_between_band =
740 (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
741 bb_diff_between_band = (band == BAND_ON_2_4G) ?
742 bb_diff_between_band :
743 (-1 * bb_diff_between_band);
744 rtldm->default_ofdm_index += bb_diff_between_band * 2;
746 rtl8821ae_dm_clear_txpower_tracking_state(hw);
749 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
750 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
754 static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
757 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
758 u32 _board = rtlefuse->board_type; /*need efuse define*/
759 u32 _interface = 0x01; /* ODM_ITRF_PCIE */
760 u32 _platform = 0x08;/* ODM_WIN */
761 u32 cond = condition;
763 if (condition == 0xCDCDCDCD)
766 cond = condition & 0xFF;
767 if ((_board != cond) && cond != 0xFF)
770 cond = condition & 0xFF00;
772 if ((_interface & cond) == 0 && cond != 0x07)
775 cond = condition & 0xFF0000;
777 if ((_platform & cond) == 0 && cond != 0x0F)
782 static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
784 enum radio_path rfpath, u32 regaddr)
786 if (addr == 0xfe || addr == 0xffe) {
787 /* In order not to disturb BT music when
788 * wifi init.(1ant NIC only)
792 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
797 static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
800 u32 content = 0x1000; /*RF Content: radio_a_txt*/
801 u32 maskforphyset = (u32)(content & 0xE000);
803 _rtl8821ae_config_rf_reg(hw, addr, data,
804 RF90_PATH_A, addr | maskforphyset);
807 static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
810 u32 content = 0x1001; /*RF Content: radio_b_txt*/
811 u32 maskforphyset = (u32)(content & 0xE000);
813 _rtl8821ae_config_rf_reg(hw, addr, data,
814 RF90_PATH_B, addr | maskforphyset);
817 static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
822 else if (addr == 0xfd)
824 else if (addr == 0xfc)
826 else if (addr == 0xfb)
828 else if (addr == 0xfa)
830 else if (addr == 0xf9)
833 rtl_set_bbreg(hw, addr, MASKDWORD, data);
838 static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
840 struct rtl_priv *rtlpriv = rtl_priv(hw);
841 struct rtl_phy *rtlphy = &rtlpriv->phy;
842 u8 band, rfpath, txnum, rate_section;
844 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
845 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
846 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
847 for (rate_section = 0;
848 rate_section < TX_PWR_BY_RATE_NUM_SECTION;
850 rtlphy->tx_power_by_rate_offset[band]
851 [rfpath][txnum][rate_section] = 0;
854 static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
859 struct rtl_priv *rtlpriv = rtl_priv(hw);
860 struct rtl_phy *rtlphy = &rtlpriv->phy;
862 if (path > RF90_PATH_D) {
863 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
864 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
868 if (band == BAND_ON_2_4G) {
869 switch (rate_section) {
871 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
874 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
877 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
880 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
882 case VHT_1SSMCS0_1SSMCS9:
883 rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
885 case VHT_2SSMCS0_2SSMCS9:
886 rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
889 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
890 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
891 rate_section, path, txnum);
894 } else if (band == BAND_ON_5G) {
895 switch (rate_section) {
897 rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
900 rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
903 rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
905 case VHT_1SSMCS0_1SSMCS9:
906 rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
908 case VHT_2SSMCS0_2SSMCS9:
909 rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
912 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
913 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
914 rate_section, path, txnum);
918 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
919 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
923 static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
925 u8 txnum, u8 rate_section)
927 struct rtl_priv *rtlpriv = rtl_priv(hw);
928 struct rtl_phy *rtlphy = &rtlpriv->phy;
931 if (path > RF90_PATH_D) {
932 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
933 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
938 if (band == BAND_ON_2_4G) {
939 switch (rate_section) {
941 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
944 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
947 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
950 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
952 case VHT_1SSMCS0_1SSMCS9:
953 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
955 case VHT_2SSMCS0_2SSMCS9:
956 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
959 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
960 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
961 rate_section, path, txnum);
964 } else if (band == BAND_ON_5G) {
965 switch (rate_section) {
967 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
970 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
973 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
975 case VHT_1SSMCS0_1SSMCS9:
976 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
978 case VHT_2SSMCS0_2SSMCS9:
979 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
982 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
983 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
984 rate_section, path, txnum);
988 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
989 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
995 static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
997 struct rtl_priv *rtlpriv = rtl_priv(hw);
998 struct rtl_phy *rtlphy = &rtlpriv->phy;
1000 u8 base = 0, path = 0;
1002 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
1003 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
1004 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1005 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
1007 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
1008 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1009 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
1011 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
1012 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1013 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
1015 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
1016 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1017 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
1019 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
1020 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1021 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1023 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
1024 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1025 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1027 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
1028 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1029 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
1031 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
1032 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1033 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
1035 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
1036 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1037 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
1039 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
1040 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1041 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1043 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
1044 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1045 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1049 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
1050 u8 end, u8 base_val)
1056 for (i = 3; i >= 0; --i) {
1057 if (i >= start && i <= end) {
1058 /* Get the exact value */
1059 temp_value = (u8)(*data >> (i * 8)) & 0xF;
1060 temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
1062 /* Change the value to a relative value */
1063 temp_value = (temp_value > base_val) ? temp_value -
1064 base_val : base_val - temp_value;
1066 temp_value = (u8)(*data >> (i * 8)) & 0xFF;
1069 temp_data |= temp_value;
1074 static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
1076 struct rtl_priv *rtlpriv = rtl_priv(hw);
1077 struct rtl_phy *rtlphy = &rtlpriv->phy;
1078 u8 regulation, bw, channel, rate_section;
1079 char temp_pwrlmt = 0;
1081 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1082 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
1083 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1084 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1085 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1086 [bw][rate_section][channel][RF90_PATH_A];
1087 if (temp_pwrlmt == MAX_POWER_INDEX) {
1088 if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
1089 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1090 "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1091 1, bw, rate_section, channel, RF90_PATH_A);
1092 if (rate_section == 2) {
1093 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1094 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1095 } else if (rate_section == 4) {
1096 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1097 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1098 } else if (rate_section == 3) {
1099 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1100 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1101 } else if (rate_section == 5) {
1102 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1103 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1106 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d", temp_pwrlmt);
1115 static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1116 enum band_type band, u8 rate)
1118 struct rtl_priv *rtlpriv = rtl_priv(hw);
1120 if (band == BAND_ON_2_4G) {
1163 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1164 "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1168 } else if (band == BAND_ON_5G) {
1203 case MGN_VHT1SS_MCS0:
1204 case MGN_VHT1SS_MCS1:
1205 case MGN_VHT1SS_MCS2:
1206 case MGN_VHT1SS_MCS3:
1207 case MGN_VHT1SS_MCS4:
1208 case MGN_VHT1SS_MCS5:
1209 case MGN_VHT1SS_MCS6:
1210 case MGN_VHT1SS_MCS7:
1211 case MGN_VHT1SS_MCS8:
1212 case MGN_VHT1SS_MCS9:
1216 case MGN_VHT2SS_MCS0:
1217 case MGN_VHT2SS_MCS1:
1218 case MGN_VHT2SS_MCS2:
1219 case MGN_VHT2SS_MCS3:
1220 case MGN_VHT2SS_MCS4:
1221 case MGN_VHT2SS_MCS5:
1222 case MGN_VHT2SS_MCS6:
1223 case MGN_VHT2SS_MCS7:
1224 case MGN_VHT2SS_MCS8:
1225 case MGN_VHT2SS_MCS9:
1230 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1231 "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1240 static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1242 struct rtl_priv *rtlpriv = rtl_priv(hw);
1243 struct rtl_phy *rtlphy = &rtlpriv->phy;
1244 u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1245 u8 regulation, bw, channel, rate_section;
1246 u8 base_index2_4G = 0;
1247 u8 base_index5G = 0;
1248 char temp_value = 0, temp_pwrlmt = 0;
1251 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1252 "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1254 _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1256 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1257 for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) {
1258 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1259 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1260 /* obtain the base dBm values in 2.4G band
1261 CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1262 if (rate_section == 0) { /*CCK*/
1264 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1265 BAND_ON_2_4G, MGN_11M);
1266 } else if (rate_section == 1) { /*OFDM*/
1268 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1269 BAND_ON_2_4G, MGN_54M);
1270 } else if (rate_section == 2) { /*HT IT*/
1272 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1273 BAND_ON_2_4G, MGN_MCS7);
1274 } else if (rate_section == 3) { /*HT 2T*/
1276 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1277 BAND_ON_2_4G, MGN_MCS15);
1280 temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1281 [bw][rate_section][channel][RF90_PATH_A];
1283 for (rf_path = RF90_PATH_A;
1284 rf_path < MAX_RF_PATH_NUM;
1286 if (rate_section == 3)
1287 bw40_pwr_base_dbm2_4G =
1288 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1290 bw40_pwr_base_dbm2_4G =
1291 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1293 if (temp_pwrlmt != MAX_POWER_INDEX) {
1294 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1295 rtlphy->txpwr_limit_2_4g[regulation]
1296 [bw][rate_section][channel][rf_path] =
1300 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1301 "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",
1302 regulation, bw, rate_section, channel,
1303 rtlphy->txpwr_limit_2_4g[regulation][bw]
1304 [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1305 ? 0 : temp_pwrlmt/2, channel, rf_path,
1306 bw40_pwr_base_dbm2_4G);
1312 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1313 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
1314 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1315 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1316 /* obtain the base dBm values in 5G band
1317 OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1318 VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1319 if (rate_section == 1) { /*OFDM*/
1321 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1322 BAND_ON_5G, MGN_54M);
1323 } else if (rate_section == 2) { /*HT 1T*/
1325 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1326 BAND_ON_5G, MGN_MCS7);
1327 } else if (rate_section == 3) { /*HT 2T*/
1329 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1330 BAND_ON_5G, MGN_MCS15);
1331 } else if (rate_section == 4) { /*VHT 1T*/
1333 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1334 BAND_ON_5G, MGN_VHT1SS_MCS7);
1335 } else if (rate_section == 5) { /*VHT 2T*/
1337 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1338 BAND_ON_5G, MGN_VHT2SS_MCS7);
1341 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1342 [bw][rate_section][channel]
1345 for (rf_path = RF90_PATH_A;
1346 rf_path < MAX_RF_PATH_NUM;
1348 if (rate_section == 3 || rate_section == 5)
1349 bw40_pwr_base_dbm5G =
1350 rtlphy->txpwr_by_rate_base_5g[rf_path]
1351 [RF_2TX][base_index5G];
1353 bw40_pwr_base_dbm5G =
1354 rtlphy->txpwr_by_rate_base_5g[rf_path]
1355 [RF_1TX][base_index5G];
1357 if (temp_pwrlmt != MAX_POWER_INDEX) {
1359 temp_pwrlmt - bw40_pwr_base_dbm5G;
1360 rtlphy->txpwr_limit_5g[regulation]
1361 [bw][rate_section][channel]
1362 [rf_path] = temp_value;
1365 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1366 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
1367 regulation, bw, rate_section,
1368 channel, rtlphy->txpwr_limit_5g[regulation]
1369 [bw][rate_section][channel][rf_path],
1370 temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1376 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1377 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1380 static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1382 struct rtl_priv *rtlpriv = rtl_priv(hw);
1383 struct rtl_phy *rtlphy = &rtlpriv->phy;
1386 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1387 "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1389 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1390 for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j)
1391 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1392 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1393 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1394 rtlphy->txpwr_limit_2_4g
1398 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1399 for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j)
1400 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1401 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1402 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1403 rtlphy->txpwr_limit_5g
1408 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1409 "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1412 static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1414 struct rtl_priv *rtlpriv = rtl_priv(hw);
1415 struct rtl_phy *rtlphy = &rtlpriv->phy;
1416 u8 base = 0, rfPath = 0;
1418 for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
1419 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1420 _phy_convert_txpower_dbm_to_relative_value(
1421 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0],
1424 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1425 _phy_convert_txpower_dbm_to_relative_value(
1426 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1],
1428 _phy_convert_txpower_dbm_to_relative_value(
1429 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2],
1432 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1433 _phy_convert_txpower_dbm_to_relative_value(
1434 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3],
1436 _phy_convert_txpower_dbm_to_relative_value(
1437 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4],
1440 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1442 _phy_convert_txpower_dbm_to_relative_value(
1443 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5],
1446 _phy_convert_txpower_dbm_to_relative_value(
1447 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6],
1450 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1451 _phy_convert_txpower_dbm_to_relative_value(
1452 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7],
1454 _phy_convert_txpower_dbm_to_relative_value(
1455 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8],
1457 _phy_convert_txpower_dbm_to_relative_value(
1458 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1461 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1462 _phy_convert_txpower_dbm_to_relative_value(
1463 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1465 _phy_convert_txpower_dbm_to_relative_value(
1466 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10],
1468 _phy_convert_txpower_dbm_to_relative_value(
1469 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11],
1472 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM);
1473 _phy_convert_txpower_dbm_to_relative_value(
1474 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1],
1476 _phy_convert_txpower_dbm_to_relative_value(
1477 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2],
1480 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7);
1481 _phy_convert_txpower_dbm_to_relative_value(
1482 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3],
1484 _phy_convert_txpower_dbm_to_relative_value(
1485 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4],
1488 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15);
1489 _phy_convert_txpower_dbm_to_relative_value(
1490 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5],
1492 _phy_convert_txpower_dbm_to_relative_value(
1493 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6],
1496 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1497 _phy_convert_txpower_dbm_to_relative_value(
1498 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7],
1500 _phy_convert_txpower_dbm_to_relative_value(
1501 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8],
1503 _phy_convert_txpower_dbm_to_relative_value(
1504 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1507 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1508 _phy_convert_txpower_dbm_to_relative_value(
1509 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1511 _phy_convert_txpower_dbm_to_relative_value(
1512 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10],
1514 _phy_convert_txpower_dbm_to_relative_value(
1515 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11],
1519 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1520 "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1523 static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1525 _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1526 _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1529 /* string is in decimal */
1530 static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
1535 while (str[i] != '\0') {
1536 if (str[i] >= '0' && str[i] <= '9') {
1538 *pint += (str[i] - '0');
1548 static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
1554 if (str1[num] != str2[num])
1560 static char _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1561 u8 band, u8 channel)
1563 struct rtl_priv *rtlpriv = rtl_priv(hw);
1564 char channel_index = -1;
1565 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
1566 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
1567 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
1568 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149,
1569 151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171,
1572 if (band == BAND_ON_2_4G)
1573 channel_index = channel - 1;
1574 else if (band == BAND_ON_5G) {
1575 for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) {
1576 if (channel_5g[i] == channel)
1580 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
1583 if (channel_index == -1)
1584 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1585 "Invalid Channel %d of Band %d in %s", channel,
1588 return channel_index;
1591 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1592 u8 *pband, u8 *pbandwidth,
1593 u8 *prate_section, u8 *prf_path,
1594 u8 *pchannel, u8 *ppower_limit)
1596 struct rtl_priv *rtlpriv = rtl_priv(hw);
1597 struct rtl_phy *rtlphy = &rtlpriv->phy;
1598 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1600 char power_limit = 0, prev_power_limit, ret;
1602 if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1603 !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1605 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1606 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1607 channel, power_limit);
1610 power_limit = power_limit > MAX_POWER_INDEX ?
1611 MAX_POWER_INDEX : power_limit;
1613 if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1615 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1617 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1619 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1622 if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1624 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1626 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1627 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1629 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1630 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1632 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1633 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1635 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1636 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1639 if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1641 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1643 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1645 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1648 if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1649 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1656 channel_index = ret;
1658 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1659 [bandwidth][rate_section]
1660 [channel_index][RF90_PATH_A];
1662 if (power_limit < prev_power_limit)
1663 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1664 [rate_section][channel_index][RF90_PATH_A] =
1667 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1668 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1669 regulation, bandwidth, rate_section, channel_index,
1670 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1671 [rate_section][channel_index][RF90_PATH_A]);
1672 } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1673 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1680 channel_index = ret;
1682 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1683 [rate_section][channel_index]
1686 if (power_limit < prev_power_limit)
1687 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1688 [rate_section][channel_index][RF90_PATH_A] = power_limit;
1690 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1691 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1692 regulation, bandwidth, rate_section, channel,
1693 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1694 [rate_section][channel_index][RF90_PATH_A]);
1696 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1697 "Cannot recognize the band info in %s\n", pband);
1702 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1703 u8 *regulation, u8 *band,
1704 u8 *bandwidth, u8 *rate_section,
1705 u8 *rf_path, u8 *channel,
1708 _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1709 rate_section, rf_path, channel,
1713 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1715 struct rtl_priv *rtlpriv = rtl_priv(hw);
1716 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1721 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1722 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1723 array = RTL8812AE_TXPWR_LMT;
1725 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1726 array = RTL8821AE_TXPWR_LMT;
1729 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1732 for (i = 0; i < array_len; i += 7) {
1733 u8 *regulation = array[i];
1734 u8 *band = array[i+1];
1735 u8 *bandwidth = array[i+2];
1736 u8 *rate = array[i+3];
1737 u8 *rf_path = array[i+4];
1738 u8 *chnl = array[i+5];
1739 u8 *val = array[i+6];
1741 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1742 bandwidth, rate, rf_path,
1747 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1749 struct rtl_priv *rtlpriv = rtl_priv(hw);
1750 struct rtl_phy *rtlphy = &rtlpriv->phy;
1751 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1754 _rtl8821ae_phy_init_txpower_limit(hw);
1756 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1757 if (rtlefuse->eeprom_regulatory != 2)
1758 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1760 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1761 BASEBAND_CONFIG_PHY_REG);
1762 if (rtstatus != true) {
1763 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
1766 _rtl8821ae_phy_init_tx_power_by_rate(hw);
1767 if (rtlefuse->autoload_failflag == false) {
1768 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1769 BASEBAND_CONFIG_PHY_REG);
1771 if (rtstatus != true) {
1772 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
1776 _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1778 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1779 if (rtlefuse->eeprom_regulatory != 2)
1780 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1782 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1783 BASEBAND_CONFIG_AGC_TAB);
1785 if (rtstatus != true) {
1786 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1789 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1790 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1794 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1796 struct rtl_priv *rtlpriv = rtl_priv(hw);
1797 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1802 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1803 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1804 arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1805 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1807 arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1808 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1810 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1811 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1812 for (i = 0; i < arraylength; i += 2) {
1814 v2 = (u8)ptrarray[i + 1];
1815 if (v1 < 0xCDCDCDCD) {
1816 rtl_write_byte(rtlpriv, v1, (u8)v2);
1819 if (!_rtl8821ae_check_condition(hw, v1)) {
1820 /*Discard the following (offset, data) pairs*/
1821 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1822 while (v2 != 0xDEAD &&
1824 v2 != 0xCDCD && i < arraylength - 2) {
1825 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1827 i -= 2; /* prevent from for-loop += 2*/
1828 } else {/*Configure matched pairs and skip to end of if-else.*/
1829 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1830 while (v2 != 0xDEAD &&
1832 v2 != 0xCDCD && i < arraylength - 2) {
1833 rtl_write_byte(rtlpriv, v1, v2);
1834 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1837 while (v2 != 0xDEAD && i < arraylength - 2)
1838 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1845 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1848 struct rtl_priv *rtlpriv = rtl_priv(hw);
1849 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1855 if (configtype == BASEBAND_CONFIG_PHY_REG) {
1856 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1857 arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1858 array_table = RTL8812AE_PHY_REG_ARRAY;
1860 arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1861 array_table = RTL8821AE_PHY_REG_ARRAY;
1864 for (i = 0; i < arraylen; i += 2) {
1865 v1 = array_table[i];
1866 v2 = array_table[i + 1];
1867 if (v1 < 0xCDCDCDCD) {
1868 _rtl8821ae_config_bb_reg(hw, v1, v2);
1870 } else {/*This line is the start line of branch.*/
1871 if (!_rtl8821ae_check_condition(hw, v1)) {
1872 /*Discard the following (offset, data) pairs*/
1873 READ_NEXT_PAIR(array_table, v1, v2, i);
1874 while (v2 != 0xDEAD &&
1878 READ_NEXT_PAIR(array_table, v1,
1882 i -= 2; /* prevent from for-loop += 2*/
1883 } else {/*Configure matched pairs and skip to end of if-else.*/
1884 READ_NEXT_PAIR(array_table, v1, v2, i);
1885 while (v2 != 0xDEAD &&
1889 _rtl8821ae_config_bb_reg(hw, v1,
1891 READ_NEXT_PAIR(array_table, v1,
1895 while (v2 != 0xDEAD &&
1897 READ_NEXT_PAIR(array_table, v1,
1903 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1904 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1905 arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1906 array_table = RTL8812AE_AGC_TAB_ARRAY;
1908 arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1909 array_table = RTL8821AE_AGC_TAB_ARRAY;
1912 for (i = 0; i < arraylen; i = i + 2) {
1913 v1 = array_table[i];
1914 v2 = array_table[i+1];
1915 if (v1 < 0xCDCDCDCD) {
1916 rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1919 } else {/*This line is the start line of branch.*/
1920 if (!_rtl8821ae_check_condition(hw, v1)) {
1921 /*Discard the following (offset, data) pairs*/
1922 READ_NEXT_PAIR(array_table, v1, v2, i);
1923 while (v2 != 0xDEAD &&
1927 READ_NEXT_PAIR(array_table, v1,
1930 i -= 2; /* prevent from for-loop += 2*/
1931 } else {/*Configure matched pairs and skip to end of if-else.*/
1932 READ_NEXT_PAIR(array_table, v1, v2, i);
1933 while (v2 != 0xDEAD &&
1937 rtl_set_bbreg(hw, v1, MASKDWORD,
1940 READ_NEXT_PAIR(array_table, v1,
1944 while (v2 != 0xDEAD &&
1946 READ_NEXT_PAIR(array_table, v1,
1950 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1951 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1952 array_table[i], array_table[i + 1]);
1959 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1963 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1964 index = (u8)((regaddr - 0xC20) / 4);
1965 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1966 index = (u8)((regaddr - 0xE20) / 4);
1968 RT_ASSERT(!COMP_INIT,
1969 "Invalid RegAddr 0x%x\n", regaddr);
1973 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1974 u32 band, u32 rfpath,
1975 u32 txnum, u32 regaddr,
1976 u32 bitmask, u32 data)
1978 struct rtl_priv *rtlpriv = rtl_priv(hw);
1979 struct rtl_phy *rtlphy = &rtlpriv->phy;
1980 u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1982 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1983 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1984 band = BAND_ON_2_4G;
1986 if (rfpath >= MAX_RF_PATH) {
1987 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1988 rfpath = MAX_RF_PATH - 1;
1990 if (txnum >= MAX_RF_PATH) {
1991 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1992 txnum = MAX_RF_PATH - 1;
1994 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1995 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1996 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1997 band, rfpath, txnum, rate_section,
1998 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
2001 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
2004 struct rtl_priv *rtlpriv = rtl_priv(hw);
2005 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2009 u32 v1, v2, v3, v4, v5, v6;
2011 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
2012 arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
2013 array = RTL8812AE_PHY_REG_ARRAY_PG;
2015 arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
2016 array = RTL8821AE_PHY_REG_ARRAY_PG;
2019 if (configtype != BASEBAND_CONFIG_PHY_REG) {
2020 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
2021 "configtype != BaseBand_Config_PHY_REG\n");
2024 for (i = 0; i < arraylen; i += 6) {
2032 if (v1 < 0xCDCDCDCD) {
2033 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
2034 (v4 == 0xfe || v4 == 0xffe)) {
2039 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
2042 else if (v4 == 0xfd)
2044 else if (v4 == 0xfc)
2046 else if (v4 == 0xfb)
2048 else if (v4 == 0xfa)
2050 else if (v4 == 0xf9)
2053 _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
2057 /*don't need the hw_body*/
2058 if (!_rtl8821ae_check_condition(hw, v1)) {
2059 i += 2; /* skip the pair of expression*/
2063 while (v2 != 0xDEAD) {
2076 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2077 enum radio_path rfpath)
2080 bool rtstatus = true;
2081 u32 *radioa_array_table_a, *radioa_array_table_b;
2082 u16 radioa_arraylen_a, radioa_arraylen_b;
2083 struct rtl_priv *rtlpriv = rtl_priv(hw);
2086 radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
2087 radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
2088 radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
2089 radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2090 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2091 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2092 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2096 for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2097 v1 = radioa_array_table_a[i];
2098 v2 = radioa_array_table_a[i+1];
2099 if (v1 < 0xcdcdcdcd) {
2100 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2102 } else{/*This line is the start line of branch.*/
2103 if (!_rtl8821ae_check_condition(hw, v1)) {
2104 /*Discard the following (offset, data) pairs*/
2105 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2106 while (v2 != 0xDEAD &&
2108 v2 != 0xCDCD && i < radioa_arraylen_a-2)
2109 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2111 i -= 2; /* prevent from for-loop += 2*/
2112 } else {/*Configure matched pairs and skip to end of if-else.*/
2113 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2114 while (v2 != 0xDEAD &&
2116 v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2117 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2118 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2121 while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2122 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2129 for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2130 v1 = radioa_array_table_b[i];
2131 v2 = radioa_array_table_b[i+1];
2132 if (v1 < 0xcdcdcdcd) {
2133 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2135 } else{/*This line is the start line of branch.*/
2136 if (!_rtl8821ae_check_condition(hw, v1)) {
2137 /*Discard the following (offset, data) pairs*/
2138 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2139 while (v2 != 0xDEAD &&
2141 v2 != 0xCDCD && i < radioa_arraylen_b-2)
2142 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2144 i -= 2; /* prevent from for-loop += 2*/
2145 } else {/*Configure matched pairs and skip to end of if-else.*/
2146 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2147 while (v2 != 0xDEAD &&
2149 v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2150 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2151 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2154 while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2155 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2161 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2162 "switch case not process\n");
2165 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2166 "switch case not process\n");
2172 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2173 enum radio_path rfpath)
2175 #define READ_NEXT_RF_PAIR(v1, v2, i) \
2178 v1 = radioa_array_table[i]; \
2179 v2 = radioa_array_table[i+1]; \
2184 bool rtstatus = true;
2185 u32 *radioa_array_table;
2186 u16 radioa_arraylen;
2187 struct rtl_priv *rtlpriv = rtl_priv(hw);
2188 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2191 radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2192 radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2193 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2194 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2195 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2199 for (i = 0; i < radioa_arraylen; i = i + 2) {
2200 v1 = radioa_array_table[i];
2201 v2 = radioa_array_table[i+1];
2202 if (v1 < 0xcdcdcdcd)
2203 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2204 else{/*This line is the start line of branch.*/
2205 if (!_rtl8821ae_check_condition(hw, v1)) {
2206 /*Discard the following (offset, data) pairs*/
2207 READ_NEXT_RF_PAIR(v1, v2, i);
2208 while (v2 != 0xDEAD &&
2210 v2 != 0xCDCD && i < radioa_arraylen - 2)
2211 READ_NEXT_RF_PAIR(v1, v2, i);
2213 i -= 2; /* prevent from for-loop += 2*/
2214 } else {/*Configure matched pairs and skip to end of if-else.*/
2215 READ_NEXT_RF_PAIR(v1, v2, i);
2216 while (v2 != 0xDEAD &&
2218 v2 != 0xCDCD && i < radioa_arraylen - 2) {
2219 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2220 READ_NEXT_RF_PAIR(v1, v2, i);
2223 while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2224 READ_NEXT_RF_PAIR(v1, v2, i);
2231 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2232 "switch case not process\n");
2235 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2236 "switch case not process\n");
2239 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2240 "switch case not process\n");
2246 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2248 struct rtl_priv *rtlpriv = rtl_priv(hw);
2249 struct rtl_phy *rtlphy = &rtlpriv->phy;
2251 rtlphy->default_initialgain[0] =
2252 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2253 rtlphy->default_initialgain[1] =
2254 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2255 rtlphy->default_initialgain[2] =
2256 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2257 rtlphy->default_initialgain[3] =
2258 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2260 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2261 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2262 rtlphy->default_initialgain[0],
2263 rtlphy->default_initialgain[1],
2264 rtlphy->default_initialgain[2],
2265 rtlphy->default_initialgain[3]);
2267 rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2268 ROFDM0_RXDETECTOR3, MASKBYTE0);
2269 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2270 ROFDM0_RXDETECTOR2, MASKDWORD);
2272 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2273 "Default framesync (0x%x) = 0x%x\n",
2274 ROFDM0_RXDETECTOR3, rtlphy->framesync);
2277 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2279 struct rtl_priv *rtlpriv = rtl_priv(hw);
2280 struct rtl_phy *rtlphy = &rtlpriv->phy;
2282 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2283 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2285 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2286 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2288 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2289 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2291 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2292 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2294 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2295 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2297 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2298 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2300 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2301 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2304 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2306 struct rtl_priv *rtlpriv = rtl_priv(hw);
2307 struct rtl_phy *rtlphy = &rtlpriv->phy;
2311 txpwr_level = rtlphy->cur_cck_txpwridx;
2312 txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2313 WIRELESS_MODE_B, txpwr_level);
2314 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2315 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2317 txpwr_level) > txpwr_dbm)
2319 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2321 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2322 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2323 WIRELESS_MODE_N_24G,
2324 txpwr_level) > txpwr_dbm)
2326 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2328 *powerlevel = txpwr_dbm;
2331 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2333 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
2334 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
2335 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
2336 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140,
2337 142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165,
2338 167, 168, 169, 171, 173, 175, 177
2343 if (channel <= 14) {
2345 *chnl_index = channel - 1;
2349 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2350 if (channel_5g[i] == channel) {
2359 static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2361 char rate_section = 0;
2395 case DESC_RATEMCS10:
2396 case DESC_RATEMCS11:
2399 case DESC_RATEMCS12:
2400 case DESC_RATEMCS13:
2401 case DESC_RATEMCS14:
2402 case DESC_RATEMCS15:
2405 case DESC_RATEVHT1SS_MCS0:
2406 case DESC_RATEVHT1SS_MCS1:
2407 case DESC_RATEVHT1SS_MCS2:
2408 case DESC_RATEVHT1SS_MCS3:
2411 case DESC_RATEVHT1SS_MCS4:
2412 case DESC_RATEVHT1SS_MCS5:
2413 case DESC_RATEVHT1SS_MCS6:
2414 case DESC_RATEVHT1SS_MCS7:
2417 case DESC_RATEVHT1SS_MCS8:
2418 case DESC_RATEVHT1SS_MCS9:
2419 case DESC_RATEVHT2SS_MCS0:
2420 case DESC_RATEVHT2SS_MCS1:
2423 case DESC_RATEVHT2SS_MCS2:
2424 case DESC_RATEVHT2SS_MCS3:
2425 case DESC_RATEVHT2SS_MCS4:
2426 case DESC_RATEVHT2SS_MCS5:
2429 case DESC_RATEVHT2SS_MCS6:
2430 case DESC_RATEVHT2SS_MCS7:
2431 case DESC_RATEVHT2SS_MCS8:
2432 case DESC_RATEVHT2SS_MCS9:
2436 RT_ASSERT(true, "Rate_Section is Illegal\n");
2440 return rate_section;
2443 static char _rtl8812ae_phy_get_world_wide_limit(char *limit_table)
2445 char min = limit_table[0];
2448 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2449 if (limit_table[i] < min)
2450 min = limit_table[i];
2455 static char _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2457 enum ht_channel_width bandwidth,
2458 enum radio_path rf_path,
2459 u8 rate, u8 channel)
2461 struct rtl_priv *rtlpriv = rtl_priv(hw);
2462 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2463 struct rtl_phy *rtlphy = &rtlpriv->phy;
2464 short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2465 rate_section = -1, channel_temp = -1;
2466 u16 bd, regu, bdwidth, sec, chnl;
2467 char power_limit = MAX_POWER_INDEX;
2469 if (rtlefuse->eeprom_regulatory == 2)
2470 return MAX_POWER_INDEX;
2472 regulation = TXPWR_LMT_WW;
2474 if (band == BAND_ON_2_4G)
2476 else if (band == BAND_ON_5G)
2479 if (bandwidth == HT_CHANNEL_WIDTH_20)
2481 else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2483 else if (bandwidth == HT_CHANNEL_WIDTH_80)
2515 case DESC_RATEMCS10:
2516 case DESC_RATEMCS11:
2517 case DESC_RATEMCS12:
2518 case DESC_RATEMCS13:
2519 case DESC_RATEMCS14:
2520 case DESC_RATEMCS15:
2523 case DESC_RATEVHT1SS_MCS0:
2524 case DESC_RATEVHT1SS_MCS1:
2525 case DESC_RATEVHT1SS_MCS2:
2526 case DESC_RATEVHT1SS_MCS3:
2527 case DESC_RATEVHT1SS_MCS4:
2528 case DESC_RATEVHT1SS_MCS5:
2529 case DESC_RATEVHT1SS_MCS6:
2530 case DESC_RATEVHT1SS_MCS7:
2531 case DESC_RATEVHT1SS_MCS8:
2532 case DESC_RATEVHT1SS_MCS9:
2535 case DESC_RATEVHT2SS_MCS0:
2536 case DESC_RATEVHT2SS_MCS1:
2537 case DESC_RATEVHT2SS_MCS2:
2538 case DESC_RATEVHT2SS_MCS3:
2539 case DESC_RATEVHT2SS_MCS4:
2540 case DESC_RATEVHT2SS_MCS5:
2541 case DESC_RATEVHT2SS_MCS6:
2542 case DESC_RATEVHT2SS_MCS7:
2543 case DESC_RATEVHT2SS_MCS8:
2544 case DESC_RATEVHT2SS_MCS9:
2548 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2549 "Wrong rate 0x%x\n", rate);
2553 if (band_temp == BAND_ON_5G && rate_section == 0)
2554 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2555 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2557 /*workaround for wrong index combination to obtain tx power limit,
2558 OFDM only exists in BW 20M*/
2559 if (rate_section == 1)
2562 /*workaround for wrong index combination to obtain tx power limit,
2563 *HT on 80M will reference to HT on 40M
2565 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2566 bandwidth_temp == 2)
2569 if (band == BAND_ON_2_4G)
2570 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2571 BAND_ON_2_4G, channel);
2572 else if (band == BAND_ON_5G)
2573 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2574 BAND_ON_5G, channel);
2575 else if (band == BAND_ON_BOTH)
2576 ;/* BAND_ON_BOTH don't care temporarily */
2578 if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2579 rate_section == -1 || channel_temp == -1) {
2580 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2581 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2582 band_temp, regulation, bandwidth_temp, rf_path,
2583 rate_section, channel_temp);
2584 return MAX_POWER_INDEX;
2589 bdwidth = bandwidth_temp;
2591 chnl = channel_temp;
2593 if (band == BAND_ON_2_4G) {
2594 char limits[10] = {0};
2597 for (i = 0; i < 4; ++i)
2598 limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2599 [sec][chnl][rf_path];
2601 power_limit = (regulation == TXPWR_LMT_WW) ?
2602 _rtl8812ae_phy_get_world_wide_limit(limits) :
2603 rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2604 [sec][chnl][rf_path];
2605 } else if (band == BAND_ON_5G) {
2606 char limits[10] = {0};
2609 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2610 limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2611 [sec][chnl][rf_path];
2613 power_limit = (regulation == TXPWR_LMT_WW) ?
2614 _rtl8812ae_phy_get_world_wide_limit(limits) :
2615 rtlphy->txpwr_limit_5g[regu][chnl]
2616 [sec][chnl][rf_path];
2618 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2619 "No power limit table of the specified band\n");
2624 static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2625 u8 band, u8 path, u8 rate)
2627 struct rtl_priv *rtlpriv = rtl_priv(hw);
2628 struct rtl_phy *rtlphy = &rtlpriv->phy;
2629 u8 shift = 0, rate_section, tx_num;
2630 char tx_pwr_diff = 0;
2633 rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2634 tx_num = RF_TX_NUM_NONIMPLEMENT;
2636 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2637 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2638 (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2651 case DESC_RATEMCS12:
2652 case DESC_RATEVHT1SS_MCS0:
2653 case DESC_RATEVHT1SS_MCS4:
2654 case DESC_RATEVHT1SS_MCS8:
2655 case DESC_RATEVHT2SS_MCS2:
2656 case DESC_RATEVHT2SS_MCS6:
2665 case DESC_RATEMCS13:
2666 case DESC_RATEVHT1SS_MCS1:
2667 case DESC_RATEVHT1SS_MCS5:
2668 case DESC_RATEVHT1SS_MCS9:
2669 case DESC_RATEVHT2SS_MCS3:
2670 case DESC_RATEVHT2SS_MCS7:
2678 case DESC_RATEMCS10:
2679 case DESC_RATEMCS14:
2680 case DESC_RATEVHT1SS_MCS2:
2681 case DESC_RATEVHT1SS_MCS6:
2682 case DESC_RATEVHT2SS_MCS0:
2683 case DESC_RATEVHT2SS_MCS4:
2684 case DESC_RATEVHT2SS_MCS8:
2692 case DESC_RATEMCS11:
2693 case DESC_RATEMCS15:
2694 case DESC_RATEVHT1SS_MCS3:
2695 case DESC_RATEVHT1SS_MCS7:
2696 case DESC_RATEVHT2SS_MCS1:
2697 case DESC_RATEVHT2SS_MCS5:
2698 case DESC_RATEVHT2SS_MCS9:
2702 RT_ASSERT(true, "Rate_Section is Illegal\n");
2706 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2707 [tx_num][rate_section] >> shift) & 0xff;
2709 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2710 if (rtlpriv->efuse.eeprom_regulatory != 2) {
2711 limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2712 rtlphy->current_chan_bw, path, rate,
2713 rtlphy->current_channel);
2715 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2716 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2718 if (tx_pwr_diff < (-limit))
2719 tx_pwr_diff = -limit;
2723 tx_pwr_diff = limit;
2725 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2727 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2728 "Maximum power by rate %d, final power by rate %d\n",
2729 limit, tx_pwr_diff);
2735 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2736 u8 rate, u8 bandwidth, u8 channel)
2738 struct rtl_priv *rtlpriv = rtl_priv(hw);
2739 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2740 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2741 u8 index = (channel - 1);
2743 bool in_24g = false;
2744 char powerdiff_byrate = 0;
2746 if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2747 (channel > 14 || channel < 1)) ||
2748 ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2750 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2751 "Illegal channel!!\n");
2754 in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2756 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2757 txpower = rtlefuse->txpwrlevel_cck[path][index];
2758 else if (DESC_RATE6M <= rate)
2759 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2761 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2763 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2764 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2765 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2767 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2768 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2769 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2770 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2771 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2772 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2773 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2774 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2775 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2776 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2777 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2778 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2779 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2780 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2781 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2782 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2783 (DESC_RATEVHT1SS_MCS0 <= rate &&
2784 rate <= DESC_RATEVHT2SS_MCS9))
2785 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2786 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2787 (DESC_RATEVHT2SS_MCS0 <= rate &&
2788 rate <= DESC_RATEVHT2SS_MCS9))
2789 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2792 if (DESC_RATE6M <= rate)
2793 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2795 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2798 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2799 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2800 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2802 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2803 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2804 (DESC_RATEVHT1SS_MCS0 <= rate &&
2805 rate <= DESC_RATEVHT2SS_MCS9))
2806 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2807 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2808 (DESC_RATEVHT2SS_MCS0 <= rate &&
2809 rate <= DESC_RATEVHT2SS_MCS9))
2810 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2811 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2812 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2813 (DESC_RATEVHT1SS_MCS0 <= rate &&
2814 rate <= DESC_RATEVHT2SS_MCS9))
2815 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2816 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2817 (DESC_RATEVHT2SS_MCS0 <= rate &&
2818 rate <= DESC_RATEVHT2SS_MCS9))
2819 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2820 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2821 u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2822 42, 58, 106, 122, 138, 155, 171
2826 for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i)
2827 if (channel_5g_80m[i] == channel)
2830 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2831 (DESC_RATEVHT1SS_MCS0 <= rate &&
2832 rate <= DESC_RATEVHT2SS_MCS9))
2833 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2834 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2835 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2836 (DESC_RATEVHT2SS_MCS0 <= rate &&
2837 rate <= DESC_RATEVHT2SS_MCS9))
2838 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2839 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2840 + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2843 if (rtlefuse->eeprom_regulatory != 2)
2845 _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2848 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2849 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2850 txpower -= powerdiff_byrate;
2852 txpower += powerdiff_byrate;
2854 if (rate > DESC_RATE11M)
2855 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2857 txpower += rtlpriv->dm.remnant_cck_idx;
2859 if (txpower > MAX_POWER_INDEX)
2860 txpower = MAX_POWER_INDEX;
2865 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2866 u8 power_index, u8 path, u8 rate)
2868 struct rtl_priv *rtlpriv = rtl_priv(hw);
2870 if (path == RF90_PATH_A) {
2873 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2874 MASKBYTE0, power_index);
2877 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2878 MASKBYTE1, power_index);
2881 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2882 MASKBYTE2, power_index);
2885 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2886 MASKBYTE3, power_index);
2889 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2890 MASKBYTE0, power_index);
2893 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2894 MASKBYTE1, power_index);
2897 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2898 MASKBYTE2, power_index);
2901 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2902 MASKBYTE3, power_index);
2905 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2906 MASKBYTE0, power_index);
2909 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2910 MASKBYTE1, power_index);
2913 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2914 MASKBYTE2, power_index);
2917 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2918 MASKBYTE3, power_index);
2921 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2922 MASKBYTE0, power_index);
2925 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2926 MASKBYTE1, power_index);
2929 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2930 MASKBYTE2, power_index);
2933 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2934 MASKBYTE3, power_index);
2937 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2938 MASKBYTE0, power_index);
2941 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2942 MASKBYTE1, power_index);
2945 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2946 MASKBYTE2, power_index);
2949 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2950 MASKBYTE3, power_index);
2953 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2954 MASKBYTE0, power_index);
2957 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2958 MASKBYTE1, power_index);
2960 case DESC_RATEMCS10:
2961 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2962 MASKBYTE2, power_index);
2964 case DESC_RATEMCS11:
2965 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2966 MASKBYTE3, power_index);
2968 case DESC_RATEMCS12:
2969 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2970 MASKBYTE0, power_index);
2972 case DESC_RATEMCS13:
2973 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2974 MASKBYTE1, power_index);
2976 case DESC_RATEMCS14:
2977 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2978 MASKBYTE2, power_index);
2980 case DESC_RATEMCS15:
2981 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2982 MASKBYTE3, power_index);
2984 case DESC_RATEVHT1SS_MCS0:
2985 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2986 MASKBYTE0, power_index);
2988 case DESC_RATEVHT1SS_MCS1:
2989 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2990 MASKBYTE1, power_index);
2992 case DESC_RATEVHT1SS_MCS2:
2993 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2994 MASKBYTE2, power_index);
2996 case DESC_RATEVHT1SS_MCS3:
2997 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2998 MASKBYTE3, power_index);
3000 case DESC_RATEVHT1SS_MCS4:
3001 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3002 MASKBYTE0, power_index);
3004 case DESC_RATEVHT1SS_MCS5:
3005 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3006 MASKBYTE1, power_index);
3008 case DESC_RATEVHT1SS_MCS6:
3009 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3010 MASKBYTE2, power_index);
3012 case DESC_RATEVHT1SS_MCS7:
3013 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3014 MASKBYTE3, power_index);
3016 case DESC_RATEVHT1SS_MCS8:
3017 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3018 MASKBYTE0, power_index);
3020 case DESC_RATEVHT1SS_MCS9:
3021 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3022 MASKBYTE1, power_index);
3024 case DESC_RATEVHT2SS_MCS0:
3025 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3026 MASKBYTE2, power_index);
3028 case DESC_RATEVHT2SS_MCS1:
3029 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3030 MASKBYTE3, power_index);
3032 case DESC_RATEVHT2SS_MCS2:
3033 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3034 MASKBYTE0, power_index);
3036 case DESC_RATEVHT2SS_MCS3:
3037 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3038 MASKBYTE1, power_index);
3040 case DESC_RATEVHT2SS_MCS4:
3041 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3042 MASKBYTE2, power_index);
3044 case DESC_RATEVHT2SS_MCS5:
3045 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3046 MASKBYTE3, power_index);
3048 case DESC_RATEVHT2SS_MCS6:
3049 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3050 MASKBYTE0, power_index);
3052 case DESC_RATEVHT2SS_MCS7:
3053 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3054 MASKBYTE1, power_index);
3056 case DESC_RATEVHT2SS_MCS8:
3057 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3058 MASKBYTE2, power_index);
3060 case DESC_RATEVHT2SS_MCS9:
3061 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3062 MASKBYTE3, power_index);
3065 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3066 "Invalid Rate!!\n");
3069 } else if (path == RF90_PATH_B) {
3072 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3073 MASKBYTE0, power_index);
3076 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3077 MASKBYTE1, power_index);
3080 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3081 MASKBYTE2, power_index);
3084 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3085 MASKBYTE3, power_index);
3088 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3089 MASKBYTE0, power_index);
3092 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3093 MASKBYTE1, power_index);
3096 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3097 MASKBYTE2, power_index);
3100 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3101 MASKBYTE3, power_index);
3104 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3105 MASKBYTE0, power_index);
3108 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3109 MASKBYTE1, power_index);
3112 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3113 MASKBYTE2, power_index);
3116 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3117 MASKBYTE3, power_index);
3120 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3121 MASKBYTE0, power_index);
3124 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3125 MASKBYTE1, power_index);
3128 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3129 MASKBYTE2, power_index);
3132 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3133 MASKBYTE3, power_index);
3136 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3137 MASKBYTE0, power_index);
3140 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3141 MASKBYTE1, power_index);
3144 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3145 MASKBYTE2, power_index);
3148 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3149 MASKBYTE3, power_index);
3152 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3153 MASKBYTE0, power_index);
3156 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3157 MASKBYTE1, power_index);
3159 case DESC_RATEMCS10:
3160 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3161 MASKBYTE2, power_index);
3163 case DESC_RATEMCS11:
3164 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3165 MASKBYTE3, power_index);
3167 case DESC_RATEMCS12:
3168 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3169 MASKBYTE0, power_index);
3171 case DESC_RATEMCS13:
3172 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3173 MASKBYTE1, power_index);
3175 case DESC_RATEMCS14:
3176 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3177 MASKBYTE2, power_index);
3179 case DESC_RATEMCS15:
3180 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3181 MASKBYTE3, power_index);
3183 case DESC_RATEVHT1SS_MCS0:
3184 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3185 MASKBYTE0, power_index);
3187 case DESC_RATEVHT1SS_MCS1:
3188 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3189 MASKBYTE1, power_index);
3191 case DESC_RATEVHT1SS_MCS2:
3192 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3193 MASKBYTE2, power_index);
3195 case DESC_RATEVHT1SS_MCS3:
3196 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3197 MASKBYTE3, power_index);
3199 case DESC_RATEVHT1SS_MCS4:
3200 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3201 MASKBYTE0, power_index);
3203 case DESC_RATEVHT1SS_MCS5:
3204 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3205 MASKBYTE1, power_index);
3207 case DESC_RATEVHT1SS_MCS6:
3208 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3209 MASKBYTE2, power_index);
3211 case DESC_RATEVHT1SS_MCS7:
3212 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3213 MASKBYTE3, power_index);
3215 case DESC_RATEVHT1SS_MCS8:
3216 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3217 MASKBYTE0, power_index);
3219 case DESC_RATEVHT1SS_MCS9:
3220 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3221 MASKBYTE1, power_index);
3223 case DESC_RATEVHT2SS_MCS0:
3224 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3225 MASKBYTE2, power_index);
3227 case DESC_RATEVHT2SS_MCS1:
3228 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3229 MASKBYTE3, power_index);
3231 case DESC_RATEVHT2SS_MCS2:
3232 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3233 MASKBYTE0, power_index);
3235 case DESC_RATEVHT2SS_MCS3:
3236 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3237 MASKBYTE1, power_index);
3239 case DESC_RATEVHT2SS_MCS4:
3240 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3241 MASKBYTE2, power_index);
3243 case DESC_RATEVHT2SS_MCS5:
3244 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3245 MASKBYTE3, power_index);
3247 case DESC_RATEVHT2SS_MCS6:
3248 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3249 MASKBYTE0, power_index);
3251 case DESC_RATEVHT2SS_MCS7:
3252 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3253 MASKBYTE1, power_index);
3255 case DESC_RATEVHT2SS_MCS8:
3256 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3257 MASKBYTE2, power_index);
3259 case DESC_RATEVHT2SS_MCS9:
3260 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3261 MASKBYTE3, power_index);
3264 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3265 "Invalid Rate!!\n");
3269 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3270 "Invalid RFPath!!\n");
3274 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3276 u8 channel, u8 size)
3278 struct rtl_priv *rtlpriv = rtl_priv(hw);
3279 struct rtl_phy *rtlphy = &rtlpriv->phy;
3283 for (i = 0; i < size; i++) {
3285 _rtl8821ae_get_txpower_index(hw, path, array[i],
3286 rtlphy->current_chan_bw,
3288 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3293 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3294 u8 bw, u8 channel, u8 path)
3296 struct rtl_priv *rtlpriv = rtl_priv(hw);
3297 struct rtl_phy *rtlphy = &rtlpriv->phy;
3300 u32 power_level, data, offset;
3302 if (path >= rtlphy->num_total_rfpath)
3306 if (path == RF90_PATH_A) {
3308 _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3309 DESC_RATEMCS7, bw, channel);
3310 offset = RA_TXPWRTRAING;
3313 _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3314 DESC_RATEMCS7, bw, channel);
3315 offset = RB_TXPWRTRAING;
3318 for (i = 0; i < 3; i++) {
3320 power_level = power_level - 10;
3322 power_level = power_level - 8;
3324 power_level = power_level - 6;
3326 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3328 rtl_set_bbreg(hw, offset, 0xffffff, data);
3331 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3332 u8 channel, u8 path)
3334 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3335 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3336 struct rtl_priv *rtlpriv = rtl_priv(hw);
3337 struct rtl_phy *rtlphy = &rtlpriv->phy;
3338 u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3340 u8 sizes_of_cck_retes = 4;
3341 u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3342 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3343 DESC_RATE48M, DESC_RATE54M};
3344 u8 sizes_of_ofdm_retes = 8;
3345 u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3346 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3347 DESC_RATEMCS6, DESC_RATEMCS7};
3348 u8 sizes_of_ht_retes_1t = 8;
3349 u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9,
3350 DESC_RATEMCS10, DESC_RATEMCS11,
3351 DESC_RATEMCS12, DESC_RATEMCS13,
3352 DESC_RATEMCS14, DESC_RATEMCS15};
3353 u8 sizes_of_ht_retes_2t = 8;
3354 u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3355 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3356 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3357 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3358 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3359 u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3360 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3361 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3362 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3363 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3364 u8 sizes_of_vht_retes = 10;
3366 if (rtlhal->current_bandtype == BAND_ON_2_4G)
3367 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3368 sizes_of_cck_retes);
3370 _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3371 sizes_of_ofdm_retes);
3372 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3373 sizes_of_ht_retes_1t);
3374 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3375 sizes_of_vht_retes);
3377 if (rtlphy->num_total_rfpath >= 2) {
3378 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3380 sizes_of_ht_retes_2t);
3381 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3383 sizes_of_vht_retes);
3386 _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3390 /*just in case, write txpower in DW, to reduce time*/
3391 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3393 struct rtl_priv *rtlpriv = rtl_priv(hw);
3394 struct rtl_phy *rtlphy = &rtlpriv->phy;
3397 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3398 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3401 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3402 enum wireless_mode wirelessmode,
3408 switch (wirelessmode) {
3409 case WIRELESS_MODE_B:
3412 case WIRELESS_MODE_G:
3413 case WIRELESS_MODE_N_24G:
3420 pwrout_dbm = txpwridx / 2 + offset;
3424 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3426 struct rtl_priv *rtlpriv = rtl_priv(hw);
3427 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3428 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3430 if (!is_hal_stop(rtlhal)) {
3431 switch (operation) {
3432 case SCAN_OPT_BACKUP_BAND0:
3433 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3434 rtlpriv->cfg->ops->set_hw_reg(hw,
3439 case SCAN_OPT_BACKUP_BAND1:
3440 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3441 rtlpriv->cfg->ops->set_hw_reg(hw,
3446 case SCAN_OPT_RESTORE:
3447 iotype = IO_CMD_RESUME_DM_BY_SCAN;
3448 rtlpriv->cfg->ops->set_hw_reg(hw,
3453 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3454 "Unknown Scan Backup operation.\n");
3460 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3462 u16 reg_rf_mode_bw, tmp = 0;
3464 reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3466 case HT_CHANNEL_WIDTH_20:
3467 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3469 case HT_CHANNEL_WIDTH_20_40:
3470 tmp = reg_rf_mode_bw | BIT(7);
3471 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3473 case HT_CHANNEL_WIDTH_80:
3474 tmp = reg_rf_mode_bw | BIT(8);
3475 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3478 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3483 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3485 struct rtl_phy *rtlphy = &rtlpriv->phy;
3486 struct rtl_mac *mac = rtl_mac(rtlpriv);
3487 u8 sc_set_40 = 0, sc_set_20 = 0;
3489 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3490 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3491 sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3492 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3493 sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3495 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3496 "SCMapping: Not Correct Primary40MHz Setting\n");
3498 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3499 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3500 sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3501 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3502 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3503 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3504 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3505 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3506 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3507 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3508 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3509 sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3511 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3512 "SCMapping: Not Correct Primary40MHz Setting\n");
3513 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3514 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3515 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3516 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3517 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3519 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3520 "SCMapping: Not Correct Primary40MHz Setting\n");
3522 return (sc_set_40 << 4) | sc_set_20;
3525 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3527 struct rtl_priv *rtlpriv = rtl_priv(hw);
3528 struct rtl_phy *rtlphy = &rtlpriv->phy;
3532 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3533 "Switch to %s bandwidth\n",
3534 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3536 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3537 "40MHz" : "80MHz")));
3539 _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3540 sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3541 rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3543 switch (rtlphy->current_chan_bw) {
3544 case HT_CHANNEL_WIDTH_20:
3545 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3546 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3548 if (rtlphy->rf_type == RF_2T2R)
3549 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3551 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3553 case HT_CHANNEL_WIDTH_20_40:
3554 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3555 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3556 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3557 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3559 if (rtlphy->reg_837 & BIT(2))
3562 if (rtlphy->rf_type == RF_2T2R)
3567 /* 0x848[25:22] = 0x6 */
3568 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3570 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3571 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3573 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3576 case HT_CHANNEL_WIDTH_80:
3577 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3578 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3580 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3581 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3582 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3584 if (rtlphy->reg_837 & BIT(2))
3587 if (rtlphy->rf_type == RF_2T2R)
3592 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3596 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3597 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3601 rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3603 rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3604 rtlphy->set_bwmode_inprogress = false;
3606 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3609 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3610 enum nl80211_channel_type ch_type)
3612 struct rtl_priv *rtlpriv = rtl_priv(hw);
3613 struct rtl_phy *rtlphy = &rtlpriv->phy;
3614 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3615 u8 tmp_bw = rtlphy->current_chan_bw;
3617 if (rtlphy->set_bwmode_inprogress)
3619 rtlphy->set_bwmode_inprogress = true;
3620 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3621 rtl8821ae_phy_set_bw_mode_callback(hw);
3623 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3624 "FALSE driver sleep or unload\n");
3625 rtlphy->set_bwmode_inprogress = false;
3626 rtlphy->current_chan_bw = tmp_bw;
3630 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3632 struct rtl_priv *rtlpriv = rtl_priv(hw);
3633 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3634 struct rtl_phy *rtlphy = &rtlpriv->phy;
3635 u8 channel = rtlphy->current_channel;
3639 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3640 "switch to channel%d\n", rtlphy->current_channel);
3641 if (is_hal_stop(rtlhal))
3644 if (36 <= channel && channel <= 48)
3646 else if (50 <= channel && channel <= 64)
3648 else if (100 <= channel && channel <= 116)
3650 else if (118 <= channel)
3654 rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3656 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3657 if (36 <= channel && channel <= 64)
3659 else if (100 <= channel && channel <= 140)
3661 else if (140 < channel)
3665 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3666 BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3668 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3669 BMASKBYTE0, channel);
3672 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3673 if (36 <= channel && channel <= 64)
3675 else if (100 <= channel && channel <= 140)
3679 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3680 BRFREGOFFSETMASK, data);
3684 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3687 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3689 struct rtl_priv *rtlpriv = rtl_priv(hw);
3690 struct rtl_phy *rtlphy = &rtlpriv->phy;
3691 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3692 u32 timeout = 1000, timecount = 0;
3693 u8 channel = rtlphy->current_channel;
3695 if (rtlphy->sw_chnl_inprogress)
3697 if (rtlphy->set_bwmode_inprogress)
3700 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3701 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3702 "sw_chnl_inprogress false driver sleep or unload\n");
3705 while (rtlphy->lck_inprogress && timecount < timeout) {
3710 if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3711 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3712 else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3713 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3715 rtlphy->sw_chnl_inprogress = true;
3719 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3720 "switch to channel%d, band type is %d\n",
3721 rtlphy->current_channel, rtlhal->current_bandtype);
3723 rtl8821ae_phy_sw_chnl_callback(hw);
3725 rtl8821ae_dm_clear_txpower_tracking_state(hw);
3726 rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3728 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3729 rtlphy->sw_chnl_inprogress = false;
3733 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3735 u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3736 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3737 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3738 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3739 110, 112, 114, 116, 118, 120, 122, 124, 126,
3740 128, 130, 132, 134, 136, 138, 140, 149, 151,
3741 153, 155, 157, 159, 161, 163, 165};
3745 for (place = 14; place < sizeof(channel_all); place++)
3746 if (channel_all[place] == chnl)
3753 #define MACBB_REG_NUM 10
3754 #define AFE_REG_NUM 14
3755 #define RF_REG_NUM 3
3757 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3759 u32 *backup_macbb_reg, u32 mac_bb_num)
3761 struct rtl_priv *rtlpriv = rtl_priv(hw);
3764 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3765 /*save MACBB default value*/
3766 for (i = 0; i < mac_bb_num; i++)
3767 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3769 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3772 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3773 u32 *backup_afe_REG, u32 afe_num)
3775 struct rtl_priv *rtlpriv = rtl_priv(hw);
3778 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3779 /*Save AFE Parameters */
3780 for (i = 0; i < afe_num; i++)
3781 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3782 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3785 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3786 u32 *rfb_backup, u32 *backup_rf_reg,
3789 struct rtl_priv *rtlpriv = rtl_priv(hw);
3792 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3793 /*Save RF Parameters*/
3794 for (i = 0; i < rf_num; i++) {
3795 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3797 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3800 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3803 static void _rtl8821ae_iqk_configure_mac(
3804 struct ieee80211_hw *hw
3807 struct rtl_priv *rtlpriv = rtl_priv(hw);
3808 /* ========MAC register setting========*/
3809 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3810 rtl_write_byte(rtlpriv, 0x522, 0x3f);
3811 rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3812 rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/
3813 rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/
3816 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3817 enum radio_path path, u32 tx_x, u32 tx_y)
3819 struct rtl_priv *rtlpriv = rtl_priv(hw);
3822 /* [31] = 1 --> Page C1 */
3823 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3824 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3825 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3826 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3827 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3828 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3829 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3830 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3832 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3833 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3834 rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3835 rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3842 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3843 enum radio_path path, u32 rx_x, u32 rx_y)
3845 struct rtl_priv *rtlpriv = rtl_priv(hw);
3848 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3849 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3850 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3851 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3852 "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3854 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3855 "0xc10 = %x ====>fill to IQC\n",
3856 rtl_read_dword(rtlpriv, 0xc10));
3865 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3867 struct rtl_priv *rtlpriv = rtl_priv(hw);
3868 struct rtl_phy *rtlphy = &rtlpriv->phy;
3869 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3871 u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3872 int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3873 int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3874 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3875 bool tx0iqkok = false, rx0iqkok = false;
3876 bool vdf_enable = false;
3877 int i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3878 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3880 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3881 "BandWidth = %d.\n",
3882 rtlphy->current_chan_bw);
3883 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3886 while (cal < cal_num) {
3889 temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3891 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3892 /*========Path-A AFE all on========*/
3893 /*Port 0 DAC/ADC on*/
3894 rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3895 rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3896 rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3897 rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3898 rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3899 rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3900 rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3901 rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3902 rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3903 rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3905 rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3908 /* ====== LOK ====== */
3909 /*DAC/ADC sampling rate (160 MHz)*/
3910 rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3912 /* 2. LoK RF Setting (at BW = 20M) */
3913 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3914 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */
3915 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3916 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3917 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3918 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3919 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3920 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3921 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3922 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3923 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3924 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3925 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3926 rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3928 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3929 rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3931 if (rtlhal->current_bandtype)
3932 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3934 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3936 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3937 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3938 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3939 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3940 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3942 mdelay(10); /* Delay 10ms */
3943 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3945 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3946 rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3948 switch (rtlphy->current_chan_bw) {
3950 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3953 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3959 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3961 /* 3. TX RF Setting */
3962 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3963 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3964 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3965 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3966 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3967 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3968 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3969 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3970 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3971 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3972 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3973 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3974 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3975 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3976 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3978 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3979 rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3980 if (rtlhal->current_bandtype)
3981 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3983 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3985 if (vdf_enable == 1) {
3986 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3987 for (k = 0; k <= 2; k++) {
3990 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3991 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3992 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3995 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3996 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3997 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
4000 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4001 "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4002 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4003 "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4004 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4005 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
4006 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
4007 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4008 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4009 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
4010 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
4015 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4019 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4020 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4022 mdelay(10); /* Delay 10ms */
4023 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4026 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4027 if ((~iqk_ready) || (delay_count > 20))
4035 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4036 /* ============TXIQK Check============== */
4037 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4040 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4041 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4042 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4043 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4047 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4048 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4051 if (cal_retry == 10)
4057 if (cal_retry == 10)
4063 tx_x0[cal] = vdf_x[k-1];
4064 tx_y0[cal] = vdf_y[k-1];
4067 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4068 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4069 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4073 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4074 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4076 mdelay(10); /* Delay 10ms */
4077 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4080 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4081 if ((~iqk_ready) || (delay_count > 20))
4089 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4090 /* ============TXIQK Check============== */
4091 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4094 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4095 tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4096 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4097 tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4101 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4102 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4105 if (cal_retry == 10)
4111 if (cal_retry == 10)
4117 if (tx0iqkok == false)
4118 break; /* TXK fail, Don't do RXK */
4120 if (vdf_enable == 1) {
4121 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */
4122 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4123 for (k = 0; k <= 2; k++) {
4124 /* ====== RX mode TXK (RXK Step 1) ====== */
4125 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4126 /* 1. TX RF Setting */
4127 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4128 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4129 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4130 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4131 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4132 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4133 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4135 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4136 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4137 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4138 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4139 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4140 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4141 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4145 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4146 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4147 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4152 rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4153 rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4154 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4159 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4160 "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4161 vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4162 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4163 "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4164 vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4165 rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4166 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4167 rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4168 rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4169 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4170 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4171 rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4177 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4178 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4179 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4183 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4184 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4186 mdelay(10); /* Delay 10ms */
4187 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4190 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4191 if ((~iqk_ready) || (delay_count > 20))
4199 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4200 /* ============TXIQK Check============== */
4201 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4204 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4205 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4206 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4207 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4213 if (cal_retry == 10)
4219 if (cal_retry == 10)
4224 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4225 tx_x0_rxk[cal] = tx_x0[cal];
4226 tx_y0_rxk[cal] = tx_y0[cal];
4231 "RXK Step 1 fail\n");
4234 /* ====== RX IQK ====== */
4235 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4236 /* 1. RX RF Setting */
4237 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4238 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4239 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4240 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4241 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4242 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4243 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4245 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4246 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4247 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4248 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4249 rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4250 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4251 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4253 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4254 rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4255 rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4256 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4258 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4261 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */
4262 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4267 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4268 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4270 mdelay(10); /* Delay 10ms */
4271 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4274 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4275 if ((~iqk_ready) || (delay_count > 20))
4283 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4284 /* ============RXIQK Check============== */
4285 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4287 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4288 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4289 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4290 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4294 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4295 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4298 if (cal_retry == 10)
4305 if (cal_retry == 10)
4312 rx_x0[cal] = vdf_x[k-1];
4313 rx_y0[cal] = vdf_y[k-1];
4315 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */
4319 /* ====== RX mode TXK (RXK Step 1) ====== */
4320 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4321 /* 1. TX RF Setting */
4322 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4323 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4324 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4325 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4326 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4327 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4328 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4329 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4330 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4331 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4333 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4334 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4335 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4336 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4337 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4338 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4342 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4343 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4345 mdelay(10); /* Delay 10ms */
4346 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4349 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4350 if ((~iqk_ready) || (delay_count > 20))
4358 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4359 /* ============TXIQK Check============== */
4360 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4363 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4364 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4365 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4366 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4372 if (cal_retry == 10)
4378 if (cal_retry == 10)
4383 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4384 tx_x0_rxk[cal] = tx_x0[cal];
4385 tx_y0_rxk[cal] = tx_y0[cal];
4387 RT_TRACE(rtlpriv, COMP_IQK,
4391 /* ====== RX IQK ====== */
4392 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4393 /* 1. RX RF Setting */
4394 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4395 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4396 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4397 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4398 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4399 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4400 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4402 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4403 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4404 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4405 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4406 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4407 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4408 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4410 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4411 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4412 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4413 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4415 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4417 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4422 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4423 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4425 mdelay(10); /* Delay 10ms */
4426 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4429 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4430 if ((~iqk_ready) || (delay_count > 20))
4438 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4439 /* ============RXIQK Check============== */
4440 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4442 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4443 rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4444 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4445 rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4449 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4450 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4453 if (cal_retry == 10)
4460 if (cal_retry == 10)
4470 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4471 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4479 /* FillIQK Result */
4482 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4483 "========Path_A =======\n");
4484 if (tx_average == 0)
4487 for (i = 0; i < tx_average; i++) {
4488 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4489 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4490 (tx_x0_rxk[i])>>21&0x000007ff, i,
4491 (tx_y0_rxk[i])>>21&0x000007ff);
4492 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4493 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4494 (tx_x0[i])>>21&0x000007ff, i,
4495 (tx_y0[i])>>21&0x000007ff);
4497 for (i = 0; i < tx_average; i++) {
4498 for (ii = i+1; ii < tx_average; ii++) {
4499 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4500 if (dx < 3 && dx > -3) {
4501 dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4502 if (dy < 3 && dy > -3) {
4503 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4504 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4515 _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4517 _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4519 if (rx_average == 0)
4522 for (i = 0; i < rx_average; i++)
4523 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4524 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4525 (rx_x0[i])>>21&0x000007ff, i,
4526 (rx_y0[i])>>21&0x000007ff);
4527 for (i = 0; i < rx_average; i++) {
4528 for (ii = i+1; ii < rx_average; ii++) {
4529 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4530 if (dx < 4 && dx > -4) {
4531 dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4532 if (dy < 4 && dy > -4) {
4533 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4534 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4545 _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4547 _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4554 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4555 enum radio_path path,
4557 u32 *rf_backup, u32 rf_reg_num)
4559 struct rtl_priv *rtlpriv = rtl_priv(hw);
4562 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4563 for (i = 0; i < RF_REG_NUM; i++)
4564 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4569 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4570 "RestoreRF Path A Success!!!!\n");
4577 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4578 u32 *afe_backup, u32 *backup_afe_reg,
4582 struct rtl_priv *rtlpriv = rtl_priv(hw);
4584 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4585 /* Reload AFE Parameters */
4586 for (i = 0; i < afe_num; i++)
4587 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4588 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4589 rtl_write_dword(rtlpriv, 0xc80, 0x0);
4590 rtl_write_dword(rtlpriv, 0xc84, 0x0);
4591 rtl_write_dword(rtlpriv, 0xc88, 0x0);
4592 rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4593 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4594 rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4595 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4596 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4597 rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4598 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4601 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4603 u32 *backup_macbb_reg,
4607 struct rtl_priv *rtlpriv = rtl_priv(hw);
4609 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4610 /* Reload MacBB Parameters */
4611 for (i = 0; i < macbb_num; i++)
4612 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4613 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4616 #undef MACBB_REG_NUM
4620 #define MACBB_REG_NUM 11
4621 #define AFE_REG_NUM 12
4622 #define RF_REG_NUM 3
4624 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4626 u32 macbb_backup[MACBB_REG_NUM];
4627 u32 afe_backup[AFE_REG_NUM];
4628 u32 rfa_backup[RF_REG_NUM];
4629 u32 rfb_backup[RF_REG_NUM];
4630 u32 backup_macbb_reg[MACBB_REG_NUM] = {
4631 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4632 0xe00, 0xe50, 0x838, 0x82c
4634 u32 backup_afe_reg[AFE_REG_NUM] = {
4635 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4636 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4638 u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4640 _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4642 _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4643 _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4646 _rtl8821ae_iqk_configure_mac(hw);
4647 _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4648 _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4651 _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4652 _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4656 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4658 struct rtl_priv *rtlpriv = rtl_priv(hw);
4659 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4660 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4661 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4664 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4666 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4669 #undef IQK_ADDA_REG_NUM
4670 #undef IQK_DELAY_TIME
4672 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4676 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4677 u8 thermal_value, u8 threshold)
4679 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4681 rtldm->thermalvalue_iqk = thermal_value;
4682 rtl8812ae_phy_iq_calibrate(hw, false);
4685 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4687 struct rtl_priv *rtlpriv = rtl_priv(hw);
4688 struct rtl_phy *rtlphy = &rtlpriv->phy;
4690 if (!rtlphy->lck_inprogress) {
4691 spin_lock(&rtlpriv->locks.iqk_lock);
4692 rtlphy->lck_inprogress = true;
4693 spin_unlock(&rtlpriv->locks.iqk_lock);
4695 _rtl8821ae_phy_iq_calibrate(hw);
4697 spin_lock(&rtlpriv->locks.iqk_lock);
4698 rtlphy->lck_inprogress = false;
4699 spin_unlock(&rtlpriv->locks.iqk_lock);
4703 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4705 struct rtl_priv *rtlpriv = rtl_priv(hw);
4706 struct rtl_phy *rtlphy = &rtlpriv->phy;
4709 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4710 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4711 (int)(sizeof(rtlphy->iqk_matrix) /
4712 sizeof(struct iqk_matrix_regs)),
4713 IQK_MATRIX_SETTINGS_NUM);
4715 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4716 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4717 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4718 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4719 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4721 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4722 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4723 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4724 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4726 rtlphy->iqk_matrix[i].iqk_done = false;
4730 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4731 u8 thermal_value, u8 threshold)
4733 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4735 rtl8821ae_reset_iqk_result(hw);
4737 rtldm->thermalvalue_iqk = thermal_value;
4738 rtl8821ae_phy_iq_calibrate(hw, false);
4741 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4745 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
4749 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4751 _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4754 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4756 struct rtl_priv *rtlpriv = rtl_priv(hw);
4757 struct rtl_phy *rtlphy = &rtlpriv->phy;
4758 bool postprocessing = false;
4760 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4761 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4762 iotype, rtlphy->set_io_inprogress);
4765 case IO_CMD_RESUME_DM_BY_SCAN:
4766 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4767 "[IO CMD] Resume DM after scan.\n");
4768 postprocessing = true;
4770 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4771 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4772 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4773 "[IO CMD] Pause DM before scan.\n");
4774 postprocessing = true;
4777 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4778 "switch case not process\n");
4782 if (postprocessing && !rtlphy->set_io_inprogress) {
4783 rtlphy->set_io_inprogress = true;
4784 rtlphy->current_io_type = iotype;
4788 rtl8821ae_phy_set_io(hw);
4789 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4793 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4795 struct rtl_priv *rtlpriv = rtl_priv(hw);
4796 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4797 struct rtl_phy *rtlphy = &rtlpriv->phy;
4799 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4800 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4801 rtlphy->current_io_type, rtlphy->set_io_inprogress);
4802 switch (rtlphy->current_io_type) {
4803 case IO_CMD_RESUME_DM_BY_SCAN:
4804 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4805 _rtl8821ae_resume_tx_beacon(hw);
4806 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4807 rtl8821ae_dm_write_cck_cca_thres(hw,
4808 rtlphy->initgain_backup.cca);
4810 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4811 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4812 _rtl8821ae_stop_tx_beacon(hw);
4813 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4814 rtl8821ae_dm_write_dig(hw, 0x17);
4815 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4816 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4818 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4821 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4822 "switch case not process\n");
4825 rtlphy->set_io_inprogress = false;
4826 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4827 "(%#x)\n", rtlphy->current_io_type);
4830 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4832 struct rtl_priv *rtlpriv = rtl_priv(hw);
4834 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4835 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4836 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4837 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4838 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4841 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4842 enum rf_pwrstate rfpwr_state)
4844 struct rtl_priv *rtlpriv = rtl_priv(hw);
4845 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4846 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4847 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4848 bool bresult = true;
4850 struct rtl8192_tx_ring *ring = NULL;
4852 switch (rfpwr_state) {
4854 if ((ppsc->rfpwr_state == ERFOFF) &&
4855 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4856 bool rtstatus = false;
4857 u32 initializecount = 0;
4861 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4862 "IPS Set eRf nic enable\n");
4863 rtstatus = rtl_ps_enable_nic(hw);
4864 } while (!rtstatus && (initializecount < 10));
4865 RT_CLEAR_PS_LEVEL(ppsc,
4866 RT_RF_OFF_LEVL_HALT_NIC);
4868 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4869 "Set ERFON sleeped:%d ms\n",
4870 jiffies_to_msecs(jiffies -
4872 last_sleep_jiffies));
4873 ppsc->last_awake_jiffies = jiffies;
4874 rtl8821ae_phy_set_rf_on(hw);
4876 if (mac->link_state == MAC80211_LINKED) {
4877 rtlpriv->cfg->ops->led_control(hw,
4880 rtlpriv->cfg->ops->led_control(hw,
4885 for (queue_id = 0, i = 0;
4886 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4887 ring = &pcipriv->dev.tx_ring[queue_id];
4888 if (queue_id == BEACON_QUEUE ||
4889 skb_queue_len(&ring->queue) == 0) {
4893 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4894 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4896 skb_queue_len(&ring->queue));
4901 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4902 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4903 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4904 MAX_DOZE_WAITING_TIMES_9x,
4906 skb_queue_len(&ring->queue));
4911 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4912 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4913 "IPS Set eRf nic disable\n");
4914 rtl_ps_disable_nic(hw);
4915 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4917 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4918 rtlpriv->cfg->ops->led_control(hw,
4921 rtlpriv->cfg->ops->led_control(hw,
4927 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4928 "switch case not process\n");
4933 ppsc->rfpwr_state = rfpwr_state;
4937 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4938 enum rf_pwrstate rfpwr_state)
4940 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4942 bool bresult = false;
4944 if (rfpwr_state == ppsc->rfpwr_state)
4946 bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);