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 s8 reg_swing_2g = -1;/* 0xff; */
471 s8 reg_swing_5g = -1;/* 0xff; */
472 s8 swing_2g = -1 * reg_swing_2g;
473 s8 swing_5g = -1 * reg_swing_5g;
475 const s8 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 s8 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\n", 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\n", 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;
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\n", 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 s8 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 s8 _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 s8 channel_index = -1;
1567 if (band == BAND_ON_2_4G)
1568 channel_index = channel - 1;
1569 else if (band == BAND_ON_5G) {
1570 for (i = 0; i < sizeof(channel5g)/sizeof(u8); ++i) {
1571 if (channel5g[i] == channel)
1575 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s\n",
1578 if (channel_index == -1)
1579 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1580 "Invalid Channel %d of Band %d in %s\n", channel,
1583 return channel_index;
1586 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1587 u8 *pband, u8 *pbandwidth,
1588 u8 *prate_section, u8 *prf_path,
1589 u8 *pchannel, u8 *ppower_limit)
1591 struct rtl_priv *rtlpriv = rtl_priv(hw);
1592 struct rtl_phy *rtlphy = &rtlpriv->phy;
1593 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1595 s8 power_limit = 0, prev_power_limit, ret;
1597 if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1598 !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1600 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1601 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1602 channel, power_limit);
1605 power_limit = power_limit > MAX_POWER_INDEX ?
1606 MAX_POWER_INDEX : power_limit;
1608 if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1610 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1612 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1614 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1617 if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1619 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1621 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1622 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1624 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1625 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1627 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1628 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1630 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1631 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1634 if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1636 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1638 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1640 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1643 if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1644 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1651 channel_index = ret;
1653 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1654 [bandwidth][rate_section]
1655 [channel_index][RF90_PATH_A];
1657 if (power_limit < prev_power_limit)
1658 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1659 [rate_section][channel_index][RF90_PATH_A] =
1662 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1663 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1664 regulation, bandwidth, rate_section, channel_index,
1665 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1666 [rate_section][channel_index][RF90_PATH_A]);
1667 } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1668 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1675 channel_index = ret;
1677 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1678 [rate_section][channel_index]
1681 if (power_limit < prev_power_limit)
1682 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1683 [rate_section][channel_index][RF90_PATH_A] = power_limit;
1685 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1686 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1687 regulation, bandwidth, rate_section, channel,
1688 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1689 [rate_section][channel_index][RF90_PATH_A]);
1691 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1692 "Cannot recognize the band info in %s\n", pband);
1697 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1698 u8 *regulation, u8 *band,
1699 u8 *bandwidth, u8 *rate_section,
1700 u8 *rf_path, u8 *channel,
1703 _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1704 rate_section, rf_path, channel,
1708 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1710 struct rtl_priv *rtlpriv = rtl_priv(hw);
1711 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1716 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1717 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1718 array = RTL8812AE_TXPWR_LMT;
1720 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1721 array = RTL8821AE_TXPWR_LMT;
1724 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1727 for (i = 0; i < array_len; i += 7) {
1728 u8 *regulation = array[i];
1729 u8 *band = array[i+1];
1730 u8 *bandwidth = array[i+2];
1731 u8 *rate = array[i+3];
1732 u8 *rf_path = array[i+4];
1733 u8 *chnl = array[i+5];
1734 u8 *val = array[i+6];
1736 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1737 bandwidth, rate, rf_path,
1742 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1744 struct rtl_priv *rtlpriv = rtl_priv(hw);
1745 struct rtl_phy *rtlphy = &rtlpriv->phy;
1746 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1749 _rtl8821ae_phy_init_txpower_limit(hw);
1751 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1752 if (rtlefuse->eeprom_regulatory != 2)
1753 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1755 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1756 BASEBAND_CONFIG_PHY_REG);
1757 if (rtstatus != true) {
1758 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
1761 _rtl8821ae_phy_init_tx_power_by_rate(hw);
1762 if (rtlefuse->autoload_failflag == false) {
1763 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1764 BASEBAND_CONFIG_PHY_REG);
1766 if (rtstatus != true) {
1767 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
1771 _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1773 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1774 if (rtlefuse->eeprom_regulatory != 2)
1775 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1777 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1778 BASEBAND_CONFIG_AGC_TAB);
1780 if (rtstatus != true) {
1781 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1784 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1785 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1789 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1791 struct rtl_priv *rtlpriv = rtl_priv(hw);
1792 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1797 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1798 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1799 arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1800 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1802 arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1803 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1805 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1806 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1807 for (i = 0; i < arraylength; i += 2) {
1809 v2 = (u8)ptrarray[i + 1];
1810 if (v1 < 0xCDCDCDCD) {
1811 rtl_write_byte(rtlpriv, v1, (u8)v2);
1814 if (!_rtl8821ae_check_condition(hw, v1)) {
1815 /*Discard the following (offset, data) pairs*/
1816 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1817 while (v2 != 0xDEAD &&
1819 v2 != 0xCDCD && i < arraylength - 2) {
1820 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1822 i -= 2; /* prevent from for-loop += 2*/
1823 } else {/*Configure matched pairs and skip to end of if-else.*/
1824 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1825 while (v2 != 0xDEAD &&
1827 v2 != 0xCDCD && i < arraylength - 2) {
1828 rtl_write_byte(rtlpriv, v1, v2);
1829 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1832 while (v2 != 0xDEAD && i < arraylength - 2)
1833 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1840 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1843 struct rtl_priv *rtlpriv = rtl_priv(hw);
1844 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1850 if (configtype == BASEBAND_CONFIG_PHY_REG) {
1851 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1852 arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1853 array_table = RTL8812AE_PHY_REG_ARRAY;
1855 arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1856 array_table = RTL8821AE_PHY_REG_ARRAY;
1859 for (i = 0; i < arraylen; i += 2) {
1860 v1 = array_table[i];
1861 v2 = array_table[i + 1];
1862 if (v1 < 0xCDCDCDCD) {
1863 _rtl8821ae_config_bb_reg(hw, v1, v2);
1865 } else {/*This line is the start line of branch.*/
1866 if (!_rtl8821ae_check_condition(hw, v1)) {
1867 /*Discard the following (offset, data) pairs*/
1868 READ_NEXT_PAIR(array_table, v1, v2, i);
1869 while (v2 != 0xDEAD &&
1873 READ_NEXT_PAIR(array_table, v1,
1877 i -= 2; /* prevent from for-loop += 2*/
1878 } else {/*Configure matched pairs and skip to end of if-else.*/
1879 READ_NEXT_PAIR(array_table, v1, v2, i);
1880 while (v2 != 0xDEAD &&
1884 _rtl8821ae_config_bb_reg(hw, v1,
1886 READ_NEXT_PAIR(array_table, v1,
1890 while (v2 != 0xDEAD &&
1892 READ_NEXT_PAIR(array_table, v1,
1898 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1899 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1900 arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1901 array_table = RTL8812AE_AGC_TAB_ARRAY;
1903 arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1904 array_table = RTL8821AE_AGC_TAB_ARRAY;
1907 for (i = 0; i < arraylen; i = i + 2) {
1908 v1 = array_table[i];
1909 v2 = array_table[i+1];
1910 if (v1 < 0xCDCDCDCD) {
1911 rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1914 } else {/*This line is the start line of branch.*/
1915 if (!_rtl8821ae_check_condition(hw, v1)) {
1916 /*Discard the following (offset, data) pairs*/
1917 READ_NEXT_PAIR(array_table, v1, v2, i);
1918 while (v2 != 0xDEAD &&
1922 READ_NEXT_PAIR(array_table, v1,
1925 i -= 2; /* prevent from for-loop += 2*/
1926 } else {/*Configure matched pairs and skip to end of if-else.*/
1927 READ_NEXT_PAIR(array_table, v1, v2, i);
1928 while (v2 != 0xDEAD &&
1932 rtl_set_bbreg(hw, v1, MASKDWORD,
1935 READ_NEXT_PAIR(array_table, v1,
1939 while (v2 != 0xDEAD &&
1941 READ_NEXT_PAIR(array_table, v1,
1945 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1946 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1947 array_table[i], array_table[i + 1]);
1954 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1958 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1959 index = (u8)((regaddr - 0xC20) / 4);
1960 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1961 index = (u8)((regaddr - 0xE20) / 4);
1963 RT_ASSERT(!COMP_INIT,
1964 "Invalid RegAddr 0x%x\n", regaddr);
1968 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1969 u32 band, u32 rfpath,
1970 u32 txnum, u32 regaddr,
1971 u32 bitmask, u32 data)
1973 struct rtl_priv *rtlpriv = rtl_priv(hw);
1974 struct rtl_phy *rtlphy = &rtlpriv->phy;
1975 u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1977 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1978 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1979 band = BAND_ON_2_4G;
1981 if (rfpath >= MAX_RF_PATH) {
1982 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1983 rfpath = MAX_RF_PATH - 1;
1985 if (txnum >= MAX_RF_PATH) {
1986 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1987 txnum = MAX_RF_PATH - 1;
1989 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1990 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1991 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1992 band, rfpath, txnum, rate_section,
1993 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1996 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
1999 struct rtl_priv *rtlpriv = rtl_priv(hw);
2000 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2004 u32 v1, v2, v3, v4, v5, v6;
2006 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
2007 arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
2008 array = RTL8812AE_PHY_REG_ARRAY_PG;
2010 arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
2011 array = RTL8821AE_PHY_REG_ARRAY_PG;
2014 if (configtype != BASEBAND_CONFIG_PHY_REG) {
2015 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
2016 "configtype != BaseBand_Config_PHY_REG\n");
2019 for (i = 0; i < arraylen; i += 6) {
2027 if (v1 < 0xCDCDCDCD) {
2028 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
2029 (v4 == 0xfe || v4 == 0xffe)) {
2034 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
2037 else if (v4 == 0xfd)
2039 else if (v4 == 0xfc)
2041 else if (v4 == 0xfb)
2043 else if (v4 == 0xfa)
2045 else if (v4 == 0xf9)
2048 _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
2052 /*don't need the hw_body*/
2053 if (!_rtl8821ae_check_condition(hw, v1)) {
2054 i += 2; /* skip the pair of expression*/
2058 while (v2 != 0xDEAD) {
2071 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2072 enum radio_path rfpath)
2075 bool rtstatus = true;
2076 u32 *radioa_array_table_a, *radioa_array_table_b;
2077 u16 radioa_arraylen_a, radioa_arraylen_b;
2078 struct rtl_priv *rtlpriv = rtl_priv(hw);
2081 radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
2082 radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
2083 radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
2084 radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2085 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2086 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2087 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2091 for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2092 v1 = radioa_array_table_a[i];
2093 v2 = radioa_array_table_a[i+1];
2094 if (v1 < 0xcdcdcdcd) {
2095 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2097 } else{/*This line is the start line of branch.*/
2098 if (!_rtl8821ae_check_condition(hw, v1)) {
2099 /*Discard the following (offset, data) pairs*/
2100 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2101 while (v2 != 0xDEAD &&
2103 v2 != 0xCDCD && i < radioa_arraylen_a-2)
2104 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2106 i -= 2; /* prevent from for-loop += 2*/
2107 } else {/*Configure matched pairs and skip to end of if-else.*/
2108 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2109 while (v2 != 0xDEAD &&
2111 v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2112 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2113 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2116 while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2117 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2124 for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2125 v1 = radioa_array_table_b[i];
2126 v2 = radioa_array_table_b[i+1];
2127 if (v1 < 0xcdcdcdcd) {
2128 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2130 } else{/*This line is the start line of branch.*/
2131 if (!_rtl8821ae_check_condition(hw, v1)) {
2132 /*Discard the following (offset, data) pairs*/
2133 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2134 while (v2 != 0xDEAD &&
2136 v2 != 0xCDCD && i < radioa_arraylen_b-2)
2137 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2139 i -= 2; /* prevent from for-loop += 2*/
2140 } else {/*Configure matched pairs and skip to end of if-else.*/
2141 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2142 while (v2 != 0xDEAD &&
2144 v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2145 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2146 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2149 while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2150 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2157 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2158 "switch case %#x not processed\n", rfpath);
2164 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2165 enum radio_path rfpath)
2167 #define READ_NEXT_RF_PAIR(v1, v2, i) \
2170 v1 = radioa_array_table[i]; \
2171 v2 = radioa_array_table[i+1]; \
2176 bool rtstatus = true;
2177 u32 *radioa_array_table;
2178 u16 radioa_arraylen;
2179 struct rtl_priv *rtlpriv = rtl_priv(hw);
2180 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2183 radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2184 radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2185 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2186 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2187 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2191 for (i = 0; i < radioa_arraylen; i = i + 2) {
2192 v1 = radioa_array_table[i];
2193 v2 = radioa_array_table[i+1];
2194 if (v1 < 0xcdcdcdcd)
2195 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2196 else{/*This line is the start line of branch.*/
2197 if (!_rtl8821ae_check_condition(hw, v1)) {
2198 /*Discard the following (offset, data) pairs*/
2199 READ_NEXT_RF_PAIR(v1, v2, i);
2200 while (v2 != 0xDEAD &&
2202 v2 != 0xCDCD && i < radioa_arraylen - 2)
2203 READ_NEXT_RF_PAIR(v1, v2, i);
2205 i -= 2; /* prevent from for-loop += 2*/
2206 } else {/*Configure matched pairs and skip to end of if-else.*/
2207 READ_NEXT_RF_PAIR(v1, v2, i);
2208 while (v2 != 0xDEAD &&
2210 v2 != 0xCDCD && i < radioa_arraylen - 2) {
2211 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2212 READ_NEXT_RF_PAIR(v1, v2, i);
2215 while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2216 READ_NEXT_RF_PAIR(v1, v2, i);
2225 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2226 "switch case %#x not processed\n", rfpath);
2232 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2234 struct rtl_priv *rtlpriv = rtl_priv(hw);
2235 struct rtl_phy *rtlphy = &rtlpriv->phy;
2237 rtlphy->default_initialgain[0] =
2238 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2239 rtlphy->default_initialgain[1] =
2240 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2241 rtlphy->default_initialgain[2] =
2242 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2243 rtlphy->default_initialgain[3] =
2244 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2246 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2247 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2248 rtlphy->default_initialgain[0],
2249 rtlphy->default_initialgain[1],
2250 rtlphy->default_initialgain[2],
2251 rtlphy->default_initialgain[3]);
2253 rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2254 ROFDM0_RXDETECTOR3, MASKBYTE0);
2255 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2256 ROFDM0_RXDETECTOR2, MASKDWORD);
2258 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2259 "Default framesync (0x%x) = 0x%x\n",
2260 ROFDM0_RXDETECTOR3, rtlphy->framesync);
2263 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2265 struct rtl_priv *rtlpriv = rtl_priv(hw);
2266 struct rtl_phy *rtlphy = &rtlpriv->phy;
2268 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2269 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2271 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2272 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2274 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2275 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2277 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2278 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2280 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2281 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2283 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2284 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2286 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2287 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2290 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2292 struct rtl_priv *rtlpriv = rtl_priv(hw);
2293 struct rtl_phy *rtlphy = &rtlpriv->phy;
2297 txpwr_level = rtlphy->cur_cck_txpwridx;
2298 txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2299 WIRELESS_MODE_B, txpwr_level);
2300 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2301 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2303 txpwr_level) > txpwr_dbm)
2305 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2307 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2308 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2309 WIRELESS_MODE_N_24G,
2310 txpwr_level) > txpwr_dbm)
2312 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2314 *powerlevel = txpwr_dbm;
2317 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2322 if (channel <= 14) {
2324 *chnl_index = channel - 1;
2328 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2329 if (channel5g[i] == channel) {
2338 static s8 _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2340 s8 rate_section = 0;
2374 case DESC_RATEMCS10:
2375 case DESC_RATEMCS11:
2378 case DESC_RATEMCS12:
2379 case DESC_RATEMCS13:
2380 case DESC_RATEMCS14:
2381 case DESC_RATEMCS15:
2384 case DESC_RATEVHT1SS_MCS0:
2385 case DESC_RATEVHT1SS_MCS1:
2386 case DESC_RATEVHT1SS_MCS2:
2387 case DESC_RATEVHT1SS_MCS3:
2390 case DESC_RATEVHT1SS_MCS4:
2391 case DESC_RATEVHT1SS_MCS5:
2392 case DESC_RATEVHT1SS_MCS6:
2393 case DESC_RATEVHT1SS_MCS7:
2396 case DESC_RATEVHT1SS_MCS8:
2397 case DESC_RATEVHT1SS_MCS9:
2398 case DESC_RATEVHT2SS_MCS0:
2399 case DESC_RATEVHT2SS_MCS1:
2402 case DESC_RATEVHT2SS_MCS2:
2403 case DESC_RATEVHT2SS_MCS3:
2404 case DESC_RATEVHT2SS_MCS4:
2405 case DESC_RATEVHT2SS_MCS5:
2408 case DESC_RATEVHT2SS_MCS6:
2409 case DESC_RATEVHT2SS_MCS7:
2410 case DESC_RATEVHT2SS_MCS8:
2411 case DESC_RATEVHT2SS_MCS9:
2415 RT_ASSERT(true, "Rate_Section is Illegal\n");
2419 return rate_section;
2422 static s8 _rtl8812ae_phy_get_world_wide_limit(s8 *limit_table)
2424 s8 min = limit_table[0];
2427 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2428 if (limit_table[i] < min)
2429 min = limit_table[i];
2434 static s8 _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2436 enum ht_channel_width bandwidth,
2437 enum radio_path rf_path,
2438 u8 rate, u8 channel)
2440 struct rtl_priv *rtlpriv = rtl_priv(hw);
2441 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2442 struct rtl_phy *rtlphy = &rtlpriv->phy;
2443 short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2444 rate_section = -1, channel_temp = -1;
2445 u16 bd, regu, bdwidth, sec, chnl;
2446 s8 power_limit = MAX_POWER_INDEX;
2448 if (rtlefuse->eeprom_regulatory == 2)
2449 return MAX_POWER_INDEX;
2451 regulation = TXPWR_LMT_WW;
2453 if (band == BAND_ON_2_4G)
2455 else if (band == BAND_ON_5G)
2458 if (bandwidth == HT_CHANNEL_WIDTH_20)
2460 else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2462 else if (bandwidth == HT_CHANNEL_WIDTH_80)
2494 case DESC_RATEMCS10:
2495 case DESC_RATEMCS11:
2496 case DESC_RATEMCS12:
2497 case DESC_RATEMCS13:
2498 case DESC_RATEMCS14:
2499 case DESC_RATEMCS15:
2502 case DESC_RATEVHT1SS_MCS0:
2503 case DESC_RATEVHT1SS_MCS1:
2504 case DESC_RATEVHT1SS_MCS2:
2505 case DESC_RATEVHT1SS_MCS3:
2506 case DESC_RATEVHT1SS_MCS4:
2507 case DESC_RATEVHT1SS_MCS5:
2508 case DESC_RATEVHT1SS_MCS6:
2509 case DESC_RATEVHT1SS_MCS7:
2510 case DESC_RATEVHT1SS_MCS8:
2511 case DESC_RATEVHT1SS_MCS9:
2514 case DESC_RATEVHT2SS_MCS0:
2515 case DESC_RATEVHT2SS_MCS1:
2516 case DESC_RATEVHT2SS_MCS2:
2517 case DESC_RATEVHT2SS_MCS3:
2518 case DESC_RATEVHT2SS_MCS4:
2519 case DESC_RATEVHT2SS_MCS5:
2520 case DESC_RATEVHT2SS_MCS6:
2521 case DESC_RATEVHT2SS_MCS7:
2522 case DESC_RATEVHT2SS_MCS8:
2523 case DESC_RATEVHT2SS_MCS9:
2527 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2528 "Wrong rate 0x%x\n", rate);
2532 if (band_temp == BAND_ON_5G && rate_section == 0)
2533 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2534 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2536 /*workaround for wrong index combination to obtain tx power limit,
2537 OFDM only exists in BW 20M*/
2538 if (rate_section == 1)
2541 /*workaround for wrong index combination to obtain tx power limit,
2542 *HT on 80M will reference to HT on 40M
2544 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2545 bandwidth_temp == 2)
2548 if (band == BAND_ON_2_4G)
2549 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2550 BAND_ON_2_4G, channel);
2551 else if (band == BAND_ON_5G)
2552 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2553 BAND_ON_5G, channel);
2554 else if (band == BAND_ON_BOTH)
2555 ;/* BAND_ON_BOTH don't care temporarily */
2557 if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2558 rate_section == -1 || channel_temp == -1) {
2559 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2560 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2561 band_temp, regulation, bandwidth_temp, rf_path,
2562 rate_section, channel_temp);
2563 return MAX_POWER_INDEX;
2568 bdwidth = bandwidth_temp;
2570 chnl = channel_temp;
2572 if (band == BAND_ON_2_4G) {
2573 s8 limits[10] = {0};
2576 for (i = 0; i < 4; ++i)
2577 limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2578 [sec][chnl][rf_path];
2580 power_limit = (regulation == TXPWR_LMT_WW) ?
2581 _rtl8812ae_phy_get_world_wide_limit(limits) :
2582 rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2583 [sec][chnl][rf_path];
2584 } else if (band == BAND_ON_5G) {
2585 s8 limits[10] = {0};
2588 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2589 limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2590 [sec][chnl][rf_path];
2592 power_limit = (regulation == TXPWR_LMT_WW) ?
2593 _rtl8812ae_phy_get_world_wide_limit(limits) :
2594 rtlphy->txpwr_limit_5g[regu][chnl]
2595 [sec][chnl][rf_path];
2597 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2598 "No power limit table of the specified band\n");
2603 static s8 _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2604 u8 band, u8 path, u8 rate)
2606 struct rtl_priv *rtlpriv = rtl_priv(hw);
2607 struct rtl_phy *rtlphy = &rtlpriv->phy;
2608 u8 shift = 0, rate_section, tx_num;
2612 rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2613 tx_num = RF_TX_NUM_NONIMPLEMENT;
2615 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2616 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2617 (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2630 case DESC_RATEMCS12:
2631 case DESC_RATEVHT1SS_MCS0:
2632 case DESC_RATEVHT1SS_MCS4:
2633 case DESC_RATEVHT1SS_MCS8:
2634 case DESC_RATEVHT2SS_MCS2:
2635 case DESC_RATEVHT2SS_MCS6:
2644 case DESC_RATEMCS13:
2645 case DESC_RATEVHT1SS_MCS1:
2646 case DESC_RATEVHT1SS_MCS5:
2647 case DESC_RATEVHT1SS_MCS9:
2648 case DESC_RATEVHT2SS_MCS3:
2649 case DESC_RATEVHT2SS_MCS7:
2657 case DESC_RATEMCS10:
2658 case DESC_RATEMCS14:
2659 case DESC_RATEVHT1SS_MCS2:
2660 case DESC_RATEVHT1SS_MCS6:
2661 case DESC_RATEVHT2SS_MCS0:
2662 case DESC_RATEVHT2SS_MCS4:
2663 case DESC_RATEVHT2SS_MCS8:
2671 case DESC_RATEMCS11:
2672 case DESC_RATEMCS15:
2673 case DESC_RATEVHT1SS_MCS3:
2674 case DESC_RATEVHT1SS_MCS7:
2675 case DESC_RATEVHT2SS_MCS1:
2676 case DESC_RATEVHT2SS_MCS5:
2677 case DESC_RATEVHT2SS_MCS9:
2681 RT_ASSERT(true, "Rate_Section is Illegal\n");
2685 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2686 [tx_num][rate_section] >> shift) & 0xff;
2688 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2689 if (rtlpriv->efuse.eeprom_regulatory != 2) {
2690 limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2691 rtlphy->current_chan_bw, path, rate,
2692 rtlphy->current_channel);
2694 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2695 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2697 if (tx_pwr_diff < (-limit))
2698 tx_pwr_diff = -limit;
2702 tx_pwr_diff = limit;
2704 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2706 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2707 "Maximum power by rate %d, final power by rate %d\n",
2708 limit, tx_pwr_diff);
2714 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2715 u8 rate, u8 bandwidth, u8 channel)
2717 struct rtl_priv *rtlpriv = rtl_priv(hw);
2718 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2719 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2720 u8 index = (channel - 1);
2722 bool in_24g = false;
2723 s8 powerdiff_byrate = 0;
2725 if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2726 (channel > 14 || channel < 1)) ||
2727 ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2729 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2730 "Illegal channel!!\n");
2733 in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2735 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2736 txpower = rtlefuse->txpwrlevel_cck[path][index];
2737 else if (DESC_RATE6M <= rate)
2738 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2740 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2742 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2743 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2744 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2746 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2747 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2748 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2749 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2750 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2751 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2752 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2753 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2754 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2755 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2756 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2757 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2758 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2759 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2760 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2761 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2762 (DESC_RATEVHT1SS_MCS0 <= rate &&
2763 rate <= DESC_RATEVHT2SS_MCS9))
2764 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2765 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2766 (DESC_RATEVHT2SS_MCS0 <= rate &&
2767 rate <= DESC_RATEVHT2SS_MCS9))
2768 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2771 if (DESC_RATE6M <= rate)
2772 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2774 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2777 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2778 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2779 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2781 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2782 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2783 (DESC_RATEVHT1SS_MCS0 <= rate &&
2784 rate <= DESC_RATEVHT2SS_MCS9))
2785 txpower += rtlefuse->txpwr_5g_bw20diff[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_5g_bw20diff[path][TX_2S];
2790 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2791 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2792 (DESC_RATEVHT1SS_MCS0 <= rate &&
2793 rate <= DESC_RATEVHT2SS_MCS9))
2794 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2795 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2796 (DESC_RATEVHT2SS_MCS0 <= rate &&
2797 rate <= DESC_RATEVHT2SS_MCS9))
2798 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2799 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2802 for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i)
2803 if (channel5g_80m[i] == channel)
2806 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2807 (DESC_RATEVHT1SS_MCS0 <= rate &&
2808 rate <= DESC_RATEVHT2SS_MCS9))
2809 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2810 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2811 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2812 (DESC_RATEVHT2SS_MCS0 <= rate &&
2813 rate <= DESC_RATEVHT2SS_MCS9))
2814 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2815 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2816 + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2819 if (rtlefuse->eeprom_regulatory != 2)
2821 _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2824 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2825 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2826 txpower -= powerdiff_byrate;
2828 txpower += powerdiff_byrate;
2830 if (rate > DESC_RATE11M)
2831 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2833 txpower += rtlpriv->dm.remnant_cck_idx;
2835 if (txpower > MAX_POWER_INDEX)
2836 txpower = MAX_POWER_INDEX;
2841 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2842 u8 power_index, u8 path, u8 rate)
2844 struct rtl_priv *rtlpriv = rtl_priv(hw);
2846 if (path == RF90_PATH_A) {
2849 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2850 MASKBYTE0, power_index);
2853 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2854 MASKBYTE1, power_index);
2857 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2858 MASKBYTE2, power_index);
2861 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2862 MASKBYTE3, power_index);
2865 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2866 MASKBYTE0, power_index);
2869 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2870 MASKBYTE1, power_index);
2873 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2874 MASKBYTE2, power_index);
2877 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2878 MASKBYTE3, power_index);
2881 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2882 MASKBYTE0, power_index);
2885 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2886 MASKBYTE1, power_index);
2889 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2890 MASKBYTE2, power_index);
2893 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2894 MASKBYTE3, power_index);
2897 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2898 MASKBYTE0, power_index);
2901 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2902 MASKBYTE1, power_index);
2905 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2906 MASKBYTE2, power_index);
2909 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2910 MASKBYTE3, power_index);
2913 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2914 MASKBYTE0, power_index);
2917 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2918 MASKBYTE1, power_index);
2921 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2922 MASKBYTE2, power_index);
2925 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2926 MASKBYTE3, power_index);
2929 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2930 MASKBYTE0, power_index);
2933 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2934 MASKBYTE1, power_index);
2936 case DESC_RATEMCS10:
2937 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2938 MASKBYTE2, power_index);
2940 case DESC_RATEMCS11:
2941 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2942 MASKBYTE3, power_index);
2944 case DESC_RATEMCS12:
2945 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2946 MASKBYTE0, power_index);
2948 case DESC_RATEMCS13:
2949 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2950 MASKBYTE1, power_index);
2952 case DESC_RATEMCS14:
2953 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2954 MASKBYTE2, power_index);
2956 case DESC_RATEMCS15:
2957 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2958 MASKBYTE3, power_index);
2960 case DESC_RATEVHT1SS_MCS0:
2961 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2962 MASKBYTE0, power_index);
2964 case DESC_RATEVHT1SS_MCS1:
2965 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2966 MASKBYTE1, power_index);
2968 case DESC_RATEVHT1SS_MCS2:
2969 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2970 MASKBYTE2, power_index);
2972 case DESC_RATEVHT1SS_MCS3:
2973 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2974 MASKBYTE3, power_index);
2976 case DESC_RATEVHT1SS_MCS4:
2977 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2978 MASKBYTE0, power_index);
2980 case DESC_RATEVHT1SS_MCS5:
2981 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2982 MASKBYTE1, power_index);
2984 case DESC_RATEVHT1SS_MCS6:
2985 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2986 MASKBYTE2, power_index);
2988 case DESC_RATEVHT1SS_MCS7:
2989 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2990 MASKBYTE3, power_index);
2992 case DESC_RATEVHT1SS_MCS8:
2993 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2994 MASKBYTE0, power_index);
2996 case DESC_RATEVHT1SS_MCS9:
2997 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2998 MASKBYTE1, power_index);
3000 case DESC_RATEVHT2SS_MCS0:
3001 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3002 MASKBYTE2, power_index);
3004 case DESC_RATEVHT2SS_MCS1:
3005 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3006 MASKBYTE3, power_index);
3008 case DESC_RATEVHT2SS_MCS2:
3009 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3010 MASKBYTE0, power_index);
3012 case DESC_RATEVHT2SS_MCS3:
3013 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3014 MASKBYTE1, power_index);
3016 case DESC_RATEVHT2SS_MCS4:
3017 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3018 MASKBYTE2, power_index);
3020 case DESC_RATEVHT2SS_MCS5:
3021 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3022 MASKBYTE3, power_index);
3024 case DESC_RATEVHT2SS_MCS6:
3025 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3026 MASKBYTE0, power_index);
3028 case DESC_RATEVHT2SS_MCS7:
3029 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3030 MASKBYTE1, power_index);
3032 case DESC_RATEVHT2SS_MCS8:
3033 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3034 MASKBYTE2, power_index);
3036 case DESC_RATEVHT2SS_MCS9:
3037 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3038 MASKBYTE3, power_index);
3041 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3042 "Invalid Rate!!\n");
3045 } else if (path == RF90_PATH_B) {
3048 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3049 MASKBYTE0, power_index);
3052 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3053 MASKBYTE1, power_index);
3056 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3057 MASKBYTE2, power_index);
3060 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3061 MASKBYTE3, power_index);
3064 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3065 MASKBYTE0, power_index);
3068 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3069 MASKBYTE1, power_index);
3072 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3073 MASKBYTE2, power_index);
3076 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3077 MASKBYTE3, power_index);
3080 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3081 MASKBYTE0, power_index);
3084 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3085 MASKBYTE1, power_index);
3088 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3089 MASKBYTE2, power_index);
3092 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3093 MASKBYTE3, power_index);
3096 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3097 MASKBYTE0, power_index);
3100 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3101 MASKBYTE1, power_index);
3104 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3105 MASKBYTE2, power_index);
3108 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3109 MASKBYTE3, power_index);
3112 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3113 MASKBYTE0, power_index);
3116 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3117 MASKBYTE1, power_index);
3120 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3121 MASKBYTE2, power_index);
3124 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3125 MASKBYTE3, power_index);
3128 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3129 MASKBYTE0, power_index);
3132 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3133 MASKBYTE1, power_index);
3135 case DESC_RATEMCS10:
3136 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3137 MASKBYTE2, power_index);
3139 case DESC_RATEMCS11:
3140 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3141 MASKBYTE3, power_index);
3143 case DESC_RATEMCS12:
3144 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3145 MASKBYTE0, power_index);
3147 case DESC_RATEMCS13:
3148 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3149 MASKBYTE1, power_index);
3151 case DESC_RATEMCS14:
3152 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3153 MASKBYTE2, power_index);
3155 case DESC_RATEMCS15:
3156 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3157 MASKBYTE3, power_index);
3159 case DESC_RATEVHT1SS_MCS0:
3160 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3161 MASKBYTE0, power_index);
3163 case DESC_RATEVHT1SS_MCS1:
3164 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3165 MASKBYTE1, power_index);
3167 case DESC_RATEVHT1SS_MCS2:
3168 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3169 MASKBYTE2, power_index);
3171 case DESC_RATEVHT1SS_MCS3:
3172 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3173 MASKBYTE3, power_index);
3175 case DESC_RATEVHT1SS_MCS4:
3176 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3177 MASKBYTE0, power_index);
3179 case DESC_RATEVHT1SS_MCS5:
3180 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3181 MASKBYTE1, power_index);
3183 case DESC_RATEVHT1SS_MCS6:
3184 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3185 MASKBYTE2, power_index);
3187 case DESC_RATEVHT1SS_MCS7:
3188 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3189 MASKBYTE3, power_index);
3191 case DESC_RATEVHT1SS_MCS8:
3192 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3193 MASKBYTE0, power_index);
3195 case DESC_RATEVHT1SS_MCS9:
3196 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3197 MASKBYTE1, power_index);
3199 case DESC_RATEVHT2SS_MCS0:
3200 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3201 MASKBYTE2, power_index);
3203 case DESC_RATEVHT2SS_MCS1:
3204 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3205 MASKBYTE3, power_index);
3207 case DESC_RATEVHT2SS_MCS2:
3208 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3209 MASKBYTE0, power_index);
3211 case DESC_RATEVHT2SS_MCS3:
3212 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3213 MASKBYTE1, power_index);
3215 case DESC_RATEVHT2SS_MCS4:
3216 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3217 MASKBYTE2, power_index);
3219 case DESC_RATEVHT2SS_MCS5:
3220 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3221 MASKBYTE3, power_index);
3223 case DESC_RATEVHT2SS_MCS6:
3224 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3225 MASKBYTE0, power_index);
3227 case DESC_RATEVHT2SS_MCS7:
3228 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3229 MASKBYTE1, power_index);
3231 case DESC_RATEVHT2SS_MCS8:
3232 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3233 MASKBYTE2, power_index);
3235 case DESC_RATEVHT2SS_MCS9:
3236 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3237 MASKBYTE3, power_index);
3240 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3241 "Invalid Rate!!\n");
3245 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3246 "Invalid RFPath!!\n");
3250 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3252 u8 channel, u8 size)
3254 struct rtl_priv *rtlpriv = rtl_priv(hw);
3255 struct rtl_phy *rtlphy = &rtlpriv->phy;
3259 for (i = 0; i < size; i++) {
3261 _rtl8821ae_get_txpower_index(hw, path, array[i],
3262 rtlphy->current_chan_bw,
3264 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3269 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3270 u8 bw, u8 channel, u8 path)
3272 struct rtl_priv *rtlpriv = rtl_priv(hw);
3273 struct rtl_phy *rtlphy = &rtlpriv->phy;
3276 u32 power_level, data, offset;
3278 if (path >= rtlphy->num_total_rfpath)
3282 if (path == RF90_PATH_A) {
3284 _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3285 DESC_RATEMCS7, bw, channel);
3286 offset = RA_TXPWRTRAING;
3289 _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3290 DESC_RATEMCS7, bw, channel);
3291 offset = RB_TXPWRTRAING;
3294 for (i = 0; i < 3; i++) {
3296 power_level = power_level - 10;
3298 power_level = power_level - 8;
3300 power_level = power_level - 6;
3302 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3304 rtl_set_bbreg(hw, offset, 0xffffff, data);
3307 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3308 u8 channel, u8 path)
3310 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3311 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3312 struct rtl_priv *rtlpriv = rtl_priv(hw);
3313 struct rtl_phy *rtlphy = &rtlpriv->phy;
3314 u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3316 u8 sizes_of_cck_retes = 4;
3317 u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3318 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3319 DESC_RATE48M, DESC_RATE54M};
3320 u8 sizes_of_ofdm_retes = 8;
3321 u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3322 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3323 DESC_RATEMCS6, DESC_RATEMCS7};
3324 u8 sizes_of_ht_retes_1t = 8;
3325 u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9,
3326 DESC_RATEMCS10, DESC_RATEMCS11,
3327 DESC_RATEMCS12, DESC_RATEMCS13,
3328 DESC_RATEMCS14, DESC_RATEMCS15};
3329 u8 sizes_of_ht_retes_2t = 8;
3330 u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3331 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3332 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3333 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3334 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3335 u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3336 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3337 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3338 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3339 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3340 u8 sizes_of_vht_retes = 10;
3342 if (rtlhal->current_bandtype == BAND_ON_2_4G)
3343 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3344 sizes_of_cck_retes);
3346 _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3347 sizes_of_ofdm_retes);
3348 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3349 sizes_of_ht_retes_1t);
3350 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3351 sizes_of_vht_retes);
3353 if (rtlphy->num_total_rfpath >= 2) {
3354 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3356 sizes_of_ht_retes_2t);
3357 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3359 sizes_of_vht_retes);
3362 _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3366 /*just in case, write txpower in DW, to reduce time*/
3367 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3369 struct rtl_priv *rtlpriv = rtl_priv(hw);
3370 struct rtl_phy *rtlphy = &rtlpriv->phy;
3373 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3374 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3377 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3378 enum wireless_mode wirelessmode,
3384 switch (wirelessmode) {
3385 case WIRELESS_MODE_B:
3388 case WIRELESS_MODE_G:
3389 case WIRELESS_MODE_N_24G:
3396 pwrout_dbm = txpwridx / 2 + offset;
3400 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3402 struct rtl_priv *rtlpriv = rtl_priv(hw);
3403 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3404 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3406 if (!is_hal_stop(rtlhal)) {
3407 switch (operation) {
3408 case SCAN_OPT_BACKUP_BAND0:
3409 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3410 rtlpriv->cfg->ops->set_hw_reg(hw,
3415 case SCAN_OPT_BACKUP_BAND1:
3416 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3417 rtlpriv->cfg->ops->set_hw_reg(hw,
3422 case SCAN_OPT_RESTORE:
3423 iotype = IO_CMD_RESUME_DM_BY_SCAN;
3424 rtlpriv->cfg->ops->set_hw_reg(hw,
3429 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3430 "Unknown Scan Backup operation.\n");
3436 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3438 u16 reg_rf_mode_bw, tmp = 0;
3440 reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3442 case HT_CHANNEL_WIDTH_20:
3443 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3445 case HT_CHANNEL_WIDTH_20_40:
3446 tmp = reg_rf_mode_bw | BIT(7);
3447 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3449 case HT_CHANNEL_WIDTH_80:
3450 tmp = reg_rf_mode_bw | BIT(8);
3451 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3454 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3459 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3461 struct rtl_phy *rtlphy = &rtlpriv->phy;
3462 struct rtl_mac *mac = rtl_mac(rtlpriv);
3463 u8 sc_set_40 = 0, sc_set_20 = 0;
3465 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3466 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3467 sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3468 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3469 sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3471 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3472 "SCMapping: Not Correct Primary40MHz Setting\n");
3474 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3475 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3476 sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3477 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3478 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3479 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3480 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3481 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3482 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3483 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3484 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3485 sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3487 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3488 "SCMapping: Not Correct Primary40MHz Setting\n");
3489 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3490 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3491 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3492 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3493 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3495 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3496 "SCMapping: Not Correct Primary40MHz Setting\n");
3498 return (sc_set_40 << 4) | sc_set_20;
3501 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3503 struct rtl_priv *rtlpriv = rtl_priv(hw);
3504 struct rtl_phy *rtlphy = &rtlpriv->phy;
3508 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3509 "Switch to %s bandwidth\n",
3510 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3512 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3513 "40MHz" : "80MHz")));
3515 _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3516 sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3517 rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3519 switch (rtlphy->current_chan_bw) {
3520 case HT_CHANNEL_WIDTH_20:
3521 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3522 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3524 if (rtlphy->rf_type == RF_2T2R)
3525 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3527 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3529 case HT_CHANNEL_WIDTH_20_40:
3530 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3531 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3532 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3533 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3535 if (rtlphy->reg_837 & BIT(2))
3538 if (rtlphy->rf_type == RF_2T2R)
3543 /* 0x848[25:22] = 0x6 */
3544 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3546 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3547 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3549 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3552 case HT_CHANNEL_WIDTH_80:
3553 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3554 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3556 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3557 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3558 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3560 if (rtlphy->reg_837 & BIT(2))
3563 if (rtlphy->rf_type == RF_2T2R)
3568 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3572 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3573 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3577 rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3579 rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3580 rtlphy->set_bwmode_inprogress = false;
3582 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3585 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3586 enum nl80211_channel_type ch_type)
3588 struct rtl_priv *rtlpriv = rtl_priv(hw);
3589 struct rtl_phy *rtlphy = &rtlpriv->phy;
3590 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3591 u8 tmp_bw = rtlphy->current_chan_bw;
3593 if (rtlphy->set_bwmode_inprogress)
3595 rtlphy->set_bwmode_inprogress = true;
3596 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3597 rtl8821ae_phy_set_bw_mode_callback(hw);
3599 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3600 "FALSE driver sleep or unload\n");
3601 rtlphy->set_bwmode_inprogress = false;
3602 rtlphy->current_chan_bw = tmp_bw;
3606 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3608 struct rtl_priv *rtlpriv = rtl_priv(hw);
3609 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3610 struct rtl_phy *rtlphy = &rtlpriv->phy;
3611 u8 channel = rtlphy->current_channel;
3615 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3616 "switch to channel%d\n", rtlphy->current_channel);
3617 if (is_hal_stop(rtlhal))
3620 if (36 <= channel && channel <= 48)
3622 else if (50 <= channel && channel <= 64)
3624 else if (100 <= channel && channel <= 116)
3626 else if (118 <= channel)
3630 rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3632 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3633 if (36 <= channel && channel <= 64)
3635 else if (100 <= channel && channel <= 140)
3637 else if (140 < channel)
3641 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3642 BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3644 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3645 BMASKBYTE0, channel);
3648 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3649 if (36 <= channel && channel <= 64)
3651 else if (100 <= channel && channel <= 140)
3655 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3656 BRFREGOFFSETMASK, data);
3660 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3663 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3665 struct rtl_priv *rtlpriv = rtl_priv(hw);
3666 struct rtl_phy *rtlphy = &rtlpriv->phy;
3667 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3668 u32 timeout = 1000, timecount = 0;
3669 u8 channel = rtlphy->current_channel;
3671 if (rtlphy->sw_chnl_inprogress)
3673 if (rtlphy->set_bwmode_inprogress)
3676 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3677 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3678 "sw_chnl_inprogress false driver sleep or unload\n");
3681 while (rtlphy->lck_inprogress && timecount < timeout) {
3686 if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3687 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3688 else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3689 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3691 rtlphy->sw_chnl_inprogress = true;
3695 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3696 "switch to channel%d, band type is %d\n",
3697 rtlphy->current_channel, rtlhal->current_bandtype);
3699 rtl8821ae_phy_sw_chnl_callback(hw);
3701 rtl8821ae_dm_clear_txpower_tracking_state(hw);
3702 rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3704 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3705 rtlphy->sw_chnl_inprogress = false;
3709 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3711 u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3712 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3713 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3714 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3715 110, 112, 114, 116, 118, 120, 122, 124, 126,
3716 128, 130, 132, 134, 136, 138, 140, 149, 151,
3717 153, 155, 157, 159, 161, 163, 165};
3721 for (place = 14; place < sizeof(channel_all); place++)
3722 if (channel_all[place] == chnl)
3729 #define MACBB_REG_NUM 10
3730 #define AFE_REG_NUM 14
3731 #define RF_REG_NUM 3
3733 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3735 u32 *backup_macbb_reg, u32 mac_bb_num)
3737 struct rtl_priv *rtlpriv = rtl_priv(hw);
3740 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3741 /*save MACBB default value*/
3742 for (i = 0; i < mac_bb_num; i++)
3743 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3745 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3748 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3749 u32 *backup_afe_REG, u32 afe_num)
3751 struct rtl_priv *rtlpriv = rtl_priv(hw);
3754 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3755 /*Save AFE Parameters */
3756 for (i = 0; i < afe_num; i++)
3757 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3758 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3761 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3762 u32 *rfb_backup, u32 *backup_rf_reg,
3765 struct rtl_priv *rtlpriv = rtl_priv(hw);
3768 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3769 /*Save RF Parameters*/
3770 for (i = 0; i < rf_num; i++) {
3771 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3773 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3776 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3779 static void _rtl8821ae_iqk_configure_mac(
3780 struct ieee80211_hw *hw
3783 struct rtl_priv *rtlpriv = rtl_priv(hw);
3784 /* ========MAC register setting========*/
3785 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3786 rtl_write_byte(rtlpriv, 0x522, 0x3f);
3787 rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3788 rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/
3789 rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/
3792 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3793 enum radio_path path, u32 tx_x, u32 tx_y)
3795 struct rtl_priv *rtlpriv = rtl_priv(hw);
3798 /* [31] = 1 --> Page C1 */
3799 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3800 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3801 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3802 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3803 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3804 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3805 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3806 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3808 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3809 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3810 rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3811 rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3818 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3819 enum radio_path path, u32 rx_x, u32 rx_y)
3821 struct rtl_priv *rtlpriv = rtl_priv(hw);
3824 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3825 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3826 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3827 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3828 "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3830 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3831 "0xc10 = %x ====>fill to IQC\n",
3832 rtl_read_dword(rtlpriv, 0xc10));
3841 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3843 struct rtl_priv *rtlpriv = rtl_priv(hw);
3844 struct rtl_phy *rtlphy = &rtlpriv->phy;
3845 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3847 u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3848 int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3849 int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3850 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3851 bool tx0iqkok = false, rx0iqkok = false;
3852 bool vdf_enable = false;
3853 int i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3854 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3856 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3857 "BandWidth = %d.\n",
3858 rtlphy->current_chan_bw);
3859 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3862 while (cal < cal_num) {
3865 temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3867 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3868 /*========Path-A AFE all on========*/
3869 /*Port 0 DAC/ADC on*/
3870 rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3871 rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3872 rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3873 rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3874 rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3875 rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3876 rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3877 rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3878 rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3879 rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3881 rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3884 /* ====== LOK ====== */
3885 /*DAC/ADC sampling rate (160 MHz)*/
3886 rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3888 /* 2. LoK RF Setting (at BW = 20M) */
3889 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3890 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */
3891 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3892 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3893 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3894 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3895 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3896 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3897 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3898 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3899 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3900 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3901 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3902 rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3904 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3905 rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3907 if (rtlhal->current_bandtype)
3908 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3910 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3912 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3913 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3914 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3915 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3916 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3918 mdelay(10); /* Delay 10ms */
3919 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3921 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3922 rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3924 switch (rtlphy->current_chan_bw) {
3926 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3929 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3935 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3937 /* 3. TX RF Setting */
3938 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3939 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3940 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3941 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3942 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3943 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3944 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3945 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3946 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3947 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3948 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3949 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3950 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3951 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3952 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3954 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3955 rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3956 if (rtlhal->current_bandtype)
3957 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3959 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3961 if (vdf_enable == 1) {
3962 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3963 for (k = 0; k <= 2; k++) {
3966 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3967 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3968 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3971 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3972 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3973 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3976 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3977 "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3978 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3979 "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3980 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3981 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3982 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3983 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3984 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3985 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3986 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3991 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3995 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3996 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3998 mdelay(10); /* Delay 10ms */
3999 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4002 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4003 if ((~iqk_ready) || (delay_count > 20))
4011 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4012 /* ============TXIQK Check============== */
4013 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4016 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4017 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4018 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4019 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4023 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4024 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4027 if (cal_retry == 10)
4033 if (cal_retry == 10)
4039 tx_x0[cal] = vdf_x[k-1];
4040 tx_y0[cal] = vdf_y[k-1];
4043 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4044 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4045 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4049 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4050 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4052 mdelay(10); /* Delay 10ms */
4053 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4056 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4057 if ((~iqk_ready) || (delay_count > 20))
4065 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4066 /* ============TXIQK Check============== */
4067 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4070 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4071 tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4072 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4073 tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4077 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4078 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4081 if (cal_retry == 10)
4087 if (cal_retry == 10)
4093 if (tx0iqkok == false)
4094 break; /* TXK fail, Don't do RXK */
4096 if (vdf_enable == 1) {
4097 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */
4098 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4099 for (k = 0; k <= 2; k++) {
4100 /* ====== RX mode TXK (RXK Step 1) ====== */
4101 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4102 /* 1. TX RF Setting */
4103 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4104 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4105 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4106 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4107 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4108 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4109 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4111 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4112 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4113 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4114 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4115 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4116 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4117 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4121 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4122 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4123 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4128 rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4129 rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4130 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4135 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4136 "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4137 vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4138 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4139 "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4140 vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4141 rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4142 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4143 rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4144 rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4145 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4146 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4147 rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4153 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4154 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4155 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4159 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4160 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4162 mdelay(10); /* Delay 10ms */
4163 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4166 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4167 if ((~iqk_ready) || (delay_count > 20))
4175 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4176 /* ============TXIQK Check============== */
4177 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4180 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4181 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4182 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4183 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4189 if (cal_retry == 10)
4195 if (cal_retry == 10)
4200 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4201 tx_x0_rxk[cal] = tx_x0[cal];
4202 tx_y0_rxk[cal] = tx_y0[cal];
4207 "RXK Step 1 fail\n");
4210 /* ====== RX IQK ====== */
4211 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4212 /* 1. RX RF Setting */
4213 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4214 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4215 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4216 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4217 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4218 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4219 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4221 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4222 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4223 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4224 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4225 rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4226 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4227 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4229 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4230 rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4231 rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4232 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4234 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4237 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */
4238 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4243 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4244 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4246 mdelay(10); /* Delay 10ms */
4247 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4250 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4251 if ((~iqk_ready) || (delay_count > 20))
4259 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4260 /* ============RXIQK Check============== */
4261 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4263 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4264 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4265 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4266 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4270 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4271 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4274 if (cal_retry == 10)
4281 if (cal_retry == 10)
4288 rx_x0[cal] = vdf_x[k-1];
4289 rx_y0[cal] = vdf_y[k-1];
4291 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */
4295 /* ====== RX mode TXK (RXK Step 1) ====== */
4296 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4297 /* 1. TX RF Setting */
4298 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4299 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4300 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4301 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4302 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4303 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4304 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4305 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4306 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4307 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4309 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4310 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4311 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4312 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4313 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4314 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4318 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4319 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4321 mdelay(10); /* Delay 10ms */
4322 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4325 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4326 if ((~iqk_ready) || (delay_count > 20))
4334 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4335 /* ============TXIQK Check============== */
4336 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4339 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4340 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4341 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4342 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4348 if (cal_retry == 10)
4354 if (cal_retry == 10)
4359 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4360 tx_x0_rxk[cal] = tx_x0[cal];
4361 tx_y0_rxk[cal] = tx_y0[cal];
4363 RT_TRACE(rtlpriv, COMP_IQK,
4367 /* ====== RX IQK ====== */
4368 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4369 /* 1. RX RF Setting */
4370 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4371 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4372 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4373 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4374 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4375 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4376 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4378 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4379 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4380 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4381 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4382 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4383 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4384 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4386 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4387 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4388 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4389 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4391 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4393 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4398 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4399 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4401 mdelay(10); /* Delay 10ms */
4402 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4405 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4406 if ((~iqk_ready) || (delay_count > 20))
4414 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4415 /* ============RXIQK Check============== */
4416 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4418 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4419 rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4420 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4421 rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4425 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4426 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4429 if (cal_retry == 10)
4436 if (cal_retry == 10)
4446 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4447 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4455 /* FillIQK Result */
4458 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4459 "========Path_A =======\n");
4460 if (tx_average == 0)
4463 for (i = 0; i < tx_average; i++) {
4464 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4465 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4466 (tx_x0_rxk[i])>>21&0x000007ff, i,
4467 (tx_y0_rxk[i])>>21&0x000007ff);
4468 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4469 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4470 (tx_x0[i])>>21&0x000007ff, i,
4471 (tx_y0[i])>>21&0x000007ff);
4473 for (i = 0; i < tx_average; i++) {
4474 for (ii = i+1; ii < tx_average; ii++) {
4475 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4476 if (dx < 3 && dx > -3) {
4477 dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4478 if (dy < 3 && dy > -3) {
4479 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4480 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4491 _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4493 _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4495 if (rx_average == 0)
4498 for (i = 0; i < rx_average; i++)
4499 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4500 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4501 (rx_x0[i])>>21&0x000007ff, i,
4502 (rx_y0[i])>>21&0x000007ff);
4503 for (i = 0; i < rx_average; i++) {
4504 for (ii = i+1; ii < rx_average; ii++) {
4505 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4506 if (dx < 4 && dx > -4) {
4507 dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4508 if (dy < 4 && dy > -4) {
4509 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4510 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4521 _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4523 _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4530 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4531 enum radio_path path,
4533 u32 *rf_backup, u32 rf_reg_num)
4535 struct rtl_priv *rtlpriv = rtl_priv(hw);
4538 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4539 for (i = 0; i < RF_REG_NUM; i++)
4540 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4545 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4546 "RestoreRF Path A Success!!!!\n");
4553 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4554 u32 *afe_backup, u32 *backup_afe_reg,
4558 struct rtl_priv *rtlpriv = rtl_priv(hw);
4560 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4561 /* Reload AFE Parameters */
4562 for (i = 0; i < afe_num; i++)
4563 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4564 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4565 rtl_write_dword(rtlpriv, 0xc80, 0x0);
4566 rtl_write_dword(rtlpriv, 0xc84, 0x0);
4567 rtl_write_dword(rtlpriv, 0xc88, 0x0);
4568 rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4569 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4570 rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4571 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4572 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4573 rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4574 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4577 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4579 u32 *backup_macbb_reg,
4583 struct rtl_priv *rtlpriv = rtl_priv(hw);
4585 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4586 /* Reload MacBB Parameters */
4587 for (i = 0; i < macbb_num; i++)
4588 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4589 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4592 #undef MACBB_REG_NUM
4596 #define MACBB_REG_NUM 11
4597 #define AFE_REG_NUM 12
4598 #define RF_REG_NUM 3
4600 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4602 u32 macbb_backup[MACBB_REG_NUM];
4603 u32 afe_backup[AFE_REG_NUM];
4604 u32 rfa_backup[RF_REG_NUM];
4605 u32 rfb_backup[RF_REG_NUM];
4606 u32 backup_macbb_reg[MACBB_REG_NUM] = {
4607 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4608 0xe00, 0xe50, 0x838, 0x82c
4610 u32 backup_afe_reg[AFE_REG_NUM] = {
4611 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4612 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4614 u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4616 _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4618 _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4619 _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4622 _rtl8821ae_iqk_configure_mac(hw);
4623 _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4624 _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4627 _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4628 _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4632 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4634 struct rtl_priv *rtlpriv = rtl_priv(hw);
4635 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4636 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4637 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4640 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4642 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4645 #undef IQK_ADDA_REG_NUM
4646 #undef IQK_DELAY_TIME
4648 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4652 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4653 u8 thermal_value, u8 threshold)
4655 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4657 rtldm->thermalvalue_iqk = thermal_value;
4658 rtl8812ae_phy_iq_calibrate(hw, false);
4661 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4663 struct rtl_priv *rtlpriv = rtl_priv(hw);
4664 struct rtl_phy *rtlphy = &rtlpriv->phy;
4666 if (!rtlphy->lck_inprogress) {
4667 spin_lock(&rtlpriv->locks.iqk_lock);
4668 rtlphy->lck_inprogress = true;
4669 spin_unlock(&rtlpriv->locks.iqk_lock);
4671 _rtl8821ae_phy_iq_calibrate(hw);
4673 spin_lock(&rtlpriv->locks.iqk_lock);
4674 rtlphy->lck_inprogress = false;
4675 spin_unlock(&rtlpriv->locks.iqk_lock);
4679 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4681 struct rtl_priv *rtlpriv = rtl_priv(hw);
4682 struct rtl_phy *rtlphy = &rtlpriv->phy;
4685 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4686 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4687 (int)(sizeof(rtlphy->iqk_matrix) /
4688 sizeof(struct iqk_matrix_regs)),
4689 IQK_MATRIX_SETTINGS_NUM);
4691 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4692 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4693 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4694 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4695 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4697 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4698 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4699 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4700 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4702 rtlphy->iqk_matrix[i].iqk_done = false;
4706 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4707 u8 thermal_value, u8 threshold)
4709 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4711 rtl8821ae_reset_iqk_result(hw);
4713 rtldm->thermalvalue_iqk = thermal_value;
4714 rtl8821ae_phy_iq_calibrate(hw, false);
4717 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4721 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
4725 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4727 _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4730 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4732 struct rtl_priv *rtlpriv = rtl_priv(hw);
4733 struct rtl_phy *rtlphy = &rtlpriv->phy;
4734 bool postprocessing = false;
4736 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4737 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4738 iotype, rtlphy->set_io_inprogress);
4741 case IO_CMD_RESUME_DM_BY_SCAN:
4742 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4743 "[IO CMD] Resume DM after scan.\n");
4744 postprocessing = true;
4746 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4747 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4748 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4749 "[IO CMD] Pause DM before scan.\n");
4750 postprocessing = true;
4753 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4754 "switch case %#x not processed\n", iotype);
4758 if (postprocessing && !rtlphy->set_io_inprogress) {
4759 rtlphy->set_io_inprogress = true;
4760 rtlphy->current_io_type = iotype;
4764 rtl8821ae_phy_set_io(hw);
4765 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4769 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4771 struct rtl_priv *rtlpriv = rtl_priv(hw);
4772 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4773 struct rtl_phy *rtlphy = &rtlpriv->phy;
4775 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4776 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4777 rtlphy->current_io_type, rtlphy->set_io_inprogress);
4778 switch (rtlphy->current_io_type) {
4779 case IO_CMD_RESUME_DM_BY_SCAN:
4780 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4781 _rtl8821ae_resume_tx_beacon(hw);
4782 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4783 rtl8821ae_dm_write_cck_cca_thres(hw,
4784 rtlphy->initgain_backup.cca);
4786 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4787 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4788 _rtl8821ae_stop_tx_beacon(hw);
4789 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4790 rtl8821ae_dm_write_dig(hw, 0x17);
4791 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4792 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4794 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4797 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4798 "switch case %#x not processed\n",
4799 rtlphy->current_io_type);
4802 rtlphy->set_io_inprogress = false;
4803 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4804 "(%#x)\n", rtlphy->current_io_type);
4807 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4809 struct rtl_priv *rtlpriv = rtl_priv(hw);
4811 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4812 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4813 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4814 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4815 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4818 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4819 enum rf_pwrstate rfpwr_state)
4821 struct rtl_priv *rtlpriv = rtl_priv(hw);
4822 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4823 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4824 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4825 bool bresult = true;
4827 struct rtl8192_tx_ring *ring = NULL;
4829 switch (rfpwr_state) {
4831 if ((ppsc->rfpwr_state == ERFOFF) &&
4832 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4833 bool rtstatus = false;
4834 u32 initializecount = 0;
4838 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4839 "IPS Set eRf nic enable\n");
4840 rtstatus = rtl_ps_enable_nic(hw);
4841 } while (!rtstatus && (initializecount < 10));
4842 RT_CLEAR_PS_LEVEL(ppsc,
4843 RT_RF_OFF_LEVL_HALT_NIC);
4845 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4846 "Set ERFON sleeped:%d ms\n",
4847 jiffies_to_msecs(jiffies -
4849 last_sleep_jiffies));
4850 ppsc->last_awake_jiffies = jiffies;
4851 rtl8821ae_phy_set_rf_on(hw);
4853 if (mac->link_state == MAC80211_LINKED) {
4854 rtlpriv->cfg->ops->led_control(hw,
4857 rtlpriv->cfg->ops->led_control(hw,
4862 for (queue_id = 0, i = 0;
4863 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4864 ring = &pcipriv->dev.tx_ring[queue_id];
4865 if (queue_id == BEACON_QUEUE ||
4866 skb_queue_len(&ring->queue) == 0) {
4870 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4871 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4873 skb_queue_len(&ring->queue));
4878 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4879 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4880 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4881 MAX_DOZE_WAITING_TIMES_9x,
4883 skb_queue_len(&ring->queue));
4888 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4889 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4890 "IPS Set eRf nic disable\n");
4891 rtl_ps_disable_nic(hw);
4892 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4894 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4895 rtlpriv->cfg->ops->led_control(hw,
4898 rtlpriv->cfg->ops->led_control(hw,
4904 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4905 "switch case %#x not processed\n", rfpwr_state);
4910 ppsc->rfpwr_state = rfpwr_state;
4914 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4915 enum rf_pwrstate rfpwr_state)
4917 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4919 bool bresult = false;
4921 if (rfpwr_state == ppsc->rfpwr_state)
4923 bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);