]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/rtlwifi/rtl8821ae/phy.c
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[karo-tx-linux.git] / drivers / net / wireless / rtlwifi / rtl8821ae / phy.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  Realtek Corporation.
4  *
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.
8  *
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
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25
26 #include "../wifi.h"
27 #include "../pci.h"
28 #include "../ps.h"
29 #include "reg.h"
30 #include "def.h"
31 #include "phy.h"
32 #include "rf.h"
33 #include "dm.h"
34 #include "table.h"
35 #include "trx.h"
36 #include "../btcoexist/halbt_precomp.h"
37 #include "hw.h"
38 #include "../efuse.h"
39
40 #define READ_NEXT_PAIR(array_table, v1, v2, i) \
41         do { \
42                 i += 2; \
43                 v1 = array_table[i]; \
44                 v2 = array_table[i+1]; \
45         } while (0)
46
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,
51                                            u32 data);
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,
57                                                      u8 configtype);
58 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
59                                                        u8 configtype);
60 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
61
62 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
63                                             enum wireless_mode wirelessmode,
64                                             u8 txpwridx);
65 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw);
66 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw);
67
68 static void rtl8812ae_fixspur(struct ieee80211_hw *hw,
69                               enum ht_channel_width band_width, u8 channel)
70 {
71         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
72
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*/
78                 else
79                         rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2);
80                         /* 0x8AC[11:10] = 2'b10*/
81
82                 /* <20120914, Kordan> A workarould to resolve
83                  * 2480Mhz spur by setting ADC clock as 160M. (Asked by Binson)
84                  */
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);
90                         /* 0x8C4[30] = 1*/
91                 } else if (band_width == HT_CHANNEL_WIDTH_20_40 &&
92                            channel == 11) {
93                         rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
94                         /*0x8C4[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);
99                         /*0x8C4[30] = 0*/
100                 }
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.
104                  */
105                 if (band_width == HT_CHANNEL_WIDTH_20 &&
106                     (channel == 13 || channel == 14))
107                         rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
108                         /*0x8AC[9:8] = 11*/
109                 else if (channel  <= 14) /*2.4G only*/
110                         rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
111                         /*0x8AC[9:8] = 10*/
112         }
113 }
114
115 u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
116                                u32 bitmask)
117 {
118         struct rtl_priv *rtlpriv = rtl_priv(hw);
119         u32 returnvalue, originalvalue, bitshift;
120
121         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
122                  "regaddr(%#x), bitmask(%#x)\n",
123                  regaddr, bitmask);
124         originalvalue = rtl_read_dword(rtlpriv, regaddr);
125         bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
126         returnvalue = (originalvalue & bitmask) >> bitshift;
127
128         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
129                  "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
130                  bitmask, regaddr, originalvalue);
131         return returnvalue;
132 }
133
134 void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw,
135                               u32 regaddr, u32 bitmask, u32 data)
136 {
137         struct rtl_priv *rtlpriv = rtl_priv(hw);
138         u32 originalvalue, bitshift;
139
140         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
141                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
142                  regaddr, bitmask, data);
143
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));
149         }
150
151         rtl_write_dword(rtlpriv, regaddr, data);
152
153         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
154                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
155                  regaddr, bitmask, data);
156 }
157
158 u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw,
159                                enum radio_path rfpath, u32 regaddr,
160                                u32 bitmask)
161 {
162         struct rtl_priv *rtlpriv = rtl_priv(hw);
163         u32 original_value, readback_value, bitshift;
164         unsigned long flags;
165
166         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
167                  "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
168                  regaddr, rfpath, bitmask);
169
170         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
171
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;
175
176         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
177
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);
181
182         return readback_value;
183 }
184
185 void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw,
186                            enum radio_path rfpath,
187                            u32 regaddr, u32 bitmask, u32 data)
188 {
189         struct rtl_priv *rtlpriv = rtl_priv(hw);
190         u32 original_value, bitshift;
191         unsigned long flags;
192
193         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
194                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
195                   regaddr, bitmask, data, rfpath);
196
197         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
198
199         if (bitmask != RFREG_OFFSET_MASK) {
200                 original_value =
201                    _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
202                 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
203                 data = ((original_value & (~bitmask)) | (data << bitshift));
204         }
205
206         _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data);
207
208         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
209
210         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
211                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
212                  regaddr, bitmask, data, rfpath);
213 }
214
215 static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
216                                          enum radio_path rfpath, u32 offset)
217 {
218         struct rtl_priv *rtlpriv = rtl_priv(hw);
219         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
220         bool is_pi_mode = false;
221         u32 retvalue = 0;
222
223         /* 2009/06/17 MH We can not execute IO for power
224         save or other accident mode.*/
225         if (RT_CANNOT_IO(hw)) {
226                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
227                 return 0xFFFFFFFF;
228         }
229         /* <20120809, Kordan> CCA OFF(when entering),
230                 asked by James to avoid reading the wrong value.
231             <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
232         if (offset != 0x0 &&
233             !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
234             (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
235                 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1);
236         offset &= 0xff;
237
238         if (rfpath == RF90_PATH_A)
239                 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4);
240         else if (rfpath == RF90_PATH_B)
241                 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4);
242
243         rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset);
244
245         if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
246             (IS_VENDOR_8812A_C_CUT(rtlhal->version)))
247                 udelay(20);
248
249         if (is_pi_mode) {
250                 if (rfpath == RF90_PATH_A)
251                         retvalue =
252                           rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA);
253                 else if (rfpath == RF90_PATH_B)
254                         retvalue =
255                           rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA);
256         } else {
257                 if (rfpath == RF90_PATH_A)
258                         retvalue =
259                           rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA);
260                 else if (rfpath == RF90_PATH_B)
261                         retvalue =
262                           rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA);
263         }
264
265         /*<20120809, Kordan> CCA ON(when exiting),
266          * asked by James to avoid reading the wrong value.
267          *   <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!
268          */
269         if (offset != 0x0 &&
270             !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
271             (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
272                 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0);
273         return retvalue;
274 }
275
276 static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
277                                            enum radio_path rfpath, u32 offset,
278                                            u32 data)
279 {
280         struct rtl_priv *rtlpriv = rtl_priv(hw);
281         struct rtl_phy *rtlphy = &rtlpriv->phy;
282         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
283         u32 data_and_addr;
284         u32 newoffset;
285
286         if (RT_CANNOT_IO(hw)) {
287                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
288                 return;
289         }
290         offset &= 0xff;
291         newoffset = offset;
292         data_and_addr = ((newoffset << 20) |
293                          (data & 0x000fffff)) & 0x0fffffff;
294         rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
295         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
296                  "RFW-%d Addr[0x%x]=0x%x\n",
297                  rfpath, pphyreg->rf3wire_offset, data_and_addr);
298 }
299
300 static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
301 {
302         u32 i;
303
304         for (i = 0; i <= 31; i++) {
305                 if (((bitmask >> i) & 0x1) == 1)
306                         break;
307         }
308         return i;
309 }
310
311 bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw)
312 {
313         bool rtstatus = 0;
314
315         rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw);
316
317         return rtstatus;
318 }
319
320 bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw)
321 {
322         bool rtstatus = true;
323         struct rtl_priv *rtlpriv = rtl_priv(hw);
324         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
325         struct rtl_phy *rtlphy = &rtlpriv->phy;
326         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
327         u8 regval;
328         u8 crystal_cap;
329
330         phy_init_bb_rf_register_definition(hw);
331
332         regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
333         regval |= FEN_PCIEA;
334         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval);
335         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
336                        regval | FEN_BB_GLB_RSTN | FEN_BBRSTB);
337
338         rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7);
339         rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7);
340
341         rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw);
342
343         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
344                 crystal_cap = rtlefuse->crystalcap & 0x3F;
345                 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000,
346                               (crystal_cap | (crystal_cap << 6)));
347         } else {
348                 crystal_cap = rtlefuse->crystalcap & 0x3F;
349                 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
350                               (crystal_cap | (crystal_cap << 6)));
351         }
352         rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);
353
354         return rtstatus;
355 }
356
357 bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
358 {
359         return rtl8821ae_phy_rf6052_config(hw);
360 }
361
362 u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8  band,
363                            u8 rf_path)
364 {
365         struct rtl_priv *rtlpriv = rtl_priv(hw);
366         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
367         struct rtl_dm *rtldm = rtl_dm(rtlpriv);
368         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
369         char reg_swing_2g = -1;/* 0xff; */
370         char reg_swing_5g = -1;/* 0xff; */
371         char swing_2g = -1 * reg_swing_2g;
372         char swing_5g = -1 * reg_swing_5g;
373         u32  out = 0x200;
374         const char auto_temp = -1;
375
376         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
377                  "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
378                  (int)swing_2g, (int)swing_5g,
379                  (int)rtlefuse->autoload_failflag);
380
381         if (rtlefuse->autoload_failflag) {
382                 if (band == BAND_ON_2_4G) {
383                         rtldm->swing_diff_2g = swing_2g;
384                         if (swing_2g == 0) {
385                                 out = 0x200; /* 0 dB */
386                         } else if (swing_2g == -3) {
387                                 out = 0x16A; /* -3 dB */
388                         } else if (swing_2g == -6) {
389                                 out = 0x101; /* -6 dB */
390                         } else if (swing_2g == -9) {
391                                 out = 0x0B6; /* -9 dB */
392                         } else {
393                                 rtldm->swing_diff_2g = 0;
394                                 out = 0x200;
395                         }
396                 } else if (band == BAND_ON_5G) {
397                         rtldm->swing_diff_5g = swing_5g;
398                         if (swing_5g == 0) {
399                                 out = 0x200; /* 0 dB */
400                         } else if (swing_5g == -3) {
401                                 out = 0x16A; /* -3 dB */
402                         } else if (swing_5g == -6) {
403                                 out = 0x101; /* -6 dB */
404                         } else if (swing_5g == -9) {
405                                 out = 0x0B6; /* -9 dB */
406                         } else {
407                                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
408                                         rtldm->swing_diff_5g = -3;
409                                         out = 0x16A;
410                                 } else {
411                                         rtldm->swing_diff_5g = 0;
412                                         out = 0x200;
413                                 }
414                         }
415                 } else {
416                         rtldm->swing_diff_2g = -3;
417                         rtldm->swing_diff_5g = -3;
418                         out = 0x16A; /* -3 dB */
419                 }
420         } else {
421             u32 swing = 0, swing_a = 0, swing_b = 0;
422
423             if (band == BAND_ON_2_4G) {
424                         if (reg_swing_2g == auto_temp) {
425                                 efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
426                                 swing = (swing == 0xFF) ? 0x00 : swing;
427                         } else if (swing_2g ==  0) {
428                                 swing = 0x00; /* 0 dB */
429                         } else if (swing_2g == -3) {
430                                 swing = 0x05; /* -3 dB */
431                         } else if (swing_2g == -6) {
432                                 swing = 0x0A; /* -6 dB */
433                         } else if (swing_2g == -9) {
434                                 swing = 0xFF; /* -9 dB */
435                         } else {
436                                 swing = 0x00;
437                         }
438                 } else {
439                         if (reg_swing_5g == auto_temp) {
440                                 efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
441                                 swing = (swing == 0xFF) ? 0x00 : swing;
442                         } else if (swing_5g ==  0) {
443                                 swing = 0x00; /* 0 dB */
444                         } else if (swing_5g == -3) {
445                                 swing = 0x05; /* -3 dB */
446                         } else if (swing_5g == -6) {
447                                 swing = 0x0A; /* -6 dB */
448                         } else if (swing_5g == -9) {
449                                 swing = 0xFF; /* -9 dB */
450                         } else {
451                                 swing = 0x00;
452                         }
453                 }
454
455                 swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
456                 swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
457                 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
458                          "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
459                          swing_a, swing_b);
460
461                 /* 3 Path-A */
462                 if (swing_a == 0x0) {
463                         if (band == BAND_ON_2_4G)
464                                 rtldm->swing_diff_2g = 0;
465                         else
466                                 rtldm->swing_diff_5g = 0;
467                         out = 0x200; /* 0 dB */
468                 } else if (swing_a == 0x1) {
469                         if (band == BAND_ON_2_4G)
470                                 rtldm->swing_diff_2g = -3;
471                         else
472                                 rtldm->swing_diff_5g = -3;
473                         out = 0x16A; /* -3 dB */
474                 } else if (swing_a == 0x2) {
475                         if (band == BAND_ON_2_4G)
476                                 rtldm->swing_diff_2g = -6;
477                         else
478                                 rtldm->swing_diff_5g = -6;
479                         out = 0x101; /* -6 dB */
480                 } else if (swing_a == 0x3) {
481                         if (band == BAND_ON_2_4G)
482                                 rtldm->swing_diff_2g = -9;
483                         else
484                                 rtldm->swing_diff_5g = -9;
485                         out = 0x0B6; /* -9 dB */
486                 }
487                 /* 3 Path-B */
488                 if (swing_b == 0x0) {
489                         if (band == BAND_ON_2_4G)
490                                 rtldm->swing_diff_2g = 0;
491                         else
492                                 rtldm->swing_diff_5g = 0;
493                         out = 0x200; /* 0 dB */
494                 } else if (swing_b == 0x1) {
495                         if (band == BAND_ON_2_4G)
496                                 rtldm->swing_diff_2g = -3;
497                         else
498                                 rtldm->swing_diff_5g = -3;
499                         out = 0x16A; /* -3 dB */
500                 } else if (swing_b == 0x2) {
501                         if (band == BAND_ON_2_4G)
502                                 rtldm->swing_diff_2g = -6;
503                         else
504                                 rtldm->swing_diff_5g = -6;
505                         out = 0x101; /* -6 dB */
506                 } else if (swing_b == 0x3) {
507                         if (band == BAND_ON_2_4G)
508                                 rtldm->swing_diff_2g = -9;
509                         else
510                                 rtldm->swing_diff_5g = -9;
511                         out = 0x0B6; /* -9 dB */
512                 }
513         }
514
515         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
516                  "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out);
517          return out;
518 }
519
520 void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
521 {
522         struct rtl_priv *rtlpriv = rtl_priv(hw);
523         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
524         struct rtl_dm *rtldm = rtl_dm(rtlpriv);
525         u8 current_band = rtlhal->current_bandtype;
526         u32 txpath, rxpath;
527         char bb_diff_between_band;
528
529         txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
530         rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
531         rtlhal->current_bandtype = (enum band_type) band;
532         /* reconfig BB/RF according to wireless mode */
533         if (rtlhal->current_bandtype == BAND_ON_2_4G) {
534                 /* BB & RF Config */
535                 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
536
537                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
538                         /* 0xCB0[15:12] = 0x7 (LNA_On)*/
539                         rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
540                         /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
541                         rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
542                 }
543
544                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
545                         /*0x834[1:0] = 0x1*/
546                         rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
547                 }
548
549                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
550                         /* 0xC1C[11:8] = 0 */
551                         rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
552                 } else {
553                         /* 0x82C[1:0] = 2b'00 */
554                         rtl_set_bbreg(hw, 0x82c, 0x3, 0);
555                 }
556                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
557                         rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
558                                       0x77777777);
559                         rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
560                                       0x77777777);
561                         rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x000);
562                         rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x000);
563                 }
564
565                 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
566                 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
567
568                 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
569         } else {/* 5G band */
570                 u16 count, reg_41a;
571
572                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
573                         /*0xCB0[15:12] = 0x5 (LNA_On)*/
574                         rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
575                         /*0xCB0[7:4] = 0x4 (PAPE_A)*/
576                         rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
577                 }
578                 /*CCK_CHECK_en*/
579                 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
580
581                 count = 0;
582                 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
583                 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
584                          "Reg41A value %d", reg_41a);
585                 reg_41a &= 0x30;
586                 while ((reg_41a != 0x30) && (count < 50)) {
587                         udelay(50);
588                         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
589
590                         reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
591                         reg_41a &= 0x30;
592                         count++;
593                         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
594                                  "Reg41A value %d", reg_41a);
595                 }
596                 if (count != 0)
597                         RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
598                                  "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
599                                  count, reg_41a);
600
601                 /* 2012/02/01, Sinda add registry to switch workaround
602                 without long-run verification for scan issue. */
603                 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
604
605                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
606                         /*0x834[1:0] = 0x2*/
607                         rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
608                 }
609
610                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
611                         /* AGC table select */
612                         /* 0xC1C[11:8] = 1*/
613                         rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
614                 } else
615                         /* 0x82C[1:0] = 2'b00 */
616                         rtl_set_bbreg(hw, 0x82c, 0x3, 1);
617
618                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
619                         rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
620                                       0x77337777);
621                         rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
622                                       0x77337777);
623                         rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x010);
624                         rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x010);
625                 }
626
627                 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
628                 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
629
630                 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
631                          "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
632                          rtlpriv->dm.ofdm_index[RF90_PATH_A]);
633         }
634
635         if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
636             (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
637                 /* 0xC1C[31:21] */
638                 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
639                               phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
640                 /* 0xE1C[31:21] */
641                 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
642                               phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
643
644                 /* <20121005, Kordan> When TxPowerTrack is ON,
645                  *      we should take care of the change of BB swing.
646                  *   That is, reset all info to trigger Tx power tracking.
647                  */
648                 if (band != current_band) {
649                         bb_diff_between_band =
650                                 (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
651                         bb_diff_between_band = (band == BAND_ON_2_4G) ?
652                                                 bb_diff_between_band :
653                                                 (-1 * bb_diff_between_band);
654                         rtldm->default_ofdm_index += bb_diff_between_band * 2;
655                 }
656                 rtl8821ae_dm_clear_txpower_tracking_state(hw);
657         }
658
659         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
660                  "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
661         return;
662 }
663
664 static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
665                                        const u32 condition)
666 {
667         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
668         u32 _board = rtlefuse->board_type; /*need efuse define*/
669         u32 _interface = 0x01; /* ODM_ITRF_PCIE */
670         u32 _platform = 0x08;/* ODM_WIN */
671         u32 cond = condition;
672
673         if (condition == 0xCDCDCDCD)
674                 return true;
675
676         cond = condition & 0xFF;
677         if ((_board != cond) && cond != 0xFF)
678                 return false;
679
680         cond = condition & 0xFF00;
681         cond = cond >> 8;
682         if ((_interface & cond) == 0 && cond != 0x07)
683                 return false;
684
685         cond = condition & 0xFF0000;
686         cond = cond >> 16;
687         if ((_platform & cond) == 0 && cond != 0x0F)
688                 return false;
689         return true;
690 }
691
692 static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
693                                      u32 addr, u32 data,
694                                      enum radio_path rfpath, u32 regaddr)
695 {
696         if (addr == 0xfe || addr == 0xffe) {
697                 /* In order not to disturb BT music when
698                  * wifi init.(1ant NIC only)
699                  */
700                 mdelay(50);
701         } else {
702                 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
703                 udelay(1);
704         }
705 }
706
707 static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
708                                          u32 addr, u32 data)
709 {
710         u32 content = 0x1000; /*RF Content: radio_a_txt*/
711         u32 maskforphyset = (u32)(content & 0xE000);
712
713         _rtl8821ae_config_rf_reg(hw, addr, data,
714                                  RF90_PATH_A, addr | maskforphyset);
715 }
716
717 static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
718                                          u32 addr, u32 data)
719 {
720         u32 content = 0x1001; /*RF Content: radio_b_txt*/
721         u32 maskforphyset = (u32)(content & 0xE000);
722
723         _rtl8821ae_config_rf_reg(hw, addr, data,
724                                  RF90_PATH_B, addr | maskforphyset);
725 }
726
727 static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
728                                      u32 addr, u32 data)
729 {
730         if (addr == 0xfe)
731                 mdelay(50);
732         else if (addr == 0xfd)
733                 mdelay(5);
734         else if (addr == 0xfc)
735                 mdelay(1);
736         else if (addr == 0xfb)
737                 udelay(50);
738         else if (addr == 0xfa)
739                 udelay(5);
740         else if (addr == 0xf9)
741                 udelay(1);
742         else
743                 rtl_set_bbreg(hw, addr, MASKDWORD, data);
744
745         udelay(1);
746 }
747
748 static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
749 {
750         struct rtl_priv *rtlpriv = rtl_priv(hw);
751         struct rtl_phy *rtlphy = &rtlpriv->phy;
752         u8 band, rfpath, txnum, rate_section;
753
754         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
755                 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
756                         for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
757                                 for (rate_section = 0;
758                                      rate_section < TX_PWR_BY_RATE_NUM_SECTION;
759                                      ++rate_section)
760                                         rtlphy->tx_power_by_rate_offset[band]
761                                             [rfpath][txnum][rate_section] = 0;
762 }
763
764 static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
765                                           u8 band, u8 path,
766                                           u8 rate_section,
767                                           u8 txnum, u8 value)
768 {
769         struct rtl_priv *rtlpriv = rtl_priv(hw);
770         struct rtl_phy *rtlphy = &rtlpriv->phy;
771
772         if (path > RF90_PATH_D) {
773                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
774                         "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
775                 return;
776         }
777
778         if (band == BAND_ON_2_4G) {
779                 switch (rate_section) {
780                 case CCK:
781                         rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
782                         break;
783                 case OFDM:
784                         rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
785                         break;
786                 case HT_MCS0_MCS7:
787                         rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
788                         break;
789                 case HT_MCS8_MCS15:
790                         rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
791                         break;
792                 case VHT_1SSMCS0_1SSMCS9:
793                         rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
794                         break;
795                 case VHT_2SSMCS0_2SSMCS9:
796                         rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
797                         break;
798                 default:
799                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
800                                  "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
801                                  rate_section, path, txnum);
802                         break;
803                 }
804         } else if (band == BAND_ON_5G) {
805                 switch (rate_section) {
806                 case OFDM:
807                         rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
808                         break;
809                 case HT_MCS0_MCS7:
810                         rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
811                         break;
812                 case HT_MCS8_MCS15:
813                         rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
814                         break;
815                 case VHT_1SSMCS0_1SSMCS9:
816                         rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
817                         break;
818                 case VHT_2SSMCS0_2SSMCS9:
819                         rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
820                         break;
821                 default:
822                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
823                                 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
824                                 rate_section, path, txnum);
825                         break;
826                 }
827         } else {
828                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
829                         "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
830         }
831 }
832
833 static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
834                                                   u8 band, u8 path,
835                                                   u8 txnum, u8 rate_section)
836 {
837         struct rtl_priv *rtlpriv = rtl_priv(hw);
838         struct rtl_phy *rtlphy = &rtlpriv->phy;
839         u8 value = 0;
840
841         if (path > RF90_PATH_D) {
842                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
843                          "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
844                          path);
845                 return 0;
846         }
847
848         if (band == BAND_ON_2_4G) {
849                 switch (rate_section) {
850                 case CCK:
851                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
852                         break;
853                 case OFDM:
854                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
855                         break;
856                 case HT_MCS0_MCS7:
857                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
858                         break;
859                 case HT_MCS8_MCS15:
860                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
861                         break;
862                 case VHT_1SSMCS0_1SSMCS9:
863                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
864                         break;
865                 case VHT_2SSMCS0_2SSMCS9:
866                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
867                         break;
868                 default:
869                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
870                                  "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
871                                  rate_section, path, txnum);
872                         break;
873                 }
874         } else if (band == BAND_ON_5G) {
875                 switch (rate_section) {
876                 case OFDM:
877                         value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
878                         break;
879                 case HT_MCS0_MCS7:
880                         value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
881                         break;
882                 case HT_MCS8_MCS15:
883                         value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
884                         break;
885                 case VHT_1SSMCS0_1SSMCS9:
886                         value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
887                         break;
888                 case VHT_2SSMCS0_2SSMCS9:
889                         value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
890                         break;
891                 default:
892                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
893                                  "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
894                                  rate_section, path, txnum);
895                         break;
896                 }
897         } else {
898                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
899                          "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
900         }
901
902         return value;
903 }
904
905 static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
906 {
907         struct rtl_priv *rtlpriv = rtl_priv(hw);
908         struct rtl_phy *rtlphy = &rtlpriv->phy;
909         u16 rawValue = 0;
910         u8 base = 0, path = 0;
911
912         for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
913                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
914                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
915                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
916
917                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
918                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
919                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
920
921                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
922                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
923                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
924
925                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
926                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
927                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
928
929                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
930                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
931                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
932
933                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
934                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
935                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
936
937                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
938                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
939                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
940
941                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
942                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
943                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
944
945                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
946                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
947                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
948
949                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
950                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
951                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
952
953                 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
954                 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
955                 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
956         }
957 }
958
959 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
960                                                 u8 end, u8 base_val)
961 {
962         char i = 0;
963         u8 temp_value = 0;
964         u32 temp_data = 0;
965
966         for (i = 3; i >= 0; --i) {
967                 if (i >= start && i <= end) {
968                         /* Get the exact value */
969                         temp_value = (u8)(*data >> (i * 8)) & 0xF;
970                         temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
971
972                         /* Change the value to a relative value */
973                         temp_value = (temp_value > base_val) ? temp_value -
974                                         base_val : base_val - temp_value;
975                 } else {
976                         temp_value = (u8)(*data >> (i * 8)) & 0xFF;
977                 }
978                 temp_data <<= 8;
979                 temp_data |= temp_value;
980         }
981         *data = temp_data;
982 }
983
984 static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
985 {
986         struct rtl_priv *rtlpriv = rtl_priv(hw);
987         struct rtl_phy *rtlphy = &rtlpriv->phy;
988         u8 regulation, bw, channel, rate_section;
989         char temp_pwrlmt = 0;
990
991         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
992                 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
993                         for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
994                                 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
995                                         temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
996                                                 [bw][rate_section][channel][RF90_PATH_A];
997                                         if (temp_pwrlmt == MAX_POWER_INDEX) {
998                                                 if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
999                                                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1000                                                                 "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1001                                                                 1, bw, rate_section, channel, RF90_PATH_A);
1002                                                         if (rate_section == 2) {
1003                                                                 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1004                                                                         rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1005                                                         } else if (rate_section == 4) {
1006                                                                 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1007                                                                         rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1008                                                         } else if (rate_section == 3) {
1009                                                                 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1010                                                                         rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1011                                                         } else if (rate_section == 5) {
1012                                                                 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1013                                                                         rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1014                                                         }
1015
1016                                                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d", temp_pwrlmt);
1017                                                 }
1018                                         }
1019                                 }
1020                         }
1021                 }
1022         }
1023 }
1024
1025 static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1026                                                    enum band_type band, u8 rate)
1027 {
1028         struct rtl_priv *rtlpriv = rtl_priv(hw);
1029         u8 index = 0;
1030         if (band == BAND_ON_2_4G) {
1031                 switch (rate) {
1032                 case MGN_1M:
1033                 case MGN_2M:
1034                 case MGN_5_5M:
1035                 case MGN_11M:
1036                         index = 0;
1037                         break;
1038
1039                 case MGN_6M:
1040                 case MGN_9M:
1041                 case MGN_12M:
1042                 case MGN_18M:
1043                 case MGN_24M:
1044                 case MGN_36M:
1045                 case MGN_48M:
1046                 case MGN_54M:
1047                         index = 1;
1048                         break;
1049
1050                 case MGN_MCS0:
1051                 case MGN_MCS1:
1052                 case MGN_MCS2:
1053                 case MGN_MCS3:
1054                 case MGN_MCS4:
1055                 case MGN_MCS5:
1056                 case MGN_MCS6:
1057                 case MGN_MCS7:
1058                         index = 2;
1059                         break;
1060
1061                 case MGN_MCS8:
1062                 case MGN_MCS9:
1063                 case MGN_MCS10:
1064                 case MGN_MCS11:
1065                 case MGN_MCS12:
1066                 case MGN_MCS13:
1067                 case MGN_MCS14:
1068                 case MGN_MCS15:
1069                         index = 3;
1070                         break;
1071
1072                 default:
1073                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1074                                 "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1075                                 rate);
1076                         break;
1077                 }
1078         } else if (band == BAND_ON_5G) {
1079                 switch (rate) {
1080                 case MGN_6M:
1081                 case MGN_9M:
1082                 case MGN_12M:
1083                 case MGN_18M:
1084                 case MGN_24M:
1085                 case MGN_36M:
1086                 case MGN_48M:
1087                 case MGN_54M:
1088                         index = 0;
1089                         break;
1090
1091                 case MGN_MCS0:
1092                 case MGN_MCS1:
1093                 case MGN_MCS2:
1094                 case MGN_MCS3:
1095                 case MGN_MCS4:
1096                 case MGN_MCS5:
1097                 case MGN_MCS6:
1098                 case MGN_MCS7:
1099                         index = 1;
1100                         break;
1101
1102                 case MGN_MCS8:
1103                 case MGN_MCS9:
1104                 case MGN_MCS10:
1105                 case MGN_MCS11:
1106                 case MGN_MCS12:
1107                 case MGN_MCS13:
1108                 case MGN_MCS14:
1109                 case MGN_MCS15:
1110                         index = 2;
1111                         break;
1112
1113                 case MGN_VHT1SS_MCS0:
1114                 case MGN_VHT1SS_MCS1:
1115                 case MGN_VHT1SS_MCS2:
1116                 case MGN_VHT1SS_MCS3:
1117                 case MGN_VHT1SS_MCS4:
1118                 case MGN_VHT1SS_MCS5:
1119                 case MGN_VHT1SS_MCS6:
1120                 case MGN_VHT1SS_MCS7:
1121                 case MGN_VHT1SS_MCS8:
1122                 case MGN_VHT1SS_MCS9:
1123                         index = 3;
1124                         break;
1125
1126                 case MGN_VHT2SS_MCS0:
1127                 case MGN_VHT2SS_MCS1:
1128                 case MGN_VHT2SS_MCS2:
1129                 case MGN_VHT2SS_MCS3:
1130                 case MGN_VHT2SS_MCS4:
1131                 case MGN_VHT2SS_MCS5:
1132                 case MGN_VHT2SS_MCS6:
1133                 case MGN_VHT2SS_MCS7:
1134                 case MGN_VHT2SS_MCS8:
1135                 case MGN_VHT2SS_MCS9:
1136                         index = 4;
1137                         break;
1138
1139                 default:
1140                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1141                                 "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1142                                 rate);
1143                         break;
1144                 }
1145         }
1146
1147         return index;
1148 }
1149
1150 static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1151 {
1152         struct rtl_priv *rtlpriv = rtl_priv(hw);
1153         struct rtl_phy *rtlphy = &rtlpriv->phy;
1154         u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1155         u8 regulation, bw, channel, rate_section;
1156         u8 base_index2_4G = 0;
1157         u8 base_index5G = 0;
1158         char temp_value = 0, temp_pwrlmt = 0;
1159         u8 rf_path = 0;
1160
1161         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1162                 "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1163
1164         _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1165
1166         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1167                 for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) {
1168                         for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1169                                 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1170                                         /* obtain the base dBm values in 2.4G band
1171                                          CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1172                                         if (rate_section == 0) { /*CCK*/
1173                                                 base_index2_4G =
1174                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1175                                                         BAND_ON_2_4G, MGN_11M);
1176                                         } else if (rate_section == 1) { /*OFDM*/
1177                                                 base_index2_4G =
1178                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1179                                                         BAND_ON_2_4G, MGN_54M);
1180                                         } else if (rate_section == 2) { /*HT IT*/
1181                                                 base_index2_4G =
1182                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1183                                                         BAND_ON_2_4G, MGN_MCS7);
1184                                         } else if (rate_section == 3) { /*HT 2T*/
1185                                                 base_index2_4G =
1186                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1187                                                         BAND_ON_2_4G, MGN_MCS15);
1188                                         }
1189
1190                                         temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1191                                                 [bw][rate_section][channel][RF90_PATH_A];
1192
1193                                         for (rf_path = RF90_PATH_A;
1194                                                 rf_path < MAX_RF_PATH_NUM;
1195                                                 ++rf_path) {
1196                                                 if (rate_section == 3)
1197                                                         bw40_pwr_base_dbm2_4G =
1198                                                         rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1199                                                 else
1200                                                         bw40_pwr_base_dbm2_4G =
1201                                                         rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1202
1203                                                 if (temp_pwrlmt != MAX_POWER_INDEX) {
1204                                                         temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1205                                                         rtlphy->txpwr_limit_2_4g[regulation]
1206                                                                 [bw][rate_section][channel][rf_path] =
1207                                                                 temp_value;
1208                                                 }
1209
1210                                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1211                                                         "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n",
1212                                                         regulation, bw, rate_section, channel,
1213                                                         rtlphy->txpwr_limit_2_4g[regulation][bw]
1214                                                         [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1215                                                         ? 0 : temp_pwrlmt/2, channel, rf_path,
1216                                                         bw40_pwr_base_dbm2_4G);
1217                                         }
1218                                 }
1219                         }
1220                 }
1221         }
1222         for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1223                 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
1224                         for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1225                                 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1226                                         /* obtain the base dBm values in 5G band
1227                                          OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1228                                         VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1229                                         if (rate_section == 1) { /*OFDM*/
1230                                                 base_index5G =
1231                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1232                                                         BAND_ON_5G, MGN_54M);
1233                                         } else if (rate_section == 2) { /*HT 1T*/
1234                                                 base_index5G =
1235                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1236                                                         BAND_ON_5G, MGN_MCS7);
1237                                         } else if (rate_section == 3) { /*HT 2T*/
1238                                                 base_index5G =
1239                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1240                                                         BAND_ON_5G, MGN_MCS15);
1241                                         } else if (rate_section == 4) { /*VHT 1T*/
1242                                                 base_index5G =
1243                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1244                                                         BAND_ON_5G, MGN_VHT1SS_MCS7);
1245                                         } else if (rate_section == 5) { /*VHT 2T*/
1246                                                 base_index5G =
1247                                                         _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1248                                                         BAND_ON_5G, MGN_VHT2SS_MCS7);
1249                                         }
1250
1251                                         temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1252                                                 [bw][rate_section][channel]
1253                                                 [RF90_PATH_A];
1254
1255                                         for (rf_path = RF90_PATH_A;
1256                                              rf_path < MAX_RF_PATH_NUM;
1257                                              ++rf_path) {
1258                                                 if (rate_section == 3 || rate_section == 5)
1259                                                         bw40_pwr_base_dbm5G =
1260                                                         rtlphy->txpwr_by_rate_base_5g[rf_path]
1261                                                         [RF_2TX][base_index5G];
1262                                                 else
1263                                                         bw40_pwr_base_dbm5G =
1264                                                         rtlphy->txpwr_by_rate_base_5g[rf_path]
1265                                                         [RF_1TX][base_index5G];
1266
1267                                                 if (temp_pwrlmt != MAX_POWER_INDEX) {
1268                                                         temp_value =
1269                                                                 temp_pwrlmt - bw40_pwr_base_dbm5G;
1270                                                         rtlphy->txpwr_limit_5g[regulation]
1271                                                                 [bw][rate_section][channel]
1272                                                                 [rf_path] = temp_value;
1273                                                 }
1274
1275                                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1276                                                         "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
1277                                                         regulation, bw, rate_section,
1278                                                         channel, rtlphy->txpwr_limit_5g[regulation]
1279                                                         [bw][rate_section][channel][rf_path],
1280                                                         temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1281                                         }
1282                                 }
1283                         }
1284                 }
1285         }
1286         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1287                  "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1288 }
1289
1290 static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1291 {
1292         struct rtl_priv *rtlpriv = rtl_priv(hw);
1293         struct rtl_phy *rtlphy = &rtlpriv->phy;
1294         u8 i, j, k, l, m;
1295
1296         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1297                  "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1298
1299         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1300                 for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j)
1301                         for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1302                                 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1303                                         for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1304                                                 rtlphy->txpwr_limit_2_4g
1305                                                                 [i][j][k][m][l]
1306                                                         = MAX_POWER_INDEX;
1307         }
1308         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1309                 for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j)
1310                         for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1311                                 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1312                                         for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1313                                                 rtlphy->txpwr_limit_5g
1314                                                                 [i][j][k][m][l]
1315                                                         = MAX_POWER_INDEX;
1316         }
1317
1318         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1319                  "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1320 }
1321
1322 static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1323 {
1324         struct rtl_priv *rtlpriv = rtl_priv(hw);
1325         struct rtl_phy *rtlphy = &rtlpriv->phy;
1326         u8 base = 0, rfPath = 0;
1327
1328         for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
1329                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1330                 _phy_convert_txpower_dbm_to_relative_value(
1331                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0],
1332                         0, 3, base);
1333
1334                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1335                 _phy_convert_txpower_dbm_to_relative_value(
1336                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1],
1337                         0, 3, base);
1338                 _phy_convert_txpower_dbm_to_relative_value(
1339                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2],
1340                         0, 3, base);
1341
1342                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1343                 _phy_convert_txpower_dbm_to_relative_value(
1344                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3],
1345                         0, 3, base);
1346                 _phy_convert_txpower_dbm_to_relative_value(
1347                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4],
1348                         0, 3, base);
1349
1350                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1351
1352                 _phy_convert_txpower_dbm_to_relative_value(
1353                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5],
1354                         0, 3, base);
1355
1356                 _phy_convert_txpower_dbm_to_relative_value(
1357                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6],
1358                         0, 3, base);
1359
1360                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1361                 _phy_convert_txpower_dbm_to_relative_value(
1362                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7],
1363                         0, 3, base);
1364                 _phy_convert_txpower_dbm_to_relative_value(
1365                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8],
1366                         0, 3, base);
1367                 _phy_convert_txpower_dbm_to_relative_value(
1368                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1369                         0, 1, base);
1370
1371                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1372                 _phy_convert_txpower_dbm_to_relative_value(
1373                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1374                         2, 3, base);
1375                 _phy_convert_txpower_dbm_to_relative_value(
1376                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10],
1377                         0, 3, base);
1378                 _phy_convert_txpower_dbm_to_relative_value(
1379                         &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11],
1380                         0, 3, base);
1381
1382                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM);
1383                 _phy_convert_txpower_dbm_to_relative_value(
1384                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1],
1385                         0, 3, base);
1386                 _phy_convert_txpower_dbm_to_relative_value(
1387                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2],
1388                         0, 3, base);
1389
1390                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7);
1391                 _phy_convert_txpower_dbm_to_relative_value(
1392                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3],
1393                         0, 3, base);
1394                 _phy_convert_txpower_dbm_to_relative_value(
1395                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4],
1396                         0, 3, base);
1397
1398                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15);
1399                 _phy_convert_txpower_dbm_to_relative_value(
1400                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5],
1401                         0, 3, base);
1402                 _phy_convert_txpower_dbm_to_relative_value(
1403                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6],
1404                         0, 3, base);
1405
1406                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1407                 _phy_convert_txpower_dbm_to_relative_value(
1408                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7],
1409                         0, 3, base);
1410                 _phy_convert_txpower_dbm_to_relative_value(
1411                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8],
1412                         0, 3, base);
1413                 _phy_convert_txpower_dbm_to_relative_value(
1414                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1415                         0, 1, base);
1416
1417                 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1418                 _phy_convert_txpower_dbm_to_relative_value(
1419                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1420                         2, 3, base);
1421                 _phy_convert_txpower_dbm_to_relative_value(
1422                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10],
1423                         0, 3, base);
1424                 _phy_convert_txpower_dbm_to_relative_value(
1425                         &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11],
1426                         0, 3, base);
1427         }
1428
1429         RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1430                 "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1431 }
1432
1433 static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1434 {
1435         _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1436         _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1437 }
1438
1439 /* string is in decimal */
1440 static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
1441 {
1442         u16 i = 0;
1443         *pint = 0;
1444
1445         while (str[i] != '\0') {
1446                 if (str[i] >= '0' && str[i] <= '9') {
1447                         *pint *= 10;
1448                         *pint += (str[i] - '0');
1449                 } else {
1450                         return false;
1451                 }
1452                 ++i;
1453         }
1454
1455         return true;
1456 }
1457
1458 static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
1459 {
1460         if (num == 0)
1461                 return false;
1462         while (num > 0) {
1463                 num--;
1464                 if (str1[num] != str2[num])
1465                         return false;
1466         }
1467         return true;
1468 }
1469
1470 static char _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1471                                               u8 band, u8 channel)
1472 {
1473         struct rtl_priv *rtlpriv = rtl_priv(hw);
1474         char channel_index = -1;
1475         u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
1476                 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
1477                 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
1478                 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149,
1479                 151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171,
1480                 173, 175, 177};
1481         u8  i = 0;
1482         if (band == BAND_ON_2_4G)
1483                 channel_index = channel - 1;
1484         else if (band == BAND_ON_5G) {
1485                 for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) {
1486                         if (channel_5g[i] == channel)
1487                                 channel_index = i;
1488                 }
1489         } else
1490                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
1491                          band,  __func__);
1492
1493         if (channel_index == -1)
1494                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1495                          "Invalid Channel %d of Band %d in %s", channel,
1496                          band, __func__);
1497
1498         return channel_index;
1499 }
1500
1501 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1502                                       u8 *pband, u8 *pbandwidth,
1503                                       u8 *prate_section, u8 *prf_path,
1504                                       u8 *pchannel, u8 *ppower_limit)
1505 {
1506         struct rtl_priv *rtlpriv = rtl_priv(hw);
1507         struct rtl_phy *rtlphy = &rtlpriv->phy;
1508         u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1509         u8 channel_index;
1510         char power_limit = 0, prev_power_limit, ret;
1511
1512         if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1513             !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1514                                                 &power_limit)) {
1515                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1516                          "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1517                           channel, power_limit);
1518         }
1519
1520         power_limit = power_limit > MAX_POWER_INDEX ?
1521                       MAX_POWER_INDEX : power_limit;
1522
1523         if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1524                 regulation = 0;
1525         else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1526                 regulation = 1;
1527         else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1528                 regulation = 2;
1529         else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1530                 regulation = 3;
1531
1532         if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1533                 rate_section = 0;
1534         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1535                 rate_section = 1;
1536         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1537                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1538                 rate_section = 2;
1539         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1540                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1541                 rate_section = 3;
1542         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1543                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1544                 rate_section = 4;
1545         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1546                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1547                 rate_section = 5;
1548
1549         if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1550                 bandwidth = 0;
1551         else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1552                 bandwidth = 1;
1553         else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1554                 bandwidth = 2;
1555         else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1556                 bandwidth = 3;
1557
1558         if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1559                 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1560                                                                BAND_ON_2_4G,
1561                                                                channel);
1562
1563                 if (ret == -1)
1564                         return;
1565
1566                 channel_index = ret;
1567
1568                 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1569                                                 [bandwidth][rate_section]
1570                                                 [channel_index][RF90_PATH_A];
1571
1572                 if (power_limit < prev_power_limit)
1573                         rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1574                                 [rate_section][channel_index][RF90_PATH_A] =
1575                                                                    power_limit;
1576
1577                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1578                          "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1579                           regulation, bandwidth, rate_section, channel_index,
1580                           rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1581                                 [rate_section][channel_index][RF90_PATH_A]);
1582         } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1583                 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1584                                                                BAND_ON_5G,
1585                                                                channel);
1586
1587                 if (ret == -1)
1588                         return;
1589
1590                 channel_index = ret;
1591
1592                 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1593                                                 [rate_section][channel_index]
1594                                                 [RF90_PATH_A];
1595
1596                 if (power_limit < prev_power_limit)
1597                         rtlphy->txpwr_limit_5g[regulation][bandwidth]
1598                         [rate_section][channel_index][RF90_PATH_A] = power_limit;
1599
1600                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1601                          "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1602                           regulation, bandwidth, rate_section, channel,
1603                           rtlphy->txpwr_limit_5g[regulation][bandwidth]
1604                                 [rate_section][channel_index][RF90_PATH_A]);
1605         } else {
1606                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1607                          "Cannot recognize the band info in %s\n", pband);
1608                 return;
1609         }
1610 }
1611
1612 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1613                                           u8 *regulation, u8 *band,
1614                                           u8 *bandwidth, u8 *rate_section,
1615                                           u8 *rf_path, u8 *channel,
1616                                           u8 *power_limit)
1617 {
1618         _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1619                                          rate_section, rf_path, channel,
1620                                          power_limit);
1621 }
1622
1623 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1624 {
1625         struct rtl_priv *rtlpriv = rtl_priv(hw);
1626         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1627         u32 i = 0;
1628         u32 array_len;
1629         u8 **array;
1630
1631         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1632                 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1633                 array = RTL8812AE_TXPWR_LMT;
1634         } else {
1635                 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1636                 array = RTL8821AE_TXPWR_LMT;
1637         }
1638
1639         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1640                  "\n");
1641
1642         for (i = 0; i < array_len; i += 7) {
1643                 u8 *regulation = array[i];
1644                 u8 *band = array[i+1];
1645                 u8 *bandwidth = array[i+2];
1646                 u8 *rate = array[i+3];
1647                 u8 *rf_path = array[i+4];
1648                 u8 *chnl = array[i+5];
1649                 u8 *val = array[i+6];
1650
1651                 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1652                                                    bandwidth, rate, rf_path,
1653                                                    chnl, val);
1654         }
1655 }
1656
1657 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1658 {
1659         struct rtl_priv *rtlpriv = rtl_priv(hw);
1660         struct rtl_phy *rtlphy = &rtlpriv->phy;
1661         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1662         bool rtstatus;
1663
1664         _rtl8821ae_phy_init_txpower_limit(hw);
1665
1666         /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1667         if (rtlefuse->eeprom_regulatory != 2)
1668                 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1669
1670         rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1671                                                        BASEBAND_CONFIG_PHY_REG);
1672         if (rtstatus != true) {
1673                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
1674                 return false;
1675         }
1676         _rtl8821ae_phy_init_tx_power_by_rate(hw);
1677         if (rtlefuse->autoload_failflag == false) {
1678                 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1679                                                     BASEBAND_CONFIG_PHY_REG);
1680         }
1681         if (rtstatus != true) {
1682                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
1683                 return false;
1684         }
1685
1686         _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1687
1688         /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1689         if (rtlefuse->eeprom_regulatory != 2)
1690                 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1691
1692         rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1693                                                 BASEBAND_CONFIG_AGC_TAB);
1694
1695         if (rtstatus != true) {
1696                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1697                 return false;
1698         }
1699         rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1700                         RFPGA0_XA_HSSIPARAMETER2, 0x200));
1701         return true;
1702 }
1703
1704 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1705 {
1706         struct rtl_priv *rtlpriv = rtl_priv(hw);
1707         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1708         u32 i, v1, v2;
1709         u32 arraylength;
1710         u32 *ptrarray;
1711
1712         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1713         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1714                 arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1715                 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1716         } else {
1717                 arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1718                 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1719         }
1720         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1721                  "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1722         for (i = 0; i < arraylength; i += 2) {
1723                 v1 = ptrarray[i];
1724                 v2 = (u8)ptrarray[i + 1];
1725                 if (v1 < 0xCDCDCDCD) {
1726                         rtl_write_byte(rtlpriv, v1, (u8)v2);
1727                         continue;
1728                 } else {
1729                         if (!_rtl8821ae_check_condition(hw, v1)) {
1730                                 /*Discard the following (offset, data) pairs*/
1731                                 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1732                                 while (v2 != 0xDEAD &&
1733                                        v2 != 0xCDEF &&
1734                                        v2 != 0xCDCD && i < arraylength - 2) {
1735                                         READ_NEXT_PAIR(ptrarray, v1, v2, i);
1736                                 }
1737                                 i -= 2; /* prevent from for-loop += 2*/
1738                         } else {/*Configure matched pairs and skip to end of if-else.*/
1739                                 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1740                                 while (v2 != 0xDEAD &&
1741                                        v2 != 0xCDEF &&
1742                                        v2 != 0xCDCD && i < arraylength - 2) {
1743                                         rtl_write_byte(rtlpriv, v1, v2);
1744                                         READ_NEXT_PAIR(ptrarray, v1, v2, i);
1745                                 }
1746
1747                                 while (v2 != 0xDEAD && i < arraylength - 2)
1748                                         READ_NEXT_PAIR(ptrarray, v1, v2, i);
1749                         }
1750                 }
1751         }
1752         return true;
1753 }
1754
1755 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1756                                                      u8 configtype)
1757 {
1758         struct rtl_priv *rtlpriv = rtl_priv(hw);
1759         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1760         int i;
1761         u32 *array_table;
1762         u16 arraylen;
1763         u32 v1 = 0, v2 = 0;
1764
1765         if (configtype == BASEBAND_CONFIG_PHY_REG) {
1766                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1767                         arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1768                         array_table = RTL8812AE_PHY_REG_ARRAY;
1769                 } else {
1770                         arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1771                         array_table = RTL8821AE_PHY_REG_ARRAY;
1772                 }
1773
1774                 for (i = 0; i < arraylen; i += 2) {
1775                         v1 = array_table[i];
1776                         v2 = array_table[i + 1];
1777                         if (v1 < 0xCDCDCDCD) {
1778                                 _rtl8821ae_config_bb_reg(hw, v1, v2);
1779                                 continue;
1780                         } else {/*This line is the start line of branch.*/
1781                                 if (!_rtl8821ae_check_condition(hw, v1)) {
1782                                         /*Discard the following (offset, data) pairs*/
1783                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1784                                         while (v2 != 0xDEAD &&
1785                                                v2 != 0xCDEF &&
1786                                                v2 != 0xCDCD &&
1787                                                i < arraylen - 2) {
1788                                                 READ_NEXT_PAIR(array_table, v1,
1789                                                                 v2, i);
1790                                         }
1791
1792                                         i -= 2; /* prevent from for-loop += 2*/
1793                                 } else {/*Configure matched pairs and skip to end of if-else.*/
1794                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1795                                         while (v2 != 0xDEAD &&
1796                                                v2 != 0xCDEF &&
1797                                                v2 != 0xCDCD &&
1798                                                i < arraylen - 2) {
1799                                                 _rtl8821ae_config_bb_reg(hw, v1,
1800                                                                          v2);
1801                                                 READ_NEXT_PAIR(array_table, v1,
1802                                                                v2, i);
1803                                         }
1804
1805                                         while (v2 != 0xDEAD &&
1806                                                i < arraylen - 2) {
1807                                                 READ_NEXT_PAIR(array_table, v1,
1808                                                                v2, i);
1809                                         }
1810                                 }
1811                         }
1812                 }
1813         } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1814                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1815                         arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1816                         array_table = RTL8812AE_AGC_TAB_ARRAY;
1817                 } else {
1818                         arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1819                         array_table = RTL8821AE_AGC_TAB_ARRAY;
1820                 }
1821
1822                 for (i = 0; i < arraylen; i = i + 2) {
1823                         v1 = array_table[i];
1824                         v2 = array_table[i+1];
1825                         if (v1 < 0xCDCDCDCD) {
1826                                 rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1827                                 udelay(1);
1828                                 continue;
1829                         } else {/*This line is the start line of branch.*/
1830                                 if (!_rtl8821ae_check_condition(hw, v1)) {
1831                                         /*Discard the following (offset, data) pairs*/
1832                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1833                                         while (v2 != 0xDEAD &&
1834                                                v2 != 0xCDEF &&
1835                                                v2 != 0xCDCD &&
1836                                                i < arraylen - 2) {
1837                                                 READ_NEXT_PAIR(array_table, v1,
1838                                                                 v2, i);
1839                                         }
1840                                         i -= 2; /* prevent from for-loop += 2*/
1841                                 } else {/*Configure matched pairs and skip to end of if-else.*/
1842                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1843                                         while (v2 != 0xDEAD &&
1844                                                v2 != 0xCDEF &&
1845                                                v2 != 0xCDCD &&
1846                                                i < arraylen - 2) {
1847                                                 rtl_set_bbreg(hw, v1, MASKDWORD,
1848                                                               v2);
1849                                                 udelay(1);
1850                                                 READ_NEXT_PAIR(array_table, v1,
1851                                                                v2, i);
1852                                         }
1853
1854                                         while (v2 != 0xDEAD &&
1855                                                 i < arraylen - 2) {
1856                                                 READ_NEXT_PAIR(array_table, v1,
1857                                                                 v2, i);
1858                                         }
1859                                 }
1860                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1861                                          "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1862                                           array_table[i],  array_table[i + 1]);
1863                         }
1864                 }
1865         }
1866         return true;
1867 }
1868
1869 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1870 {
1871         u8 index = 0;
1872         regaddr &= 0xFFF;
1873         if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1874                 index = (u8)((regaddr - 0xC20) / 4);
1875         else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1876                 index = (u8)((regaddr - 0xE20) / 4);
1877         else
1878                 RT_ASSERT(!COMP_INIT,
1879                           "Invalid RegAddr 0x%x\n", regaddr);
1880         return index;
1881 }
1882
1883 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1884                                               u32 band, u32 rfpath,
1885                                               u32 txnum, u32 regaddr,
1886                                               u32 bitmask, u32 data)
1887 {
1888         struct rtl_priv *rtlpriv = rtl_priv(hw);
1889         struct rtl_phy *rtlphy = &rtlpriv->phy;
1890         u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1891
1892         if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1893                 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1894                 band = BAND_ON_2_4G;
1895         }
1896         if (rfpath >= MAX_RF_PATH) {
1897                 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1898                 rfpath = MAX_RF_PATH - 1;
1899         }
1900         if (txnum >= MAX_RF_PATH) {
1901                 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1902                 txnum = MAX_RF_PATH - 1;
1903         }
1904         rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1905         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1906                  "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1907                  band, rfpath, txnum, rate_section,
1908                  rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1909 }
1910
1911 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
1912                                                         u8 configtype)
1913 {
1914         struct rtl_priv *rtlpriv = rtl_priv(hw);
1915         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1916         int i;
1917         u32 *array;
1918         u16 arraylen;
1919         u32 v1, v2, v3, v4, v5, v6;
1920
1921         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1922                 arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
1923                 array = RTL8812AE_PHY_REG_ARRAY_PG;
1924         } else {
1925                 arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
1926                 array = RTL8821AE_PHY_REG_ARRAY_PG;
1927         }
1928
1929         if (configtype != BASEBAND_CONFIG_PHY_REG) {
1930                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
1931                          "configtype != BaseBand_Config_PHY_REG\n");
1932                 return true;
1933         }
1934         for (i = 0; i < arraylen; i += 6) {
1935                 v1 = array[i];
1936                 v2 = array[i+1];
1937                 v3 = array[i+2];
1938                 v4 = array[i+3];
1939                 v5 = array[i+4];
1940                 v6 = array[i+5];
1941
1942                 if (v1 < 0xCDCDCDCD) {
1943                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
1944                                 (v4 == 0xfe || v4 == 0xffe)) {
1945                                 msleep(50);
1946                                 continue;
1947                         }
1948
1949                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1950                                 if (v4 == 0xfe)
1951                                         msleep(50);
1952                                 else if (v4 == 0xfd)
1953                                         mdelay(5);
1954                                 else if (v4 == 0xfc)
1955                                         mdelay(1);
1956                                 else if (v4 == 0xfb)
1957                                         udelay(50);
1958                                 else if (v4 == 0xfa)
1959                                         udelay(5);
1960                                 else if (v4 == 0xf9)
1961                                         udelay(1);
1962                         }
1963                         _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
1964                                                           v4, v5, v6);
1965                         continue;
1966                 } else {
1967                          /*don't need the hw_body*/
1968                         if (!_rtl8821ae_check_condition(hw, v1)) {
1969                                 i += 2; /* skip the pair of expression*/
1970                                 v1 = array[i];
1971                                 v2 = array[i+1];
1972                                 v3 = array[i+2];
1973                                 while (v2 != 0xDEAD) {
1974                                         i += 3;
1975                                         v1 = array[i];
1976                                         v2 = array[i+1];
1977                                         v3 = array[i+2];
1978                                 }
1979                         }
1980                 }
1981         }
1982
1983         return true;
1984 }
1985
1986 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
1987                                              enum radio_path rfpath)
1988 {
1989         int i;
1990         bool rtstatus = true;
1991         u32 *radioa_array_table_a, *radioa_array_table_b;
1992         u16 radioa_arraylen_a, radioa_arraylen_b;
1993         struct rtl_priv *rtlpriv = rtl_priv(hw);
1994         u32 v1 = 0, v2 = 0;
1995
1996         radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
1997         radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
1998         radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
1999         radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2000         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2001                  "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2002         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2003         rtstatus = true;
2004         switch (rfpath) {
2005         case RF90_PATH_A:
2006                 for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2007                         v1 = radioa_array_table_a[i];
2008                         v2 = radioa_array_table_a[i+1];
2009                         if (v1 < 0xcdcdcdcd) {
2010                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2011                                 continue;
2012                         } else{/*This line is the start line of branch.*/
2013                                 if (!_rtl8821ae_check_condition(hw, v1)) {
2014                                         /*Discard the following (offset, data) pairs*/
2015                                         READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2016                                         while (v2 != 0xDEAD &&
2017                                                v2 != 0xCDEF &&
2018                                                v2 != 0xCDCD && i < radioa_arraylen_a-2)
2019                                                 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2020
2021                                         i -= 2; /* prevent from for-loop += 2*/
2022                                 } else {/*Configure matched pairs and skip to end of if-else.*/
2023                                         READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2024                                         while (v2 != 0xDEAD &&
2025                                                v2 != 0xCDEF &&
2026                                                v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2027                                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2028                                                 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2029                                         }
2030
2031                                         while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2032                                                 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2033
2034                                 }
2035                         }
2036                 }
2037                 break;
2038         case RF90_PATH_B:
2039                 for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2040                         v1 = radioa_array_table_b[i];
2041                         v2 = radioa_array_table_b[i+1];
2042                         if (v1 < 0xcdcdcdcd) {
2043                                 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2044                                 continue;
2045                         } else{/*This line is the start line of branch.*/
2046                                 if (!_rtl8821ae_check_condition(hw, v1)) {
2047                                         /*Discard the following (offset, data) pairs*/
2048                                         READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2049                                         while (v2 != 0xDEAD &&
2050                                                v2 != 0xCDEF &&
2051                                                v2 != 0xCDCD && i < radioa_arraylen_b-2)
2052                                                 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2053
2054                                         i -= 2; /* prevent from for-loop += 2*/
2055                                 } else {/*Configure matched pairs and skip to end of if-else.*/
2056                                         READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2057                                         while (v2 != 0xDEAD &&
2058                                                v2 != 0xCDEF &&
2059                                                v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2060                                                 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2061                                                 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2062                                         }
2063
2064                                         while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2065                                                 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2066                                 }
2067                         }
2068                 }
2069                 break;
2070         case RF90_PATH_C:
2071                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2072                          "switch case not process\n");
2073                 break;
2074         case RF90_PATH_D:
2075                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2076                          "switch case not process\n");
2077                 break;
2078         }
2079         return true;
2080 }
2081
2082 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2083                                                 enum radio_path rfpath)
2084 {
2085         #define READ_NEXT_RF_PAIR(v1, v2, i) \
2086         do { \
2087                 i += 2; \
2088                 v1 = radioa_array_table[i]; \
2089                 v2 = radioa_array_table[i+1]; \
2090         } \
2091         while (0)
2092
2093         int i;
2094         bool rtstatus = true;
2095         u32 *radioa_array_table;
2096         u16 radioa_arraylen;
2097         struct rtl_priv *rtlpriv = rtl_priv(hw);
2098         /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2099         u32 v1 = 0, v2 = 0;
2100
2101         radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2102         radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2103         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2104                  "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2105         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2106         rtstatus = true;
2107         switch (rfpath) {
2108         case RF90_PATH_A:
2109                 for (i = 0; i < radioa_arraylen; i = i + 2) {
2110                         v1 = radioa_array_table[i];
2111                         v2 = radioa_array_table[i+1];
2112                         if (v1 < 0xcdcdcdcd)
2113                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2114                         else{/*This line is the start line of branch.*/
2115                                 if (!_rtl8821ae_check_condition(hw, v1)) {
2116                                         /*Discard the following (offset, data) pairs*/
2117                                         READ_NEXT_RF_PAIR(v1, v2, i);
2118                                         while (v2 != 0xDEAD &&
2119                                                 v2 != 0xCDEF &&
2120                                                 v2 != 0xCDCD && i < radioa_arraylen - 2)
2121                                                 READ_NEXT_RF_PAIR(v1, v2, i);
2122
2123                                         i -= 2; /* prevent from for-loop += 2*/
2124                                 } else {/*Configure matched pairs and skip to end of if-else.*/
2125                                         READ_NEXT_RF_PAIR(v1, v2, i);
2126                                         while (v2 != 0xDEAD &&
2127                                                v2 != 0xCDEF &&
2128                                                v2 != 0xCDCD && i < radioa_arraylen - 2) {
2129                                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2130                                                 READ_NEXT_RF_PAIR(v1, v2, i);
2131                                         }
2132
2133                                         while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2134                                                 READ_NEXT_RF_PAIR(v1, v2, i);
2135                                 }
2136                         }
2137                 }
2138                 break;
2139
2140         case RF90_PATH_B:
2141                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2142                          "switch case not process\n");
2143                 break;
2144         case RF90_PATH_C:
2145                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2146                          "switch case not process\n");
2147                 break;
2148         case RF90_PATH_D:
2149                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2150                          "switch case not process\n");
2151                 break;
2152         }
2153         return true;
2154 }
2155
2156 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2157 {
2158         struct rtl_priv *rtlpriv = rtl_priv(hw);
2159         struct rtl_phy *rtlphy = &rtlpriv->phy;
2160
2161         rtlphy->default_initialgain[0] =
2162             (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2163         rtlphy->default_initialgain[1] =
2164             (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2165         rtlphy->default_initialgain[2] =
2166             (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2167         rtlphy->default_initialgain[3] =
2168             (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2169
2170         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2171                  "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2172                   rtlphy->default_initialgain[0],
2173                   rtlphy->default_initialgain[1],
2174                   rtlphy->default_initialgain[2],
2175                   rtlphy->default_initialgain[3]);
2176
2177         rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2178                                                ROFDM0_RXDETECTOR3, MASKBYTE0);
2179         rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2180                                               ROFDM0_RXDETECTOR2, MASKDWORD);
2181
2182         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2183                  "Default framesync (0x%x) = 0x%x\n",
2184                   ROFDM0_RXDETECTOR3, rtlphy->framesync);
2185 }
2186
2187 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2188 {
2189         struct rtl_priv *rtlpriv = rtl_priv(hw);
2190         struct rtl_phy *rtlphy = &rtlpriv->phy;
2191
2192         rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2193         rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2194
2195         rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2196         rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2197
2198         rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2199         rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2200
2201         rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2202         rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2203
2204         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2205         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2206
2207         rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2208         rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2209
2210         rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2211         rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2212 }
2213
2214 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2215 {
2216         struct rtl_priv *rtlpriv = rtl_priv(hw);
2217         struct rtl_phy *rtlphy = &rtlpriv->phy;
2218         u8 txpwr_level;
2219         long txpwr_dbm;
2220
2221         txpwr_level = rtlphy->cur_cck_txpwridx;
2222         txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2223                                                  WIRELESS_MODE_B, txpwr_level);
2224         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2225         if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2226                                          WIRELESS_MODE_G,
2227                                          txpwr_level) > txpwr_dbm)
2228                 txpwr_dbm =
2229                     _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2230                                                  txpwr_level);
2231         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2232         if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2233                                          WIRELESS_MODE_N_24G,
2234                                          txpwr_level) > txpwr_dbm)
2235                 txpwr_dbm =
2236                     _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2237                                                  txpwr_level);
2238         *powerlevel = txpwr_dbm;
2239 }
2240
2241 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2242 {
2243         u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
2244                 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
2245                 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
2246                 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140,
2247                 142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165,
2248                 167, 168, 169, 171, 173, 175, 177
2249         };
2250         u8 i = 0;
2251         bool in_24g = true;
2252
2253         if (channel <= 14) {
2254                 in_24g = true;
2255                 *chnl_index = channel - 1;
2256         } else {
2257                 in_24g = false;
2258
2259                 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2260                         if (channel_5g[i] == channel) {
2261                                 *chnl_index = i;
2262                                 return in_24g;
2263                         }
2264                 }
2265         }
2266         return in_24g;
2267 }
2268
2269 static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2270 {
2271         char rate_section = 0;
2272         switch (rate) {
2273         case DESC_RATE1M:
2274         case DESC_RATE2M:
2275         case DESC_RATE5_5M:
2276         case DESC_RATE11M:
2277                 rate_section = 0;
2278                 break;
2279         case DESC_RATE6M:
2280         case DESC_RATE9M:
2281         case DESC_RATE12M:
2282         case DESC_RATE18M:
2283                 rate_section = 1;
2284                 break;
2285         case DESC_RATE24M:
2286         case DESC_RATE36M:
2287         case DESC_RATE48M:
2288         case DESC_RATE54M:
2289                 rate_section = 2;
2290                 break;
2291         case DESC_RATEMCS0:
2292         case DESC_RATEMCS1:
2293         case DESC_RATEMCS2:
2294         case DESC_RATEMCS3:
2295                 rate_section = 3;
2296                 break;
2297         case DESC_RATEMCS4:
2298         case DESC_RATEMCS5:
2299         case DESC_RATEMCS6:
2300         case DESC_RATEMCS7:
2301                 rate_section = 4;
2302                 break;
2303         case DESC_RATEMCS8:
2304         case DESC_RATEMCS9:
2305         case DESC_RATEMCS10:
2306         case DESC_RATEMCS11:
2307                 rate_section = 5;
2308                 break;
2309         case DESC_RATEMCS12:
2310         case DESC_RATEMCS13:
2311         case DESC_RATEMCS14:
2312         case DESC_RATEMCS15:
2313                 rate_section = 6;
2314                 break;
2315         case DESC_RATEVHT1SS_MCS0:
2316         case DESC_RATEVHT1SS_MCS1:
2317         case DESC_RATEVHT1SS_MCS2:
2318         case DESC_RATEVHT1SS_MCS3:
2319                 rate_section = 7;
2320                 break;
2321         case DESC_RATEVHT1SS_MCS4:
2322         case DESC_RATEVHT1SS_MCS5:
2323         case DESC_RATEVHT1SS_MCS6:
2324         case DESC_RATEVHT1SS_MCS7:
2325                 rate_section = 8;
2326                 break;
2327         case DESC_RATEVHT1SS_MCS8:
2328         case DESC_RATEVHT1SS_MCS9:
2329         case DESC_RATEVHT2SS_MCS0:
2330         case DESC_RATEVHT2SS_MCS1:
2331                 rate_section = 9;
2332                 break;
2333         case DESC_RATEVHT2SS_MCS2:
2334         case DESC_RATEVHT2SS_MCS3:
2335         case DESC_RATEVHT2SS_MCS4:
2336         case DESC_RATEVHT2SS_MCS5:
2337                 rate_section = 10;
2338                 break;
2339         case DESC_RATEVHT2SS_MCS6:
2340         case DESC_RATEVHT2SS_MCS7:
2341         case DESC_RATEVHT2SS_MCS8:
2342         case DESC_RATEVHT2SS_MCS9:
2343                 rate_section = 11;
2344                 break;
2345         default:
2346                 RT_ASSERT(true, "Rate_Section is Illegal\n");
2347                 break;
2348         }
2349
2350         return rate_section;
2351 }
2352
2353 static char _rtl8812ae_phy_get_world_wide_limit(char  *limit_table)
2354 {
2355         char min = limit_table[0];
2356         u8 i = 0;
2357
2358         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2359                 if (limit_table[i] < min)
2360                         min = limit_table[i];
2361         }
2362         return min;
2363 }
2364
2365 static char _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2366                                              u8 band,
2367                                              enum ht_channel_width bandwidth,
2368                                              enum radio_path rf_path,
2369                                              u8 rate, u8 channel)
2370 {
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         char power_limit = MAX_POWER_INDEX;
2378
2379         if (rtlefuse->eeprom_regulatory == 2)
2380                 return MAX_POWER_INDEX;
2381
2382         regulation = TXPWR_LMT_WW;
2383
2384         if (band == BAND_ON_2_4G)
2385                 band_temp = 0;
2386         else if (band == BAND_ON_5G)
2387                 band_temp = 1;
2388
2389         if (bandwidth == HT_CHANNEL_WIDTH_20)
2390                 bandwidth_temp = 0;
2391         else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2392                 bandwidth_temp = 1;
2393         else if (bandwidth == HT_CHANNEL_WIDTH_80)
2394                 bandwidth_temp = 2;
2395
2396         switch (rate) {
2397         case DESC_RATE1M:
2398         case DESC_RATE2M:
2399         case DESC_RATE5_5M:
2400         case DESC_RATE11M:
2401                 rate_section = 0;
2402                 break;
2403         case DESC_RATE6M:
2404         case DESC_RATE9M:
2405         case DESC_RATE12M:
2406         case DESC_RATE18M:
2407         case DESC_RATE24M:
2408         case DESC_RATE36M:
2409         case DESC_RATE48M:
2410         case DESC_RATE54M:
2411                 rate_section = 1;
2412                 break;
2413         case DESC_RATEMCS0:
2414         case DESC_RATEMCS1:
2415         case DESC_RATEMCS2:
2416         case DESC_RATEMCS3:
2417         case DESC_RATEMCS4:
2418         case DESC_RATEMCS5:
2419         case DESC_RATEMCS6:
2420         case DESC_RATEMCS7:
2421                 rate_section = 2;
2422                 break;
2423         case DESC_RATEMCS8:
2424         case DESC_RATEMCS9:
2425         case DESC_RATEMCS10:
2426         case DESC_RATEMCS11:
2427         case DESC_RATEMCS12:
2428         case DESC_RATEMCS13:
2429         case DESC_RATEMCS14:
2430         case DESC_RATEMCS15:
2431                 rate_section = 3;
2432                 break;
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:
2443                 rate_section = 4;
2444                 break;
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:
2455                 rate_section = 5;
2456                 break;
2457         default:
2458                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2459                         "Wrong rate 0x%x\n", rate);
2460                 break;
2461         }
2462
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);
2466
2467         /*workaround for wrong index combination to obtain tx power limit,
2468           OFDM only exists in BW 20M*/
2469         if (rate_section == 1)
2470                 bandwidth_temp = 0;
2471
2472         /*workaround for wrong index combination to obtain tx power limit,
2473          *HT on 80M will reference to HT on 40M
2474          */
2475         if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2476             bandwidth_temp == 2)
2477                 bandwidth_temp = 1;
2478
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 */
2487
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;
2495         }
2496
2497         bd = band_temp;
2498         regu = regulation;
2499         bdwidth = bandwidth_temp;
2500         sec = rate_section;
2501         chnl = channel_temp;
2502
2503         if (band == BAND_ON_2_4G) {
2504                 char limits[10] = {0};
2505                 u8 i;
2506
2507                 for (i = 0; i < 4; ++i)
2508                         limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2509                         [sec][chnl][rf_path];
2510
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                 char limits[10] = {0};
2517                 u8 i;
2518
2519                 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2520                         limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2521                         [sec][chnl][rf_path];
2522
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];
2527         } else {
2528                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2529                          "No power limit table of the specified band\n");
2530         }
2531         return power_limit;
2532 }
2533
2534 static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2535                                         u8 band, u8 path, u8 rate)
2536 {
2537         struct rtl_priv *rtlpriv = rtl_priv(hw);
2538         struct rtl_phy *rtlphy = &rtlpriv->phy;
2539         u8 shift = 0, rate_section, tx_num;
2540         char tx_pwr_diff = 0;
2541         char limit = 0;
2542
2543         rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2544         tx_num = RF_TX_NUM_NONIMPLEMENT;
2545
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))
2549                         tx_num = RF_2TX;
2550                 else
2551                         tx_num = RF_1TX;
2552         }
2553
2554         switch (rate) {
2555         case DESC_RATE1M:
2556         case DESC_RATE6M:
2557         case DESC_RATE24M:
2558         case DESC_RATEMCS0:
2559         case DESC_RATEMCS4:
2560         case DESC_RATEMCS8:
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:
2567                 shift = 0;
2568                 break;
2569         case DESC_RATE2M:
2570         case DESC_RATE9M:
2571         case DESC_RATE36M:
2572         case DESC_RATEMCS1:
2573         case DESC_RATEMCS5:
2574         case DESC_RATEMCS9:
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:
2581                 shift = 8;
2582                 break;
2583         case DESC_RATE5_5M:
2584         case DESC_RATE12M:
2585         case DESC_RATE48M:
2586         case DESC_RATEMCS2:
2587         case DESC_RATEMCS6:
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:
2595                 shift = 16;
2596                 break;
2597         case DESC_RATE11M:
2598         case DESC_RATE18M:
2599         case DESC_RATE54M:
2600         case DESC_RATEMCS3:
2601         case DESC_RATEMCS7:
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:
2609                 shift = 24;
2610                 break;
2611         default:
2612                 RT_ASSERT(true, "Rate_Section is Illegal\n");
2613                 break;
2614         }
2615
2616         tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2617                 [tx_num][rate_section] >> shift) & 0xff;
2618
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);
2624
2625                 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9  ||
2626                          rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2627                         if (limit < 0) {
2628                                 if (tx_pwr_diff < (-limit))
2629                                         tx_pwr_diff = -limit;
2630                         }
2631                 } else {
2632                         if (limit < 0)
2633                                 tx_pwr_diff = limit;
2634                         else
2635                                 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2636                 }
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);
2640         }
2641
2642         return  tx_pwr_diff;
2643 }
2644
2645 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2646                                         u8 rate, u8 bandwidth, u8 channel)
2647 {
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);
2652         u8 txpower = 0;
2653         bool in_24g = false;
2654         char powerdiff_byrate = 0;
2655
2656         if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2657             (channel > 14 || channel < 1)) ||
2658             ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2659                 index = 0;
2660                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2661                         "Illegal channel!!\n");
2662         }
2663
2664         in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2665         if (in_24g) {
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];
2670                 else
2671                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2672
2673                 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2674                     !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2675                         txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2676
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];
2700                 }
2701         } else {
2702                 if (DESC_RATE6M <= rate)
2703                         txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2704                 else
2705                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2706                                  "INVALID Rate.\n");
2707
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];
2711
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) {
2731                         u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2732                                 42, 58, 106, 122, 138, 155, 171
2733                         };
2734                         u8 i;
2735
2736                         for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i)
2737                                 if (channel_5g_80m[i] == channel)
2738                                         index = i;
2739
2740                         if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2741                             (DESC_RATEVHT1SS_MCS0 <= rate &&
2742                              rate <= DESC_RATEVHT2SS_MCS9))
2743                                 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2744                                         + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2745                         if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2746                             (DESC_RATEVHT2SS_MCS0 <= rate &&
2747                              rate <= DESC_RATEVHT2SS_MCS9))
2748                                 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2749                                         + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2750                                         + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2751                     }
2752         }
2753         if (rtlefuse->eeprom_regulatory != 2)
2754                 powerdiff_byrate =
2755                   _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2756                                                      path, rate);
2757
2758         if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2759             rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2760                 txpower -= powerdiff_byrate;
2761         else
2762                 txpower += powerdiff_byrate;
2763
2764         if (rate > DESC_RATE11M)
2765                 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2766         else
2767                 txpower += rtlpriv->dm.remnant_cck_idx;
2768
2769         if (txpower > MAX_POWER_INDEX)
2770                 txpower = MAX_POWER_INDEX;
2771
2772         return txpower;
2773 }
2774
2775 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2776                                              u8 power_index, u8 path, u8 rate)
2777 {
2778         struct rtl_priv *rtlpriv = rtl_priv(hw);
2779
2780         if (path == RF90_PATH_A) {
2781                 switch (rate) {
2782                 case DESC_RATE1M:
2783                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2784                                       MASKBYTE0, power_index);
2785                         break;
2786                 case DESC_RATE2M:
2787                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2788                                       MASKBYTE1, power_index);
2789                         break;
2790                 case DESC_RATE5_5M:
2791                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2792                                       MASKBYTE2, power_index);
2793                         break;
2794                 case DESC_RATE11M:
2795                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2796                                       MASKBYTE3, power_index);
2797                         break;
2798                 case DESC_RATE6M:
2799                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2800                                       MASKBYTE0, power_index);
2801                         break;
2802                 case DESC_RATE9M:
2803                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2804                                       MASKBYTE1, power_index);
2805                         break;
2806                 case DESC_RATE12M:
2807                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2808                                       MASKBYTE2, power_index);
2809                         break;
2810                 case DESC_RATE18M:
2811                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2812                                       MASKBYTE3, power_index);
2813                         break;
2814                 case DESC_RATE24M:
2815                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2816                                       MASKBYTE0, power_index);
2817                         break;
2818                 case DESC_RATE36M:
2819                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2820                                       MASKBYTE1, power_index);
2821                         break;
2822                 case DESC_RATE48M:
2823                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2824                                       MASKBYTE2, power_index);
2825                         break;
2826                 case DESC_RATE54M:
2827                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2828                                       MASKBYTE3, power_index);
2829                         break;
2830                 case DESC_RATEMCS0:
2831                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2832                                       MASKBYTE0, power_index);
2833                         break;
2834                 case DESC_RATEMCS1:
2835                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2836                                       MASKBYTE1, power_index);
2837                         break;
2838                 case DESC_RATEMCS2:
2839                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2840                                       MASKBYTE2, power_index);
2841                         break;
2842                 case DESC_RATEMCS3:
2843                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2844                                       MASKBYTE3, power_index);
2845                         break;
2846                 case DESC_RATEMCS4:
2847                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2848                                       MASKBYTE0, power_index);
2849                         break;
2850                 case DESC_RATEMCS5:
2851                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2852                                       MASKBYTE1, power_index);
2853                         break;
2854                 case DESC_RATEMCS6:
2855                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2856                                       MASKBYTE2, power_index);
2857                         break;
2858                 case DESC_RATEMCS7:
2859                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2860                                       MASKBYTE3, power_index);
2861                         break;
2862                 case DESC_RATEMCS8:
2863                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2864                                       MASKBYTE0, power_index);
2865                         break;
2866                 case DESC_RATEMCS9:
2867                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2868                                       MASKBYTE1, power_index);
2869                         break;
2870                 case DESC_RATEMCS10:
2871                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2872                                       MASKBYTE2, power_index);
2873                         break;
2874                 case DESC_RATEMCS11:
2875                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2876                                       MASKBYTE3, power_index);
2877                         break;
2878                 case DESC_RATEMCS12:
2879                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2880                                       MASKBYTE0, power_index);
2881                         break;
2882                 case DESC_RATEMCS13:
2883                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2884                                       MASKBYTE1, power_index);
2885                         break;
2886                 case DESC_RATEMCS14:
2887                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2888                                       MASKBYTE2, power_index);
2889                         break;
2890                 case DESC_RATEMCS15:
2891                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2892                                       MASKBYTE3, power_index);
2893                         break;
2894                 case DESC_RATEVHT1SS_MCS0:
2895                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2896                                       MASKBYTE0, power_index);
2897                         break;
2898                 case DESC_RATEVHT1SS_MCS1:
2899                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2900                                       MASKBYTE1, power_index);
2901                         break;
2902                 case DESC_RATEVHT1SS_MCS2:
2903                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2904                                       MASKBYTE2, power_index);
2905                         break;
2906                 case DESC_RATEVHT1SS_MCS3:
2907                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2908                                       MASKBYTE3, power_index);
2909                         break;
2910                 case DESC_RATEVHT1SS_MCS4:
2911                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2912                                       MASKBYTE0, power_index);
2913                         break;
2914                 case DESC_RATEVHT1SS_MCS5:
2915                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2916                                       MASKBYTE1, power_index);
2917                         break;
2918                 case DESC_RATEVHT1SS_MCS6:
2919                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2920                                       MASKBYTE2, power_index);
2921                         break;
2922                 case DESC_RATEVHT1SS_MCS7:
2923                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2924                                       MASKBYTE3, power_index);
2925                         break;
2926                 case DESC_RATEVHT1SS_MCS8:
2927                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2928                                       MASKBYTE0, power_index);
2929                         break;
2930                 case DESC_RATEVHT1SS_MCS9:
2931                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2932                                       MASKBYTE1, power_index);
2933                         break;
2934                 case DESC_RATEVHT2SS_MCS0:
2935                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2936                                       MASKBYTE2, power_index);
2937                         break;
2938                 case DESC_RATEVHT2SS_MCS1:
2939                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2940                                       MASKBYTE3, power_index);
2941                         break;
2942                 case DESC_RATEVHT2SS_MCS2:
2943                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2944                                       MASKBYTE0, power_index);
2945                         break;
2946                 case DESC_RATEVHT2SS_MCS3:
2947                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2948                                       MASKBYTE1, power_index);
2949                         break;
2950                 case DESC_RATEVHT2SS_MCS4:
2951                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2952                                       MASKBYTE2, power_index);
2953                         break;
2954                 case DESC_RATEVHT2SS_MCS5:
2955                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2956                                       MASKBYTE3, power_index);
2957                         break;
2958                 case DESC_RATEVHT2SS_MCS6:
2959                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2960                                       MASKBYTE0, power_index);
2961                         break;
2962                 case DESC_RATEVHT2SS_MCS7:
2963                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2964                                       MASKBYTE1, power_index);
2965                         break;
2966                 case DESC_RATEVHT2SS_MCS8:
2967                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2968                                       MASKBYTE2, power_index);
2969                         break;
2970                 case DESC_RATEVHT2SS_MCS9:
2971                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2972                                       MASKBYTE3, power_index);
2973                         break;
2974                 default:
2975                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2976                                 "Invalid Rate!!\n");
2977                         break;
2978                 }
2979         } else if (path == RF90_PATH_B) {
2980                 switch (rate) {
2981                 case DESC_RATE1M:
2982                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2983                                       MASKBYTE0, power_index);
2984                         break;
2985                 case DESC_RATE2M:
2986                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2987                                       MASKBYTE1, power_index);
2988                         break;
2989                 case DESC_RATE5_5M:
2990                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2991                                       MASKBYTE2, power_index);
2992                         break;
2993                 case DESC_RATE11M:
2994                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2995                                       MASKBYTE3, power_index);
2996                         break;
2997                 case DESC_RATE6M:
2998                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2999                                       MASKBYTE0, power_index);
3000                         break;
3001                 case DESC_RATE9M:
3002                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3003                                       MASKBYTE1, power_index);
3004                         break;
3005                 case DESC_RATE12M:
3006                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3007                                       MASKBYTE2, power_index);
3008                         break;
3009                 case DESC_RATE18M:
3010                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3011                                       MASKBYTE3, power_index);
3012                         break;
3013                 case DESC_RATE24M:
3014                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3015                                       MASKBYTE0, power_index);
3016                         break;
3017                 case DESC_RATE36M:
3018                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3019                                       MASKBYTE1, power_index);
3020                         break;
3021                 case DESC_RATE48M:
3022                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3023                                       MASKBYTE2, power_index);
3024                         break;
3025                 case DESC_RATE54M:
3026                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3027                                       MASKBYTE3, power_index);
3028                         break;
3029                 case DESC_RATEMCS0:
3030                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3031                                       MASKBYTE0, power_index);
3032                         break;
3033                 case DESC_RATEMCS1:
3034                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3035                                       MASKBYTE1, power_index);
3036                         break;
3037                 case DESC_RATEMCS2:
3038                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3039                                       MASKBYTE2, power_index);
3040                         break;
3041                 case DESC_RATEMCS3:
3042                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3043                                       MASKBYTE3, power_index);
3044                         break;
3045                 case DESC_RATEMCS4:
3046                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3047                                       MASKBYTE0, power_index);
3048                         break;
3049                 case DESC_RATEMCS5:
3050                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3051                                       MASKBYTE1, power_index);
3052                         break;
3053                 case DESC_RATEMCS6:
3054                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3055                                       MASKBYTE2, power_index);
3056                         break;
3057                 case DESC_RATEMCS7:
3058                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3059                                       MASKBYTE3, power_index);
3060                         break;
3061                 case DESC_RATEMCS8:
3062                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3063                                       MASKBYTE0, power_index);
3064                         break;
3065                 case DESC_RATEMCS9:
3066                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3067                                       MASKBYTE1, power_index);
3068                         break;
3069                 case DESC_RATEMCS10:
3070                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3071                                       MASKBYTE2, power_index);
3072                         break;
3073                 case DESC_RATEMCS11:
3074                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3075                                       MASKBYTE3, power_index);
3076                         break;
3077                 case DESC_RATEMCS12:
3078                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3079                                       MASKBYTE0, power_index);
3080                         break;
3081                 case DESC_RATEMCS13:
3082                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3083                                       MASKBYTE1, power_index);
3084                         break;
3085                 case DESC_RATEMCS14:
3086                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3087                                       MASKBYTE2, power_index);
3088                         break;
3089                 case DESC_RATEMCS15:
3090                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3091                                       MASKBYTE3, power_index);
3092                         break;
3093                 case DESC_RATEVHT1SS_MCS0:
3094                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3095                                       MASKBYTE0, power_index);
3096                         break;
3097                 case DESC_RATEVHT1SS_MCS1:
3098                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3099                                       MASKBYTE1, power_index);
3100                         break;
3101                 case DESC_RATEVHT1SS_MCS2:
3102                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3103                                       MASKBYTE2, power_index);
3104                         break;
3105                 case DESC_RATEVHT1SS_MCS3:
3106                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3107                                       MASKBYTE3, power_index);
3108                         break;
3109                 case DESC_RATEVHT1SS_MCS4:
3110                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3111                                       MASKBYTE0, power_index);
3112                         break;
3113                 case DESC_RATEVHT1SS_MCS5:
3114                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3115                                       MASKBYTE1, power_index);
3116                         break;
3117                 case DESC_RATEVHT1SS_MCS6:
3118                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3119                                       MASKBYTE2, power_index);
3120                         break;
3121                 case DESC_RATEVHT1SS_MCS7:
3122                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3123                                       MASKBYTE3, power_index);
3124                         break;
3125                 case DESC_RATEVHT1SS_MCS8:
3126                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3127                                       MASKBYTE0, power_index);
3128                         break;
3129                 case DESC_RATEVHT1SS_MCS9:
3130                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3131                                       MASKBYTE1, power_index);
3132                         break;
3133                 case DESC_RATEVHT2SS_MCS0:
3134                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3135                                       MASKBYTE2, power_index);
3136                         break;
3137                 case DESC_RATEVHT2SS_MCS1:
3138                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3139                                       MASKBYTE3, power_index);
3140                         break;
3141                 case DESC_RATEVHT2SS_MCS2:
3142                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3143                                       MASKBYTE0, power_index);
3144                         break;
3145                 case DESC_RATEVHT2SS_MCS3:
3146                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3147                                       MASKBYTE1, power_index);
3148                         break;
3149                 case DESC_RATEVHT2SS_MCS4:
3150                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3151                                       MASKBYTE2, power_index);
3152                         break;
3153                 case DESC_RATEVHT2SS_MCS5:
3154                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3155                                       MASKBYTE3, power_index);
3156                         break;
3157                 case DESC_RATEVHT2SS_MCS6:
3158                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3159                                       MASKBYTE0, power_index);
3160                         break;
3161                 case DESC_RATEVHT2SS_MCS7:
3162                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3163                                       MASKBYTE1, power_index);
3164                         break;
3165                 case DESC_RATEVHT2SS_MCS8:
3166                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3167                                       MASKBYTE2, power_index);
3168                         break;
3169                 case DESC_RATEVHT2SS_MCS9:
3170                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3171                                       MASKBYTE3, power_index);
3172                         break;
3173                 default:
3174                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3175                                  "Invalid Rate!!\n");
3176                         break;
3177                 }
3178         } else {
3179                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3180                          "Invalid RFPath!!\n");
3181         }
3182 }
3183
3184 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3185                                                      u8 *array, u8 path,
3186                                                      u8 channel, u8 size)
3187 {
3188         struct rtl_priv *rtlpriv = rtl_priv(hw);
3189         struct rtl_phy *rtlphy = &rtlpriv->phy;
3190         u8 i;
3191         u8 power_index;
3192
3193         for (i = 0; i < size; i++) {
3194                 power_index =
3195                   _rtl8821ae_get_txpower_index(hw, path, array[i],
3196                                                rtlphy->current_chan_bw,
3197                                                channel);
3198                 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3199                                                  array[i]);
3200         }
3201 }
3202
3203 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3204                                                     u8 bw, u8 channel, u8 path)
3205 {
3206         struct rtl_priv *rtlpriv = rtl_priv(hw);
3207         struct rtl_phy *rtlphy = &rtlpriv->phy;
3208
3209         u8 i;
3210         u32 power_level, data, offset;
3211
3212         if (path >= rtlphy->num_total_rfpath)
3213                 return;
3214
3215         data = 0;
3216         if (path == RF90_PATH_A) {
3217                 power_level =
3218                         _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3219                         DESC_RATEMCS7, bw, channel);
3220                 offset =  RA_TXPWRTRAING;
3221         } else {
3222                 power_level =
3223                         _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3224                         DESC_RATEMCS7, bw, channel);
3225                 offset =  RB_TXPWRTRAING;
3226         }
3227
3228         for (i = 0; i < 3; i++) {
3229                 if (i == 0)
3230                         power_level = power_level - 10;
3231                 else if (i == 1)
3232                         power_level = power_level - 8;
3233                 else
3234                         power_level = power_level - 6;
3235
3236                 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3237         }
3238         rtl_set_bbreg(hw, offset, 0xffffff, data);
3239 }
3240
3241 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3242                                              u8 channel, u8 path)
3243 {
3244         /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3245         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3246         struct rtl_priv *rtlpriv = rtl_priv(hw);
3247         struct rtl_phy *rtlphy = &rtlpriv->phy;
3248         u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3249                               DESC_RATE11M};
3250         u8 sizes_of_cck_retes = 4;
3251         u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3252                                 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3253                                 DESC_RATE48M, DESC_RATE54M};
3254         u8 sizes_of_ofdm_retes = 8;
3255         u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3256                                 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3257                                 DESC_RATEMCS6, DESC_RATEMCS7};
3258         u8 sizes_of_ht_retes_1t = 8;
3259         u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9,
3260                                 DESC_RATEMCS10, DESC_RATEMCS11,
3261                                 DESC_RATEMCS12, DESC_RATEMCS13,
3262                                 DESC_RATEMCS14, DESC_RATEMCS15};
3263         u8 sizes_of_ht_retes_2t = 8;
3264         u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3265                                 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3266                                 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3267                                 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3268                              DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3269         u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3270                                 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3271                                 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3272                                 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3273                                 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3274         u8 sizes_of_vht_retes = 10;
3275
3276         if (rtlhal->current_bandtype == BAND_ON_2_4G)
3277                 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3278                                                          sizes_of_cck_retes);
3279
3280         _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3281                                                  sizes_of_ofdm_retes);
3282         _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3283                                                  sizes_of_ht_retes_1t);
3284         _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3285                                                  sizes_of_vht_retes);
3286
3287         if (rtlphy->num_total_rfpath >= 2) {
3288                 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3289                                                          channel,
3290                                                          sizes_of_ht_retes_2t);
3291                 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3292                                                          channel,
3293                                                          sizes_of_vht_retes);
3294         }
3295
3296         _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3297                                                 channel, path);
3298 }
3299
3300 /*just in case, write txpower in DW, to reduce time*/
3301 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3302 {
3303         struct rtl_priv *rtlpriv = rtl_priv(hw);
3304         struct rtl_phy *rtlphy = &rtlpriv->phy;
3305         u8 path = 0;
3306
3307         for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3308                 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3309 }
3310
3311 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3312                                             enum wireless_mode wirelessmode,
3313                                             u8 txpwridx)
3314 {
3315         long offset;
3316         long pwrout_dbm;
3317
3318         switch (wirelessmode) {
3319         case WIRELESS_MODE_B:
3320                 offset = -7;
3321                 break;
3322         case WIRELESS_MODE_G:
3323         case WIRELESS_MODE_N_24G:
3324                 offset = -8;
3325                 break;
3326         default:
3327                 offset = -8;
3328                 break;
3329         }
3330         pwrout_dbm = txpwridx / 2 + offset;
3331         return pwrout_dbm;
3332 }
3333
3334 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3335 {
3336         struct rtl_priv *rtlpriv = rtl_priv(hw);
3337         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3338         enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3339
3340         if (!is_hal_stop(rtlhal)) {
3341                 switch (operation) {
3342                 case SCAN_OPT_BACKUP_BAND0:
3343                         iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3344                         rtlpriv->cfg->ops->set_hw_reg(hw,
3345                                                       HW_VAR_IO_CMD,
3346                                                       (u8 *)&iotype);
3347
3348                         break;
3349                 case SCAN_OPT_BACKUP_BAND1:
3350                         iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3351                         rtlpriv->cfg->ops->set_hw_reg(hw,
3352                                                       HW_VAR_IO_CMD,
3353                                                       (u8 *)&iotype);
3354
3355                         break;
3356                 case SCAN_OPT_RESTORE:
3357                         iotype = IO_CMD_RESUME_DM_BY_SCAN;
3358                         rtlpriv->cfg->ops->set_hw_reg(hw,
3359                                                       HW_VAR_IO_CMD,
3360                                                       (u8 *)&iotype);
3361                         break;
3362                 default:
3363                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3364                                  "Unknown Scan Backup operation.\n");
3365                         break;
3366                 }
3367         }
3368 }
3369
3370 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3371 {
3372         u16 reg_rf_mode_bw, tmp = 0;
3373
3374         reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3375         switch (bw) {
3376         case HT_CHANNEL_WIDTH_20:
3377                 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3378                 break;
3379         case HT_CHANNEL_WIDTH_20_40:
3380                 tmp = reg_rf_mode_bw | BIT(7);
3381                 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3382                 break;
3383         case HT_CHANNEL_WIDTH_80:
3384                 tmp = reg_rf_mode_bw | BIT(8);
3385                 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3386                 break;
3387         default:
3388                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3389                 break;
3390         }
3391 }
3392
3393 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3394 {
3395         struct rtl_phy *rtlphy = &rtlpriv->phy;
3396         struct rtl_mac *mac = rtl_mac(rtlpriv);
3397         u8 sc_set_40 = 0, sc_set_20 = 0;
3398
3399         if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3400                 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3401                         sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3402                 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3403                         sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3404                 else
3405                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3406                                 "SCMapping: Not Correct Primary40MHz Setting\n");
3407
3408                 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3409                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3410                         sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3411                 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3412                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3413                         sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3414                 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3415                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3416                         sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3417                 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3418                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3419                         sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3420                 else
3421                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3422                                 "SCMapping: Not Correct Primary40MHz Setting\n");
3423         } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3424                 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3425                         sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3426                 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3427                         sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3428                 else
3429                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3430                          "SCMapping: Not Correct Primary40MHz Setting\n");
3431         }
3432         return (sc_set_40 << 4) | sc_set_20;
3433 }
3434
3435 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3436 {
3437         struct rtl_priv *rtlpriv = rtl_priv(hw);
3438         struct rtl_phy *rtlphy = &rtlpriv->phy;
3439         u8 sub_chnl = 0;
3440         u8 l1pk_val = 0;
3441
3442         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3443                  "Switch to %s bandwidth\n",
3444                   (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3445                   "20MHz" :
3446                   (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3447                   "40MHz" : "80MHz")));
3448
3449         _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3450         sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3451         rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3452
3453         switch (rtlphy->current_chan_bw) {
3454         case HT_CHANNEL_WIDTH_20:
3455                 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3456                 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3457
3458                 if (rtlphy->rf_type == RF_2T2R)
3459                         rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3460                 else
3461                         rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3462                 break;
3463         case HT_CHANNEL_WIDTH_20_40:
3464                 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3465                 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3466                 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3467                 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3468
3469                 if (rtlphy->reg_837 & BIT(2))
3470                         l1pk_val = 6;
3471                 else {
3472                         if (rtlphy->rf_type == RF_2T2R)
3473                                 l1pk_val = 7;
3474                         else
3475                                 l1pk_val = 8;
3476                 }
3477                 /* 0x848[25:22] = 0x6 */
3478                 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3479
3480                 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3481                         rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3482                 else
3483                         rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3484                 break;
3485
3486         case HT_CHANNEL_WIDTH_80:
3487                  /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3488                 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3489                 /* 0x8c4[30] = 1 */
3490                 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3491                 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3492                 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3493
3494                 if (rtlphy->reg_837 & BIT(2))
3495                         l1pk_val = 5;
3496                 else {
3497                         if (rtlphy->rf_type == RF_2T2R)
3498                                 l1pk_val = 6;
3499                         else
3500                                 l1pk_val = 7;
3501                 }
3502                 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3503
3504                 break;
3505         default:
3506                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3507                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3508                 break;
3509         }
3510
3511         rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3512
3513         rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3514         rtlphy->set_bwmode_inprogress = false;
3515
3516         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3517 }
3518
3519 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3520                             enum nl80211_channel_type ch_type)
3521 {
3522         struct rtl_priv *rtlpriv = rtl_priv(hw);
3523         struct rtl_phy *rtlphy = &rtlpriv->phy;
3524         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3525         u8 tmp_bw = rtlphy->current_chan_bw;
3526
3527         if (rtlphy->set_bwmode_inprogress)
3528                 return;
3529         rtlphy->set_bwmode_inprogress = true;
3530         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3531                 rtl8821ae_phy_set_bw_mode_callback(hw);
3532         else {
3533                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3534                          "FALSE driver sleep or unload\n");
3535                 rtlphy->set_bwmode_inprogress = false;
3536                 rtlphy->current_chan_bw = tmp_bw;
3537         }
3538 }
3539
3540 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3541 {
3542         struct rtl_priv *rtlpriv = rtl_priv(hw);
3543         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3544         struct rtl_phy *rtlphy = &rtlpriv->phy;
3545         u8 channel = rtlphy->current_channel;
3546         u8 path;
3547         u32 data;
3548
3549         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3550                  "switch to channel%d\n", rtlphy->current_channel);
3551         if (is_hal_stop(rtlhal))
3552                 return;
3553
3554         if (36 <= channel && channel <= 48)
3555                 data = 0x494;
3556         else if (50 <= channel && channel <= 64)
3557                 data = 0x453;
3558         else if (100 <= channel && channel <= 116)
3559                 data = 0x452;
3560         else if (118 <= channel)
3561                 data = 0x412;
3562         else
3563                 data = 0x96a;
3564         rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3565
3566         for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3567                 if (36 <= channel && channel <= 64)
3568                         data = 0x101;
3569                 else if (100 <= channel && channel <= 140)
3570                         data = 0x301;
3571                 else if (140 < channel)
3572                         data = 0x501;
3573                 else
3574                         data = 0x000;
3575                 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3576                         BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3577
3578                 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3579                         BMASKBYTE0, channel);
3580
3581                 if (channel > 14) {
3582                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3583                                 if (36 <= channel && channel <= 64)
3584                                         data = 0x114E9;
3585                                 else if (100 <= channel && channel <= 140)
3586                                         data = 0x110E9;
3587                                 else
3588                                         data = 0x110E9;
3589                                 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3590                                         BRFREGOFFSETMASK, data);
3591                         }
3592                 }
3593         }
3594         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3595 }
3596
3597 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3598 {
3599         struct rtl_priv *rtlpriv = rtl_priv(hw);
3600         struct rtl_phy *rtlphy = &rtlpriv->phy;
3601         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3602         u32 timeout = 1000, timecount = 0;
3603         u8 channel = rtlphy->current_channel;
3604
3605         if (rtlphy->sw_chnl_inprogress)
3606                 return 0;
3607         if (rtlphy->set_bwmode_inprogress)
3608                 return 0;
3609
3610         if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3611                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3612                          "sw_chnl_inprogress false driver sleep or unload\n");
3613                 return 0;
3614         }
3615         while (rtlphy->lck_inprogress && timecount < timeout) {
3616                 mdelay(50);
3617                 timecount += 50;
3618         }
3619
3620         if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3621                 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3622         else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3623                 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3624
3625         rtlphy->sw_chnl_inprogress = true;
3626         if (channel == 0)
3627                 channel = 1;
3628
3629         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3630                  "switch to channel%d, band type is %d\n",
3631                  rtlphy->current_channel, rtlhal->current_bandtype);
3632
3633         rtl8821ae_phy_sw_chnl_callback(hw);
3634
3635         rtl8821ae_dm_clear_txpower_tracking_state(hw);
3636         rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3637
3638         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3639         rtlphy->sw_chnl_inprogress = false;
3640         return 1;
3641 }
3642
3643 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3644 {
3645         u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3646                 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3647                 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3648                 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3649                 110, 112, 114, 116, 118, 120, 122, 124, 126,
3650                 128, 130, 132, 134, 136, 138, 140, 149, 151,
3651                 153, 155, 157, 159, 161, 163, 165};
3652         u8 place = chnl;
3653
3654         if (chnl > 14) {
3655                 for (place = 14; place < sizeof(channel_all); place++)
3656                         if (channel_all[place] == chnl)
3657                                 return place-13;
3658         }
3659
3660         return 0;
3661 }
3662
3663 #define MACBB_REG_NUM 10
3664 #define AFE_REG_NUM 14
3665 #define RF_REG_NUM 3
3666
3667 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3668                                         u32 *macbb_backup,
3669                                         u32 *backup_macbb_reg, u32 mac_bb_num)
3670 {
3671         struct rtl_priv *rtlpriv = rtl_priv(hw);
3672         u32 i;
3673
3674         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3675         /*save MACBB default value*/
3676         for (i = 0; i < mac_bb_num; i++)
3677                 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3678
3679         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3680 }
3681
3682 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3683                                       u32 *backup_afe_REG, u32 afe_num)
3684 {
3685         struct rtl_priv *rtlpriv = rtl_priv(hw);
3686         u32 i;
3687
3688         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3689         /*Save AFE Parameters */
3690         for (i = 0; i < afe_num; i++)
3691                 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3692         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3693 }
3694
3695 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3696                                      u32 *rfb_backup, u32 *backup_rf_reg,
3697                                      u32 rf_num)
3698 {
3699         struct rtl_priv *rtlpriv = rtl_priv(hw);
3700         u32 i;
3701
3702         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3703         /*Save RF Parameters*/
3704         for (i = 0; i < rf_num; i++) {
3705                 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3706                                               BMASKDWORD);
3707                 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3708                                               BMASKDWORD);
3709         }
3710         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3711 }
3712
3713 static void _rtl8821ae_iqk_configure_mac(
3714                 struct ieee80211_hw *hw
3715                 )
3716 {
3717         struct rtl_priv *rtlpriv = rtl_priv(hw);
3718         /* ========MAC register setting========*/
3719         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3720         rtl_write_byte(rtlpriv, 0x522, 0x3f);
3721         rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3722         rtl_write_byte(rtlpriv, 0x808, 0x00);           /*RX ante off*/
3723         rtl_set_bbreg(hw, 0x838, 0xf, 0xc);             /*CCA off*/
3724 }
3725
3726 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3727                                        enum radio_path path, u32 tx_x, u32 tx_y)
3728 {
3729         struct rtl_priv *rtlpriv = rtl_priv(hw);
3730         switch (path) {
3731         case RF90_PATH_A:
3732                 /* [31] = 1 --> Page C1 */
3733                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3734                 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3735                 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3736                 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3737                 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3738                 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3739                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3740                          "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3741                          tx_x, tx_y);
3742                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3743                          "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3744                          rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3745                          rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3746                 break;
3747         default:
3748                 break;
3749         }
3750 }
3751
3752 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3753                                        enum radio_path path, u32 rx_x, u32 rx_y)
3754 {
3755         struct rtl_priv *rtlpriv = rtl_priv(hw);
3756         switch (path) {
3757         case RF90_PATH_A:
3758                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3759                 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3760                 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3761                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3762                          "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3763                          rx_x>>1, rx_y>>1);
3764                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3765                          "0xc10 = %x ====>fill to IQC\n",
3766                          rtl_read_dword(rtlpriv, 0xc10));
3767                 break;
3768         default:
3769                 break;
3770         }
3771 }
3772
3773 #define cal_num 10
3774
3775 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3776 {
3777         struct rtl_priv *rtlpriv = rtl_priv(hw);
3778         struct rtl_phy *rtlphy = &rtlpriv->phy;
3779         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3780
3781         u32     tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3782         int     tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3783         int     tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3784                 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3785         bool    tx0iqkok = false, rx0iqkok = false;
3786         bool    vdf_enable = false;
3787         int     i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3788                 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3789
3790         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3791                         "BandWidth = %d.\n",
3792                          rtlphy->current_chan_bw);
3793         if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3794                 vdf_enable = true;
3795
3796         while (cal < cal_num) {
3797                 switch (path) {
3798                 case RF90_PATH_A:
3799                         temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3800                         /* Path-A LOK */
3801                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3802                         /*========Path-A AFE all on========*/
3803                         /*Port 0 DAC/ADC on*/
3804                         rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3805                         rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3806                         rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3807                         rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3808                         rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3809                         rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3810                         rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3811                         rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3812                         rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3813                         rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3814
3815                         rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3816
3817                         /* LOK Setting */
3818                         /* ====== LOK ====== */
3819                         /*DAC/ADC sampling rate (160 MHz)*/
3820                         rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3821
3822                         /* 2. LoK RF Setting (at BW = 20M) */
3823                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3824                         rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3);     /* BW 20M */
3825                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3826                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3827                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3828                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3829                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3830                         rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3831                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3832                         rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3833                         rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3834                         rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3835                         rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3836                         rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3837
3838                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3839                         rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3840
3841                         if (rtlhal->current_bandtype)
3842                                 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3843                         else
3844                                 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3845
3846                         rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3847                         rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3848                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3849                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3850                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3851
3852                         mdelay(10); /* Delay 10ms */
3853                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3854
3855                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3856                         rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3857
3858                         switch (rtlphy->current_chan_bw) {
3859                         case 1:
3860                                 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3861                                 break;
3862                         case 2:
3863                                 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3864                                 break;
3865                         default:
3866                                 break;
3867                         }
3868
3869                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3870
3871                         /* 3. TX RF Setting */
3872                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3873                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3874                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3875                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3876                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3877                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3878                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3879                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3880                         /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3881                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3882                         rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3883                         rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3884                         rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3885                         rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3886                         rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3887
3888                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3889                         rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3890                         if (rtlhal->current_bandtype)
3891                                 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3892                         else
3893                                 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3894
3895                         if (vdf_enable == 1) {
3896                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3897                                 for (k = 0; k <= 2; k++) {
3898                                         switch (k) {
3899                                         case 0:
3900                                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3901                                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3902                                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3903                                                 break;
3904                                         case 1:
3905                                                 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3906                                                 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3907                                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3908                                                 break;
3909                                         case 2:
3910                                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3911                                                         "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3912                                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3913                                                         "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3914                                                 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3915                                                 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3916                                                 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3917                                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3918                                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3919                                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3920                                                 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3921                                                 break;
3922                                         default:
3923                                                 break;
3924                                         }
3925                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3926                                         cal_retry = 0;
3927                                         while (1) {
3928                                                 /* one shot */
3929                                                 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3930                                                 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3931
3932                                                 mdelay(10); /* Delay 10ms */
3933                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3934                                                 delay_count = 0;
3935                                                 while (1) {
3936                                                         iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3937                                                         if ((~iqk_ready) || (delay_count > 20))
3938                                                                 break;
3939                                                         else{
3940                                                                 mdelay(1);
3941                                                                 delay_count++;
3942                                                         }
3943                                                 }
3944
3945                                                 if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
3946                                                         /* ============TXIQK Check============== */
3947                                                         tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3948
3949                                                         if (~tx_fail) {
3950                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3951                                                                 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3952                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3953                                                                 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3954                                                                 tx0iqkok = true;
3955                                                                 break;
3956                                                         } else {
3957                                                                 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3958                                                                 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3959                                                                 tx0iqkok = false;
3960                                                                 cal_retry++;
3961                                                                 if (cal_retry == 10)
3962                                                                         break;
3963                                                         }
3964                                                 } else {
3965                                                         tx0iqkok = false;
3966                                                         cal_retry++;
3967                                                         if (cal_retry == 10)
3968                                                                 break;
3969                                                 }
3970                                         }
3971                                 }
3972                                 if (k == 3) {
3973                                         tx_x0[cal] = vdf_x[k-1];
3974                                         tx_y0[cal] = vdf_y[k-1];
3975                                 }
3976                         } else {
3977                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3978                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3979                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3980                                 cal_retry = 0;
3981                                 while (1) {
3982                                         /* one shot */
3983                                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3984                                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3985
3986                                         mdelay(10); /* Delay 10ms */
3987                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3988                                         delay_count = 0;
3989                                         while (1) {
3990                                                 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3991                                                 if ((~iqk_ready) || (delay_count > 20))
3992                                                         break;
3993                                                 else{
3994                                                         mdelay(1);
3995                                                         delay_count++;
3996                                                 }
3997                                         }
3998
3999                                         if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4000                                                 /* ============TXIQK Check============== */
4001                                                 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4002
4003                                                 if (~tx_fail) {
4004                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4005                                                         tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4006                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4007                                                         tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4008                                                         tx0iqkok = true;
4009                                                         break;
4010                                                 } else {
4011                                                         rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4012                                                         rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4013                                                         tx0iqkok = false;
4014                                                         cal_retry++;
4015                                                         if (cal_retry == 10)
4016                                                                 break;
4017                                                 }
4018                                         } else {
4019                                                 tx0iqkok = false;
4020                                                 cal_retry++;
4021                                                 if (cal_retry == 10)
4022                                                         break;
4023                                         }
4024                                 }
4025                         }
4026
4027                         if (tx0iqkok == false)
4028                                 break;                          /* TXK fail, Don't do RXK */
4029
4030                         if (vdf_enable == 1) {
4031                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);    /* TX VDF Disable */
4032                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4033                                 for (k = 0; k <= 2; k++) {
4034                                         /* ====== RX mode TXK (RXK Step 1) ====== */
4035                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4036                                         /* 1. TX RF Setting */
4037                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4038                                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4039                                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4040                                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4041                                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4042                                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4043                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4044
4045                                         rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4046                                         rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4047                                         rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4048                                         rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4049                                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4050                                         rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4051                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4052                                         switch (k) {
4053                                         case 0:
4054                                                 {
4055                                                         rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4056                                                         rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4057                                                         rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4058                                                 }
4059                                                 break;
4060                                         case 1:
4061                                                 {
4062                                                         rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4063                                                         rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4064                                                         rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4065                                                 }
4066                                                 break;
4067                                         case 2:
4068                                                 {
4069                                                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4070                                                         "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4071                                                         vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4072                                                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4073                                                         "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4074                                                         vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4075                                                         rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4076                                                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4077                                                         rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4078                                                         rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4079                                                         rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4080                                                         rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4081                                                         rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4082                                                 }
4083                                                 break;
4084                                         default:
4085                                                 break;
4086                                         }
4087                                         rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4088                                         rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4089                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4090                                         cal_retry = 0;
4091                                         while (1) {
4092                                                 /* one shot */
4093                                                 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4094                                                 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4095
4096                                                 mdelay(10); /* Delay 10ms */
4097                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4098                                                 delay_count = 0;
4099                                                 while (1) {
4100                                                         iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4101                                                         if ((~iqk_ready) || (delay_count > 20))
4102                                                                 break;
4103                                                         else{
4104                                                                 mdelay(1);
4105                                                                 delay_count++;
4106                                                         }
4107                                                 }
4108
4109                                                 if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4110                                                         /* ============TXIQK Check============== */
4111                                                         tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4112
4113                                                         if (~tx_fail) {
4114                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4115                                                                 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4116                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4117                                                                 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4118                                                                 tx0iqkok = true;
4119                                                                 break;
4120                                                         } else{
4121                                                                 tx0iqkok = false;
4122                                                                 cal_retry++;
4123                                                                 if (cal_retry == 10)
4124                                                                         break;
4125                                                         }
4126                                                 } else {
4127                                                         tx0iqkok = false;
4128                                                         cal_retry++;
4129                                                         if (cal_retry == 10)
4130                                                                 break;
4131                                                 }
4132                                         }
4133
4134                                         if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4135                                                 tx_x0_rxk[cal] = tx_x0[cal];
4136                                                 tx_y0_rxk[cal] = tx_y0[cal];
4137                                                 tx0iqkok = true;
4138                                                 RT_TRACE(rtlpriv,
4139                                                          COMP_IQK,
4140                                                          DBG_LOUD,
4141                                                          "RXK Step 1 fail\n");
4142                                         }
4143
4144                                         /* ====== RX IQK ====== */
4145                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4146                                         /* 1. RX RF Setting */
4147                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4148                                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4149                                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4150                                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4151                                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4152                                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4153                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4154
4155                                         rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4156                                         rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4157                                         rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4158                                         rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4159                                         rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4160                                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4161                                         rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4162
4163                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4164                                         rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4165                                         rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4166                                         rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4167
4168                                         rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4169
4170                                         if (k == 2)
4171                                                 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1);  /* RX VDF Enable */
4172                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4173
4174                                         cal_retry = 0;
4175                                         while (1) {
4176                                                 /* one shot */
4177                                                 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4178                                                 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4179
4180                                                 mdelay(10); /* Delay 10ms */
4181                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4182                                                 delay_count = 0;
4183                                                 while (1) {
4184                                                         iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4185                                                         if ((~iqk_ready) || (delay_count > 20))
4186                                                                 break;
4187                                                         else{
4188                                                                 mdelay(1);
4189                                                                 delay_count++;
4190                                                         }
4191                                                 }
4192
4193                                                 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4194                                                         /* ============RXIQK Check============== */
4195                                                         rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4196                                                         if (rx_fail == 0) {
4197                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4198                                                                 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4199                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4200                                                                 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4201                                                                 rx0iqkok = true;
4202                                                                 break;
4203                                                         } else {
4204                                                                 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4205                                                                 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4206                                                                 rx0iqkok = false;
4207                                                                 cal_retry++;
4208                                                                 if (cal_retry == 10)
4209                                                                         break;
4210
4211                                                         }
4212                                                 } else{
4213                                                         rx0iqkok = false;
4214                                                         cal_retry++;
4215                                                         if (cal_retry == 10)
4216                                                                 break;
4217                                                 }
4218                                         }
4219
4220                                 }
4221                                 if (k == 3) {
4222                                         rx_x0[cal] = vdf_x[k-1];
4223                                         rx_y0[cal] = vdf_y[k-1];
4224                                 }
4225                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);    /* TX VDF Enable */
4226                         }
4227
4228                         else{
4229                                 /* ====== RX mode TXK (RXK Step 1) ====== */
4230                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4231                                 /* 1. TX RF Setting */
4232                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4233                                 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4234                                 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4235                                 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4236                                 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4237                                 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4238                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4239                                 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4240                                 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4241                                 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4242
4243                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4244                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4245                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4246                                 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4247                                 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4248                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4249                                 cal_retry = 0;
4250                                 while (1) {
4251                                         /* one shot */
4252                                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4253                                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4254
4255                                         mdelay(10); /* Delay 10ms */
4256                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4257                                         delay_count = 0;
4258                                         while (1) {
4259                                                 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4260                                                 if ((~iqk_ready) || (delay_count > 20))
4261                                                         break;
4262                                                 else{
4263                                                         mdelay(1);
4264                                                         delay_count++;
4265                                                 }
4266                                         }
4267
4268                                         if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4269                                                 /* ============TXIQK Check============== */
4270                                                 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4271
4272                                                 if (~tx_fail) {
4273                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4274                                                         tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4275                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4276                                                         tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4277                                                         tx0iqkok = true;
4278                                                         break;
4279                                                 } else {
4280                                                         tx0iqkok = false;
4281                                                         cal_retry++;
4282                                                         if (cal_retry == 10)
4283                                                                 break;
4284                                                 }
4285                                         } else{
4286                                                 tx0iqkok = false;
4287                                                 cal_retry++;
4288                                                 if (cal_retry == 10)
4289                                                         break;
4290                                         }
4291                                 }
4292
4293                                 if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4294                                         tx_x0_rxk[cal] = tx_x0[cal];
4295                                         tx_y0_rxk[cal] = tx_y0[cal];
4296                                         tx0iqkok = true;
4297                                         RT_TRACE(rtlpriv, COMP_IQK,
4298                                                  DBG_LOUD, "1");
4299                                 }
4300
4301                                 /* ====== RX IQK ====== */
4302                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4303                                 /* 1. RX RF Setting */
4304                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4305                                 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4306                                 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4307                                 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4308                                 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4309                                 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4310                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4311
4312                                 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4313                                 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4314                                 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4315                                 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4316                                 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4317                                 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4318                                 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4319
4320                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4321                                 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4322                                 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4323                                 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4324
4325                                 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4326
4327                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4328
4329                                 cal_retry = 0;
4330                                 while (1) {
4331                                         /* one shot */
4332                                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4333                                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4334
4335                                         mdelay(10); /* Delay 10ms */
4336                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4337                                         delay_count = 0;
4338                                         while (1) {
4339                                                 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4340                                                 if ((~iqk_ready) || (delay_count > 20))
4341                                                         break;
4342                                                 else{
4343                                                         mdelay(1);
4344                                                         delay_count++;
4345                                                 }
4346                                         }
4347
4348                                         if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4349                                                 /* ============RXIQK Check============== */
4350                                                 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4351                                                 if (rx_fail == 0) {
4352                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4353                                                         rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4354                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4355                                                         rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4356                                                         rx0iqkok = true;
4357                                                         break;
4358                                                 } else{
4359                                                         rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4360                                                         rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4361                                                         rx0iqkok = false;
4362                                                         cal_retry++;
4363                                                         if (cal_retry == 10)
4364                                                                 break;
4365
4366                                                 }
4367                                         } else{
4368                                                 rx0iqkok = false;
4369                                                 cal_retry++;
4370                                                 if (cal_retry == 10)
4371                                                         break;
4372                                         }
4373                                 }
4374                         }
4375
4376                         if (tx0iqkok)
4377                                 tx_average++;
4378                         if (rx0iqkok)
4379                                 rx_average++;
4380                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4381                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4382                         break;
4383                 default:
4384                         break;
4385                 }
4386                 cal++;
4387         }
4388
4389         /* FillIQK Result */
4390         switch (path) {
4391         case RF90_PATH_A:
4392                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4393                          "========Path_A =======\n");
4394                 if (tx_average == 0)
4395                         break;
4396
4397                 for (i = 0; i < tx_average; i++) {
4398                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4399                                  "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4400                                  (tx_x0_rxk[i])>>21&0x000007ff, i,
4401                                  (tx_y0_rxk[i])>>21&0x000007ff);
4402                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4403                                  "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4404                                  (tx_x0[i])>>21&0x000007ff, i,
4405                                  (tx_y0[i])>>21&0x000007ff);
4406                 }
4407                 for (i = 0; i < tx_average; i++) {
4408                         for (ii = i+1; ii < tx_average; ii++) {
4409                                 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4410                                 if (dx < 3 && dx > -3) {
4411                                         dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4412                                         if (dy < 3 && dy > -3) {
4413                                                 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4414                                                 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4415                                                 tx_finish = 1;
4416                                                 break;
4417                                         }
4418                                 }
4419                         }
4420                         if (tx_finish == 1)
4421                                 break;
4422                 }
4423
4424                 if (tx_finish == 1)
4425                         _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4426                 else
4427                         _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4428
4429                 if (rx_average == 0)
4430                         break;
4431
4432                 for (i = 0; i < rx_average; i++)
4433                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4434                                 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4435                                 (rx_x0[i])>>21&0x000007ff, i,
4436                                 (rx_y0[i])>>21&0x000007ff);
4437                 for (i = 0; i < rx_average; i++) {
4438                         for (ii = i+1; ii < rx_average; ii++) {
4439                                 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4440                                 if (dx < 4 && dx > -4) {
4441                                         dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4442                                         if (dy < 4 && dy > -4) {
4443                                                 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4444                                                 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4445                                                 rx_finish = 1;
4446                                                 break;
4447                                         }
4448                                 }
4449                         }
4450                         if (rx_finish == 1)
4451                                 break;
4452                 }
4453
4454                 if (rx_finish == 1)
4455                         _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4456                 else
4457                         _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4458                 break;
4459         default:
4460                 break;
4461         }
4462 }
4463
4464 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4465                                       enum radio_path path,
4466                                       u32 *backup_rf_reg,
4467                                       u32 *rf_backup, u32 rf_reg_num)
4468 {
4469         struct rtl_priv *rtlpriv = rtl_priv(hw);
4470         u32 i;
4471
4472         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4473         for (i = 0; i < RF_REG_NUM; i++)
4474                 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4475                               rf_backup[i]);
4476
4477         switch (path) {
4478         case RF90_PATH_A:
4479                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4480                          "RestoreRF Path A Success!!!!\n");
4481                 break;
4482         default:
4483                         break;
4484         }
4485 }
4486
4487 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4488                                        u32 *afe_backup, u32 *backup_afe_reg,
4489                                        u32 afe_num)
4490 {
4491         u32 i;
4492         struct rtl_priv *rtlpriv = rtl_priv(hw);
4493
4494         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4495         /* Reload AFE Parameters */
4496         for (i = 0; i < afe_num; i++)
4497                 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4498         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4499         rtl_write_dword(rtlpriv, 0xc80, 0x0);
4500         rtl_write_dword(rtlpriv, 0xc84, 0x0);
4501         rtl_write_dword(rtlpriv, 0xc88, 0x0);
4502         rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4503         rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4504         rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4505         rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4506         rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4507         rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4508         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4509 }
4510
4511 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4512                                          u32 *macbb_backup,
4513                                          u32 *backup_macbb_reg,
4514                                          u32 macbb_num)
4515 {
4516         u32 i;
4517         struct rtl_priv *rtlpriv = rtl_priv(hw);
4518
4519         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4520         /* Reload MacBB Parameters */
4521         for (i = 0; i < macbb_num; i++)
4522                 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4523         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4524 }
4525
4526 #undef MACBB_REG_NUM
4527 #undef AFE_REG_NUM
4528 #undef RF_REG_NUM
4529
4530 #define MACBB_REG_NUM 11
4531 #define AFE_REG_NUM 12
4532 #define RF_REG_NUM 3
4533
4534 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4535 {
4536         u32     macbb_backup[MACBB_REG_NUM];
4537         u32 afe_backup[AFE_REG_NUM];
4538         u32 rfa_backup[RF_REG_NUM];
4539         u32 rfb_backup[RF_REG_NUM];
4540         u32 backup_macbb_reg[MACBB_REG_NUM] = {
4541                 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4542                 0xe00, 0xe50, 0x838, 0x82c
4543         };
4544         u32 backup_afe_reg[AFE_REG_NUM] = {
4545                 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4546                 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4547         };
4548         u32     backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4549
4550         _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4551                                     MACBB_REG_NUM);
4552         _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4553         _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4554                                  RF_REG_NUM);
4555
4556         _rtl8821ae_iqk_configure_mac(hw);
4557         _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4558         _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4559                                   RF_REG_NUM);
4560
4561         _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4562         _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4563                                      MACBB_REG_NUM);
4564 }
4565
4566 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4567 {
4568         struct rtl_priv *rtlpriv = rtl_priv(hw);
4569         /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4570         /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4571         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4572
4573         if (main)
4574                 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4575         else
4576                 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4577 }
4578
4579 #undef IQK_ADDA_REG_NUM
4580 #undef IQK_DELAY_TIME
4581
4582 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4583 {
4584 }
4585
4586 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4587                       u8 thermal_value, u8 threshold)
4588 {
4589         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4590
4591         rtldm->thermalvalue_iqk = thermal_value;
4592         rtl8812ae_phy_iq_calibrate(hw, false);
4593 }
4594
4595 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4596 {
4597         struct rtl_priv *rtlpriv = rtl_priv(hw);
4598         struct rtl_phy *rtlphy = &rtlpriv->phy;
4599
4600         if (!rtlphy->lck_inprogress) {
4601                 spin_lock(&rtlpriv->locks.iqk_lock);
4602                 rtlphy->lck_inprogress = true;
4603                 spin_unlock(&rtlpriv->locks.iqk_lock);
4604
4605                 _rtl8821ae_phy_iq_calibrate(hw);
4606
4607                 spin_lock(&rtlpriv->locks.iqk_lock);
4608                 rtlphy->lck_inprogress = false;
4609                 spin_unlock(&rtlpriv->locks.iqk_lock);
4610         }
4611 }
4612
4613 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4614 {
4615         struct rtl_priv *rtlpriv = rtl_priv(hw);
4616         struct rtl_phy *rtlphy = &rtlpriv->phy;
4617         u8 i;
4618
4619         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4620                  "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4621                  (int)(sizeof(rtlphy->iqk_matrix) /
4622                  sizeof(struct iqk_matrix_regs)),
4623                  IQK_MATRIX_SETTINGS_NUM);
4624
4625         for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4626                 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4627                 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4628                 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4629                 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4630
4631                 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4632                 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4633                 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4634                 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4635
4636                 rtlphy->iqk_matrix[i].iqk_done = false;
4637         }
4638 }
4639
4640 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4641                       u8 thermal_value, u8 threshold)
4642 {
4643         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4644
4645         rtl8821ae_reset_iqk_result(hw);
4646
4647         rtldm->thermalvalue_iqk = thermal_value;
4648         rtl8821ae_phy_iq_calibrate(hw, false);
4649 }
4650
4651 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4652 {
4653 }
4654
4655 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
4656 {
4657 }
4658
4659 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4660 {
4661         _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4662 }
4663
4664 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4665 {
4666         struct rtl_priv *rtlpriv = rtl_priv(hw);
4667         struct rtl_phy *rtlphy = &rtlpriv->phy;
4668         bool postprocessing = false;
4669
4670         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4671                  "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4672                   iotype, rtlphy->set_io_inprogress);
4673         do {
4674                 switch (iotype) {
4675                 case IO_CMD_RESUME_DM_BY_SCAN:
4676                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4677                                  "[IO CMD] Resume DM after scan.\n");
4678                         postprocessing = true;
4679                         break;
4680                 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4681                 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4682                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4683                                  "[IO CMD] Pause DM before scan.\n");
4684                         postprocessing = true;
4685                         break;
4686                 default:
4687                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4688                                  "switch case not process\n");
4689                         break;
4690                 }
4691         } while (false);
4692         if (postprocessing && !rtlphy->set_io_inprogress) {
4693                 rtlphy->set_io_inprogress = true;
4694                 rtlphy->current_io_type = iotype;
4695         } else {
4696                 return false;
4697         }
4698         rtl8821ae_phy_set_io(hw);
4699         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4700         return true;
4701 }
4702
4703 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4704 {
4705         struct rtl_priv *rtlpriv = rtl_priv(hw);
4706         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4707         struct rtl_phy *rtlphy = &rtlpriv->phy;
4708
4709         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4710                  "--->Cmd(%#x), set_io_inprogress(%d)\n",
4711                   rtlphy->current_io_type, rtlphy->set_io_inprogress);
4712         switch (rtlphy->current_io_type) {
4713         case IO_CMD_RESUME_DM_BY_SCAN:
4714                 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4715                         _rtl8821ae_resume_tx_beacon(hw);
4716                 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4717                 rtl8821ae_dm_write_cck_cca_thres(hw,
4718                                                  rtlphy->initgain_backup.cca);
4719                 break;
4720         case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4721                 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4722                         _rtl8821ae_stop_tx_beacon(hw);
4723                 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4724                 rtl8821ae_dm_write_dig(hw, 0x17);
4725                 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4726                 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4727                 break;
4728         case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4729                 break;
4730         default:
4731                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4732                          "switch case not process\n");
4733                 break;
4734         }
4735         rtlphy->set_io_inprogress = false;
4736         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4737                  "(%#x)\n", rtlphy->current_io_type);
4738 }
4739
4740 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4741 {
4742         struct rtl_priv *rtlpriv = rtl_priv(hw);
4743
4744         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4745         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4746         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4747         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4748         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4749 }
4750
4751 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4752                                               enum rf_pwrstate rfpwr_state)
4753 {
4754         struct rtl_priv *rtlpriv = rtl_priv(hw);
4755         struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4756         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4757         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4758         bool bresult = true;
4759         u8 i, queue_id;
4760         struct rtl8192_tx_ring *ring = NULL;
4761
4762         switch (rfpwr_state) {
4763         case ERFON:
4764                 if ((ppsc->rfpwr_state == ERFOFF) &&
4765                     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4766                         bool rtstatus = false;
4767                         u32 initializecount = 0;
4768
4769                         do {
4770                                 initializecount++;
4771                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4772                                          "IPS Set eRf nic enable\n");
4773                                 rtstatus = rtl_ps_enable_nic(hw);
4774                         } while (!rtstatus && (initializecount < 10));
4775                         RT_CLEAR_PS_LEVEL(ppsc,
4776                                           RT_RF_OFF_LEVL_HALT_NIC);
4777                 } else {
4778                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4779                                  "Set ERFON sleeped:%d ms\n",
4780                                   jiffies_to_msecs(jiffies -
4781                                                    ppsc->
4782                                                    last_sleep_jiffies));
4783                         ppsc->last_awake_jiffies = jiffies;
4784                         rtl8821ae_phy_set_rf_on(hw);
4785                 }
4786                 if (mac->link_state == MAC80211_LINKED) {
4787                         rtlpriv->cfg->ops->led_control(hw,
4788                                                        LED_CTL_LINK);
4789                 } else {
4790                         rtlpriv->cfg->ops->led_control(hw,
4791                                                        LED_CTL_NO_LINK);
4792                 }
4793                 break;
4794         case ERFOFF:
4795                 for (queue_id = 0, i = 0;
4796                      queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4797                         ring = &pcipriv->dev.tx_ring[queue_id];
4798                         if (queue_id == BEACON_QUEUE ||
4799                             skb_queue_len(&ring->queue) == 0) {
4800                                 queue_id++;
4801                                 continue;
4802                         } else {
4803                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4804                                          "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4805                                          (i + 1), queue_id,
4806                                          skb_queue_len(&ring->queue));
4807
4808                                 udelay(10);
4809                                 i++;
4810                         }
4811                         if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4812                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4813                                          "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4814                                           MAX_DOZE_WAITING_TIMES_9x,
4815                                           queue_id,
4816                                           skb_queue_len(&ring->queue));
4817                                 break;
4818                         }
4819                 }
4820
4821                 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4822                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4823                                  "IPS Set eRf nic disable\n");
4824                         rtl_ps_disable_nic(hw);
4825                         RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4826                 } else {
4827                         if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4828                                 rtlpriv->cfg->ops->led_control(hw,
4829                                                                LED_CTL_NO_LINK);
4830                         } else {
4831                                 rtlpriv->cfg->ops->led_control(hw,
4832                                                                LED_CTL_POWER_OFF);
4833                         }
4834                 }
4835                 break;
4836         default:
4837                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4838                          "switch case not process\n");
4839                 bresult = false;
4840                 break;
4841         }
4842         if (bresult)
4843                 ppsc->rfpwr_state = rfpwr_state;
4844         return bresult;
4845 }
4846
4847 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4848                                       enum rf_pwrstate rfpwr_state)
4849 {
4850         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4851
4852         bool bresult = false;
4853
4854         if (rfpwr_state == ppsc->rfpwr_state)
4855                 return bresult;
4856         bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
4857         return bresult;
4858 }