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