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_hal *rtlhal = rtl_hal(rtl_priv(hw));
219 bool is_pi_mode = false;
222 /* 2009/06/17 MH We can not execute IO for power
223 save or other accident mode.*/
224 if (RT_CANNOT_IO(hw)) {
225 pr_err("return all one\n");
228 /* <20120809, Kordan> CCA OFF(when entering),
229 asked by James to avoid reading the wrong value.
230 <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
232 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
233 (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
234 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1);
237 if (rfpath == RF90_PATH_A)
238 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4);
239 else if (rfpath == RF90_PATH_B)
240 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4);
242 rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset);
244 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
245 (IS_VENDOR_8812A_C_CUT(rtlhal->version)))
249 if (rfpath == RF90_PATH_A)
251 rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA);
252 else if (rfpath == RF90_PATH_B)
254 rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA);
256 if (rfpath == RF90_PATH_A)
258 rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA);
259 else if (rfpath == RF90_PATH_B)
261 rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA);
264 /*<20120809, Kordan> CCA ON(when exiting),
265 * asked by James to avoid reading the wrong value.
266 * <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!
269 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
270 (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
271 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0);
275 static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
276 enum radio_path rfpath, u32 offset,
279 struct rtl_priv *rtlpriv = rtl_priv(hw);
280 struct rtl_phy *rtlphy = &rtlpriv->phy;
281 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
285 if (RT_CANNOT_IO(hw)) {
291 data_and_addr = ((newoffset << 20) |
292 (data & 0x000fffff)) & 0x0fffffff;
293 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
294 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
295 "RFW-%d Addr[0x%x]=0x%x\n",
296 rfpath, pphyreg->rf3wire_offset, data_and_addr);
299 static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
303 for (i = 0; i <= 31; i++) {
304 if (((bitmask >> i) & 0x1) == 1)
310 bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw)
314 rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw);
319 bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw)
321 bool rtstatus = true;
322 struct rtl_priv *rtlpriv = rtl_priv(hw);
323 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
324 struct rtl_phy *rtlphy = &rtlpriv->phy;
325 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
329 phy_init_bb_rf_register_definition(hw);
331 regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
333 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval);
334 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
335 regval | FEN_BB_GLB_RSTN | FEN_BBRSTB);
337 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7);
338 rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7);
340 rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw);
342 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
343 crystal_cap = rtlefuse->crystalcap & 0x3F;
344 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000,
345 (crystal_cap | (crystal_cap << 6)));
347 crystal_cap = rtlefuse->crystalcap & 0x3F;
348 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
349 (crystal_cap | (crystal_cap << 6)));
351 rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);
356 bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
358 return rtl8821ae_phy_rf6052_config(hw);
361 static void _rtl8812ae_phy_set_rfe_reg_24g(struct ieee80211_hw *hw)
363 struct rtl_priv *rtlpriv = rtl_priv(hw);
364 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
367 switch (rtlhal->rfe_type) {
369 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337770);
370 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337770);
371 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
372 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
373 rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1);
376 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
377 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
378 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x001);
379 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x001);
382 rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x77);
383 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
384 tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3);
385 rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp & ~0x1);
386 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
389 if (rtlpriv->btcoexist.bt_coexistence) {
390 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x777777);
391 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
393 rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000);
394 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
400 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
401 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
402 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
403 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
408 static void _rtl8812ae_phy_set_rfe_reg_5g(struct ieee80211_hw *hw)
410 struct rtl_priv *rtlpriv = rtl_priv(hw);
411 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
414 switch (rtlhal->rfe_type) {
416 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337717);
417 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337717);
418 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
419 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
422 if (rtlpriv->btcoexist.bt_coexistence) {
423 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x337717);
424 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
426 rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000);
427 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
429 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
431 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
433 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
434 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
438 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337717);
439 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337717);
440 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
441 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
442 rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1);
445 rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x33);
446 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
447 tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3);
448 rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp | 0x1);
449 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
454 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337777);
455 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
456 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
457 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
462 u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band,
465 struct rtl_priv *rtlpriv = rtl_priv(hw);
466 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
467 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
468 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
469 s8 reg_swing_2g = -1;/* 0xff; */
470 s8 reg_swing_5g = -1;/* 0xff; */
471 s8 swing_2g = -1 * reg_swing_2g;
472 s8 swing_5g = -1 * reg_swing_5g;
474 const s8 auto_temp = -1;
476 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
477 "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
478 (int)swing_2g, (int)swing_5g,
479 (int)rtlefuse->autoload_failflag);
481 if (rtlefuse->autoload_failflag) {
482 if (band == BAND_ON_2_4G) {
483 rtldm->swing_diff_2g = swing_2g;
485 out = 0x200; /* 0 dB */
486 } else if (swing_2g == -3) {
487 out = 0x16A; /* -3 dB */
488 } else if (swing_2g == -6) {
489 out = 0x101; /* -6 dB */
490 } else if (swing_2g == -9) {
491 out = 0x0B6; /* -9 dB */
493 rtldm->swing_diff_2g = 0;
496 } else if (band == BAND_ON_5G) {
497 rtldm->swing_diff_5g = swing_5g;
499 out = 0x200; /* 0 dB */
500 } else if (swing_5g == -3) {
501 out = 0x16A; /* -3 dB */
502 } else if (swing_5g == -6) {
503 out = 0x101; /* -6 dB */
504 } else if (swing_5g == -9) {
505 out = 0x0B6; /* -9 dB */
507 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
508 rtldm->swing_diff_5g = -3;
511 rtldm->swing_diff_5g = 0;
516 rtldm->swing_diff_2g = -3;
517 rtldm->swing_diff_5g = -3;
518 out = 0x16A; /* -3 dB */
521 u32 swing = 0, swing_a = 0, swing_b = 0;
523 if (band == BAND_ON_2_4G) {
524 if (reg_swing_2g == auto_temp) {
525 efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
526 swing = (swing == 0xFF) ? 0x00 : swing;
527 } else if (swing_2g == 0) {
528 swing = 0x00; /* 0 dB */
529 } else if (swing_2g == -3) {
530 swing = 0x05; /* -3 dB */
531 } else if (swing_2g == -6) {
532 swing = 0x0A; /* -6 dB */
533 } else if (swing_2g == -9) {
534 swing = 0xFF; /* -9 dB */
539 if (reg_swing_5g == auto_temp) {
540 efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
541 swing = (swing == 0xFF) ? 0x00 : swing;
542 } else if (swing_5g == 0) {
543 swing = 0x00; /* 0 dB */
544 } else if (swing_5g == -3) {
545 swing = 0x05; /* -3 dB */
546 } else if (swing_5g == -6) {
547 swing = 0x0A; /* -6 dB */
548 } else if (swing_5g == -9) {
549 swing = 0xFF; /* -9 dB */
555 swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
556 swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
557 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
558 "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
562 if (swing_a == 0x0) {
563 if (band == BAND_ON_2_4G)
564 rtldm->swing_diff_2g = 0;
566 rtldm->swing_diff_5g = 0;
567 out = 0x200; /* 0 dB */
568 } else if (swing_a == 0x1) {
569 if (band == BAND_ON_2_4G)
570 rtldm->swing_diff_2g = -3;
572 rtldm->swing_diff_5g = -3;
573 out = 0x16A; /* -3 dB */
574 } else if (swing_a == 0x2) {
575 if (band == BAND_ON_2_4G)
576 rtldm->swing_diff_2g = -6;
578 rtldm->swing_diff_5g = -6;
579 out = 0x101; /* -6 dB */
580 } else if (swing_a == 0x3) {
581 if (band == BAND_ON_2_4G)
582 rtldm->swing_diff_2g = -9;
584 rtldm->swing_diff_5g = -9;
585 out = 0x0B6; /* -9 dB */
588 if (swing_b == 0x0) {
589 if (band == BAND_ON_2_4G)
590 rtldm->swing_diff_2g = 0;
592 rtldm->swing_diff_5g = 0;
593 out = 0x200; /* 0 dB */
594 } else if (swing_b == 0x1) {
595 if (band == BAND_ON_2_4G)
596 rtldm->swing_diff_2g = -3;
598 rtldm->swing_diff_5g = -3;
599 out = 0x16A; /* -3 dB */
600 } else if (swing_b == 0x2) {
601 if (band == BAND_ON_2_4G)
602 rtldm->swing_diff_2g = -6;
604 rtldm->swing_diff_5g = -6;
605 out = 0x101; /* -6 dB */
606 } else if (swing_b == 0x3) {
607 if (band == BAND_ON_2_4G)
608 rtldm->swing_diff_2g = -9;
610 rtldm->swing_diff_5g = -9;
611 out = 0x0B6; /* -9 dB */
615 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
616 "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out);
620 void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
622 struct rtl_priv *rtlpriv = rtl_priv(hw);
623 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
624 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
625 u8 current_band = rtlhal->current_bandtype;
627 s8 bb_diff_between_band;
629 txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
630 rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
631 rtlhal->current_bandtype = (enum band_type) band;
632 /* reconfig BB/RF according to wireless mode */
633 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
635 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
637 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
638 /* 0xCB0[15:12] = 0x7 (LNA_On)*/
639 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
640 /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
641 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
644 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
646 rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
649 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
650 /* 0xC1C[11:8] = 0 */
651 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
653 /* 0x82C[1:0] = 2b'00 */
654 rtl_set_bbreg(hw, 0x82c, 0x3, 0);
657 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
658 _rtl8812ae_phy_set_rfe_reg_24g(hw);
660 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
661 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
663 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
664 } else {/* 5G band */
667 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
668 /*0xCB0[15:12] = 0x5 (LNA_On)*/
669 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
670 /*0xCB0[7:4] = 0x4 (PAPE_A)*/
671 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
674 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
677 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
678 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
679 "Reg41A value %d\n", reg_41a);
681 while ((reg_41a != 0x30) && (count < 50)) {
683 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
685 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
688 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
689 "Reg41A value %d\n", reg_41a);
692 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
693 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
696 /* 2012/02/01, Sinda add registry to switch workaround
697 without long-run verification for scan issue. */
698 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
700 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
702 rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
705 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
706 /* AGC table select */
708 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
710 /* 0x82C[1:0] = 2'b00 */
711 rtl_set_bbreg(hw, 0x82c, 0x3, 1);
713 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
714 _rtl8812ae_phy_set_rfe_reg_5g(hw);
716 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
717 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
719 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
720 "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
721 rtlpriv->dm.ofdm_index[RF90_PATH_A]);
724 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
725 (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
727 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
728 phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
730 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
731 phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
733 /* <20121005, Kordan> When TxPowerTrack is ON,
734 * we should take care of the change of BB swing.
735 * That is, reset all info to trigger Tx power tracking.
737 if (band != current_band) {
738 bb_diff_between_band =
739 (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
740 bb_diff_between_band = (band == BAND_ON_2_4G) ?
741 bb_diff_between_band :
742 (-1 * bb_diff_between_band);
743 rtldm->default_ofdm_index += bb_diff_between_band * 2;
745 rtl8821ae_dm_clear_txpower_tracking_state(hw);
748 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
749 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
753 static bool _rtl8821ae_check_positive(struct ieee80211_hw *hw,
754 const u32 condition1,
755 const u32 condition2)
757 struct rtl_priv *rtlpriv = rtl_priv(hw);
758 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
759 u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK)
760 >> CHIP_VER_RTL_SHIFT);
761 u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0));
763 u8 board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */
764 ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA */
765 ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */
766 ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA */
767 ((rtlhal->board_type & BIT(2)) >> 2) << 4; /* _BT */
769 u32 cond1 = condition1, cond2 = condition2;
770 u32 driver1 = cut_ver << 24 | /* CUT ver */
771 0 << 20 | /* interface 2/2 */
772 0x04 << 16 | /* platform */
773 rtlhal->package_type << 12 |
774 intf << 8 | /* interface 1/2 */
777 u32 driver2 = rtlhal->type_glna << 0 |
778 rtlhal->type_gpa << 8 |
779 rtlhal->type_alna << 16 |
780 rtlhal->type_apa << 24;
782 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
783 "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n",
785 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
786 "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n",
789 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
790 " (Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf);
791 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
792 " (Board, Package) = (0x%X, 0x%X)\n",
793 rtlhal->board_type, rtlhal->package_type);
795 /*============== Value Defined Check ===============*/
796 /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/
798 if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) !=
799 (driver1 & 0x0000F000)))
801 if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) !=
802 (driver1 & 0x0F000000)))
805 /*=============== Bit Defined Check ================*/
806 /* We don't care [31:28] */
809 driver1 &= 0x00FF0FFF;
811 if ((cond1 & driver1) == cond1) {
814 if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/
817 if ((cond1 & BIT(0)) != 0) /*GLNA*/
819 if ((cond1 & BIT(1)) != 0) /*GPA*/
821 if ((cond1 & BIT(2)) != 0) /*ALNA*/
823 if ((cond1 & BIT(3)) != 0) /*APA*/
826 /* BoardType of each RF path is matched*/
827 if ((cond2 & mask) == (driver2 & mask))
835 static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
838 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
839 u32 _board = rtlefuse->board_type; /*need efuse define*/
840 u32 _interface = 0x01; /* ODM_ITRF_PCIE */
841 u32 _platform = 0x08;/* ODM_WIN */
842 u32 cond = condition;
844 if (condition == 0xCDCDCDCD)
847 cond = condition & 0xFF;
848 if ((_board != cond) && cond != 0xFF)
851 cond = condition & 0xFF00;
853 if ((_interface & cond) == 0 && cond != 0x07)
856 cond = condition & 0xFF0000;
858 if ((_platform & cond) == 0 && cond != 0x0F)
863 static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
865 enum radio_path rfpath, u32 regaddr)
867 if (addr == 0xfe || addr == 0xffe) {
868 /* In order not to disturb BT music when
869 * wifi init.(1ant NIC only)
873 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
878 static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
881 u32 content = 0x1000; /*RF Content: radio_a_txt*/
882 u32 maskforphyset = (u32)(content & 0xE000);
884 _rtl8821ae_config_rf_reg(hw, addr, data,
885 RF90_PATH_A, addr | maskforphyset);
888 static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
891 u32 content = 0x1001; /*RF Content: radio_b_txt*/
892 u32 maskforphyset = (u32)(content & 0xE000);
894 _rtl8821ae_config_rf_reg(hw, addr, data,
895 RF90_PATH_B, addr | maskforphyset);
898 static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
903 else if (addr == 0xfd)
905 else if (addr == 0xfc)
907 else if (addr == 0xfb)
909 else if (addr == 0xfa)
911 else if (addr == 0xf9)
914 rtl_set_bbreg(hw, addr, MASKDWORD, data);
919 static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
921 struct rtl_priv *rtlpriv = rtl_priv(hw);
922 struct rtl_phy *rtlphy = &rtlpriv->phy;
923 u8 band, rfpath, txnum, rate_section;
925 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
926 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
927 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
928 for (rate_section = 0;
929 rate_section < TX_PWR_BY_RATE_NUM_SECTION;
931 rtlphy->tx_power_by_rate_offset[band]
932 [rfpath][txnum][rate_section] = 0;
935 static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
940 struct rtl_priv *rtlpriv = rtl_priv(hw);
941 struct rtl_phy *rtlphy = &rtlpriv->phy;
943 if (path > RF90_PATH_D) {
944 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
945 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
949 if (band == BAND_ON_2_4G) {
950 switch (rate_section) {
952 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
955 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
958 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
961 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
963 case VHT_1SSMCS0_1SSMCS9:
964 rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
966 case VHT_2SSMCS0_2SSMCS9:
967 rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
970 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
971 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
972 rate_section, path, txnum);
975 } else if (band == BAND_ON_5G) {
976 switch (rate_section) {
978 rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
981 rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
984 rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
986 case VHT_1SSMCS0_1SSMCS9:
987 rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
989 case VHT_2SSMCS0_2SSMCS9:
990 rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
993 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
994 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
995 rate_section, path, txnum);
999 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1000 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
1004 static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
1006 u8 txnum, u8 rate_section)
1008 struct rtl_priv *rtlpriv = rtl_priv(hw);
1009 struct rtl_phy *rtlphy = &rtlpriv->phy;
1012 if (path > RF90_PATH_D) {
1013 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1014 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
1019 if (band == BAND_ON_2_4G) {
1020 switch (rate_section) {
1022 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
1025 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
1028 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
1031 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
1033 case VHT_1SSMCS0_1SSMCS9:
1034 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
1036 case VHT_2SSMCS0_2SSMCS9:
1037 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
1040 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1041 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
1042 rate_section, path, txnum);
1045 } else if (band == BAND_ON_5G) {
1046 switch (rate_section) {
1048 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
1051 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
1054 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
1056 case VHT_1SSMCS0_1SSMCS9:
1057 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
1059 case VHT_2SSMCS0_2SSMCS9:
1060 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
1063 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1064 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
1065 rate_section, path, txnum);
1069 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1070 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
1076 static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
1078 struct rtl_priv *rtlpriv = rtl_priv(hw);
1079 struct rtl_phy *rtlphy = &rtlpriv->phy;
1081 u8 base = 0, path = 0;
1083 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
1084 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
1085 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1086 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
1088 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
1089 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1090 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
1092 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
1093 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1094 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
1096 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
1097 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1098 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
1100 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
1101 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1102 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1104 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
1105 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1106 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1108 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
1109 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1110 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
1112 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
1113 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1114 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
1116 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
1117 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1118 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
1120 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
1121 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1122 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1124 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
1125 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1126 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1130 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
1131 u8 end, u8 base_val)
1137 for (i = 3; i >= 0; --i) {
1138 if (i >= start && i <= end) {
1139 /* Get the exact value */
1140 temp_value = (u8)(*data >> (i * 8)) & 0xF;
1141 temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
1143 /* Change the value to a relative value */
1144 temp_value = (temp_value > base_val) ? temp_value -
1145 base_val : base_val - temp_value;
1147 temp_value = (u8)(*data >> (i * 8)) & 0xFF;
1150 temp_data |= temp_value;
1155 static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
1157 struct rtl_priv *rtlpriv = rtl_priv(hw);
1158 struct rtl_phy *rtlphy = &rtlpriv->phy;
1159 u8 regulation, bw, channel, rate_section;
1162 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1163 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
1164 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1165 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1166 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1167 [bw][rate_section][channel][RF90_PATH_A];
1168 if (temp_pwrlmt == MAX_POWER_INDEX) {
1169 if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
1170 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1171 "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1172 1, bw, rate_section, channel, RF90_PATH_A);
1173 if (rate_section == 2) {
1174 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1175 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1176 } else if (rate_section == 4) {
1177 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1178 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1179 } else if (rate_section == 3) {
1180 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1181 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1182 } else if (rate_section == 5) {
1183 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1184 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1187 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d\n", temp_pwrlmt);
1196 static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1197 enum band_type band, u8 rate)
1199 struct rtl_priv *rtlpriv = rtl_priv(hw);
1201 if (band == BAND_ON_2_4G) {
1244 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1245 "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1249 } else if (band == BAND_ON_5G) {
1284 case MGN_VHT1SS_MCS0:
1285 case MGN_VHT1SS_MCS1:
1286 case MGN_VHT1SS_MCS2:
1287 case MGN_VHT1SS_MCS3:
1288 case MGN_VHT1SS_MCS4:
1289 case MGN_VHT1SS_MCS5:
1290 case MGN_VHT1SS_MCS6:
1291 case MGN_VHT1SS_MCS7:
1292 case MGN_VHT1SS_MCS8:
1293 case MGN_VHT1SS_MCS9:
1297 case MGN_VHT2SS_MCS0:
1298 case MGN_VHT2SS_MCS1:
1299 case MGN_VHT2SS_MCS2:
1300 case MGN_VHT2SS_MCS3:
1301 case MGN_VHT2SS_MCS4:
1302 case MGN_VHT2SS_MCS5:
1303 case MGN_VHT2SS_MCS6:
1304 case MGN_VHT2SS_MCS7:
1305 case MGN_VHT2SS_MCS8:
1306 case MGN_VHT2SS_MCS9:
1311 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1312 "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1321 static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1323 struct rtl_priv *rtlpriv = rtl_priv(hw);
1324 struct rtl_phy *rtlphy = &rtlpriv->phy;
1325 u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1326 u8 regulation, bw, channel, rate_section;
1327 u8 base_index2_4G = 0;
1328 u8 base_index5G = 0;
1329 s8 temp_value = 0, temp_pwrlmt = 0;
1332 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1333 "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1335 _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1337 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1338 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
1339 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1340 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1341 /* obtain the base dBm values in 2.4G band
1342 CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1343 if (rate_section == 0) { /*CCK*/
1345 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1346 BAND_ON_2_4G, MGN_11M);
1347 } else if (rate_section == 1) { /*OFDM*/
1349 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1350 BAND_ON_2_4G, MGN_54M);
1351 } else if (rate_section == 2) { /*HT IT*/
1353 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1354 BAND_ON_2_4G, MGN_MCS7);
1355 } else if (rate_section == 3) { /*HT 2T*/
1357 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1358 BAND_ON_2_4G, MGN_MCS15);
1361 temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1362 [bw][rate_section][channel][RF90_PATH_A];
1364 for (rf_path = RF90_PATH_A;
1365 rf_path < MAX_RF_PATH_NUM;
1367 if (rate_section == 3)
1368 bw40_pwr_base_dbm2_4G =
1369 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1371 bw40_pwr_base_dbm2_4G =
1372 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1374 if (temp_pwrlmt != MAX_POWER_INDEX) {
1375 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1376 rtlphy->txpwr_limit_2_4g[regulation]
1377 [bw][rate_section][channel][rf_path] =
1381 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1382 "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",
1383 regulation, bw, rate_section, channel,
1384 rtlphy->txpwr_limit_2_4g[regulation][bw]
1385 [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1386 ? 0 : temp_pwrlmt/2, channel, rf_path,
1387 bw40_pwr_base_dbm2_4G);
1393 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1394 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
1395 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1396 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1397 /* obtain the base dBm values in 5G band
1398 OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1399 VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1400 if (rate_section == 1) { /*OFDM*/
1402 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1403 BAND_ON_5G, MGN_54M);
1404 } else if (rate_section == 2) { /*HT 1T*/
1406 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1407 BAND_ON_5G, MGN_MCS7);
1408 } else if (rate_section == 3) { /*HT 2T*/
1410 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1411 BAND_ON_5G, MGN_MCS15);
1412 } else if (rate_section == 4) { /*VHT 1T*/
1414 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1415 BAND_ON_5G, MGN_VHT1SS_MCS7);
1416 } else if (rate_section == 5) { /*VHT 2T*/
1418 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1419 BAND_ON_5G, MGN_VHT2SS_MCS7);
1422 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1423 [bw][rate_section][channel]
1426 for (rf_path = RF90_PATH_A;
1427 rf_path < MAX_RF_PATH_NUM;
1429 if (rate_section == 3 || rate_section == 5)
1430 bw40_pwr_base_dbm5G =
1431 rtlphy->txpwr_by_rate_base_5g[rf_path]
1432 [RF_2TX][base_index5G];
1434 bw40_pwr_base_dbm5G =
1435 rtlphy->txpwr_by_rate_base_5g[rf_path]
1436 [RF_1TX][base_index5G];
1438 if (temp_pwrlmt != MAX_POWER_INDEX) {
1440 temp_pwrlmt - bw40_pwr_base_dbm5G;
1441 rtlphy->txpwr_limit_5g[regulation]
1442 [bw][rate_section][channel]
1443 [rf_path] = temp_value;
1446 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1447 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
1448 regulation, bw, rate_section,
1449 channel, rtlphy->txpwr_limit_5g[regulation]
1450 [bw][rate_section][channel][rf_path],
1451 temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1457 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1458 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1461 static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1463 struct rtl_priv *rtlpriv = rtl_priv(hw);
1464 struct rtl_phy *rtlphy = &rtlpriv->phy;
1467 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1468 "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1470 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1471 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
1472 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1473 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1474 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1475 rtlphy->txpwr_limit_2_4g
1479 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1480 for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
1481 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1482 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1483 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1484 rtlphy->txpwr_limit_5g
1489 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1490 "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1493 static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1495 struct rtl_priv *rtlpriv = rtl_priv(hw);
1496 struct rtl_phy *rtlphy = &rtlpriv->phy;
1497 u8 base = 0, rfPath = 0;
1499 for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
1500 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1501 _phy_convert_txpower_dbm_to_relative_value(
1502 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0],
1505 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1506 _phy_convert_txpower_dbm_to_relative_value(
1507 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1],
1509 _phy_convert_txpower_dbm_to_relative_value(
1510 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2],
1513 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1514 _phy_convert_txpower_dbm_to_relative_value(
1515 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3],
1517 _phy_convert_txpower_dbm_to_relative_value(
1518 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4],
1521 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1523 _phy_convert_txpower_dbm_to_relative_value(
1524 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5],
1527 _phy_convert_txpower_dbm_to_relative_value(
1528 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6],
1531 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1532 _phy_convert_txpower_dbm_to_relative_value(
1533 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7],
1535 _phy_convert_txpower_dbm_to_relative_value(
1536 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8],
1538 _phy_convert_txpower_dbm_to_relative_value(
1539 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1542 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1543 _phy_convert_txpower_dbm_to_relative_value(
1544 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1546 _phy_convert_txpower_dbm_to_relative_value(
1547 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10],
1549 _phy_convert_txpower_dbm_to_relative_value(
1550 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11],
1553 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM);
1554 _phy_convert_txpower_dbm_to_relative_value(
1555 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1],
1557 _phy_convert_txpower_dbm_to_relative_value(
1558 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2],
1561 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7);
1562 _phy_convert_txpower_dbm_to_relative_value(
1563 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3],
1565 _phy_convert_txpower_dbm_to_relative_value(
1566 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4],
1569 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15);
1570 _phy_convert_txpower_dbm_to_relative_value(
1571 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5],
1573 _phy_convert_txpower_dbm_to_relative_value(
1574 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6],
1577 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1578 _phy_convert_txpower_dbm_to_relative_value(
1579 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7],
1581 _phy_convert_txpower_dbm_to_relative_value(
1582 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8],
1584 _phy_convert_txpower_dbm_to_relative_value(
1585 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1588 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1589 _phy_convert_txpower_dbm_to_relative_value(
1590 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1592 _phy_convert_txpower_dbm_to_relative_value(
1593 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10],
1595 _phy_convert_txpower_dbm_to_relative_value(
1596 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11],
1600 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1601 "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1604 static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1606 _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1607 _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1610 /* string is in decimal */
1611 static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint)
1616 while (str[i] != '\0') {
1617 if (str[i] >= '0' && str[i] <= '9') {
1619 *pint += (str[i] - '0');
1629 static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1630 u8 band, u8 channel)
1632 struct rtl_priv *rtlpriv = rtl_priv(hw);
1633 s8 channel_index = -1;
1636 if (band == BAND_ON_2_4G)
1637 channel_index = channel - 1;
1638 else if (band == BAND_ON_5G) {
1639 for (i = 0; i < sizeof(channel5g)/sizeof(u8); ++i) {
1640 if (channel5g[i] == channel)
1644 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s\n",
1647 if (channel_index == -1)
1648 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1649 "Invalid Channel %d of Band %d in %s\n", channel,
1652 return channel_index;
1655 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw,
1656 const char *pregulation,
1657 const char *pband, const char *pbandwidth,
1658 const char *prate_section, const char *prf_path,
1659 const char *pchannel, const char *ppower_limit)
1661 struct rtl_priv *rtlpriv = rtl_priv(hw);
1662 struct rtl_phy *rtlphy = &rtlpriv->phy;
1663 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1665 s8 power_limit = 0, prev_power_limit, ret;
1667 if (!_rtl8812ae_get_integer_from_string(pchannel, &channel) ||
1668 !_rtl8812ae_get_integer_from_string(ppower_limit,
1670 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1671 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1672 channel, power_limit);
1675 power_limit = power_limit > MAX_POWER_INDEX ?
1676 MAX_POWER_INDEX : power_limit;
1678 if (strcmp(pregulation, "FCC") == 0)
1680 else if (strcmp(pregulation, "MKK") == 0)
1682 else if (strcmp(pregulation, "ETSI") == 0)
1684 else if (strcmp(pregulation, "WW13") == 0)
1687 if (strcmp(prate_section, "CCK") == 0)
1689 else if (strcmp(prate_section, "OFDM") == 0)
1691 else if (strcmp(prate_section, "HT") == 0 &&
1692 strcmp(prf_path, "1T") == 0)
1694 else if (strcmp(prate_section, "HT") == 0 &&
1695 strcmp(prf_path, "2T") == 0)
1697 else if (strcmp(prate_section, "VHT") == 0 &&
1698 strcmp(prf_path, "1T") == 0)
1700 else if (strcmp(prate_section, "VHT") == 0 &&
1701 strcmp(prf_path, "2T") == 0)
1704 if (strcmp(pbandwidth, "20M") == 0)
1706 else if (strcmp(pbandwidth, "40M") == 0)
1708 else if (strcmp(pbandwidth, "80M") == 0)
1710 else if (strcmp(pbandwidth, "160M") == 0)
1713 if (strcmp(pband, "2.4G") == 0) {
1714 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1721 channel_index = ret;
1723 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1724 [bandwidth][rate_section]
1725 [channel_index][RF90_PATH_A];
1727 if (power_limit < prev_power_limit)
1728 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1729 [rate_section][channel_index][RF90_PATH_A] =
1732 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1733 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1734 regulation, bandwidth, rate_section, channel_index,
1735 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1736 [rate_section][channel_index][RF90_PATH_A]);
1737 } else if (strcmp(pband, "5G") == 0) {
1738 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1745 channel_index = ret;
1747 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1748 [rate_section][channel_index]
1751 if (power_limit < prev_power_limit)
1752 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1753 [rate_section][channel_index][RF90_PATH_A] = power_limit;
1755 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1756 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1757 regulation, bandwidth, rate_section, channel,
1758 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1759 [rate_section][channel_index][RF90_PATH_A]);
1761 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1762 "Cannot recognize the band info in %s\n", pband);
1767 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1768 const char *regulation, const char *band,
1769 const char *bandwidth, const char *rate_section,
1770 const char *rf_path, const char *channel,
1771 const char *power_limit)
1773 _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1774 rate_section, rf_path, channel,
1778 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1780 struct rtl_priv *rtlpriv = rtl_priv(hw);
1781 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1786 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1787 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1788 array = RTL8812AE_TXPWR_LMT;
1790 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1791 array = RTL8821AE_TXPWR_LMT;
1794 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1797 for (i = 0; i < array_len; i += 7) {
1798 const char *regulation = array[i];
1799 const char *band = array[i+1];
1800 const char *bandwidth = array[i+2];
1801 const char *rate = array[i+3];
1802 const char *rf_path = array[i+4];
1803 const char *chnl = array[i+5];
1804 const char *val = array[i+6];
1806 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1807 bandwidth, rate, rf_path,
1812 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1814 struct rtl_priv *rtlpriv = rtl_priv(hw);
1815 struct rtl_phy *rtlphy = &rtlpriv->phy;
1816 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1819 _rtl8821ae_phy_init_txpower_limit(hw);
1821 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1822 if (rtlefuse->eeprom_regulatory != 2)
1823 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1825 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1826 BASEBAND_CONFIG_PHY_REG);
1827 if (rtstatus != true) {
1828 pr_err("Write BB Reg Fail!!\n");
1831 _rtl8821ae_phy_init_tx_power_by_rate(hw);
1832 if (rtlefuse->autoload_failflag == false) {
1833 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1834 BASEBAND_CONFIG_PHY_REG);
1836 if (rtstatus != true) {
1837 pr_err("BB_PG Reg Fail!!\n");
1841 _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1843 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1844 if (rtlefuse->eeprom_regulatory != 2)
1845 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1847 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1848 BASEBAND_CONFIG_AGC_TAB);
1850 if (rtstatus != true) {
1851 pr_err("AGC Table Fail\n");
1854 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1855 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1860 __rtl8821ae_phy_config_with_headerfile(struct ieee80211_hw *hw,
1861 u32 *array_table, u16 arraylen,
1862 void (*set_reg)(struct ieee80211_hw *hw,
1863 u32 regaddr, u32 data))
1866 #define COND_ENDIF 3
1870 bool matched = true, skipped = false;
1872 while ((i + 1) < arraylen) {
1873 u32 v1 = array_table[i];
1874 u32 v2 = array_table[i + 1];
1876 if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/
1877 if (v1 & BIT(31)) {/* positive condition*/
1878 cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
1879 if (cond == COND_ENDIF) {/*end*/
1882 } else if (cond == COND_ELSE) /*else*/
1883 matched = skipped ? false : true;
1884 else {/*if , else if*/
1888 if (_rtl8821ae_check_positive(
1898 } else if (v1 & BIT(30)) { /*negative condition*/
1903 set_reg(hw, v1, v2);
1911 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1913 struct rtl_priv *rtlpriv = rtl_priv(hw);
1914 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1918 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1919 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1920 arraylength = RTL8821AE_MAC_1T_ARRAYLEN;
1921 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1923 arraylength = RTL8812AE_MAC_1T_ARRAYLEN;
1924 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1926 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1927 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1929 return __rtl8821ae_phy_config_with_headerfile(hw,
1930 ptrarray, arraylength, rtl_write_byte_with_val32);
1933 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1936 struct rtl_priv *rtlpriv = rtl_priv(hw);
1937 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1941 if (configtype == BASEBAND_CONFIG_PHY_REG) {
1942 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1943 arraylen = RTL8812AE_PHY_REG_1TARRAYLEN;
1944 array_table = RTL8812AE_PHY_REG_ARRAY;
1946 arraylen = RTL8821AE_PHY_REG_1TARRAYLEN;
1947 array_table = RTL8821AE_PHY_REG_ARRAY;
1950 return __rtl8821ae_phy_config_with_headerfile(hw,
1951 array_table, arraylen,
1952 _rtl8821ae_config_bb_reg);
1953 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1954 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1955 arraylen = RTL8812AE_AGC_TAB_1TARRAYLEN;
1956 array_table = RTL8812AE_AGC_TAB_ARRAY;
1958 arraylen = RTL8821AE_AGC_TAB_1TARRAYLEN;
1959 array_table = RTL8821AE_AGC_TAB_ARRAY;
1962 return __rtl8821ae_phy_config_with_headerfile(hw,
1963 array_table, arraylen,
1964 rtl_set_bbreg_with_dwmask);
1969 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1973 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1974 index = (u8)((regaddr - 0xC20) / 4);
1975 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1976 index = (u8)((regaddr - 0xE20) / 4);
1979 "rtl8821ae: Invalid RegAddr 0x%x\n", regaddr);
1983 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1984 u32 band, u32 rfpath,
1985 u32 txnum, u32 regaddr,
1986 u32 bitmask, u32 data)
1988 struct rtl_priv *rtlpriv = rtl_priv(hw);
1989 struct rtl_phy *rtlphy = &rtlpriv->phy;
1990 u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1992 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1993 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1994 band = BAND_ON_2_4G;
1996 if (rfpath >= MAX_RF_PATH) {
1997 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1998 rfpath = MAX_RF_PATH - 1;
2000 if (txnum >= MAX_RF_PATH) {
2001 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
2002 txnum = MAX_RF_PATH - 1;
2004 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
2005 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2006 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
2007 band, rfpath, txnum, rate_section,
2008 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
2011 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
2014 struct rtl_priv *rtlpriv = rtl_priv(hw);
2015 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2019 u32 v1, v2, v3, v4, v5, v6;
2021 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
2022 arraylen = RTL8812AE_PHY_REG_ARRAY_PGLEN;
2023 array = RTL8812AE_PHY_REG_ARRAY_PG;
2025 arraylen = RTL8821AE_PHY_REG_ARRAY_PGLEN;
2026 array = RTL8821AE_PHY_REG_ARRAY_PG;
2029 if (configtype != BASEBAND_CONFIG_PHY_REG) {
2030 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
2031 "configtype != BaseBand_Config_PHY_REG\n");
2034 for (i = 0; i < arraylen; i += 6) {
2042 if (v1 < 0xCDCDCDCD) {
2043 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
2044 (v4 == 0xfe || v4 == 0xffe)) {
2049 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
2052 else if (v4 == 0xfd)
2054 else if (v4 == 0xfc)
2056 else if (v4 == 0xfb)
2058 else if (v4 == 0xfa)
2060 else if (v4 == 0xf9)
2063 _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
2067 /*don't need the hw_body*/
2068 if (!_rtl8821ae_check_condition(hw, v1)) {
2069 i += 2; /* skip the pair of expression*/
2073 while (v2 != 0xDEAD) {
2086 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2087 enum radio_path rfpath)
2089 bool rtstatus = true;
2090 u32 *radioa_array_table_a, *radioa_array_table_b;
2091 u16 radioa_arraylen_a, radioa_arraylen_b;
2092 struct rtl_priv *rtlpriv = rtl_priv(hw);
2094 radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
2095 radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
2096 radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
2097 radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2098 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2099 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2100 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2104 return __rtl8821ae_phy_config_with_headerfile(hw,
2105 radioa_array_table_a, radioa_arraylen_a,
2106 _rtl8821ae_config_rf_radio_a);
2109 return __rtl8821ae_phy_config_with_headerfile(hw,
2110 radioa_array_table_b, radioa_arraylen_b,
2111 _rtl8821ae_config_rf_radio_b);
2115 pr_err("switch case %#x not processed\n", rfpath);
2121 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2122 enum radio_path rfpath)
2124 bool rtstatus = true;
2125 u32 *radioa_array_table;
2126 u16 radioa_arraylen;
2127 struct rtl_priv *rtlpriv = rtl_priv(hw);
2129 radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2130 radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2131 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2132 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2133 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2137 return __rtl8821ae_phy_config_with_headerfile(hw,
2138 radioa_array_table, radioa_arraylen,
2139 _rtl8821ae_config_rf_radio_a);
2145 pr_err("switch case %#x not processed\n", rfpath);
2151 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2153 struct rtl_priv *rtlpriv = rtl_priv(hw);
2154 struct rtl_phy *rtlphy = &rtlpriv->phy;
2156 rtlphy->default_initialgain[0] =
2157 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2158 rtlphy->default_initialgain[1] =
2159 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2160 rtlphy->default_initialgain[2] =
2161 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2162 rtlphy->default_initialgain[3] =
2163 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2165 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2166 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2167 rtlphy->default_initialgain[0],
2168 rtlphy->default_initialgain[1],
2169 rtlphy->default_initialgain[2],
2170 rtlphy->default_initialgain[3]);
2172 rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2173 ROFDM0_RXDETECTOR3, MASKBYTE0);
2174 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2175 ROFDM0_RXDETECTOR2, MASKDWORD);
2177 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2178 "Default framesync (0x%x) = 0x%x\n",
2179 ROFDM0_RXDETECTOR3, rtlphy->framesync);
2182 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2184 struct rtl_priv *rtlpriv = rtl_priv(hw);
2185 struct rtl_phy *rtlphy = &rtlpriv->phy;
2187 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2188 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2190 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2191 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2193 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2194 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2196 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2197 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2199 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2200 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2202 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2203 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2205 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2206 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2209 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2211 struct rtl_priv *rtlpriv = rtl_priv(hw);
2212 struct rtl_phy *rtlphy = &rtlpriv->phy;
2216 txpwr_level = rtlphy->cur_cck_txpwridx;
2217 txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2218 WIRELESS_MODE_B, txpwr_level);
2219 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2220 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2222 txpwr_level) > txpwr_dbm)
2224 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2226 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2227 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2228 WIRELESS_MODE_N_24G,
2229 txpwr_level) > txpwr_dbm)
2231 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2233 *powerlevel = txpwr_dbm;
2236 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2241 if (channel <= 14) {
2243 *chnl_index = channel - 1;
2247 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2248 if (channel5g[i] == channel) {
2257 static s8 _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2259 s8 rate_section = 0;
2293 case DESC_RATEMCS10:
2294 case DESC_RATEMCS11:
2297 case DESC_RATEMCS12:
2298 case DESC_RATEMCS13:
2299 case DESC_RATEMCS14:
2300 case DESC_RATEMCS15:
2303 case DESC_RATEVHT1SS_MCS0:
2304 case DESC_RATEVHT1SS_MCS1:
2305 case DESC_RATEVHT1SS_MCS2:
2306 case DESC_RATEVHT1SS_MCS3:
2309 case DESC_RATEVHT1SS_MCS4:
2310 case DESC_RATEVHT1SS_MCS5:
2311 case DESC_RATEVHT1SS_MCS6:
2312 case DESC_RATEVHT1SS_MCS7:
2315 case DESC_RATEVHT1SS_MCS8:
2316 case DESC_RATEVHT1SS_MCS9:
2317 case DESC_RATEVHT2SS_MCS0:
2318 case DESC_RATEVHT2SS_MCS1:
2321 case DESC_RATEVHT2SS_MCS2:
2322 case DESC_RATEVHT2SS_MCS3:
2323 case DESC_RATEVHT2SS_MCS4:
2324 case DESC_RATEVHT2SS_MCS5:
2327 case DESC_RATEVHT2SS_MCS6:
2328 case DESC_RATEVHT2SS_MCS7:
2329 case DESC_RATEVHT2SS_MCS8:
2330 case DESC_RATEVHT2SS_MCS9:
2334 WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2338 return rate_section;
2341 static s8 _rtl8812ae_phy_get_world_wide_limit(s8 *limit_table)
2343 s8 min = limit_table[0];
2346 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2347 if (limit_table[i] < min)
2348 min = limit_table[i];
2353 static s8 _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2355 enum ht_channel_width bandwidth,
2356 enum radio_path rf_path,
2357 u8 rate, u8 channel)
2359 struct rtl_priv *rtlpriv = rtl_priv(hw);
2360 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2361 struct rtl_phy *rtlphy = &rtlpriv->phy;
2362 short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2363 rate_section = -1, channel_temp = -1;
2364 u16 bd, regu, bdwidth, sec, chnl;
2365 s8 power_limit = MAX_POWER_INDEX;
2367 if (rtlefuse->eeprom_regulatory == 2)
2368 return MAX_POWER_INDEX;
2370 regulation = TXPWR_LMT_WW;
2372 if (band == BAND_ON_2_4G)
2374 else if (band == BAND_ON_5G)
2377 if (bandwidth == HT_CHANNEL_WIDTH_20)
2379 else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2381 else if (bandwidth == HT_CHANNEL_WIDTH_80)
2413 case DESC_RATEMCS10:
2414 case DESC_RATEMCS11:
2415 case DESC_RATEMCS12:
2416 case DESC_RATEMCS13:
2417 case DESC_RATEMCS14:
2418 case DESC_RATEMCS15:
2421 case DESC_RATEVHT1SS_MCS0:
2422 case DESC_RATEVHT1SS_MCS1:
2423 case DESC_RATEVHT1SS_MCS2:
2424 case DESC_RATEVHT1SS_MCS3:
2425 case DESC_RATEVHT1SS_MCS4:
2426 case DESC_RATEVHT1SS_MCS5:
2427 case DESC_RATEVHT1SS_MCS6:
2428 case DESC_RATEVHT1SS_MCS7:
2429 case DESC_RATEVHT1SS_MCS8:
2430 case DESC_RATEVHT1SS_MCS9:
2433 case DESC_RATEVHT2SS_MCS0:
2434 case DESC_RATEVHT2SS_MCS1:
2435 case DESC_RATEVHT2SS_MCS2:
2436 case DESC_RATEVHT2SS_MCS3:
2437 case DESC_RATEVHT2SS_MCS4:
2438 case DESC_RATEVHT2SS_MCS5:
2439 case DESC_RATEVHT2SS_MCS6:
2440 case DESC_RATEVHT2SS_MCS7:
2441 case DESC_RATEVHT2SS_MCS8:
2442 case DESC_RATEVHT2SS_MCS9:
2446 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2447 "Wrong rate 0x%x\n", rate);
2451 if (band_temp == BAND_ON_5G && rate_section == 0)
2452 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2453 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2455 /*workaround for wrong index combination to obtain tx power limit,
2456 OFDM only exists in BW 20M*/
2457 if (rate_section == 1)
2460 /*workaround for wrong index combination to obtain tx power limit,
2461 *HT on 80M will reference to HT on 40M
2463 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2464 bandwidth_temp == 2)
2467 if (band == BAND_ON_2_4G)
2468 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2469 BAND_ON_2_4G, channel);
2470 else if (band == BAND_ON_5G)
2471 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2472 BAND_ON_5G, channel);
2473 else if (band == BAND_ON_BOTH)
2474 ;/* BAND_ON_BOTH don't care temporarily */
2476 if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2477 rate_section == -1 || channel_temp == -1) {
2478 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2479 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2480 band_temp, regulation, bandwidth_temp, rf_path,
2481 rate_section, channel_temp);
2482 return MAX_POWER_INDEX;
2487 bdwidth = bandwidth_temp;
2489 chnl = channel_temp;
2491 if (band == BAND_ON_2_4G) {
2492 s8 limits[10] = {0};
2495 for (i = 0; i < 4; ++i)
2496 limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2497 [sec][chnl][rf_path];
2499 power_limit = (regulation == TXPWR_LMT_WW) ?
2500 _rtl8812ae_phy_get_world_wide_limit(limits) :
2501 rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2502 [sec][chnl][rf_path];
2503 } else if (band == BAND_ON_5G) {
2504 s8 limits[10] = {0};
2507 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2508 limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2509 [sec][chnl][rf_path];
2511 power_limit = (regulation == TXPWR_LMT_WW) ?
2512 _rtl8812ae_phy_get_world_wide_limit(limits) :
2513 rtlphy->txpwr_limit_5g[regu][chnl]
2514 [sec][chnl][rf_path];
2516 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2517 "No power limit table of the specified band\n");
2522 static s8 _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2523 u8 band, u8 path, u8 rate)
2525 struct rtl_priv *rtlpriv = rtl_priv(hw);
2526 struct rtl_phy *rtlphy = &rtlpriv->phy;
2527 u8 shift = 0, rate_section, tx_num;
2531 rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2532 tx_num = RF_TX_NUM_NONIMPLEMENT;
2534 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2535 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2536 (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2549 case DESC_RATEMCS12:
2550 case DESC_RATEVHT1SS_MCS0:
2551 case DESC_RATEVHT1SS_MCS4:
2552 case DESC_RATEVHT1SS_MCS8:
2553 case DESC_RATEVHT2SS_MCS2:
2554 case DESC_RATEVHT2SS_MCS6:
2563 case DESC_RATEMCS13:
2564 case DESC_RATEVHT1SS_MCS1:
2565 case DESC_RATEVHT1SS_MCS5:
2566 case DESC_RATEVHT1SS_MCS9:
2567 case DESC_RATEVHT2SS_MCS3:
2568 case DESC_RATEVHT2SS_MCS7:
2576 case DESC_RATEMCS10:
2577 case DESC_RATEMCS14:
2578 case DESC_RATEVHT1SS_MCS2:
2579 case DESC_RATEVHT1SS_MCS6:
2580 case DESC_RATEVHT2SS_MCS0:
2581 case DESC_RATEVHT2SS_MCS4:
2582 case DESC_RATEVHT2SS_MCS8:
2590 case DESC_RATEMCS11:
2591 case DESC_RATEMCS15:
2592 case DESC_RATEVHT1SS_MCS3:
2593 case DESC_RATEVHT1SS_MCS7:
2594 case DESC_RATEVHT2SS_MCS1:
2595 case DESC_RATEVHT2SS_MCS5:
2596 case DESC_RATEVHT2SS_MCS9:
2600 WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2604 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2605 [tx_num][rate_section] >> shift) & 0xff;
2607 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2608 if (rtlpriv->efuse.eeprom_regulatory != 2) {
2609 limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2610 rtlphy->current_chan_bw, path, rate,
2611 rtlphy->current_channel);
2613 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2614 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2616 if (tx_pwr_diff < (-limit))
2617 tx_pwr_diff = -limit;
2621 tx_pwr_diff = limit;
2623 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2625 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2626 "Maximum power by rate %d, final power by rate %d\n",
2627 limit, tx_pwr_diff);
2633 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2634 u8 rate, u8 bandwidth, u8 channel)
2636 struct rtl_priv *rtlpriv = rtl_priv(hw);
2637 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2638 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2639 u8 index = (channel - 1);
2641 bool in_24g = false;
2642 s8 powerdiff_byrate = 0;
2644 if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2645 (channel > 14 || channel < 1)) ||
2646 ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2648 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2649 "Illegal channel!!\n");
2652 in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2654 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2655 txpower = rtlefuse->txpwrlevel_cck[path][index];
2656 else if (DESC_RATE6M <= rate)
2657 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2659 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2661 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2662 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2663 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2665 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2666 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2667 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2668 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2669 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2670 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2671 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2672 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2673 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2674 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2675 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2676 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2677 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2678 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2679 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2680 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2681 (DESC_RATEVHT1SS_MCS0 <= rate &&
2682 rate <= DESC_RATEVHT2SS_MCS9))
2683 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2684 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2685 (DESC_RATEVHT2SS_MCS0 <= rate &&
2686 rate <= DESC_RATEVHT2SS_MCS9))
2687 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2690 if (DESC_RATE6M <= rate)
2691 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2693 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2696 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2697 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2698 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2700 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2701 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2702 (DESC_RATEVHT1SS_MCS0 <= rate &&
2703 rate <= DESC_RATEVHT2SS_MCS9))
2704 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2705 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2706 (DESC_RATEVHT2SS_MCS0 <= rate &&
2707 rate <= DESC_RATEVHT2SS_MCS9))
2708 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2709 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2710 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2711 (DESC_RATEVHT1SS_MCS0 <= rate &&
2712 rate <= DESC_RATEVHT2SS_MCS9))
2713 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2714 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2715 (DESC_RATEVHT2SS_MCS0 <= rate &&
2716 rate <= DESC_RATEVHT2SS_MCS9))
2717 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2718 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2721 for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i)
2722 if (channel5g_80m[i] == channel)
2725 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2726 (DESC_RATEVHT1SS_MCS0 <= rate &&
2727 rate <= DESC_RATEVHT2SS_MCS9))
2728 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2729 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2730 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2731 (DESC_RATEVHT2SS_MCS0 <= rate &&
2732 rate <= DESC_RATEVHT2SS_MCS9))
2733 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2734 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2735 + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2738 if (rtlefuse->eeprom_regulatory != 2)
2740 _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2743 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2744 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2745 txpower -= powerdiff_byrate;
2747 txpower += powerdiff_byrate;
2749 if (rate > DESC_RATE11M)
2750 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2752 txpower += rtlpriv->dm.remnant_cck_idx;
2754 if (txpower > MAX_POWER_INDEX)
2755 txpower = MAX_POWER_INDEX;
2760 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2761 u8 power_index, u8 path, u8 rate)
2763 struct rtl_priv *rtlpriv = rtl_priv(hw);
2765 if (path == RF90_PATH_A) {
2768 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2769 MASKBYTE0, power_index);
2772 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2773 MASKBYTE1, power_index);
2776 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2777 MASKBYTE2, power_index);
2780 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2781 MASKBYTE3, power_index);
2784 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2785 MASKBYTE0, power_index);
2788 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2789 MASKBYTE1, power_index);
2792 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2793 MASKBYTE2, power_index);
2796 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2797 MASKBYTE3, power_index);
2800 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2801 MASKBYTE0, power_index);
2804 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2805 MASKBYTE1, power_index);
2808 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2809 MASKBYTE2, power_index);
2812 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2813 MASKBYTE3, power_index);
2816 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2817 MASKBYTE0, power_index);
2820 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2821 MASKBYTE1, power_index);
2824 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2825 MASKBYTE2, power_index);
2828 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2829 MASKBYTE3, power_index);
2832 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2833 MASKBYTE0, power_index);
2836 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2837 MASKBYTE1, power_index);
2840 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2841 MASKBYTE2, power_index);
2844 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2845 MASKBYTE3, power_index);
2848 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2849 MASKBYTE0, power_index);
2852 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2853 MASKBYTE1, power_index);
2855 case DESC_RATEMCS10:
2856 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2857 MASKBYTE2, power_index);
2859 case DESC_RATEMCS11:
2860 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2861 MASKBYTE3, power_index);
2863 case DESC_RATEMCS12:
2864 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2865 MASKBYTE0, power_index);
2867 case DESC_RATEMCS13:
2868 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2869 MASKBYTE1, power_index);
2871 case DESC_RATEMCS14:
2872 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2873 MASKBYTE2, power_index);
2875 case DESC_RATEMCS15:
2876 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2877 MASKBYTE3, power_index);
2879 case DESC_RATEVHT1SS_MCS0:
2880 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2881 MASKBYTE0, power_index);
2883 case DESC_RATEVHT1SS_MCS1:
2884 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2885 MASKBYTE1, power_index);
2887 case DESC_RATEVHT1SS_MCS2:
2888 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2889 MASKBYTE2, power_index);
2891 case DESC_RATEVHT1SS_MCS3:
2892 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2893 MASKBYTE3, power_index);
2895 case DESC_RATEVHT1SS_MCS4:
2896 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2897 MASKBYTE0, power_index);
2899 case DESC_RATEVHT1SS_MCS5:
2900 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2901 MASKBYTE1, power_index);
2903 case DESC_RATEVHT1SS_MCS6:
2904 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2905 MASKBYTE2, power_index);
2907 case DESC_RATEVHT1SS_MCS7:
2908 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2909 MASKBYTE3, power_index);
2911 case DESC_RATEVHT1SS_MCS8:
2912 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2913 MASKBYTE0, power_index);
2915 case DESC_RATEVHT1SS_MCS9:
2916 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2917 MASKBYTE1, power_index);
2919 case DESC_RATEVHT2SS_MCS0:
2920 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2921 MASKBYTE2, power_index);
2923 case DESC_RATEVHT2SS_MCS1:
2924 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2925 MASKBYTE3, power_index);
2927 case DESC_RATEVHT2SS_MCS2:
2928 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2929 MASKBYTE0, power_index);
2931 case DESC_RATEVHT2SS_MCS3:
2932 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2933 MASKBYTE1, power_index);
2935 case DESC_RATEVHT2SS_MCS4:
2936 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2937 MASKBYTE2, power_index);
2939 case DESC_RATEVHT2SS_MCS5:
2940 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2941 MASKBYTE3, power_index);
2943 case DESC_RATEVHT2SS_MCS6:
2944 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2945 MASKBYTE0, power_index);
2947 case DESC_RATEVHT2SS_MCS7:
2948 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2949 MASKBYTE1, power_index);
2951 case DESC_RATEVHT2SS_MCS8:
2952 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2953 MASKBYTE2, power_index);
2955 case DESC_RATEVHT2SS_MCS9:
2956 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2957 MASKBYTE3, power_index);
2960 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2961 "Invalid Rate!!\n");
2964 } else if (path == RF90_PATH_B) {
2967 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2968 MASKBYTE0, power_index);
2971 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2972 MASKBYTE1, power_index);
2975 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2976 MASKBYTE2, power_index);
2979 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2980 MASKBYTE3, power_index);
2983 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2984 MASKBYTE0, power_index);
2987 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2988 MASKBYTE1, power_index);
2991 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2992 MASKBYTE2, power_index);
2995 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2996 MASKBYTE3, power_index);
2999 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3000 MASKBYTE0, power_index);
3003 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3004 MASKBYTE1, power_index);
3007 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3008 MASKBYTE2, power_index);
3011 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3012 MASKBYTE3, power_index);
3015 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3016 MASKBYTE0, power_index);
3019 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3020 MASKBYTE1, power_index);
3023 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3024 MASKBYTE2, power_index);
3027 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3028 MASKBYTE3, power_index);
3031 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3032 MASKBYTE0, power_index);
3035 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3036 MASKBYTE1, power_index);
3039 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3040 MASKBYTE2, power_index);
3043 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3044 MASKBYTE3, power_index);
3047 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3048 MASKBYTE0, power_index);
3051 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3052 MASKBYTE1, power_index);
3054 case DESC_RATEMCS10:
3055 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3056 MASKBYTE2, power_index);
3058 case DESC_RATEMCS11:
3059 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3060 MASKBYTE3, power_index);
3062 case DESC_RATEMCS12:
3063 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3064 MASKBYTE0, power_index);
3066 case DESC_RATEMCS13:
3067 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3068 MASKBYTE1, power_index);
3070 case DESC_RATEMCS14:
3071 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3072 MASKBYTE2, power_index);
3074 case DESC_RATEMCS15:
3075 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3076 MASKBYTE3, power_index);
3078 case DESC_RATEVHT1SS_MCS0:
3079 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3080 MASKBYTE0, power_index);
3082 case DESC_RATEVHT1SS_MCS1:
3083 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3084 MASKBYTE1, power_index);
3086 case DESC_RATEVHT1SS_MCS2:
3087 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3088 MASKBYTE2, power_index);
3090 case DESC_RATEVHT1SS_MCS3:
3091 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3092 MASKBYTE3, power_index);
3094 case DESC_RATEVHT1SS_MCS4:
3095 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3096 MASKBYTE0, power_index);
3098 case DESC_RATEVHT1SS_MCS5:
3099 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3100 MASKBYTE1, power_index);
3102 case DESC_RATEVHT1SS_MCS6:
3103 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3104 MASKBYTE2, power_index);
3106 case DESC_RATEVHT1SS_MCS7:
3107 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3108 MASKBYTE3, power_index);
3110 case DESC_RATEVHT1SS_MCS8:
3111 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3112 MASKBYTE0, power_index);
3114 case DESC_RATEVHT1SS_MCS9:
3115 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3116 MASKBYTE1, power_index);
3118 case DESC_RATEVHT2SS_MCS0:
3119 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3120 MASKBYTE2, power_index);
3122 case DESC_RATEVHT2SS_MCS1:
3123 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3124 MASKBYTE3, power_index);
3126 case DESC_RATEVHT2SS_MCS2:
3127 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3128 MASKBYTE0, power_index);
3130 case DESC_RATEVHT2SS_MCS3:
3131 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3132 MASKBYTE1, power_index);
3134 case DESC_RATEVHT2SS_MCS4:
3135 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3136 MASKBYTE2, power_index);
3138 case DESC_RATEVHT2SS_MCS5:
3139 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3140 MASKBYTE3, power_index);
3142 case DESC_RATEVHT2SS_MCS6:
3143 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3144 MASKBYTE0, power_index);
3146 case DESC_RATEVHT2SS_MCS7:
3147 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3148 MASKBYTE1, power_index);
3150 case DESC_RATEVHT2SS_MCS8:
3151 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3152 MASKBYTE2, power_index);
3154 case DESC_RATEVHT2SS_MCS9:
3155 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3156 MASKBYTE3, power_index);
3159 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3160 "Invalid Rate!!\n");
3164 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3165 "Invalid RFPath!!\n");
3169 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3171 u8 channel, u8 size)
3173 struct rtl_priv *rtlpriv = rtl_priv(hw);
3174 struct rtl_phy *rtlphy = &rtlpriv->phy;
3178 for (i = 0; i < size; i++) {
3180 _rtl8821ae_get_txpower_index(hw, path, array[i],
3181 rtlphy->current_chan_bw,
3183 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3188 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3189 u8 bw, u8 channel, u8 path)
3191 struct rtl_priv *rtlpriv = rtl_priv(hw);
3192 struct rtl_phy *rtlphy = &rtlpriv->phy;
3195 u32 power_level, data, offset;
3197 if (path >= rtlphy->num_total_rfpath)
3201 if (path == RF90_PATH_A) {
3203 _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3204 DESC_RATEMCS7, bw, channel);
3205 offset = RA_TXPWRTRAING;
3208 _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3209 DESC_RATEMCS7, bw, channel);
3210 offset = RB_TXPWRTRAING;
3213 for (i = 0; i < 3; i++) {
3215 power_level = power_level - 10;
3217 power_level = power_level - 8;
3219 power_level = power_level - 6;
3221 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3223 rtl_set_bbreg(hw, offset, 0xffffff, data);
3226 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3227 u8 channel, u8 path)
3229 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3230 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3231 struct rtl_priv *rtlpriv = rtl_priv(hw);
3232 struct rtl_phy *rtlphy = &rtlpriv->phy;
3233 u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3235 u8 sizes_of_cck_retes = 4;
3236 u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3237 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3238 DESC_RATE48M, DESC_RATE54M};
3239 u8 sizes_of_ofdm_retes = 8;
3240 u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3241 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3242 DESC_RATEMCS6, DESC_RATEMCS7};
3243 u8 sizes_of_ht_retes_1t = 8;
3244 u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9,
3245 DESC_RATEMCS10, DESC_RATEMCS11,
3246 DESC_RATEMCS12, DESC_RATEMCS13,
3247 DESC_RATEMCS14, DESC_RATEMCS15};
3248 u8 sizes_of_ht_retes_2t = 8;
3249 u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3250 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3251 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3252 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3253 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3254 u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3255 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3256 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3257 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3258 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3259 u8 sizes_of_vht_retes = 10;
3261 if (rtlhal->current_bandtype == BAND_ON_2_4G)
3262 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3263 sizes_of_cck_retes);
3265 _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3266 sizes_of_ofdm_retes);
3267 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3268 sizes_of_ht_retes_1t);
3269 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3270 sizes_of_vht_retes);
3272 if (rtlphy->num_total_rfpath >= 2) {
3273 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3275 sizes_of_ht_retes_2t);
3276 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3278 sizes_of_vht_retes);
3281 _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3285 /*just in case, write txpower in DW, to reduce time*/
3286 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3288 struct rtl_priv *rtlpriv = rtl_priv(hw);
3289 struct rtl_phy *rtlphy = &rtlpriv->phy;
3292 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3293 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3296 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3297 enum wireless_mode wirelessmode,
3303 switch (wirelessmode) {
3304 case WIRELESS_MODE_B:
3307 case WIRELESS_MODE_G:
3308 case WIRELESS_MODE_N_24G:
3315 pwrout_dbm = txpwridx / 2 + offset;
3319 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3321 struct rtl_priv *rtlpriv = rtl_priv(hw);
3322 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3323 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3325 if (!is_hal_stop(rtlhal)) {
3326 switch (operation) {
3327 case SCAN_OPT_BACKUP_BAND0:
3328 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3329 rtlpriv->cfg->ops->set_hw_reg(hw,
3334 case SCAN_OPT_BACKUP_BAND1:
3335 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3336 rtlpriv->cfg->ops->set_hw_reg(hw,
3341 case SCAN_OPT_RESTORE:
3342 iotype = IO_CMD_RESUME_DM_BY_SCAN;
3343 rtlpriv->cfg->ops->set_hw_reg(hw,
3348 pr_err("Unknown Scan Backup operation.\n");
3354 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3356 u16 reg_rf_mode_bw, tmp = 0;
3358 reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3360 case HT_CHANNEL_WIDTH_20:
3361 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3363 case HT_CHANNEL_WIDTH_20_40:
3364 tmp = reg_rf_mode_bw | BIT(7);
3365 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3367 case HT_CHANNEL_WIDTH_80:
3368 tmp = reg_rf_mode_bw | BIT(8);
3369 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3372 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3377 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3379 struct rtl_phy *rtlphy = &rtlpriv->phy;
3380 struct rtl_mac *mac = rtl_mac(rtlpriv);
3381 u8 sc_set_40 = 0, sc_set_20 = 0;
3383 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3384 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3385 sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3386 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3387 sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3389 pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3391 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3392 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3393 sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3394 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3395 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3396 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3397 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3398 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3399 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3400 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3401 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3402 sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3404 pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3405 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3406 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3407 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3408 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3409 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3411 pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3413 return (sc_set_40 << 4) | sc_set_20;
3416 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3418 struct rtl_priv *rtlpriv = rtl_priv(hw);
3419 struct rtl_phy *rtlphy = &rtlpriv->phy;
3423 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3424 "Switch to %s bandwidth\n",
3425 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3427 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3428 "40MHz" : "80MHz")));
3430 _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3431 sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3432 rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3434 switch (rtlphy->current_chan_bw) {
3435 case HT_CHANNEL_WIDTH_20:
3436 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3437 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3439 if (rtlphy->rf_type == RF_2T2R)
3440 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3442 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3444 case HT_CHANNEL_WIDTH_20_40:
3445 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3446 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3447 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3448 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3450 if (rtlphy->reg_837 & BIT(2))
3453 if (rtlphy->rf_type == RF_2T2R)
3458 /* 0x848[25:22] = 0x6 */
3459 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3461 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3462 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3464 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3467 case HT_CHANNEL_WIDTH_80:
3468 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3469 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3471 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3472 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3473 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3475 if (rtlphy->reg_837 & BIT(2))
3478 if (rtlphy->rf_type == RF_2T2R)
3483 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3487 pr_err("unknown bandwidth: %#X\n",
3488 rtlphy->current_chan_bw);
3492 rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3494 rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3495 rtlphy->set_bwmode_inprogress = false;
3497 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3500 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3501 enum nl80211_channel_type ch_type)
3503 struct rtl_priv *rtlpriv = rtl_priv(hw);
3504 struct rtl_phy *rtlphy = &rtlpriv->phy;
3505 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3506 u8 tmp_bw = rtlphy->current_chan_bw;
3508 if (rtlphy->set_bwmode_inprogress)
3510 rtlphy->set_bwmode_inprogress = true;
3511 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3512 rtl8821ae_phy_set_bw_mode_callback(hw);
3514 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3515 "FALSE driver sleep or unload\n");
3516 rtlphy->set_bwmode_inprogress = false;
3517 rtlphy->current_chan_bw = tmp_bw;
3521 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3523 struct rtl_priv *rtlpriv = rtl_priv(hw);
3524 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3525 struct rtl_phy *rtlphy = &rtlpriv->phy;
3526 u8 channel = rtlphy->current_channel;
3530 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3531 "switch to channel%d\n", rtlphy->current_channel);
3532 if (is_hal_stop(rtlhal))
3535 if (36 <= channel && channel <= 48)
3537 else if (50 <= channel && channel <= 64)
3539 else if (100 <= channel && channel <= 116)
3541 else if (118 <= channel)
3545 rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3547 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3548 if (36 <= channel && channel <= 64)
3550 else if (100 <= channel && channel <= 140)
3552 else if (140 < channel)
3556 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3557 BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3559 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3560 BMASKBYTE0, channel);
3563 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3564 if (36 <= channel && channel <= 64)
3566 else if (100 <= channel && channel <= 140)
3570 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3571 BRFREGOFFSETMASK, data);
3575 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3578 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3580 struct rtl_priv *rtlpriv = rtl_priv(hw);
3581 struct rtl_phy *rtlphy = &rtlpriv->phy;
3582 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3583 u32 timeout = 1000, timecount = 0;
3584 u8 channel = rtlphy->current_channel;
3586 if (rtlphy->sw_chnl_inprogress)
3588 if (rtlphy->set_bwmode_inprogress)
3591 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3592 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3593 "sw_chnl_inprogress false driver sleep or unload\n");
3596 while (rtlphy->lck_inprogress && timecount < timeout) {
3601 if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3602 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3603 else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3604 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3606 rtlphy->sw_chnl_inprogress = true;
3610 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3611 "switch to channel%d, band type is %d\n",
3612 rtlphy->current_channel, rtlhal->current_bandtype);
3614 rtl8821ae_phy_sw_chnl_callback(hw);
3616 rtl8821ae_dm_clear_txpower_tracking_state(hw);
3617 rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3619 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3620 rtlphy->sw_chnl_inprogress = false;
3624 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3626 u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3627 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3628 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3629 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3630 110, 112, 114, 116, 118, 120, 122, 124, 126,
3631 128, 130, 132, 134, 136, 138, 140, 149, 151,
3632 153, 155, 157, 159, 161, 163, 165};
3636 for (place = 14; place < sizeof(channel_all); place++)
3637 if (channel_all[place] == chnl)
3644 #define MACBB_REG_NUM 10
3645 #define AFE_REG_NUM 14
3646 #define RF_REG_NUM 3
3648 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3650 u32 *backup_macbb_reg, u32 mac_bb_num)
3652 struct rtl_priv *rtlpriv = rtl_priv(hw);
3655 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3656 /*save MACBB default value*/
3657 for (i = 0; i < mac_bb_num; i++)
3658 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3660 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3663 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3664 u32 *backup_afe_REG, u32 afe_num)
3666 struct rtl_priv *rtlpriv = rtl_priv(hw);
3669 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3670 /*Save AFE Parameters */
3671 for (i = 0; i < afe_num; i++)
3672 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3673 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3676 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3677 u32 *rfb_backup, u32 *backup_rf_reg,
3680 struct rtl_priv *rtlpriv = rtl_priv(hw);
3683 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3684 /*Save RF Parameters*/
3685 for (i = 0; i < rf_num; i++) {
3686 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3688 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3691 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3694 static void _rtl8821ae_iqk_configure_mac(
3695 struct ieee80211_hw *hw
3698 struct rtl_priv *rtlpriv = rtl_priv(hw);
3699 /* ========MAC register setting========*/
3700 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3701 rtl_write_byte(rtlpriv, 0x522, 0x3f);
3702 rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3703 rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/
3704 rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/
3707 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3708 enum radio_path path, u32 tx_x, u32 tx_y)
3710 struct rtl_priv *rtlpriv = rtl_priv(hw);
3713 /* [31] = 1 --> Page C1 */
3714 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3715 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3716 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3717 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3718 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3719 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3720 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3721 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3723 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3724 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3725 rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3726 rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3733 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3734 enum radio_path path, u32 rx_x, u32 rx_y)
3736 struct rtl_priv *rtlpriv = rtl_priv(hw);
3739 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3740 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3741 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3742 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3743 "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3745 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3746 "0xc10 = %x ====>fill to IQC\n",
3747 rtl_read_dword(rtlpriv, 0xc10));
3756 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3758 struct rtl_priv *rtlpriv = rtl_priv(hw);
3759 struct rtl_phy *rtlphy = &rtlpriv->phy;
3760 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3762 u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3763 int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3764 int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3765 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num],
3766 tx_dt[cal_num], rx_dt[cal_num];
3767 bool tx0iqkok = false, rx0iqkok = false;
3768 bool vdf_enable = false;
3769 int i, k, vdf_y[3], vdf_x[3],
3770 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3772 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3773 "BandWidth = %d.\n",
3774 rtlphy->current_chan_bw);
3775 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3778 while (cal < cal_num) {
3781 temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3783 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3784 /*========Path-A AFE all on========*/
3785 /*Port 0 DAC/ADC on*/
3786 rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3787 rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3788 rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3789 rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3790 rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3791 rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3792 rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3793 rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3794 rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3795 rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3797 rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3800 /* ====== LOK ====== */
3801 /*DAC/ADC sampling rate (160 MHz)*/
3802 rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3804 /* 2. LoK RF Setting (at BW = 20M) */
3805 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3806 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */
3807 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3808 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3809 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3810 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3811 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3812 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3813 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3814 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3815 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3816 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3817 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3818 rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3820 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3821 rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3823 if (rtlhal->current_bandtype)
3824 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3826 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3828 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3829 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3830 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3831 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3832 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3834 mdelay(10); /* Delay 10ms */
3835 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3837 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3838 rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3840 switch (rtlphy->current_chan_bw) {
3842 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3845 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3851 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3853 /* 3. TX RF Setting */
3854 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3855 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3856 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3857 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3858 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3859 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3860 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3861 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3862 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3863 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3864 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3865 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3866 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3867 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3868 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3870 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3871 rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3872 if (rtlhal->current_bandtype)
3873 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3875 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3877 if (vdf_enable == 1) {
3878 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3879 for (k = 0; k <= 2; k++) {
3882 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3883 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3884 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3887 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3888 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3889 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3892 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3893 "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3894 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3895 "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3896 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3897 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3898 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3899 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3900 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3901 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3902 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3907 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3911 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3912 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3914 mdelay(10); /* Delay 10ms */
3915 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3918 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3919 if ((~iqk_ready) || (delay_count > 20))
3927 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3928 /* ============TXIQK Check============== */
3929 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3932 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3933 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3934 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3935 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3939 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3940 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3943 if (cal_retry == 10)
3949 if (cal_retry == 10)
3955 tx_x0[cal] = vdf_x[k-1];
3956 tx_y0[cal] = vdf_y[k-1];
3959 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3960 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3961 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3965 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3966 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3968 mdelay(10); /* Delay 10ms */
3969 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3972 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3973 if ((~iqk_ready) || (delay_count > 20))
3981 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3982 /* ============TXIQK Check============== */
3983 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3986 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3987 tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3988 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3989 tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3993 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3994 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3997 if (cal_retry == 10)
4003 if (cal_retry == 10)
4009 if (tx0iqkok == false)
4010 break; /* TXK fail, Don't do RXK */
4012 if (vdf_enable == 1) {
4013 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */
4014 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4015 for (k = 0; k <= 2; k++) {
4016 /* ====== RX mode TXK (RXK Step 1) ====== */
4017 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4018 /* 1. TX RF Setting */
4019 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4020 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4021 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4022 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4023 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4024 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4025 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4027 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4028 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4029 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4030 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4031 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4032 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4033 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4037 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4038 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4039 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4044 rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4045 rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4046 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4051 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4052 "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4053 vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4054 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4055 "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4056 vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4057 rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4058 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4059 rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4060 rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4061 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4062 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4063 rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4069 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4070 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4071 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4075 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4076 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4078 mdelay(10); /* Delay 10ms */
4079 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4082 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4083 if ((~iqk_ready) || (delay_count > 20))
4091 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4092 /* ============TXIQK Check============== */
4093 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4096 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4097 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4098 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4099 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4105 if (cal_retry == 10)
4111 if (cal_retry == 10)
4116 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4117 tx_x0_rxk[cal] = tx_x0[cal];
4118 tx_y0_rxk[cal] = tx_y0[cal];
4123 "RXK Step 1 fail\n");
4126 /* ====== RX IQK ====== */
4127 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4128 /* 1. RX RF Setting */
4129 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4130 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4131 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4132 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4133 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4134 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4135 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4137 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4138 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4139 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4140 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4141 rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4142 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4143 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4145 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4146 rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4147 rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4148 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4150 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4153 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */
4154 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 /* ============RXIQK Check============== */
4177 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4179 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4180 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4181 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4182 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4186 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4187 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4190 if (cal_retry == 10)
4197 if (cal_retry == 10)
4204 rx_x0[cal] = vdf_x[k-1];
4205 rx_y0[cal] = vdf_y[k-1];
4207 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */
4211 /* ====== RX mode TXK (RXK Step 1) ====== */
4212 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4213 /* 1. TX RF Setting */
4214 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4215 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4216 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4217 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4218 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4219 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4220 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4221 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4222 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4223 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4225 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4226 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4227 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4228 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4229 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4230 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4234 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4235 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4237 mdelay(10); /* Delay 10ms */
4238 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4241 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4242 if ((~iqk_ready) || (delay_count > 20))
4250 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4251 /* ============TXIQK Check============== */
4252 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4255 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4256 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4257 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4258 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4264 if (cal_retry == 10)
4270 if (cal_retry == 10)
4275 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4276 tx_x0_rxk[cal] = tx_x0[cal];
4277 tx_y0_rxk[cal] = tx_y0[cal];
4279 RT_TRACE(rtlpriv, COMP_IQK,
4283 /* ====== RX IQK ====== */
4284 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4285 /* 1. RX RF Setting */
4286 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4287 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4288 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4289 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4290 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4291 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4292 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4294 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4295 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4296 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4297 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4298 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4299 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4300 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4302 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4303 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4304 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4305 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4307 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4309 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4314 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4315 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4317 mdelay(10); /* Delay 10ms */
4318 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4321 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4322 if ((~iqk_ready) || (delay_count > 20))
4330 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4331 /* ============RXIQK Check============== */
4332 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4334 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4335 rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4336 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4337 rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4341 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4342 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4345 if (cal_retry == 10)
4352 if (cal_retry == 10)
4362 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4363 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4371 /* FillIQK Result */
4374 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4375 "========Path_A =======\n");
4376 if (tx_average == 0)
4379 for (i = 0; i < tx_average; i++) {
4380 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4381 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4382 (tx_x0_rxk[i])>>21&0x000007ff, i,
4383 (tx_y0_rxk[i])>>21&0x000007ff);
4384 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4385 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4386 (tx_x0[i])>>21&0x000007ff, i,
4387 (tx_y0[i])>>21&0x000007ff);
4389 for (i = 0; i < tx_average; i++) {
4390 for (ii = i+1; ii < tx_average; ii++) {
4391 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4392 if (dx < 3 && dx > -3) {
4393 dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4394 if (dy < 3 && dy > -3) {
4395 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4396 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4407 _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4409 _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4411 if (rx_average == 0)
4414 for (i = 0; i < rx_average; i++)
4415 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4416 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4417 (rx_x0[i])>>21&0x000007ff, i,
4418 (rx_y0[i])>>21&0x000007ff);
4419 for (i = 0; i < rx_average; i++) {
4420 for (ii = i+1; ii < rx_average; ii++) {
4421 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4422 if (dx < 4 && dx > -4) {
4423 dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4424 if (dy < 4 && dy > -4) {
4425 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4426 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4437 _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4439 _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4446 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4447 enum radio_path path,
4449 u32 *rf_backup, u32 rf_reg_num)
4451 struct rtl_priv *rtlpriv = rtl_priv(hw);
4454 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4455 for (i = 0; i < RF_REG_NUM; i++)
4456 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4461 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4462 "RestoreRF Path A Success!!!!\n");
4469 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4470 u32 *afe_backup, u32 *backup_afe_reg,
4474 struct rtl_priv *rtlpriv = rtl_priv(hw);
4476 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4477 /* Reload AFE Parameters */
4478 for (i = 0; i < afe_num; i++)
4479 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4480 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4481 rtl_write_dword(rtlpriv, 0xc80, 0x0);
4482 rtl_write_dword(rtlpriv, 0xc84, 0x0);
4483 rtl_write_dword(rtlpriv, 0xc88, 0x0);
4484 rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4485 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4486 rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4487 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4488 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4489 rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4490 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4493 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4495 u32 *backup_macbb_reg,
4499 struct rtl_priv *rtlpriv = rtl_priv(hw);
4501 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4502 /* Reload MacBB Parameters */
4503 for (i = 0; i < macbb_num; i++)
4504 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4505 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4508 #undef MACBB_REG_NUM
4512 #define MACBB_REG_NUM 11
4513 #define AFE_REG_NUM 12
4514 #define RF_REG_NUM 3
4516 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4518 u32 macbb_backup[MACBB_REG_NUM];
4519 u32 afe_backup[AFE_REG_NUM];
4520 u32 rfa_backup[RF_REG_NUM];
4521 u32 rfb_backup[RF_REG_NUM];
4522 u32 backup_macbb_reg[MACBB_REG_NUM] = {
4523 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4524 0xe00, 0xe50, 0x838, 0x82c
4526 u32 backup_afe_reg[AFE_REG_NUM] = {
4527 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4528 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4530 u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4532 _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4534 _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4535 _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4538 _rtl8821ae_iqk_configure_mac(hw);
4539 _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4540 _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4543 _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4544 _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4548 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4550 struct rtl_priv *rtlpriv = rtl_priv(hw);
4551 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4552 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4553 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4556 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4558 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4561 #undef IQK_ADDA_REG_NUM
4562 #undef IQK_DELAY_TIME
4564 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4568 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4569 u8 thermal_value, u8 threshold)
4571 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4573 rtldm->thermalvalue_iqk = thermal_value;
4574 rtl8812ae_phy_iq_calibrate(hw, false);
4577 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4579 struct rtl_priv *rtlpriv = rtl_priv(hw);
4580 struct rtl_phy *rtlphy = &rtlpriv->phy;
4582 if (!rtlphy->lck_inprogress) {
4583 spin_lock(&rtlpriv->locks.iqk_lock);
4584 rtlphy->lck_inprogress = true;
4585 spin_unlock(&rtlpriv->locks.iqk_lock);
4587 _rtl8821ae_phy_iq_calibrate(hw);
4589 spin_lock(&rtlpriv->locks.iqk_lock);
4590 rtlphy->lck_inprogress = false;
4591 spin_unlock(&rtlpriv->locks.iqk_lock);
4595 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4597 struct rtl_priv *rtlpriv = rtl_priv(hw);
4598 struct rtl_phy *rtlphy = &rtlpriv->phy;
4601 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4602 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4603 (int)(sizeof(rtlphy->iqk_matrix) /
4604 sizeof(struct iqk_matrix_regs)),
4605 IQK_MATRIX_SETTINGS_NUM);
4607 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4608 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4609 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4610 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4611 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4613 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4614 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4615 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4616 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4618 rtlphy->iqk_matrix[i].iqk_done = false;
4622 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4623 u8 thermal_value, u8 threshold)
4625 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4627 rtl8821ae_reset_iqk_result(hw);
4629 rtldm->thermalvalue_iqk = thermal_value;
4630 rtl8821ae_phy_iq_calibrate(hw, false);
4633 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4637 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
4641 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4643 _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4646 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4648 struct rtl_priv *rtlpriv = rtl_priv(hw);
4649 struct rtl_phy *rtlphy = &rtlpriv->phy;
4650 bool postprocessing = false;
4652 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4653 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4654 iotype, rtlphy->set_io_inprogress);
4657 case IO_CMD_RESUME_DM_BY_SCAN:
4658 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4659 "[IO CMD] Resume DM after scan.\n");
4660 postprocessing = true;
4662 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4663 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4664 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4665 "[IO CMD] Pause DM before scan.\n");
4666 postprocessing = true;
4669 pr_err("switch case %#x not processed\n",
4674 if (postprocessing && !rtlphy->set_io_inprogress) {
4675 rtlphy->set_io_inprogress = true;
4676 rtlphy->current_io_type = iotype;
4680 rtl8821ae_phy_set_io(hw);
4681 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4685 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4687 struct rtl_priv *rtlpriv = rtl_priv(hw);
4688 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4689 struct rtl_phy *rtlphy = &rtlpriv->phy;
4691 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4692 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4693 rtlphy->current_io_type, rtlphy->set_io_inprogress);
4694 switch (rtlphy->current_io_type) {
4695 case IO_CMD_RESUME_DM_BY_SCAN:
4696 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4697 _rtl8821ae_resume_tx_beacon(hw);
4698 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4699 rtl8821ae_dm_write_cck_cca_thres(hw,
4700 rtlphy->initgain_backup.cca);
4702 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4703 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4704 _rtl8821ae_stop_tx_beacon(hw);
4705 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4706 rtl8821ae_dm_write_dig(hw, 0x17);
4707 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4708 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4710 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4713 pr_err("switch case %#x not processed\n",
4714 rtlphy->current_io_type);
4717 rtlphy->set_io_inprogress = false;
4718 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4719 "(%#x)\n", rtlphy->current_io_type);
4722 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4724 struct rtl_priv *rtlpriv = rtl_priv(hw);
4726 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4727 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4728 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4729 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4730 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4733 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4734 enum rf_pwrstate rfpwr_state)
4736 struct rtl_priv *rtlpriv = rtl_priv(hw);
4737 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4738 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4739 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4740 bool bresult = true;
4742 struct rtl8192_tx_ring *ring = NULL;
4744 switch (rfpwr_state) {
4746 if ((ppsc->rfpwr_state == ERFOFF) &&
4747 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4748 bool rtstatus = false;
4749 u32 initializecount = 0;
4753 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4754 "IPS Set eRf nic enable\n");
4755 rtstatus = rtl_ps_enable_nic(hw);
4756 } while (!rtstatus && (initializecount < 10));
4757 RT_CLEAR_PS_LEVEL(ppsc,
4758 RT_RF_OFF_LEVL_HALT_NIC);
4760 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4761 "Set ERFON sleeped:%d ms\n",
4762 jiffies_to_msecs(jiffies -
4764 last_sleep_jiffies));
4765 ppsc->last_awake_jiffies = jiffies;
4766 rtl8821ae_phy_set_rf_on(hw);
4768 if (mac->link_state == MAC80211_LINKED) {
4769 rtlpriv->cfg->ops->led_control(hw,
4772 rtlpriv->cfg->ops->led_control(hw,
4777 for (queue_id = 0, i = 0;
4778 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4779 ring = &pcipriv->dev.tx_ring[queue_id];
4780 if (queue_id == BEACON_QUEUE ||
4781 skb_queue_len(&ring->queue) == 0) {
4785 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4786 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4788 skb_queue_len(&ring->queue));
4793 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4794 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4795 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4796 MAX_DOZE_WAITING_TIMES_9x,
4798 skb_queue_len(&ring->queue));
4803 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4804 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4805 "IPS Set eRf nic disable\n");
4806 rtl_ps_disable_nic(hw);
4807 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4809 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4810 rtlpriv->cfg->ops->led_control(hw,
4813 rtlpriv->cfg->ops->led_control(hw,
4819 pr_err("switch case %#x not processed\n",
4825 ppsc->rfpwr_state = rfpwr_state;
4829 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4830 enum rf_pwrstate rfpwr_state)
4832 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4834 bool bresult = false;
4836 if (rfpwr_state == ppsc->rfpwr_state)
4838 bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);