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);
401 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
402 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
403 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
404 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
409 static void _rtl8812ae_phy_set_rfe_reg_5g(struct ieee80211_hw *hw)
411 struct rtl_priv *rtlpriv = rtl_priv(hw);
412 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
415 switch (rtlhal->rfe_type) {
417 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337717);
418 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337717);
419 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
420 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
423 if (rtlpriv->btcoexist.bt_coexistence) {
424 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x337717);
425 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
427 rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000);
428 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
430 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
432 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
434 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
435 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
439 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337717);
440 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337717);
441 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
442 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
443 rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1);
446 rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x33);
447 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
448 tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3);
449 rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp | 0x1);
450 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
455 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337777);
456 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
457 rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
458 rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
463 u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band,
466 struct rtl_priv *rtlpriv = rtl_priv(hw);
467 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
468 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
469 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
470 s8 reg_swing_2g = -1;/* 0xff; */
471 s8 reg_swing_5g = -1;/* 0xff; */
472 s8 swing_2g = -1 * reg_swing_2g;
473 s8 swing_5g = -1 * reg_swing_5g;
475 const s8 auto_temp = -1;
477 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
478 "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
479 (int)swing_2g, (int)swing_5g,
480 (int)rtlefuse->autoload_failflag);
482 if (rtlefuse->autoload_failflag) {
483 if (band == BAND_ON_2_4G) {
484 rtldm->swing_diff_2g = swing_2g;
486 out = 0x200; /* 0 dB */
487 } else if (swing_2g == -3) {
488 out = 0x16A; /* -3 dB */
489 } else if (swing_2g == -6) {
490 out = 0x101; /* -6 dB */
491 } else if (swing_2g == -9) {
492 out = 0x0B6; /* -9 dB */
494 rtldm->swing_diff_2g = 0;
497 } else if (band == BAND_ON_5G) {
498 rtldm->swing_diff_5g = swing_5g;
500 out = 0x200; /* 0 dB */
501 } else if (swing_5g == -3) {
502 out = 0x16A; /* -3 dB */
503 } else if (swing_5g == -6) {
504 out = 0x101; /* -6 dB */
505 } else if (swing_5g == -9) {
506 out = 0x0B6; /* -9 dB */
508 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
509 rtldm->swing_diff_5g = -3;
512 rtldm->swing_diff_5g = 0;
517 rtldm->swing_diff_2g = -3;
518 rtldm->swing_diff_5g = -3;
519 out = 0x16A; /* -3 dB */
522 u32 swing = 0, swing_a = 0, swing_b = 0;
524 if (band == BAND_ON_2_4G) {
525 if (reg_swing_2g == auto_temp) {
526 efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
527 swing = (swing == 0xFF) ? 0x00 : swing;
528 } else if (swing_2g == 0) {
529 swing = 0x00; /* 0 dB */
530 } else if (swing_2g == -3) {
531 swing = 0x05; /* -3 dB */
532 } else if (swing_2g == -6) {
533 swing = 0x0A; /* -6 dB */
534 } else if (swing_2g == -9) {
535 swing = 0xFF; /* -9 dB */
540 if (reg_swing_5g == auto_temp) {
541 efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
542 swing = (swing == 0xFF) ? 0x00 : swing;
543 } else if (swing_5g == 0) {
544 swing = 0x00; /* 0 dB */
545 } else if (swing_5g == -3) {
546 swing = 0x05; /* -3 dB */
547 } else if (swing_5g == -6) {
548 swing = 0x0A; /* -6 dB */
549 } else if (swing_5g == -9) {
550 swing = 0xFF; /* -9 dB */
556 swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
557 swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
558 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
559 "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
563 if (swing_a == 0x0) {
564 if (band == BAND_ON_2_4G)
565 rtldm->swing_diff_2g = 0;
567 rtldm->swing_diff_5g = 0;
568 out = 0x200; /* 0 dB */
569 } else if (swing_a == 0x1) {
570 if (band == BAND_ON_2_4G)
571 rtldm->swing_diff_2g = -3;
573 rtldm->swing_diff_5g = -3;
574 out = 0x16A; /* -3 dB */
575 } else if (swing_a == 0x2) {
576 if (band == BAND_ON_2_4G)
577 rtldm->swing_diff_2g = -6;
579 rtldm->swing_diff_5g = -6;
580 out = 0x101; /* -6 dB */
581 } else if (swing_a == 0x3) {
582 if (band == BAND_ON_2_4G)
583 rtldm->swing_diff_2g = -9;
585 rtldm->swing_diff_5g = -9;
586 out = 0x0B6; /* -9 dB */
589 if (swing_b == 0x0) {
590 if (band == BAND_ON_2_4G)
591 rtldm->swing_diff_2g = 0;
593 rtldm->swing_diff_5g = 0;
594 out = 0x200; /* 0 dB */
595 } else if (swing_b == 0x1) {
596 if (band == BAND_ON_2_4G)
597 rtldm->swing_diff_2g = -3;
599 rtldm->swing_diff_5g = -3;
600 out = 0x16A; /* -3 dB */
601 } else if (swing_b == 0x2) {
602 if (band == BAND_ON_2_4G)
603 rtldm->swing_diff_2g = -6;
605 rtldm->swing_diff_5g = -6;
606 out = 0x101; /* -6 dB */
607 } else if (swing_b == 0x3) {
608 if (band == BAND_ON_2_4G)
609 rtldm->swing_diff_2g = -9;
611 rtldm->swing_diff_5g = -9;
612 out = 0x0B6; /* -9 dB */
616 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
617 "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out);
621 void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
623 struct rtl_priv *rtlpriv = rtl_priv(hw);
624 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
625 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
626 u8 current_band = rtlhal->current_bandtype;
628 s8 bb_diff_between_band;
630 txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
631 rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
632 rtlhal->current_bandtype = (enum band_type) band;
633 /* reconfig BB/RF according to wireless mode */
634 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
636 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
638 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
639 /* 0xCB0[15:12] = 0x7 (LNA_On)*/
640 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
641 /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
642 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
645 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
647 rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
650 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
651 /* 0xC1C[11:8] = 0 */
652 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
654 /* 0x82C[1:0] = 2b'00 */
655 rtl_set_bbreg(hw, 0x82c, 0x3, 0);
658 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
659 _rtl8812ae_phy_set_rfe_reg_24g(hw);
661 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
662 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
664 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
665 } else {/* 5G band */
668 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
669 /*0xCB0[15:12] = 0x5 (LNA_On)*/
670 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
671 /*0xCB0[7:4] = 0x4 (PAPE_A)*/
672 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
675 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
678 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
679 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
680 "Reg41A value %d\n", reg_41a);
682 while ((reg_41a != 0x30) && (count < 50)) {
684 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
686 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
689 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
690 "Reg41A value %d\n", reg_41a);
693 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
694 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
697 /* 2012/02/01, Sinda add registry to switch workaround
698 without long-run verification for scan issue. */
699 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
701 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
703 rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
706 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
707 /* AGC table select */
709 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
711 /* 0x82C[1:0] = 2'b00 */
712 rtl_set_bbreg(hw, 0x82c, 0x3, 1);
714 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
715 _rtl8812ae_phy_set_rfe_reg_5g(hw);
717 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
718 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
720 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
721 "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
722 rtlpriv->dm.ofdm_index[RF90_PATH_A]);
725 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
726 (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
728 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
729 phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
731 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
732 phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
734 /* <20121005, Kordan> When TxPowerTrack is ON,
735 * we should take care of the change of BB swing.
736 * That is, reset all info to trigger Tx power tracking.
738 if (band != current_band) {
739 bb_diff_between_band =
740 (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
741 bb_diff_between_band = (band == BAND_ON_2_4G) ?
742 bb_diff_between_band :
743 (-1 * bb_diff_between_band);
744 rtldm->default_ofdm_index += bb_diff_between_band * 2;
746 rtl8821ae_dm_clear_txpower_tracking_state(hw);
749 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
750 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
754 static bool _rtl8821ae_check_positive(struct ieee80211_hw *hw,
755 const u32 condition1,
756 const u32 condition2)
758 struct rtl_priv *rtlpriv = rtl_priv(hw);
759 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
760 u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK)
761 >> CHIP_VER_RTL_SHIFT);
762 u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0));
764 u8 board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */
765 ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA */
766 ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */
767 ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA */
768 ((rtlhal->board_type & BIT(2)) >> 2) << 4; /* _BT */
770 u32 cond1 = condition1, cond2 = condition2;
771 u32 driver1 = cut_ver << 24 | /* CUT ver */
772 0 << 20 | /* interface 2/2 */
773 0x04 << 16 | /* platform */
774 rtlhal->package_type << 12 |
775 intf << 8 | /* interface 1/2 */
778 u32 driver2 = rtlhal->type_glna << 0 |
779 rtlhal->type_gpa << 8 |
780 rtlhal->type_alna << 16 |
781 rtlhal->type_apa << 24;
783 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
784 "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n",
786 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
787 "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n",
790 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
791 " (Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf);
792 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
793 " (Board, Package) = (0x%X, 0x%X)\n",
794 rtlhal->board_type, rtlhal->package_type);
796 /*============== Value Defined Check ===============*/
797 /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/
799 if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) !=
800 (driver1 & 0x0000F000)))
802 if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) !=
803 (driver1 & 0x0F000000)))
806 /*=============== Bit Defined Check ================*/
807 /* We don't care [31:28] */
810 driver1 &= 0x00FF0FFF;
812 if ((cond1 & driver1) == cond1) {
815 if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/
818 if ((cond1 & BIT(0)) != 0) /*GLNA*/
820 if ((cond1 & BIT(1)) != 0) /*GPA*/
822 if ((cond1 & BIT(2)) != 0) /*ALNA*/
824 if ((cond1 & BIT(3)) != 0) /*APA*/
827 /* BoardType of each RF path is matched*/
828 if ((cond2 & mask) == (driver2 & mask))
836 static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
839 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
840 u32 _board = rtlefuse->board_type; /*need efuse define*/
841 u32 _interface = 0x01; /* ODM_ITRF_PCIE */
842 u32 _platform = 0x08;/* ODM_WIN */
843 u32 cond = condition;
845 if (condition == 0xCDCDCDCD)
848 cond = condition & 0xFF;
849 if ((_board != cond) && cond != 0xFF)
852 cond = condition & 0xFF00;
854 if ((_interface & cond) == 0 && cond != 0x07)
857 cond = condition & 0xFF0000;
859 if ((_platform & cond) == 0 && cond != 0x0F)
864 static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
866 enum radio_path rfpath, u32 regaddr)
868 if (addr == 0xfe || addr == 0xffe) {
869 /* In order not to disturb BT music when
870 * wifi init.(1ant NIC only)
874 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
879 static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
882 u32 content = 0x1000; /*RF Content: radio_a_txt*/
883 u32 maskforphyset = (u32)(content & 0xE000);
885 _rtl8821ae_config_rf_reg(hw, addr, data,
886 RF90_PATH_A, addr | maskforphyset);
889 static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
892 u32 content = 0x1001; /*RF Content: radio_b_txt*/
893 u32 maskforphyset = (u32)(content & 0xE000);
895 _rtl8821ae_config_rf_reg(hw, addr, data,
896 RF90_PATH_B, addr | maskforphyset);
899 static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
904 else if (addr == 0xfd)
906 else if (addr == 0xfc)
908 else if (addr == 0xfb)
910 else if (addr == 0xfa)
912 else if (addr == 0xf9)
915 rtl_set_bbreg(hw, addr, MASKDWORD, data);
920 static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
922 struct rtl_priv *rtlpriv = rtl_priv(hw);
923 struct rtl_phy *rtlphy = &rtlpriv->phy;
924 u8 band, rfpath, txnum, rate_section;
926 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
927 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
928 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
929 for (rate_section = 0;
930 rate_section < TX_PWR_BY_RATE_NUM_SECTION;
932 rtlphy->tx_power_by_rate_offset[band]
933 [rfpath][txnum][rate_section] = 0;
936 static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
941 struct rtl_priv *rtlpriv = rtl_priv(hw);
942 struct rtl_phy *rtlphy = &rtlpriv->phy;
944 if (path > RF90_PATH_D) {
945 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
946 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
950 if (band == BAND_ON_2_4G) {
951 switch (rate_section) {
953 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
956 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
959 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
962 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
964 case VHT_1SSMCS0_1SSMCS9:
965 rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
967 case VHT_2SSMCS0_2SSMCS9:
968 rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
971 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
972 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
973 rate_section, path, txnum);
976 } else if (band == BAND_ON_5G) {
977 switch (rate_section) {
979 rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
982 rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
985 rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
987 case VHT_1SSMCS0_1SSMCS9:
988 rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
990 case VHT_2SSMCS0_2SSMCS9:
991 rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
994 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
995 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
996 rate_section, path, txnum);
1000 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1001 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
1005 static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
1007 u8 txnum, u8 rate_section)
1009 struct rtl_priv *rtlpriv = rtl_priv(hw);
1010 struct rtl_phy *rtlphy = &rtlpriv->phy;
1013 if (path > RF90_PATH_D) {
1014 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1015 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
1020 if (band == BAND_ON_2_4G) {
1021 switch (rate_section) {
1023 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
1026 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
1029 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
1032 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
1034 case VHT_1SSMCS0_1SSMCS9:
1035 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
1037 case VHT_2SSMCS0_2SSMCS9:
1038 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
1041 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1042 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
1043 rate_section, path, txnum);
1046 } else if (band == BAND_ON_5G) {
1047 switch (rate_section) {
1049 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
1052 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
1055 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
1057 case VHT_1SSMCS0_1SSMCS9:
1058 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
1060 case VHT_2SSMCS0_2SSMCS9:
1061 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
1064 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1065 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
1066 rate_section, path, txnum);
1070 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1071 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
1077 static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
1079 struct rtl_priv *rtlpriv = rtl_priv(hw);
1080 struct rtl_phy *rtlphy = &rtlpriv->phy;
1082 u8 base = 0, path = 0;
1084 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
1085 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
1086 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1087 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
1089 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
1090 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1091 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
1093 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
1094 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1095 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
1097 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
1098 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1099 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
1101 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
1102 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1103 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1105 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
1106 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1107 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1109 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
1110 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1111 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
1113 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
1114 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1115 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
1117 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
1118 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1119 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
1121 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
1122 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1123 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1125 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
1126 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
1127 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1131 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
1132 u8 end, u8 base_val)
1138 for (i = 3; i >= 0; --i) {
1139 if (i >= start && i <= end) {
1140 /* Get the exact value */
1141 temp_value = (u8)(*data >> (i * 8)) & 0xF;
1142 temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
1144 /* Change the value to a relative value */
1145 temp_value = (temp_value > base_val) ? temp_value -
1146 base_val : base_val - temp_value;
1148 temp_value = (u8)(*data >> (i * 8)) & 0xFF;
1151 temp_data |= temp_value;
1156 static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
1158 struct rtl_priv *rtlpriv = rtl_priv(hw);
1159 struct rtl_phy *rtlphy = &rtlpriv->phy;
1160 u8 regulation, bw, channel, rate_section;
1163 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1164 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
1165 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1166 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1167 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1168 [bw][rate_section][channel][RF90_PATH_A];
1169 if (temp_pwrlmt == MAX_POWER_INDEX) {
1170 if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
1171 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1172 "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1173 1, bw, rate_section, channel, RF90_PATH_A);
1174 if (rate_section == 2) {
1175 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1176 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1177 } else if (rate_section == 4) {
1178 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1179 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1180 } else if (rate_section == 3) {
1181 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1182 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1183 } else if (rate_section == 5) {
1184 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1185 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1188 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d\n", temp_pwrlmt);
1197 static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1198 enum band_type band, u8 rate)
1200 struct rtl_priv *rtlpriv = rtl_priv(hw);
1202 if (band == BAND_ON_2_4G) {
1245 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1246 "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1250 } else if (band == BAND_ON_5G) {
1285 case MGN_VHT1SS_MCS0:
1286 case MGN_VHT1SS_MCS1:
1287 case MGN_VHT1SS_MCS2:
1288 case MGN_VHT1SS_MCS3:
1289 case MGN_VHT1SS_MCS4:
1290 case MGN_VHT1SS_MCS5:
1291 case MGN_VHT1SS_MCS6:
1292 case MGN_VHT1SS_MCS7:
1293 case MGN_VHT1SS_MCS8:
1294 case MGN_VHT1SS_MCS9:
1298 case MGN_VHT2SS_MCS0:
1299 case MGN_VHT2SS_MCS1:
1300 case MGN_VHT2SS_MCS2:
1301 case MGN_VHT2SS_MCS3:
1302 case MGN_VHT2SS_MCS4:
1303 case MGN_VHT2SS_MCS5:
1304 case MGN_VHT2SS_MCS6:
1305 case MGN_VHT2SS_MCS7:
1306 case MGN_VHT2SS_MCS8:
1307 case MGN_VHT2SS_MCS9:
1312 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1313 "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1322 static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1324 struct rtl_priv *rtlpriv = rtl_priv(hw);
1325 struct rtl_phy *rtlphy = &rtlpriv->phy;
1326 u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1327 u8 regulation, bw, channel, rate_section;
1328 u8 base_index2_4G = 0;
1329 u8 base_index5G = 0;
1330 s8 temp_value = 0, temp_pwrlmt = 0;
1333 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1334 "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1336 _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1338 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1339 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
1340 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1341 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1342 /* obtain the base dBm values in 2.4G band
1343 CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1344 if (rate_section == 0) { /*CCK*/
1346 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1347 BAND_ON_2_4G, MGN_11M);
1348 } else if (rate_section == 1) { /*OFDM*/
1350 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1351 BAND_ON_2_4G, MGN_54M);
1352 } else if (rate_section == 2) { /*HT IT*/
1354 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1355 BAND_ON_2_4G, MGN_MCS7);
1356 } else if (rate_section == 3) { /*HT 2T*/
1358 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1359 BAND_ON_2_4G, MGN_MCS15);
1362 temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1363 [bw][rate_section][channel][RF90_PATH_A];
1365 for (rf_path = RF90_PATH_A;
1366 rf_path < MAX_RF_PATH_NUM;
1368 if (rate_section == 3)
1369 bw40_pwr_base_dbm2_4G =
1370 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1372 bw40_pwr_base_dbm2_4G =
1373 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1375 if (temp_pwrlmt != MAX_POWER_INDEX) {
1376 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1377 rtlphy->txpwr_limit_2_4g[regulation]
1378 [bw][rate_section][channel][rf_path] =
1382 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1383 "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",
1384 regulation, bw, rate_section, channel,
1385 rtlphy->txpwr_limit_2_4g[regulation][bw]
1386 [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1387 ? 0 : temp_pwrlmt/2, channel, rf_path,
1388 bw40_pwr_base_dbm2_4G);
1394 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1395 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
1396 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1397 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1398 /* obtain the base dBm values in 5G band
1399 OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1400 VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1401 if (rate_section == 1) { /*OFDM*/
1403 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1404 BAND_ON_5G, MGN_54M);
1405 } else if (rate_section == 2) { /*HT 1T*/
1407 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1408 BAND_ON_5G, MGN_MCS7);
1409 } else if (rate_section == 3) { /*HT 2T*/
1411 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1412 BAND_ON_5G, MGN_MCS15);
1413 } else if (rate_section == 4) { /*VHT 1T*/
1415 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1416 BAND_ON_5G, MGN_VHT1SS_MCS7);
1417 } else if (rate_section == 5) { /*VHT 2T*/
1419 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1420 BAND_ON_5G, MGN_VHT2SS_MCS7);
1423 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1424 [bw][rate_section][channel]
1427 for (rf_path = RF90_PATH_A;
1428 rf_path < MAX_RF_PATH_NUM;
1430 if (rate_section == 3 || rate_section == 5)
1431 bw40_pwr_base_dbm5G =
1432 rtlphy->txpwr_by_rate_base_5g[rf_path]
1433 [RF_2TX][base_index5G];
1435 bw40_pwr_base_dbm5G =
1436 rtlphy->txpwr_by_rate_base_5g[rf_path]
1437 [RF_1TX][base_index5G];
1439 if (temp_pwrlmt != MAX_POWER_INDEX) {
1441 temp_pwrlmt - bw40_pwr_base_dbm5G;
1442 rtlphy->txpwr_limit_5g[regulation]
1443 [bw][rate_section][channel]
1444 [rf_path] = temp_value;
1447 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1448 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
1449 regulation, bw, rate_section,
1450 channel, rtlphy->txpwr_limit_5g[regulation]
1451 [bw][rate_section][channel][rf_path],
1452 temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1458 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1459 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1462 static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1464 struct rtl_priv *rtlpriv = rtl_priv(hw);
1465 struct rtl_phy *rtlphy = &rtlpriv->phy;
1468 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1469 "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1471 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1472 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
1473 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1474 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1475 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1476 rtlphy->txpwr_limit_2_4g
1480 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1481 for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
1482 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1483 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1484 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1485 rtlphy->txpwr_limit_5g
1490 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1491 "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1494 static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1496 struct rtl_priv *rtlpriv = rtl_priv(hw);
1497 struct rtl_phy *rtlphy = &rtlpriv->phy;
1498 u8 base = 0, rfPath = 0;
1500 for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
1501 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1502 _phy_convert_txpower_dbm_to_relative_value(
1503 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0],
1506 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1507 _phy_convert_txpower_dbm_to_relative_value(
1508 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1],
1510 _phy_convert_txpower_dbm_to_relative_value(
1511 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2],
1514 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1515 _phy_convert_txpower_dbm_to_relative_value(
1516 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3],
1518 _phy_convert_txpower_dbm_to_relative_value(
1519 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4],
1522 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1524 _phy_convert_txpower_dbm_to_relative_value(
1525 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5],
1528 _phy_convert_txpower_dbm_to_relative_value(
1529 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6],
1532 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1533 _phy_convert_txpower_dbm_to_relative_value(
1534 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7],
1536 _phy_convert_txpower_dbm_to_relative_value(
1537 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8],
1539 _phy_convert_txpower_dbm_to_relative_value(
1540 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1543 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1544 _phy_convert_txpower_dbm_to_relative_value(
1545 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1547 _phy_convert_txpower_dbm_to_relative_value(
1548 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10],
1550 _phy_convert_txpower_dbm_to_relative_value(
1551 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11],
1554 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM);
1555 _phy_convert_txpower_dbm_to_relative_value(
1556 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1],
1558 _phy_convert_txpower_dbm_to_relative_value(
1559 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2],
1562 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7);
1563 _phy_convert_txpower_dbm_to_relative_value(
1564 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3],
1566 _phy_convert_txpower_dbm_to_relative_value(
1567 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4],
1570 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15);
1571 _phy_convert_txpower_dbm_to_relative_value(
1572 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5],
1574 _phy_convert_txpower_dbm_to_relative_value(
1575 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6],
1578 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1579 _phy_convert_txpower_dbm_to_relative_value(
1580 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7],
1582 _phy_convert_txpower_dbm_to_relative_value(
1583 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8],
1585 _phy_convert_txpower_dbm_to_relative_value(
1586 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1589 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1590 _phy_convert_txpower_dbm_to_relative_value(
1591 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1593 _phy_convert_txpower_dbm_to_relative_value(
1594 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10],
1596 _phy_convert_txpower_dbm_to_relative_value(
1597 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11],
1601 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1602 "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1605 static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1607 _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1608 _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1611 /* string is in decimal */
1612 static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
1617 while (str[i] != '\0') {
1618 if (str[i] >= '0' && str[i] <= '9') {
1620 *pint += (str[i] - '0');
1630 static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
1636 if (str1[num] != str2[num])
1642 static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1643 u8 band, u8 channel)
1645 struct rtl_priv *rtlpriv = rtl_priv(hw);
1646 s8 channel_index = -1;
1649 if (band == BAND_ON_2_4G)
1650 channel_index = channel - 1;
1651 else if (band == BAND_ON_5G) {
1652 for (i = 0; i < sizeof(channel5g)/sizeof(u8); ++i) {
1653 if (channel5g[i] == channel)
1657 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s\n",
1660 if (channel_index == -1)
1661 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1662 "Invalid Channel %d of Band %d in %s\n", channel,
1665 return channel_index;
1668 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1669 u8 *pband, u8 *pbandwidth,
1670 u8 *prate_section, u8 *prf_path,
1671 u8 *pchannel, u8 *ppower_limit)
1673 struct rtl_priv *rtlpriv = rtl_priv(hw);
1674 struct rtl_phy *rtlphy = &rtlpriv->phy;
1675 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1677 s8 power_limit = 0, prev_power_limit, ret;
1679 if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1680 !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1682 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1683 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1684 channel, power_limit);
1687 power_limit = power_limit > MAX_POWER_INDEX ?
1688 MAX_POWER_INDEX : power_limit;
1690 if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1692 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1694 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1696 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1699 if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1701 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1703 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1704 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1706 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1707 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1709 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1710 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1712 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1713 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1716 if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1718 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1720 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1722 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1725 if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1726 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1733 channel_index = ret;
1735 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1736 [bandwidth][rate_section]
1737 [channel_index][RF90_PATH_A];
1739 if (power_limit < prev_power_limit)
1740 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1741 [rate_section][channel_index][RF90_PATH_A] =
1744 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1745 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1746 regulation, bandwidth, rate_section, channel_index,
1747 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1748 [rate_section][channel_index][RF90_PATH_A]);
1749 } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1750 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1757 channel_index = ret;
1759 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1760 [rate_section][channel_index]
1763 if (power_limit < prev_power_limit)
1764 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1765 [rate_section][channel_index][RF90_PATH_A] = power_limit;
1767 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1768 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1769 regulation, bandwidth, rate_section, channel,
1770 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1771 [rate_section][channel_index][RF90_PATH_A]);
1773 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1774 "Cannot recognize the band info in %s\n", pband);
1779 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1780 u8 *regulation, u8 *band,
1781 u8 *bandwidth, u8 *rate_section,
1782 u8 *rf_path, u8 *channel,
1785 _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1786 rate_section, rf_path, channel,
1790 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1792 struct rtl_priv *rtlpriv = rtl_priv(hw);
1793 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1798 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1799 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1800 array = RTL8812AE_TXPWR_LMT;
1802 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1803 array = RTL8821AE_TXPWR_LMT;
1806 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1809 for (i = 0; i < array_len; i += 7) {
1810 u8 *regulation = array[i];
1811 u8 *band = array[i+1];
1812 u8 *bandwidth = array[i+2];
1813 u8 *rate = array[i+3];
1814 u8 *rf_path = array[i+4];
1815 u8 *chnl = array[i+5];
1816 u8 *val = array[i+6];
1818 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1819 bandwidth, rate, rf_path,
1824 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1826 struct rtl_priv *rtlpriv = rtl_priv(hw);
1827 struct rtl_phy *rtlphy = &rtlpriv->phy;
1828 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1831 _rtl8821ae_phy_init_txpower_limit(hw);
1833 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1834 if (rtlefuse->eeprom_regulatory != 2)
1835 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1837 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1838 BASEBAND_CONFIG_PHY_REG);
1839 if (rtstatus != true) {
1840 pr_err("Write BB Reg Fail!!\n");
1843 _rtl8821ae_phy_init_tx_power_by_rate(hw);
1844 if (rtlefuse->autoload_failflag == false) {
1845 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1846 BASEBAND_CONFIG_PHY_REG);
1848 if (rtstatus != true) {
1849 pr_err("BB_PG Reg Fail!!\n");
1853 _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1855 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1856 if (rtlefuse->eeprom_regulatory != 2)
1857 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1859 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1860 BASEBAND_CONFIG_AGC_TAB);
1862 if (rtstatus != true) {
1863 pr_err("AGC Table Fail\n");
1866 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1867 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1872 __rtl8821ae_phy_config_with_headerfile(struct ieee80211_hw *hw,
1873 u32 *array_table, u16 arraylen,
1874 void (*set_reg)(struct ieee80211_hw *hw,
1875 u32 regaddr, u32 data))
1878 #define COND_ENDIF 3
1882 bool matched = true, skipped = false;
1884 while ((i + 1) < arraylen) {
1885 u32 v1 = array_table[i];
1886 u32 v2 = array_table[i + 1];
1888 if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/
1889 if (v1 & BIT(31)) {/* positive condition*/
1890 cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
1891 if (cond == COND_ENDIF) {/*end*/
1894 } else if (cond == COND_ELSE) /*else*/
1895 matched = skipped ? false : true;
1896 else {/*if , else if*/
1900 if (_rtl8821ae_check_positive(
1910 } else if (v1 & BIT(30)) { /*negative condition*/
1915 set_reg(hw, v1, v2);
1923 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1925 struct rtl_priv *rtlpriv = rtl_priv(hw);
1926 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1930 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1931 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1932 arraylength = RTL8821AE_MAC_1T_ARRAYLEN;
1933 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1935 arraylength = RTL8812AE_MAC_1T_ARRAYLEN;
1936 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1938 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1939 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1941 return __rtl8821ae_phy_config_with_headerfile(hw,
1942 ptrarray, arraylength, rtl_write_byte_with_val32);
1945 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1948 struct rtl_priv *rtlpriv = rtl_priv(hw);
1949 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1953 if (configtype == BASEBAND_CONFIG_PHY_REG) {
1954 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1955 arraylen = RTL8812AE_PHY_REG_1TARRAYLEN;
1956 array_table = RTL8812AE_PHY_REG_ARRAY;
1958 arraylen = RTL8821AE_PHY_REG_1TARRAYLEN;
1959 array_table = RTL8821AE_PHY_REG_ARRAY;
1962 return __rtl8821ae_phy_config_with_headerfile(hw,
1963 array_table, arraylen,
1964 _rtl8821ae_config_bb_reg);
1965 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1966 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1967 arraylen = RTL8812AE_AGC_TAB_1TARRAYLEN;
1968 array_table = RTL8812AE_AGC_TAB_ARRAY;
1970 arraylen = RTL8821AE_AGC_TAB_1TARRAYLEN;
1971 array_table = RTL8821AE_AGC_TAB_ARRAY;
1974 return __rtl8821ae_phy_config_with_headerfile(hw,
1975 array_table, arraylen,
1976 rtl_set_bbreg_with_dwmask);
1981 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1985 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1986 index = (u8)((regaddr - 0xC20) / 4);
1987 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1988 index = (u8)((regaddr - 0xE20) / 4);
1991 "rtl8821ae: Invalid RegAddr 0x%x\n", regaddr);
1995 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1996 u32 band, u32 rfpath,
1997 u32 txnum, u32 regaddr,
1998 u32 bitmask, u32 data)
2000 struct rtl_priv *rtlpriv = rtl_priv(hw);
2001 struct rtl_phy *rtlphy = &rtlpriv->phy;
2002 u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
2004 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
2005 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
2006 band = BAND_ON_2_4G;
2008 if (rfpath >= MAX_RF_PATH) {
2009 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
2010 rfpath = MAX_RF_PATH - 1;
2012 if (txnum >= MAX_RF_PATH) {
2013 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
2014 txnum = MAX_RF_PATH - 1;
2016 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
2017 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2018 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
2019 band, rfpath, txnum, rate_section,
2020 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
2023 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
2026 struct rtl_priv *rtlpriv = rtl_priv(hw);
2027 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2031 u32 v1, v2, v3, v4, v5, v6;
2033 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
2034 arraylen = RTL8812AE_PHY_REG_ARRAY_PGLEN;
2035 array = RTL8812AE_PHY_REG_ARRAY_PG;
2037 arraylen = RTL8821AE_PHY_REG_ARRAY_PGLEN;
2038 array = RTL8821AE_PHY_REG_ARRAY_PG;
2041 if (configtype != BASEBAND_CONFIG_PHY_REG) {
2042 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
2043 "configtype != BaseBand_Config_PHY_REG\n");
2046 for (i = 0; i < arraylen; i += 6) {
2054 if (v1 < 0xCDCDCDCD) {
2055 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
2056 (v4 == 0xfe || v4 == 0xffe)) {
2061 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
2064 else if (v4 == 0xfd)
2066 else if (v4 == 0xfc)
2068 else if (v4 == 0xfb)
2070 else if (v4 == 0xfa)
2072 else if (v4 == 0xf9)
2075 _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
2079 /*don't need the hw_body*/
2080 if (!_rtl8821ae_check_condition(hw, v1)) {
2081 i += 2; /* skip the pair of expression*/
2085 while (v2 != 0xDEAD) {
2098 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2099 enum radio_path rfpath)
2101 bool rtstatus = true;
2102 u32 *radioa_array_table_a, *radioa_array_table_b;
2103 u16 radioa_arraylen_a, radioa_arraylen_b;
2104 struct rtl_priv *rtlpriv = rtl_priv(hw);
2106 radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
2107 radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
2108 radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
2109 radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2110 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2111 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2112 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2116 return __rtl8821ae_phy_config_with_headerfile(hw,
2117 radioa_array_table_a, radioa_arraylen_a,
2118 _rtl8821ae_config_rf_radio_a);
2121 return __rtl8821ae_phy_config_with_headerfile(hw,
2122 radioa_array_table_b, radioa_arraylen_b,
2123 _rtl8821ae_config_rf_radio_b);
2127 pr_err("switch case %#x not processed\n", rfpath);
2133 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2134 enum radio_path rfpath)
2136 bool rtstatus = true;
2137 u32 *radioa_array_table;
2138 u16 radioa_arraylen;
2139 struct rtl_priv *rtlpriv = rtl_priv(hw);
2141 radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2142 radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2143 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2144 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2145 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2149 return __rtl8821ae_phy_config_with_headerfile(hw,
2150 radioa_array_table, radioa_arraylen,
2151 _rtl8821ae_config_rf_radio_a);
2157 pr_err("switch case %#x not processed\n", rfpath);
2163 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2165 struct rtl_priv *rtlpriv = rtl_priv(hw);
2166 struct rtl_phy *rtlphy = &rtlpriv->phy;
2168 rtlphy->default_initialgain[0] =
2169 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2170 rtlphy->default_initialgain[1] =
2171 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2172 rtlphy->default_initialgain[2] =
2173 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2174 rtlphy->default_initialgain[3] =
2175 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2177 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2178 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2179 rtlphy->default_initialgain[0],
2180 rtlphy->default_initialgain[1],
2181 rtlphy->default_initialgain[2],
2182 rtlphy->default_initialgain[3]);
2184 rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2185 ROFDM0_RXDETECTOR3, MASKBYTE0);
2186 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2187 ROFDM0_RXDETECTOR2, MASKDWORD);
2189 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2190 "Default framesync (0x%x) = 0x%x\n",
2191 ROFDM0_RXDETECTOR3, rtlphy->framesync);
2194 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2196 struct rtl_priv *rtlpriv = rtl_priv(hw);
2197 struct rtl_phy *rtlphy = &rtlpriv->phy;
2199 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2200 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2202 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2203 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2205 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2206 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2208 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2209 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2211 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2212 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2214 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2215 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2217 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2218 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2221 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2223 struct rtl_priv *rtlpriv = rtl_priv(hw);
2224 struct rtl_phy *rtlphy = &rtlpriv->phy;
2228 txpwr_level = rtlphy->cur_cck_txpwridx;
2229 txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2230 WIRELESS_MODE_B, txpwr_level);
2231 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2232 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2234 txpwr_level) > txpwr_dbm)
2236 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2238 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2239 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2240 WIRELESS_MODE_N_24G,
2241 txpwr_level) > txpwr_dbm)
2243 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2245 *powerlevel = txpwr_dbm;
2248 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2253 if (channel <= 14) {
2255 *chnl_index = channel - 1;
2259 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2260 if (channel5g[i] == channel) {
2269 static s8 _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2271 s8 rate_section = 0;
2305 case DESC_RATEMCS10:
2306 case DESC_RATEMCS11:
2309 case DESC_RATEMCS12:
2310 case DESC_RATEMCS13:
2311 case DESC_RATEMCS14:
2312 case DESC_RATEMCS15:
2315 case DESC_RATEVHT1SS_MCS0:
2316 case DESC_RATEVHT1SS_MCS1:
2317 case DESC_RATEVHT1SS_MCS2:
2318 case DESC_RATEVHT1SS_MCS3:
2321 case DESC_RATEVHT1SS_MCS4:
2322 case DESC_RATEVHT1SS_MCS5:
2323 case DESC_RATEVHT1SS_MCS6:
2324 case DESC_RATEVHT1SS_MCS7:
2327 case DESC_RATEVHT1SS_MCS8:
2328 case DESC_RATEVHT1SS_MCS9:
2329 case DESC_RATEVHT2SS_MCS0:
2330 case DESC_RATEVHT2SS_MCS1:
2333 case DESC_RATEVHT2SS_MCS2:
2334 case DESC_RATEVHT2SS_MCS3:
2335 case DESC_RATEVHT2SS_MCS4:
2336 case DESC_RATEVHT2SS_MCS5:
2339 case DESC_RATEVHT2SS_MCS6:
2340 case DESC_RATEVHT2SS_MCS7:
2341 case DESC_RATEVHT2SS_MCS8:
2342 case DESC_RATEVHT2SS_MCS9:
2346 WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2350 return rate_section;
2353 static s8 _rtl8812ae_phy_get_world_wide_limit(s8 *limit_table)
2355 s8 min = limit_table[0];
2358 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2359 if (limit_table[i] < min)
2360 min = limit_table[i];
2365 static s8 _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2367 enum ht_channel_width bandwidth,
2368 enum radio_path rf_path,
2369 u8 rate, u8 channel)
2371 struct rtl_priv *rtlpriv = rtl_priv(hw);
2372 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2373 struct rtl_phy *rtlphy = &rtlpriv->phy;
2374 short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2375 rate_section = -1, channel_temp = -1;
2376 u16 bd, regu, bdwidth, sec, chnl;
2377 s8 power_limit = MAX_POWER_INDEX;
2379 if (rtlefuse->eeprom_regulatory == 2)
2380 return MAX_POWER_INDEX;
2382 regulation = TXPWR_LMT_WW;
2384 if (band == BAND_ON_2_4G)
2386 else if (band == BAND_ON_5G)
2389 if (bandwidth == HT_CHANNEL_WIDTH_20)
2391 else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2393 else if (bandwidth == HT_CHANNEL_WIDTH_80)
2425 case DESC_RATEMCS10:
2426 case DESC_RATEMCS11:
2427 case DESC_RATEMCS12:
2428 case DESC_RATEMCS13:
2429 case DESC_RATEMCS14:
2430 case DESC_RATEMCS15:
2433 case DESC_RATEVHT1SS_MCS0:
2434 case DESC_RATEVHT1SS_MCS1:
2435 case DESC_RATEVHT1SS_MCS2:
2436 case DESC_RATEVHT1SS_MCS3:
2437 case DESC_RATEVHT1SS_MCS4:
2438 case DESC_RATEVHT1SS_MCS5:
2439 case DESC_RATEVHT1SS_MCS6:
2440 case DESC_RATEVHT1SS_MCS7:
2441 case DESC_RATEVHT1SS_MCS8:
2442 case DESC_RATEVHT1SS_MCS9:
2445 case DESC_RATEVHT2SS_MCS0:
2446 case DESC_RATEVHT2SS_MCS1:
2447 case DESC_RATEVHT2SS_MCS2:
2448 case DESC_RATEVHT2SS_MCS3:
2449 case DESC_RATEVHT2SS_MCS4:
2450 case DESC_RATEVHT2SS_MCS5:
2451 case DESC_RATEVHT2SS_MCS6:
2452 case DESC_RATEVHT2SS_MCS7:
2453 case DESC_RATEVHT2SS_MCS8:
2454 case DESC_RATEVHT2SS_MCS9:
2458 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2459 "Wrong rate 0x%x\n", rate);
2463 if (band_temp == BAND_ON_5G && rate_section == 0)
2464 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2465 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2467 /*workaround for wrong index combination to obtain tx power limit,
2468 OFDM only exists in BW 20M*/
2469 if (rate_section == 1)
2472 /*workaround for wrong index combination to obtain tx power limit,
2473 *HT on 80M will reference to HT on 40M
2475 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2476 bandwidth_temp == 2)
2479 if (band == BAND_ON_2_4G)
2480 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2481 BAND_ON_2_4G, channel);
2482 else if (band == BAND_ON_5G)
2483 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2484 BAND_ON_5G, channel);
2485 else if (band == BAND_ON_BOTH)
2486 ;/* BAND_ON_BOTH don't care temporarily */
2488 if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2489 rate_section == -1 || channel_temp == -1) {
2490 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2491 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2492 band_temp, regulation, bandwidth_temp, rf_path,
2493 rate_section, channel_temp);
2494 return MAX_POWER_INDEX;
2499 bdwidth = bandwidth_temp;
2501 chnl = channel_temp;
2503 if (band == BAND_ON_2_4G) {
2504 s8 limits[10] = {0};
2507 for (i = 0; i < 4; ++i)
2508 limits[i] = rtlphy->txpwr_limit_2_4g[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_2_4g[regu][bdwidth]
2514 [sec][chnl][rf_path];
2515 } else if (band == BAND_ON_5G) {
2516 s8 limits[10] = {0};
2519 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2520 limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2521 [sec][chnl][rf_path];
2523 power_limit = (regulation == TXPWR_LMT_WW) ?
2524 _rtl8812ae_phy_get_world_wide_limit(limits) :
2525 rtlphy->txpwr_limit_5g[regu][chnl]
2526 [sec][chnl][rf_path];
2528 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2529 "No power limit table of the specified band\n");
2534 static s8 _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2535 u8 band, u8 path, u8 rate)
2537 struct rtl_priv *rtlpriv = rtl_priv(hw);
2538 struct rtl_phy *rtlphy = &rtlpriv->phy;
2539 u8 shift = 0, rate_section, tx_num;
2543 rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2544 tx_num = RF_TX_NUM_NONIMPLEMENT;
2546 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2547 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2548 (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2561 case DESC_RATEMCS12:
2562 case DESC_RATEVHT1SS_MCS0:
2563 case DESC_RATEVHT1SS_MCS4:
2564 case DESC_RATEVHT1SS_MCS8:
2565 case DESC_RATEVHT2SS_MCS2:
2566 case DESC_RATEVHT2SS_MCS6:
2575 case DESC_RATEMCS13:
2576 case DESC_RATEVHT1SS_MCS1:
2577 case DESC_RATEVHT1SS_MCS5:
2578 case DESC_RATEVHT1SS_MCS9:
2579 case DESC_RATEVHT2SS_MCS3:
2580 case DESC_RATEVHT2SS_MCS7:
2588 case DESC_RATEMCS10:
2589 case DESC_RATEMCS14:
2590 case DESC_RATEVHT1SS_MCS2:
2591 case DESC_RATEVHT1SS_MCS6:
2592 case DESC_RATEVHT2SS_MCS0:
2593 case DESC_RATEVHT2SS_MCS4:
2594 case DESC_RATEVHT2SS_MCS8:
2602 case DESC_RATEMCS11:
2603 case DESC_RATEMCS15:
2604 case DESC_RATEVHT1SS_MCS3:
2605 case DESC_RATEVHT1SS_MCS7:
2606 case DESC_RATEVHT2SS_MCS1:
2607 case DESC_RATEVHT2SS_MCS5:
2608 case DESC_RATEVHT2SS_MCS9:
2612 WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2616 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2617 [tx_num][rate_section] >> shift) & 0xff;
2619 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2620 if (rtlpriv->efuse.eeprom_regulatory != 2) {
2621 limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2622 rtlphy->current_chan_bw, path, rate,
2623 rtlphy->current_channel);
2625 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2626 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2628 if (tx_pwr_diff < (-limit))
2629 tx_pwr_diff = -limit;
2633 tx_pwr_diff = limit;
2635 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2637 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2638 "Maximum power by rate %d, final power by rate %d\n",
2639 limit, tx_pwr_diff);
2645 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2646 u8 rate, u8 bandwidth, u8 channel)
2648 struct rtl_priv *rtlpriv = rtl_priv(hw);
2649 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2650 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2651 u8 index = (channel - 1);
2653 bool in_24g = false;
2654 s8 powerdiff_byrate = 0;
2656 if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2657 (channel > 14 || channel < 1)) ||
2658 ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2660 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2661 "Illegal channel!!\n");
2664 in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2666 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2667 txpower = rtlefuse->txpwrlevel_cck[path][index];
2668 else if (DESC_RATE6M <= rate)
2669 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2671 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2673 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2674 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2675 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2677 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2678 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2679 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2680 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2681 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2682 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2683 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2684 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2685 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2686 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2687 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2688 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2689 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2690 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2691 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2692 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2693 (DESC_RATEVHT1SS_MCS0 <= rate &&
2694 rate <= DESC_RATEVHT2SS_MCS9))
2695 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2696 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2697 (DESC_RATEVHT2SS_MCS0 <= rate &&
2698 rate <= DESC_RATEVHT2SS_MCS9))
2699 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2702 if (DESC_RATE6M <= rate)
2703 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2705 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2708 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2709 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2710 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2712 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2713 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2714 (DESC_RATEVHT1SS_MCS0 <= rate &&
2715 rate <= DESC_RATEVHT2SS_MCS9))
2716 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2717 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2718 (DESC_RATEVHT2SS_MCS0 <= rate &&
2719 rate <= DESC_RATEVHT2SS_MCS9))
2720 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2721 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2722 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2723 (DESC_RATEVHT1SS_MCS0 <= rate &&
2724 rate <= DESC_RATEVHT2SS_MCS9))
2725 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2726 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2727 (DESC_RATEVHT2SS_MCS0 <= rate &&
2728 rate <= DESC_RATEVHT2SS_MCS9))
2729 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2730 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2733 for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i)
2734 if (channel5g_80m[i] == channel)
2737 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2738 (DESC_RATEVHT1SS_MCS0 <= rate &&
2739 rate <= DESC_RATEVHT2SS_MCS9))
2740 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2741 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2742 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2743 (DESC_RATEVHT2SS_MCS0 <= rate &&
2744 rate <= DESC_RATEVHT2SS_MCS9))
2745 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2746 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2747 + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2750 if (rtlefuse->eeprom_regulatory != 2)
2752 _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2755 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2756 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2757 txpower -= powerdiff_byrate;
2759 txpower += powerdiff_byrate;
2761 if (rate > DESC_RATE11M)
2762 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2764 txpower += rtlpriv->dm.remnant_cck_idx;
2766 if (txpower > MAX_POWER_INDEX)
2767 txpower = MAX_POWER_INDEX;
2772 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2773 u8 power_index, u8 path, u8 rate)
2775 struct rtl_priv *rtlpriv = rtl_priv(hw);
2777 if (path == RF90_PATH_A) {
2780 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2781 MASKBYTE0, power_index);
2784 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2785 MASKBYTE1, power_index);
2788 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2789 MASKBYTE2, power_index);
2792 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2793 MASKBYTE3, power_index);
2796 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2797 MASKBYTE0, power_index);
2800 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2801 MASKBYTE1, power_index);
2804 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2805 MASKBYTE2, power_index);
2808 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2809 MASKBYTE3, power_index);
2812 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2813 MASKBYTE0, power_index);
2816 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2817 MASKBYTE1, power_index);
2820 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2821 MASKBYTE2, power_index);
2824 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2825 MASKBYTE3, power_index);
2828 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2829 MASKBYTE0, power_index);
2832 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2833 MASKBYTE1, power_index);
2836 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2837 MASKBYTE2, power_index);
2840 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2841 MASKBYTE3, power_index);
2844 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2845 MASKBYTE0, power_index);
2848 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2849 MASKBYTE1, power_index);
2852 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2853 MASKBYTE2, power_index);
2856 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2857 MASKBYTE3, power_index);
2860 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2861 MASKBYTE0, power_index);
2864 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2865 MASKBYTE1, power_index);
2867 case DESC_RATEMCS10:
2868 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2869 MASKBYTE2, power_index);
2871 case DESC_RATEMCS11:
2872 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2873 MASKBYTE3, power_index);
2875 case DESC_RATEMCS12:
2876 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2877 MASKBYTE0, power_index);
2879 case DESC_RATEMCS13:
2880 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2881 MASKBYTE1, power_index);
2883 case DESC_RATEMCS14:
2884 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2885 MASKBYTE2, power_index);
2887 case DESC_RATEMCS15:
2888 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2889 MASKBYTE3, power_index);
2891 case DESC_RATEVHT1SS_MCS0:
2892 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2893 MASKBYTE0, power_index);
2895 case DESC_RATEVHT1SS_MCS1:
2896 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2897 MASKBYTE1, power_index);
2899 case DESC_RATEVHT1SS_MCS2:
2900 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2901 MASKBYTE2, power_index);
2903 case DESC_RATEVHT1SS_MCS3:
2904 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2905 MASKBYTE3, power_index);
2907 case DESC_RATEVHT1SS_MCS4:
2908 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2909 MASKBYTE0, power_index);
2911 case DESC_RATEVHT1SS_MCS5:
2912 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2913 MASKBYTE1, power_index);
2915 case DESC_RATEVHT1SS_MCS6:
2916 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2917 MASKBYTE2, power_index);
2919 case DESC_RATEVHT1SS_MCS7:
2920 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2921 MASKBYTE3, power_index);
2923 case DESC_RATEVHT1SS_MCS8:
2924 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2925 MASKBYTE0, power_index);
2927 case DESC_RATEVHT1SS_MCS9:
2928 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2929 MASKBYTE1, power_index);
2931 case DESC_RATEVHT2SS_MCS0:
2932 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2933 MASKBYTE2, power_index);
2935 case DESC_RATEVHT2SS_MCS1:
2936 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2937 MASKBYTE3, power_index);
2939 case DESC_RATEVHT2SS_MCS2:
2940 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2941 MASKBYTE0, power_index);
2943 case DESC_RATEVHT2SS_MCS3:
2944 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2945 MASKBYTE1, power_index);
2947 case DESC_RATEVHT2SS_MCS4:
2948 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2949 MASKBYTE2, power_index);
2951 case DESC_RATEVHT2SS_MCS5:
2952 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2953 MASKBYTE3, power_index);
2955 case DESC_RATEVHT2SS_MCS6:
2956 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2957 MASKBYTE0, power_index);
2959 case DESC_RATEVHT2SS_MCS7:
2960 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2961 MASKBYTE1, power_index);
2963 case DESC_RATEVHT2SS_MCS8:
2964 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2965 MASKBYTE2, power_index);
2967 case DESC_RATEVHT2SS_MCS9:
2968 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2969 MASKBYTE3, power_index);
2972 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2973 "Invalid Rate!!\n");
2976 } else if (path == RF90_PATH_B) {
2979 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2980 MASKBYTE0, power_index);
2983 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2984 MASKBYTE1, power_index);
2987 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2988 MASKBYTE2, power_index);
2991 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2992 MASKBYTE3, power_index);
2995 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2996 MASKBYTE0, power_index);
2999 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3000 MASKBYTE1, power_index);
3003 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3004 MASKBYTE2, power_index);
3007 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3008 MASKBYTE3, power_index);
3011 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3012 MASKBYTE0, power_index);
3015 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3016 MASKBYTE1, power_index);
3019 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3020 MASKBYTE2, power_index);
3023 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3024 MASKBYTE3, power_index);
3027 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3028 MASKBYTE0, power_index);
3031 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3032 MASKBYTE1, power_index);
3035 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3036 MASKBYTE2, power_index);
3039 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3040 MASKBYTE3, power_index);
3043 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3044 MASKBYTE0, power_index);
3047 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3048 MASKBYTE1, power_index);
3051 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3052 MASKBYTE2, power_index);
3055 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3056 MASKBYTE3, power_index);
3059 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3060 MASKBYTE0, power_index);
3063 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3064 MASKBYTE1, power_index);
3066 case DESC_RATEMCS10:
3067 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3068 MASKBYTE2, power_index);
3070 case DESC_RATEMCS11:
3071 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3072 MASKBYTE3, power_index);
3074 case DESC_RATEMCS12:
3075 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3076 MASKBYTE0, power_index);
3078 case DESC_RATEMCS13:
3079 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3080 MASKBYTE1, power_index);
3082 case DESC_RATEMCS14:
3083 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3084 MASKBYTE2, power_index);
3086 case DESC_RATEMCS15:
3087 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3088 MASKBYTE3, power_index);
3090 case DESC_RATEVHT1SS_MCS0:
3091 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3092 MASKBYTE0, power_index);
3094 case DESC_RATEVHT1SS_MCS1:
3095 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3096 MASKBYTE1, power_index);
3098 case DESC_RATEVHT1SS_MCS2:
3099 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3100 MASKBYTE2, power_index);
3102 case DESC_RATEVHT1SS_MCS3:
3103 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3104 MASKBYTE3, power_index);
3106 case DESC_RATEVHT1SS_MCS4:
3107 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3108 MASKBYTE0, power_index);
3110 case DESC_RATEVHT1SS_MCS5:
3111 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3112 MASKBYTE1, power_index);
3114 case DESC_RATEVHT1SS_MCS6:
3115 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3116 MASKBYTE2, power_index);
3118 case DESC_RATEVHT1SS_MCS7:
3119 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3120 MASKBYTE3, power_index);
3122 case DESC_RATEVHT1SS_MCS8:
3123 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3124 MASKBYTE0, power_index);
3126 case DESC_RATEVHT1SS_MCS9:
3127 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3128 MASKBYTE1, power_index);
3130 case DESC_RATEVHT2SS_MCS0:
3131 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3132 MASKBYTE2, power_index);
3134 case DESC_RATEVHT2SS_MCS1:
3135 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3136 MASKBYTE3, power_index);
3138 case DESC_RATEVHT2SS_MCS2:
3139 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3140 MASKBYTE0, power_index);
3142 case DESC_RATEVHT2SS_MCS3:
3143 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3144 MASKBYTE1, power_index);
3146 case DESC_RATEVHT2SS_MCS4:
3147 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3148 MASKBYTE2, power_index);
3150 case DESC_RATEVHT2SS_MCS5:
3151 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3152 MASKBYTE3, power_index);
3154 case DESC_RATEVHT2SS_MCS6:
3155 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3156 MASKBYTE0, power_index);
3158 case DESC_RATEVHT2SS_MCS7:
3159 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3160 MASKBYTE1, power_index);
3162 case DESC_RATEVHT2SS_MCS8:
3163 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3164 MASKBYTE2, power_index);
3166 case DESC_RATEVHT2SS_MCS9:
3167 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3168 MASKBYTE3, power_index);
3171 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3172 "Invalid Rate!!\n");
3176 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3177 "Invalid RFPath!!\n");
3181 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3183 u8 channel, u8 size)
3185 struct rtl_priv *rtlpriv = rtl_priv(hw);
3186 struct rtl_phy *rtlphy = &rtlpriv->phy;
3190 for (i = 0; i < size; i++) {
3192 _rtl8821ae_get_txpower_index(hw, path, array[i],
3193 rtlphy->current_chan_bw,
3195 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3200 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3201 u8 bw, u8 channel, u8 path)
3203 struct rtl_priv *rtlpriv = rtl_priv(hw);
3204 struct rtl_phy *rtlphy = &rtlpriv->phy;
3207 u32 power_level, data, offset;
3209 if (path >= rtlphy->num_total_rfpath)
3213 if (path == RF90_PATH_A) {
3215 _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3216 DESC_RATEMCS7, bw, channel);
3217 offset = RA_TXPWRTRAING;
3220 _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3221 DESC_RATEMCS7, bw, channel);
3222 offset = RB_TXPWRTRAING;
3225 for (i = 0; i < 3; i++) {
3227 power_level = power_level - 10;
3229 power_level = power_level - 8;
3231 power_level = power_level - 6;
3233 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3235 rtl_set_bbreg(hw, offset, 0xffffff, data);
3238 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3239 u8 channel, u8 path)
3241 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3242 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3243 struct rtl_priv *rtlpriv = rtl_priv(hw);
3244 struct rtl_phy *rtlphy = &rtlpriv->phy;
3245 u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3247 u8 sizes_of_cck_retes = 4;
3248 u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3249 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3250 DESC_RATE48M, DESC_RATE54M};
3251 u8 sizes_of_ofdm_retes = 8;
3252 u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3253 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3254 DESC_RATEMCS6, DESC_RATEMCS7};
3255 u8 sizes_of_ht_retes_1t = 8;
3256 u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9,
3257 DESC_RATEMCS10, DESC_RATEMCS11,
3258 DESC_RATEMCS12, DESC_RATEMCS13,
3259 DESC_RATEMCS14, DESC_RATEMCS15};
3260 u8 sizes_of_ht_retes_2t = 8;
3261 u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3262 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3263 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3264 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3265 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3266 u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3267 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3268 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3269 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3270 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3271 u8 sizes_of_vht_retes = 10;
3273 if (rtlhal->current_bandtype == BAND_ON_2_4G)
3274 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3275 sizes_of_cck_retes);
3277 _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3278 sizes_of_ofdm_retes);
3279 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3280 sizes_of_ht_retes_1t);
3281 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3282 sizes_of_vht_retes);
3284 if (rtlphy->num_total_rfpath >= 2) {
3285 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3287 sizes_of_ht_retes_2t);
3288 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3290 sizes_of_vht_retes);
3293 _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3297 /*just in case, write txpower in DW, to reduce time*/
3298 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3300 struct rtl_priv *rtlpriv = rtl_priv(hw);
3301 struct rtl_phy *rtlphy = &rtlpriv->phy;
3304 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3305 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3308 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3309 enum wireless_mode wirelessmode,
3315 switch (wirelessmode) {
3316 case WIRELESS_MODE_B:
3319 case WIRELESS_MODE_G:
3320 case WIRELESS_MODE_N_24G:
3327 pwrout_dbm = txpwridx / 2 + offset;
3331 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3333 struct rtl_priv *rtlpriv = rtl_priv(hw);
3334 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3335 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3337 if (!is_hal_stop(rtlhal)) {
3338 switch (operation) {
3339 case SCAN_OPT_BACKUP_BAND0:
3340 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3341 rtlpriv->cfg->ops->set_hw_reg(hw,
3346 case SCAN_OPT_BACKUP_BAND1:
3347 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3348 rtlpriv->cfg->ops->set_hw_reg(hw,
3353 case SCAN_OPT_RESTORE:
3354 iotype = IO_CMD_RESUME_DM_BY_SCAN;
3355 rtlpriv->cfg->ops->set_hw_reg(hw,
3360 pr_err("Unknown Scan Backup operation.\n");
3366 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3368 u16 reg_rf_mode_bw, tmp = 0;
3370 reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3372 case HT_CHANNEL_WIDTH_20:
3373 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3375 case HT_CHANNEL_WIDTH_20_40:
3376 tmp = reg_rf_mode_bw | BIT(7);
3377 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3379 case HT_CHANNEL_WIDTH_80:
3380 tmp = reg_rf_mode_bw | BIT(8);
3381 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3384 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3389 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3391 struct rtl_phy *rtlphy = &rtlpriv->phy;
3392 struct rtl_mac *mac = rtl_mac(rtlpriv);
3393 u8 sc_set_40 = 0, sc_set_20 = 0;
3395 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3396 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3397 sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3398 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3399 sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3401 pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3403 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3404 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3405 sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3406 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3407 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3408 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3409 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3410 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3411 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3412 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3413 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3414 sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3416 pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3417 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3418 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3419 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3420 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3421 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3423 pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3425 return (sc_set_40 << 4) | sc_set_20;
3428 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3430 struct rtl_priv *rtlpriv = rtl_priv(hw);
3431 struct rtl_phy *rtlphy = &rtlpriv->phy;
3435 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3436 "Switch to %s bandwidth\n",
3437 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3439 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3440 "40MHz" : "80MHz")));
3442 _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3443 sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3444 rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3446 switch (rtlphy->current_chan_bw) {
3447 case HT_CHANNEL_WIDTH_20:
3448 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3449 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3451 if (rtlphy->rf_type == RF_2T2R)
3452 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3454 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3456 case HT_CHANNEL_WIDTH_20_40:
3457 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3458 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3459 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3460 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3462 if (rtlphy->reg_837 & BIT(2))
3465 if (rtlphy->rf_type == RF_2T2R)
3470 /* 0x848[25:22] = 0x6 */
3471 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3473 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3474 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3476 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3479 case HT_CHANNEL_WIDTH_80:
3480 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3481 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3483 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3484 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3485 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3487 if (rtlphy->reg_837 & BIT(2))
3490 if (rtlphy->rf_type == RF_2T2R)
3495 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3499 pr_err("unknown bandwidth: %#X\n",
3500 rtlphy->current_chan_bw);
3504 rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3506 rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3507 rtlphy->set_bwmode_inprogress = false;
3509 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3512 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3513 enum nl80211_channel_type ch_type)
3515 struct rtl_priv *rtlpriv = rtl_priv(hw);
3516 struct rtl_phy *rtlphy = &rtlpriv->phy;
3517 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3518 u8 tmp_bw = rtlphy->current_chan_bw;
3520 if (rtlphy->set_bwmode_inprogress)
3522 rtlphy->set_bwmode_inprogress = true;
3523 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3524 rtl8821ae_phy_set_bw_mode_callback(hw);
3526 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3527 "FALSE driver sleep or unload\n");
3528 rtlphy->set_bwmode_inprogress = false;
3529 rtlphy->current_chan_bw = tmp_bw;
3533 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3535 struct rtl_priv *rtlpriv = rtl_priv(hw);
3536 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3537 struct rtl_phy *rtlphy = &rtlpriv->phy;
3538 u8 channel = rtlphy->current_channel;
3542 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3543 "switch to channel%d\n", rtlphy->current_channel);
3544 if (is_hal_stop(rtlhal))
3547 if (36 <= channel && channel <= 48)
3549 else if (50 <= channel && channel <= 64)
3551 else if (100 <= channel && channel <= 116)
3553 else if (118 <= channel)
3557 rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3559 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3560 if (36 <= channel && channel <= 64)
3562 else if (100 <= channel && channel <= 140)
3564 else if (140 < channel)
3568 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3569 BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3571 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3572 BMASKBYTE0, channel);
3575 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3576 if (36 <= channel && channel <= 64)
3578 else if (100 <= channel && channel <= 140)
3582 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3583 BRFREGOFFSETMASK, data);
3587 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3590 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3592 struct rtl_priv *rtlpriv = rtl_priv(hw);
3593 struct rtl_phy *rtlphy = &rtlpriv->phy;
3594 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3595 u32 timeout = 1000, timecount = 0;
3596 u8 channel = rtlphy->current_channel;
3598 if (rtlphy->sw_chnl_inprogress)
3600 if (rtlphy->set_bwmode_inprogress)
3603 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3604 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3605 "sw_chnl_inprogress false driver sleep or unload\n");
3608 while (rtlphy->lck_inprogress && timecount < timeout) {
3613 if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3614 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3615 else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3616 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3618 rtlphy->sw_chnl_inprogress = true;
3622 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3623 "switch to channel%d, band type is %d\n",
3624 rtlphy->current_channel, rtlhal->current_bandtype);
3626 rtl8821ae_phy_sw_chnl_callback(hw);
3628 rtl8821ae_dm_clear_txpower_tracking_state(hw);
3629 rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3631 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3632 rtlphy->sw_chnl_inprogress = false;
3636 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3638 u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3639 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3640 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3641 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3642 110, 112, 114, 116, 118, 120, 122, 124, 126,
3643 128, 130, 132, 134, 136, 138, 140, 149, 151,
3644 153, 155, 157, 159, 161, 163, 165};
3648 for (place = 14; place < sizeof(channel_all); place++)
3649 if (channel_all[place] == chnl)
3656 #define MACBB_REG_NUM 10
3657 #define AFE_REG_NUM 14
3658 #define RF_REG_NUM 3
3660 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3662 u32 *backup_macbb_reg, u32 mac_bb_num)
3664 struct rtl_priv *rtlpriv = rtl_priv(hw);
3667 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3668 /*save MACBB default value*/
3669 for (i = 0; i < mac_bb_num; i++)
3670 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3672 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3675 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3676 u32 *backup_afe_REG, u32 afe_num)
3678 struct rtl_priv *rtlpriv = rtl_priv(hw);
3681 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3682 /*Save AFE Parameters */
3683 for (i = 0; i < afe_num; i++)
3684 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3685 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3688 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3689 u32 *rfb_backup, u32 *backup_rf_reg,
3692 struct rtl_priv *rtlpriv = rtl_priv(hw);
3695 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3696 /*Save RF Parameters*/
3697 for (i = 0; i < rf_num; i++) {
3698 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3700 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3703 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3706 static void _rtl8821ae_iqk_configure_mac(
3707 struct ieee80211_hw *hw
3710 struct rtl_priv *rtlpriv = rtl_priv(hw);
3711 /* ========MAC register setting========*/
3712 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3713 rtl_write_byte(rtlpriv, 0x522, 0x3f);
3714 rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3715 rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/
3716 rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/
3719 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3720 enum radio_path path, u32 tx_x, u32 tx_y)
3722 struct rtl_priv *rtlpriv = rtl_priv(hw);
3725 /* [31] = 1 --> Page C1 */
3726 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3727 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3728 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3729 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3730 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3731 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3732 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3733 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3735 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3736 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3737 rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3738 rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3745 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3746 enum radio_path path, u32 rx_x, u32 rx_y)
3748 struct rtl_priv *rtlpriv = rtl_priv(hw);
3751 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3752 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3753 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3754 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3755 "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3757 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3758 "0xc10 = %x ====>fill to IQC\n",
3759 rtl_read_dword(rtlpriv, 0xc10));
3768 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3770 struct rtl_priv *rtlpriv = rtl_priv(hw);
3771 struct rtl_phy *rtlphy = &rtlpriv->phy;
3772 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3774 u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3775 int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3776 int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3777 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num],
3778 tx_dt[cal_num], rx_dt[cal_num];
3779 bool tx0iqkok = false, rx0iqkok = false;
3780 bool vdf_enable = false;
3781 int i, k, vdf_y[3], vdf_x[3],
3782 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3784 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3785 "BandWidth = %d.\n",
3786 rtlphy->current_chan_bw);
3787 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3790 while (cal < cal_num) {
3793 temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3795 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3796 /*========Path-A AFE all on========*/
3797 /*Port 0 DAC/ADC on*/
3798 rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3799 rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3800 rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3801 rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3802 rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3803 rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3804 rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3805 rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3806 rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3807 rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3809 rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3812 /* ====== LOK ====== */
3813 /*DAC/ADC sampling rate (160 MHz)*/
3814 rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3816 /* 2. LoK RF Setting (at BW = 20M) */
3817 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3818 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */
3819 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3820 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3821 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3822 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3823 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3824 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3825 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3826 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3827 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3828 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3829 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3830 rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3832 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3833 rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3835 if (rtlhal->current_bandtype)
3836 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3838 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3840 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3841 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3842 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3843 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3844 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3846 mdelay(10); /* Delay 10ms */
3847 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3849 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3850 rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3852 switch (rtlphy->current_chan_bw) {
3854 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3857 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3863 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3865 /* 3. TX RF Setting */
3866 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3867 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3868 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3869 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3870 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3871 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3872 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3873 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3874 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3875 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3876 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3877 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3878 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3879 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3880 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3882 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3883 rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3884 if (rtlhal->current_bandtype)
3885 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3887 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3889 if (vdf_enable == 1) {
3890 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3891 for (k = 0; k <= 2; k++) {
3894 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3895 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3896 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3899 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3900 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3901 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3904 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3905 "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3906 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3907 "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3908 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3909 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3910 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3911 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3912 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3913 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3914 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3919 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3923 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3924 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3926 mdelay(10); /* Delay 10ms */
3927 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3930 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3931 if ((~iqk_ready) || (delay_count > 20))
3939 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3940 /* ============TXIQK Check============== */
3941 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3944 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3945 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3946 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3947 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3951 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3952 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3955 if (cal_retry == 10)
3961 if (cal_retry == 10)
3967 tx_x0[cal] = vdf_x[k-1];
3968 tx_y0[cal] = vdf_y[k-1];
3971 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3972 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3973 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3977 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3978 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3980 mdelay(10); /* Delay 10ms */
3981 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3984 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3985 if ((~iqk_ready) || (delay_count > 20))
3993 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3994 /* ============TXIQK Check============== */
3995 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3998 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3999 tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4000 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4001 tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4005 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4006 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4009 if (cal_retry == 10)
4015 if (cal_retry == 10)
4021 if (tx0iqkok == false)
4022 break; /* TXK fail, Don't do RXK */
4024 if (vdf_enable == 1) {
4025 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */
4026 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4027 for (k = 0; k <= 2; k++) {
4028 /* ====== RX mode TXK (RXK Step 1) ====== */
4029 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4030 /* 1. TX RF Setting */
4031 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4032 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4033 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4034 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4035 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4036 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4037 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4039 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4040 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4041 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4042 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4043 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4044 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4045 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4049 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4050 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4051 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4056 rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4057 rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4058 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4063 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4064 "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4065 vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4066 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4067 "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4068 vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4069 rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4070 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4071 rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4072 rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4073 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4074 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4075 rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4081 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4082 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4083 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4087 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4088 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4090 mdelay(10); /* Delay 10ms */
4091 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4094 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4095 if ((~iqk_ready) || (delay_count > 20))
4103 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4104 /* ============TXIQK Check============== */
4105 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4108 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4109 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4110 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4111 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4117 if (cal_retry == 10)
4123 if (cal_retry == 10)
4128 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4129 tx_x0_rxk[cal] = tx_x0[cal];
4130 tx_y0_rxk[cal] = tx_y0[cal];
4135 "RXK Step 1 fail\n");
4138 /* ====== RX IQK ====== */
4139 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4140 /* 1. RX RF Setting */
4141 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4142 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4143 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4144 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4145 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4146 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4147 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4149 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4150 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4151 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4152 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4153 rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4154 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4155 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4157 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4158 rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4159 rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4160 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4162 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4165 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */
4166 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4171 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4172 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4174 mdelay(10); /* Delay 10ms */
4175 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4178 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4179 if ((~iqk_ready) || (delay_count > 20))
4187 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4188 /* ============RXIQK Check============== */
4189 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4191 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4192 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4193 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4194 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4198 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4199 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4202 if (cal_retry == 10)
4209 if (cal_retry == 10)
4216 rx_x0[cal] = vdf_x[k-1];
4217 rx_y0[cal] = vdf_y[k-1];
4219 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */
4223 /* ====== RX mode TXK (RXK Step 1) ====== */
4224 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4225 /* 1. TX RF Setting */
4226 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4227 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4228 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4229 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4230 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4231 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4232 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4233 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4234 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4235 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4237 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4238 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4239 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4240 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4241 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4242 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4246 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4247 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4249 mdelay(10); /* Delay 10ms */
4250 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4253 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4254 if ((~iqk_ready) || (delay_count > 20))
4262 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4263 /* ============TXIQK Check============== */
4264 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4267 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4268 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4269 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4270 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4276 if (cal_retry == 10)
4282 if (cal_retry == 10)
4287 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4288 tx_x0_rxk[cal] = tx_x0[cal];
4289 tx_y0_rxk[cal] = tx_y0[cal];
4291 RT_TRACE(rtlpriv, COMP_IQK,
4295 /* ====== RX IQK ====== */
4296 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4297 /* 1. RX RF Setting */
4298 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4299 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4300 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4301 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4302 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4303 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4304 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4306 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4307 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4308 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4309 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4310 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4311 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4312 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4314 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4315 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4316 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4317 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4319 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4321 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4326 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4327 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4329 mdelay(10); /* Delay 10ms */
4330 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4333 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4334 if ((~iqk_ready) || (delay_count > 20))
4342 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4343 /* ============RXIQK Check============== */
4344 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4346 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4347 rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4348 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4349 rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4353 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4354 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4357 if (cal_retry == 10)
4364 if (cal_retry == 10)
4374 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4375 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4383 /* FillIQK Result */
4386 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4387 "========Path_A =======\n");
4388 if (tx_average == 0)
4391 for (i = 0; i < tx_average; i++) {
4392 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4393 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4394 (tx_x0_rxk[i])>>21&0x000007ff, i,
4395 (tx_y0_rxk[i])>>21&0x000007ff);
4396 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4397 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4398 (tx_x0[i])>>21&0x000007ff, i,
4399 (tx_y0[i])>>21&0x000007ff);
4401 for (i = 0; i < tx_average; i++) {
4402 for (ii = i+1; ii < tx_average; ii++) {
4403 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4404 if (dx < 3 && dx > -3) {
4405 dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4406 if (dy < 3 && dy > -3) {
4407 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4408 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4419 _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4421 _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4423 if (rx_average == 0)
4426 for (i = 0; i < rx_average; i++)
4427 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4428 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4429 (rx_x0[i])>>21&0x000007ff, i,
4430 (rx_y0[i])>>21&0x000007ff);
4431 for (i = 0; i < rx_average; i++) {
4432 for (ii = i+1; ii < rx_average; ii++) {
4433 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4434 if (dx < 4 && dx > -4) {
4435 dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4436 if (dy < 4 && dy > -4) {
4437 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4438 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4449 _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4451 _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4458 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4459 enum radio_path path,
4461 u32 *rf_backup, u32 rf_reg_num)
4463 struct rtl_priv *rtlpriv = rtl_priv(hw);
4466 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4467 for (i = 0; i < RF_REG_NUM; i++)
4468 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4473 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4474 "RestoreRF Path A Success!!!!\n");
4481 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4482 u32 *afe_backup, u32 *backup_afe_reg,
4486 struct rtl_priv *rtlpriv = rtl_priv(hw);
4488 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4489 /* Reload AFE Parameters */
4490 for (i = 0; i < afe_num; i++)
4491 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4492 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4493 rtl_write_dword(rtlpriv, 0xc80, 0x0);
4494 rtl_write_dword(rtlpriv, 0xc84, 0x0);
4495 rtl_write_dword(rtlpriv, 0xc88, 0x0);
4496 rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4497 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4498 rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4499 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4500 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4501 rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4502 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4505 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4507 u32 *backup_macbb_reg,
4511 struct rtl_priv *rtlpriv = rtl_priv(hw);
4513 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4514 /* Reload MacBB Parameters */
4515 for (i = 0; i < macbb_num; i++)
4516 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4517 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4520 #undef MACBB_REG_NUM
4524 #define MACBB_REG_NUM 11
4525 #define AFE_REG_NUM 12
4526 #define RF_REG_NUM 3
4528 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4530 u32 macbb_backup[MACBB_REG_NUM];
4531 u32 afe_backup[AFE_REG_NUM];
4532 u32 rfa_backup[RF_REG_NUM];
4533 u32 rfb_backup[RF_REG_NUM];
4534 u32 backup_macbb_reg[MACBB_REG_NUM] = {
4535 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4536 0xe00, 0xe50, 0x838, 0x82c
4538 u32 backup_afe_reg[AFE_REG_NUM] = {
4539 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4540 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4542 u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4544 _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4546 _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4547 _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4550 _rtl8821ae_iqk_configure_mac(hw);
4551 _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4552 _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4555 _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4556 _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4560 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4562 struct rtl_priv *rtlpriv = rtl_priv(hw);
4563 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4564 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4565 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4568 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4570 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4573 #undef IQK_ADDA_REG_NUM
4574 #undef IQK_DELAY_TIME
4576 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4580 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4581 u8 thermal_value, u8 threshold)
4583 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4585 rtldm->thermalvalue_iqk = thermal_value;
4586 rtl8812ae_phy_iq_calibrate(hw, false);
4589 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4591 struct rtl_priv *rtlpriv = rtl_priv(hw);
4592 struct rtl_phy *rtlphy = &rtlpriv->phy;
4594 if (!rtlphy->lck_inprogress) {
4595 spin_lock(&rtlpriv->locks.iqk_lock);
4596 rtlphy->lck_inprogress = true;
4597 spin_unlock(&rtlpriv->locks.iqk_lock);
4599 _rtl8821ae_phy_iq_calibrate(hw);
4601 spin_lock(&rtlpriv->locks.iqk_lock);
4602 rtlphy->lck_inprogress = false;
4603 spin_unlock(&rtlpriv->locks.iqk_lock);
4607 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4609 struct rtl_priv *rtlpriv = rtl_priv(hw);
4610 struct rtl_phy *rtlphy = &rtlpriv->phy;
4613 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4614 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4615 (int)(sizeof(rtlphy->iqk_matrix) /
4616 sizeof(struct iqk_matrix_regs)),
4617 IQK_MATRIX_SETTINGS_NUM);
4619 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4620 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4621 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4622 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4623 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4625 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4626 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4627 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4628 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4630 rtlphy->iqk_matrix[i].iqk_done = false;
4634 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4635 u8 thermal_value, u8 threshold)
4637 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4639 rtl8821ae_reset_iqk_result(hw);
4641 rtldm->thermalvalue_iqk = thermal_value;
4642 rtl8821ae_phy_iq_calibrate(hw, false);
4645 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4649 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
4653 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4655 _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4658 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4660 struct rtl_priv *rtlpriv = rtl_priv(hw);
4661 struct rtl_phy *rtlphy = &rtlpriv->phy;
4662 bool postprocessing = false;
4664 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4665 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4666 iotype, rtlphy->set_io_inprogress);
4669 case IO_CMD_RESUME_DM_BY_SCAN:
4670 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4671 "[IO CMD] Resume DM after scan.\n");
4672 postprocessing = true;
4674 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4675 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4676 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4677 "[IO CMD] Pause DM before scan.\n");
4678 postprocessing = true;
4681 pr_err("switch case %#x not processed\n",
4686 if (postprocessing && !rtlphy->set_io_inprogress) {
4687 rtlphy->set_io_inprogress = true;
4688 rtlphy->current_io_type = iotype;
4692 rtl8821ae_phy_set_io(hw);
4693 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4697 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4699 struct rtl_priv *rtlpriv = rtl_priv(hw);
4700 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4701 struct rtl_phy *rtlphy = &rtlpriv->phy;
4703 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4704 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4705 rtlphy->current_io_type, rtlphy->set_io_inprogress);
4706 switch (rtlphy->current_io_type) {
4707 case IO_CMD_RESUME_DM_BY_SCAN:
4708 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4709 _rtl8821ae_resume_tx_beacon(hw);
4710 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4711 rtl8821ae_dm_write_cck_cca_thres(hw,
4712 rtlphy->initgain_backup.cca);
4714 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4715 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4716 _rtl8821ae_stop_tx_beacon(hw);
4717 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4718 rtl8821ae_dm_write_dig(hw, 0x17);
4719 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4720 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4722 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4725 pr_err("switch case %#x not processed\n",
4726 rtlphy->current_io_type);
4729 rtlphy->set_io_inprogress = false;
4730 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4731 "(%#x)\n", rtlphy->current_io_type);
4734 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4736 struct rtl_priv *rtlpriv = rtl_priv(hw);
4738 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4739 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4740 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4741 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4742 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4745 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4746 enum rf_pwrstate rfpwr_state)
4748 struct rtl_priv *rtlpriv = rtl_priv(hw);
4749 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4750 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4751 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4752 bool bresult = true;
4754 struct rtl8192_tx_ring *ring = NULL;
4756 switch (rfpwr_state) {
4758 if ((ppsc->rfpwr_state == ERFOFF) &&
4759 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4760 bool rtstatus = false;
4761 u32 initializecount = 0;
4765 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4766 "IPS Set eRf nic enable\n");
4767 rtstatus = rtl_ps_enable_nic(hw);
4768 } while (!rtstatus && (initializecount < 10));
4769 RT_CLEAR_PS_LEVEL(ppsc,
4770 RT_RF_OFF_LEVL_HALT_NIC);
4772 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4773 "Set ERFON sleeped:%d ms\n",
4774 jiffies_to_msecs(jiffies -
4776 last_sleep_jiffies));
4777 ppsc->last_awake_jiffies = jiffies;
4778 rtl8821ae_phy_set_rf_on(hw);
4780 if (mac->link_state == MAC80211_LINKED) {
4781 rtlpriv->cfg->ops->led_control(hw,
4784 rtlpriv->cfg->ops->led_control(hw,
4789 for (queue_id = 0, i = 0;
4790 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4791 ring = &pcipriv->dev.tx_ring[queue_id];
4792 if (queue_id == BEACON_QUEUE ||
4793 skb_queue_len(&ring->queue) == 0) {
4797 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4798 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4800 skb_queue_len(&ring->queue));
4805 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4806 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4807 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4808 MAX_DOZE_WAITING_TIMES_9x,
4810 skb_queue_len(&ring->queue));
4815 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4816 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4817 "IPS Set eRf nic disable\n");
4818 rtl_ps_disable_nic(hw);
4819 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4821 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4822 rtlpriv->cfg->ops->led_control(hw,
4825 rtlpriv->cfg->ops->led_control(hw,
4831 pr_err("switch case %#x not processed\n",
4837 ppsc->rfpwr_state = rfpwr_state;
4841 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4842 enum rf_pwrstate rfpwr_state)
4844 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4846 bool bresult = false;
4848 if (rfpwr_state == ppsc->rfpwr_state)
4850 bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);