GNU Linux-libre 4.4.289-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         char reg_swing_2g = -1;/* 0xff; */
471         char reg_swing_5g = -1;/* 0xff; */
472         char swing_2g = -1 * reg_swing_2g;
473         char swing_5g = -1 * reg_swing_5g;
474         u32  out = 0x200;
475         const char 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         char 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", 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", 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         char i = 0;
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         char 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", 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         char 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 char _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         char channel_index = -1;
1565         u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
1566                 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
1567                 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
1568                 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149,
1569                 151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171,
1570                 173, 175, 177};
1571         u8  i = 0;
1572         if (band == BAND_ON_2_4G)
1573                 channel_index = channel - 1;
1574         else if (band == BAND_ON_5G) {
1575                 for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) {
1576                         if (channel_5g[i] == channel)
1577                                 channel_index = i;
1578                 }
1579         } else
1580                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
1581                          band,  __func__);
1582
1583         if (channel_index == -1)
1584                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1585                          "Invalid Channel %d of Band %d in %s", channel,
1586                          band, __func__);
1587
1588         return channel_index;
1589 }
1590
1591 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1592                                       u8 *pband, u8 *pbandwidth,
1593                                       u8 *prate_section, u8 *prf_path,
1594                                       u8 *pchannel, u8 *ppower_limit)
1595 {
1596         struct rtl_priv *rtlpriv = rtl_priv(hw);
1597         struct rtl_phy *rtlphy = &rtlpriv->phy;
1598         u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1599         u8 channel_index;
1600         char power_limit = 0, prev_power_limit, ret;
1601
1602         if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1603             !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1604                                                 &power_limit)) {
1605                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1606                          "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1607                           channel, power_limit);
1608         }
1609
1610         power_limit = power_limit > MAX_POWER_INDEX ?
1611                       MAX_POWER_INDEX : power_limit;
1612
1613         if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1614                 regulation = 0;
1615         else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1616                 regulation = 1;
1617         else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1618                 regulation = 2;
1619         else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1620                 regulation = 3;
1621
1622         if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1623                 rate_section = 0;
1624         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1625                 rate_section = 1;
1626         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1627                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1628                 rate_section = 2;
1629         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1630                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1631                 rate_section = 3;
1632         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1633                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1634                 rate_section = 4;
1635         else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1636                  _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1637                 rate_section = 5;
1638
1639         if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1640                 bandwidth = 0;
1641         else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1642                 bandwidth = 1;
1643         else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1644                 bandwidth = 2;
1645         else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1646                 bandwidth = 3;
1647
1648         if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1649                 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1650                                                                BAND_ON_2_4G,
1651                                                                channel);
1652
1653                 if (ret == -1)
1654                         return;
1655
1656                 channel_index = ret;
1657
1658                 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1659                                                 [bandwidth][rate_section]
1660                                                 [channel_index][RF90_PATH_A];
1661
1662                 if (power_limit < prev_power_limit)
1663                         rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1664                                 [rate_section][channel_index][RF90_PATH_A] =
1665                                                                    power_limit;
1666
1667                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1668                          "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1669                           regulation, bandwidth, rate_section, channel_index,
1670                           rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1671                                 [rate_section][channel_index][RF90_PATH_A]);
1672         } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1673                 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1674                                                                BAND_ON_5G,
1675                                                                channel);
1676
1677                 if (ret == -1)
1678                         return;
1679
1680                 channel_index = ret;
1681
1682                 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1683                                                 [rate_section][channel_index]
1684                                                 [RF90_PATH_A];
1685
1686                 if (power_limit < prev_power_limit)
1687                         rtlphy->txpwr_limit_5g[regulation][bandwidth]
1688                         [rate_section][channel_index][RF90_PATH_A] = power_limit;
1689
1690                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1691                          "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1692                           regulation, bandwidth, rate_section, channel,
1693                           rtlphy->txpwr_limit_5g[regulation][bandwidth]
1694                                 [rate_section][channel_index][RF90_PATH_A]);
1695         } else {
1696                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1697                          "Cannot recognize the band info in %s\n", pband);
1698                 return;
1699         }
1700 }
1701
1702 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1703                                           u8 *regulation, u8 *band,
1704                                           u8 *bandwidth, u8 *rate_section,
1705                                           u8 *rf_path, u8 *channel,
1706                                           u8 *power_limit)
1707 {
1708         _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1709                                          rate_section, rf_path, channel,
1710                                          power_limit);
1711 }
1712
1713 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1714 {
1715         struct rtl_priv *rtlpriv = rtl_priv(hw);
1716         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1717         u32 i = 0;
1718         u32 array_len;
1719         u8 **array;
1720
1721         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1722                 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1723                 array = RTL8812AE_TXPWR_LMT;
1724         } else {
1725                 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1726                 array = RTL8821AE_TXPWR_LMT;
1727         }
1728
1729         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1730                  "\n");
1731
1732         for (i = 0; i < array_len; i += 7) {
1733                 u8 *regulation = array[i];
1734                 u8 *band = array[i+1];
1735                 u8 *bandwidth = array[i+2];
1736                 u8 *rate = array[i+3];
1737                 u8 *rf_path = array[i+4];
1738                 u8 *chnl = array[i+5];
1739                 u8 *val = array[i+6];
1740
1741                 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1742                                                    bandwidth, rate, rf_path,
1743                                                    chnl, val);
1744         }
1745 }
1746
1747 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1748 {
1749         struct rtl_priv *rtlpriv = rtl_priv(hw);
1750         struct rtl_phy *rtlphy = &rtlpriv->phy;
1751         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1752         bool rtstatus;
1753
1754         _rtl8821ae_phy_init_txpower_limit(hw);
1755
1756         /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1757         if (rtlefuse->eeprom_regulatory != 2)
1758                 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1759
1760         rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1761                                                        BASEBAND_CONFIG_PHY_REG);
1762         if (rtstatus != true) {
1763                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
1764                 return false;
1765         }
1766         _rtl8821ae_phy_init_tx_power_by_rate(hw);
1767         if (rtlefuse->autoload_failflag == false) {
1768                 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1769                                                     BASEBAND_CONFIG_PHY_REG);
1770         }
1771         if (rtstatus != true) {
1772                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
1773                 return false;
1774         }
1775
1776         _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1777
1778         /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1779         if (rtlefuse->eeprom_regulatory != 2)
1780                 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1781
1782         rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1783                                                 BASEBAND_CONFIG_AGC_TAB);
1784
1785         if (rtstatus != true) {
1786                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1787                 return false;
1788         }
1789         rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1790                         RFPGA0_XA_HSSIPARAMETER2, 0x200));
1791         return true;
1792 }
1793
1794 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1795 {
1796         struct rtl_priv *rtlpriv = rtl_priv(hw);
1797         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1798         u32 i, v1, v2;
1799         u32 arraylength;
1800         u32 *ptrarray;
1801
1802         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1803         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1804                 arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1805                 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1806         } else {
1807                 arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1808                 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1809         }
1810         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1811                  "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1812         for (i = 0; i < arraylength; i += 2) {
1813                 v1 = ptrarray[i];
1814                 v2 = (u8)ptrarray[i + 1];
1815                 if (v1 < 0xCDCDCDCD) {
1816                         rtl_write_byte(rtlpriv, v1, (u8)v2);
1817                         continue;
1818                 } else {
1819                         if (!_rtl8821ae_check_condition(hw, v1)) {
1820                                 /*Discard the following (offset, data) pairs*/
1821                                 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1822                                 while (v2 != 0xDEAD &&
1823                                        v2 != 0xCDEF &&
1824                                        v2 != 0xCDCD && i < arraylength - 2) {
1825                                         READ_NEXT_PAIR(ptrarray, v1, v2, i);
1826                                 }
1827                                 i -= 2; /* prevent from for-loop += 2*/
1828                         } else {/*Configure matched pairs and skip to end of if-else.*/
1829                                 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1830                                 while (v2 != 0xDEAD &&
1831                                        v2 != 0xCDEF &&
1832                                        v2 != 0xCDCD && i < arraylength - 2) {
1833                                         rtl_write_byte(rtlpriv, v1, v2);
1834                                         READ_NEXT_PAIR(ptrarray, v1, v2, i);
1835                                 }
1836
1837                                 while (v2 != 0xDEAD && i < arraylength - 2)
1838                                         READ_NEXT_PAIR(ptrarray, v1, v2, i);
1839                         }
1840                 }
1841         }
1842         return true;
1843 }
1844
1845 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1846                                                      u8 configtype)
1847 {
1848         struct rtl_priv *rtlpriv = rtl_priv(hw);
1849         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1850         int i;
1851         u32 *array_table;
1852         u16 arraylen;
1853         u32 v1 = 0, v2 = 0;
1854
1855         if (configtype == BASEBAND_CONFIG_PHY_REG) {
1856                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1857                         arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1858                         array_table = RTL8812AE_PHY_REG_ARRAY;
1859                 } else {
1860                         arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1861                         array_table = RTL8821AE_PHY_REG_ARRAY;
1862                 }
1863
1864                 for (i = 0; i < arraylen; i += 2) {
1865                         v1 = array_table[i];
1866                         v2 = array_table[i + 1];
1867                         if (v1 < 0xCDCDCDCD) {
1868                                 _rtl8821ae_config_bb_reg(hw, v1, v2);
1869                                 continue;
1870                         } else {/*This line is the start line of branch.*/
1871                                 if (!_rtl8821ae_check_condition(hw, v1)) {
1872                                         /*Discard the following (offset, data) pairs*/
1873                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1874                                         while (v2 != 0xDEAD &&
1875                                                v2 != 0xCDEF &&
1876                                                v2 != 0xCDCD &&
1877                                                i < arraylen - 2) {
1878                                                 READ_NEXT_PAIR(array_table, v1,
1879                                                                 v2, i);
1880                                         }
1881
1882                                         i -= 2; /* prevent from for-loop += 2*/
1883                                 } else {/*Configure matched pairs and skip to end of if-else.*/
1884                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1885                                         while (v2 != 0xDEAD &&
1886                                                v2 != 0xCDEF &&
1887                                                v2 != 0xCDCD &&
1888                                                i < arraylen - 2) {
1889                                                 _rtl8821ae_config_bb_reg(hw, v1,
1890                                                                          v2);
1891                                                 READ_NEXT_PAIR(array_table, v1,
1892                                                                v2, i);
1893                                         }
1894
1895                                         while (v2 != 0xDEAD &&
1896                                                i < arraylen - 2) {
1897                                                 READ_NEXT_PAIR(array_table, v1,
1898                                                                v2, i);
1899                                         }
1900                                 }
1901                         }
1902                 }
1903         } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1904                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1905                         arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1906                         array_table = RTL8812AE_AGC_TAB_ARRAY;
1907                 } else {
1908                         arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1909                         array_table = RTL8821AE_AGC_TAB_ARRAY;
1910                 }
1911
1912                 for (i = 0; i < arraylen; i = i + 2) {
1913                         v1 = array_table[i];
1914                         v2 = array_table[i+1];
1915                         if (v1 < 0xCDCDCDCD) {
1916                                 rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1917                                 udelay(1);
1918                                 continue;
1919                         } else {/*This line is the start line of branch.*/
1920                                 if (!_rtl8821ae_check_condition(hw, v1)) {
1921                                         /*Discard the following (offset, data) pairs*/
1922                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1923                                         while (v2 != 0xDEAD &&
1924                                                v2 != 0xCDEF &&
1925                                                v2 != 0xCDCD &&
1926                                                i < arraylen - 2) {
1927                                                 READ_NEXT_PAIR(array_table, v1,
1928                                                                 v2, i);
1929                                         }
1930                                         i -= 2; /* prevent from for-loop += 2*/
1931                                 } else {/*Configure matched pairs and skip to end of if-else.*/
1932                                         READ_NEXT_PAIR(array_table, v1, v2, i);
1933                                         while (v2 != 0xDEAD &&
1934                                                v2 != 0xCDEF &&
1935                                                v2 != 0xCDCD &&
1936                                                i < arraylen - 2) {
1937                                                 rtl_set_bbreg(hw, v1, MASKDWORD,
1938                                                               v2);
1939                                                 udelay(1);
1940                                                 READ_NEXT_PAIR(array_table, v1,
1941                                                                v2, i);
1942                                         }
1943
1944                                         while (v2 != 0xDEAD &&
1945                                                 i < arraylen - 2) {
1946                                                 READ_NEXT_PAIR(array_table, v1,
1947                                                                 v2, i);
1948                                         }
1949                                 }
1950                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1951                                          "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1952                                           array_table[i],  array_table[i + 1]);
1953                         }
1954                 }
1955         }
1956         return true;
1957 }
1958
1959 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1960 {
1961         u8 index = 0;
1962         regaddr &= 0xFFF;
1963         if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1964                 index = (u8)((regaddr - 0xC20) / 4);
1965         else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1966                 index = (u8)((regaddr - 0xE20) / 4);
1967         else
1968                 RT_ASSERT(!COMP_INIT,
1969                           "Invalid RegAddr 0x%x\n", regaddr);
1970         return index;
1971 }
1972
1973 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1974                                               u32 band, u32 rfpath,
1975                                               u32 txnum, u32 regaddr,
1976                                               u32 bitmask, u32 data)
1977 {
1978         struct rtl_priv *rtlpriv = rtl_priv(hw);
1979         struct rtl_phy *rtlphy = &rtlpriv->phy;
1980         u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1981
1982         if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1983                 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1984                 band = BAND_ON_2_4G;
1985         }
1986         if (rfpath >= MAX_RF_PATH) {
1987                 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1988                 rfpath = MAX_RF_PATH - 1;
1989         }
1990         if (txnum >= MAX_RF_PATH) {
1991                 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1992                 txnum = MAX_RF_PATH - 1;
1993         }
1994         rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1995         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1996                  "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1997                  band, rfpath, txnum, rate_section,
1998                  rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1999 }
2000
2001 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
2002                                                         u8 configtype)
2003 {
2004         struct rtl_priv *rtlpriv = rtl_priv(hw);
2005         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2006         int i;
2007         u32 *array;
2008         u16 arraylen;
2009         u32 v1, v2, v3, v4, v5, v6;
2010
2011         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
2012                 arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
2013                 array = RTL8812AE_PHY_REG_ARRAY_PG;
2014         } else {
2015                 arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
2016                 array = RTL8821AE_PHY_REG_ARRAY_PG;
2017         }
2018
2019         if (configtype != BASEBAND_CONFIG_PHY_REG) {
2020                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
2021                          "configtype != BaseBand_Config_PHY_REG\n");
2022                 return true;
2023         }
2024         for (i = 0; i < arraylen; i += 6) {
2025                 v1 = array[i];
2026                 v2 = array[i+1];
2027                 v3 = array[i+2];
2028                 v4 = array[i+3];
2029                 v5 = array[i+4];
2030                 v6 = array[i+5];
2031
2032                 if (v1 < 0xCDCDCDCD) {
2033                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
2034                                 (v4 == 0xfe || v4 == 0xffe)) {
2035                                 msleep(50);
2036                                 continue;
2037                         }
2038
2039                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
2040                                 if (v4 == 0xfe)
2041                                         msleep(50);
2042                                 else if (v4 == 0xfd)
2043                                         mdelay(5);
2044                                 else if (v4 == 0xfc)
2045                                         mdelay(1);
2046                                 else if (v4 == 0xfb)
2047                                         udelay(50);
2048                                 else if (v4 == 0xfa)
2049                                         udelay(5);
2050                                 else if (v4 == 0xf9)
2051                                         udelay(1);
2052                         }
2053                         _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
2054                                                           v4, v5, v6);
2055                         continue;
2056                 } else {
2057                          /*don't need the hw_body*/
2058                         if (!_rtl8821ae_check_condition(hw, v1)) {
2059                                 i += 2; /* skip the pair of expression*/
2060                                 v1 = array[i];
2061                                 v2 = array[i+1];
2062                                 v3 = array[i+2];
2063                                 while (v2 != 0xDEAD) {
2064                                         i += 3;
2065                                         v1 = array[i];
2066                                         v2 = array[i+1];
2067                                         v3 = array[i+2];
2068                                 }
2069                         }
2070                 }
2071         }
2072
2073         return true;
2074 }
2075
2076 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2077                                              enum radio_path rfpath)
2078 {
2079         int i;
2080         bool rtstatus = true;
2081         u32 *radioa_array_table_a, *radioa_array_table_b;
2082         u16 radioa_arraylen_a, radioa_arraylen_b;
2083         struct rtl_priv *rtlpriv = rtl_priv(hw);
2084         u32 v1 = 0, v2 = 0;
2085
2086         radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
2087         radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
2088         radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
2089         radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2090         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2091                  "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2092         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2093         rtstatus = true;
2094         switch (rfpath) {
2095         case RF90_PATH_A:
2096                 for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2097                         v1 = radioa_array_table_a[i];
2098                         v2 = radioa_array_table_a[i+1];
2099                         if (v1 < 0xcdcdcdcd) {
2100                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2101                                 continue;
2102                         } else{/*This line is the start line of branch.*/
2103                                 if (!_rtl8821ae_check_condition(hw, v1)) {
2104                                         /*Discard the following (offset, data) pairs*/
2105                                         READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2106                                         while (v2 != 0xDEAD &&
2107                                                v2 != 0xCDEF &&
2108                                                v2 != 0xCDCD && i < radioa_arraylen_a-2)
2109                                                 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2110
2111                                         i -= 2; /* prevent from for-loop += 2*/
2112                                 } else {/*Configure matched pairs and skip to end of if-else.*/
2113                                         READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2114                                         while (v2 != 0xDEAD &&
2115                                                v2 != 0xCDEF &&
2116                                                v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2117                                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2118                                                 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2119                                         }
2120
2121                                         while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2122                                                 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2123
2124                                 }
2125                         }
2126                 }
2127                 break;
2128         case RF90_PATH_B:
2129                 for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2130                         v1 = radioa_array_table_b[i];
2131                         v2 = radioa_array_table_b[i+1];
2132                         if (v1 < 0xcdcdcdcd) {
2133                                 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2134                                 continue;
2135                         } else{/*This line is the start line of branch.*/
2136                                 if (!_rtl8821ae_check_condition(hw, v1)) {
2137                                         /*Discard the following (offset, data) pairs*/
2138                                         READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2139                                         while (v2 != 0xDEAD &&
2140                                                v2 != 0xCDEF &&
2141                                                v2 != 0xCDCD && i < radioa_arraylen_b-2)
2142                                                 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2143
2144                                         i -= 2; /* prevent from for-loop += 2*/
2145                                 } else {/*Configure matched pairs and skip to end of if-else.*/
2146                                         READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2147                                         while (v2 != 0xDEAD &&
2148                                                v2 != 0xCDEF &&
2149                                                v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2150                                                 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2151                                                 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2152                                         }
2153
2154                                         while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2155                                                 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2156                                 }
2157                         }
2158                 }
2159                 break;
2160         case RF90_PATH_C:
2161                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2162                          "switch case not process\n");
2163                 break;
2164         case RF90_PATH_D:
2165                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2166                          "switch case not process\n");
2167                 break;
2168         }
2169         return true;
2170 }
2171
2172 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2173                                                 enum radio_path rfpath)
2174 {
2175         #define READ_NEXT_RF_PAIR(v1, v2, i) \
2176         do { \
2177                 i += 2; \
2178                 v1 = radioa_array_table[i]; \
2179                 v2 = radioa_array_table[i+1]; \
2180         } \
2181         while (0)
2182
2183         int i;
2184         bool rtstatus = true;
2185         u32 *radioa_array_table;
2186         u16 radioa_arraylen;
2187         struct rtl_priv *rtlpriv = rtl_priv(hw);
2188         /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2189         u32 v1 = 0, v2 = 0;
2190
2191         radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2192         radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2193         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2194                  "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2195         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2196         rtstatus = true;
2197         switch (rfpath) {
2198         case RF90_PATH_A:
2199                 for (i = 0; i < radioa_arraylen; i = i + 2) {
2200                         v1 = radioa_array_table[i];
2201                         v2 = radioa_array_table[i+1];
2202                         if (v1 < 0xcdcdcdcd)
2203                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2204                         else{/*This line is the start line of branch.*/
2205                                 if (!_rtl8821ae_check_condition(hw, v1)) {
2206                                         /*Discard the following (offset, data) pairs*/
2207                                         READ_NEXT_RF_PAIR(v1, v2, i);
2208                                         while (v2 != 0xDEAD &&
2209                                                 v2 != 0xCDEF &&
2210                                                 v2 != 0xCDCD && i < radioa_arraylen - 2)
2211                                                 READ_NEXT_RF_PAIR(v1, v2, i);
2212
2213                                         i -= 2; /* prevent from for-loop += 2*/
2214                                 } else {/*Configure matched pairs and skip to end of if-else.*/
2215                                         READ_NEXT_RF_PAIR(v1, v2, i);
2216                                         while (v2 != 0xDEAD &&
2217                                                v2 != 0xCDEF &&
2218                                                v2 != 0xCDCD && i < radioa_arraylen - 2) {
2219                                                 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2220                                                 READ_NEXT_RF_PAIR(v1, v2, i);
2221                                         }
2222
2223                                         while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2224                                                 READ_NEXT_RF_PAIR(v1, v2, i);
2225                                 }
2226                         }
2227                 }
2228                 break;
2229
2230         case RF90_PATH_B:
2231                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2232                          "switch case not process\n");
2233                 break;
2234         case RF90_PATH_C:
2235                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2236                          "switch case not process\n");
2237                 break;
2238         case RF90_PATH_D:
2239                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2240                          "switch case not process\n");
2241                 break;
2242         }
2243         return true;
2244 }
2245
2246 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2247 {
2248         struct rtl_priv *rtlpriv = rtl_priv(hw);
2249         struct rtl_phy *rtlphy = &rtlpriv->phy;
2250
2251         rtlphy->default_initialgain[0] =
2252             (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2253         rtlphy->default_initialgain[1] =
2254             (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2255         rtlphy->default_initialgain[2] =
2256             (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2257         rtlphy->default_initialgain[3] =
2258             (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2259
2260         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2261                  "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2262                   rtlphy->default_initialgain[0],
2263                   rtlphy->default_initialgain[1],
2264                   rtlphy->default_initialgain[2],
2265                   rtlphy->default_initialgain[3]);
2266
2267         rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2268                                                ROFDM0_RXDETECTOR3, MASKBYTE0);
2269         rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2270                                               ROFDM0_RXDETECTOR2, MASKDWORD);
2271
2272         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2273                  "Default framesync (0x%x) = 0x%x\n",
2274                   ROFDM0_RXDETECTOR3, rtlphy->framesync);
2275 }
2276
2277 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2278 {
2279         struct rtl_priv *rtlpriv = rtl_priv(hw);
2280         struct rtl_phy *rtlphy = &rtlpriv->phy;
2281
2282         rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2283         rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2284
2285         rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2286         rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2287
2288         rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2289         rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2290
2291         rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2292         rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2293
2294         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2295         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2296
2297         rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2298         rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2299
2300         rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2301         rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2302 }
2303
2304 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2305 {
2306         struct rtl_priv *rtlpriv = rtl_priv(hw);
2307         struct rtl_phy *rtlphy = &rtlpriv->phy;
2308         u8 txpwr_level;
2309         long txpwr_dbm;
2310
2311         txpwr_level = rtlphy->cur_cck_txpwridx;
2312         txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2313                                                  WIRELESS_MODE_B, txpwr_level);
2314         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2315         if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2316                                          WIRELESS_MODE_G,
2317                                          txpwr_level) > txpwr_dbm)
2318                 txpwr_dbm =
2319                     _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2320                                                  txpwr_level);
2321         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2322         if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2323                                          WIRELESS_MODE_N_24G,
2324                                          txpwr_level) > txpwr_dbm)
2325                 txpwr_dbm =
2326                     _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2327                                                  txpwr_level);
2328         *powerlevel = txpwr_dbm;
2329 }
2330
2331 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2332 {
2333         u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
2334                 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
2335                 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
2336                 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140,
2337                 142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165,
2338                 167, 168, 169, 171, 173, 175, 177
2339         };
2340         u8 i = 0;
2341         bool in_24g = true;
2342
2343         if (channel <= 14) {
2344                 in_24g = true;
2345                 *chnl_index = channel - 1;
2346         } else {
2347                 in_24g = false;
2348
2349                 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2350                         if (channel_5g[i] == channel) {
2351                                 *chnl_index = i;
2352                                 return in_24g;
2353                         }
2354                 }
2355         }
2356         return in_24g;
2357 }
2358
2359 static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2360 {
2361         char rate_section = 0;
2362         switch (rate) {
2363         case DESC_RATE1M:
2364         case DESC_RATE2M:
2365         case DESC_RATE5_5M:
2366         case DESC_RATE11M:
2367                 rate_section = 0;
2368                 break;
2369         case DESC_RATE6M:
2370         case DESC_RATE9M:
2371         case DESC_RATE12M:
2372         case DESC_RATE18M:
2373                 rate_section = 1;
2374                 break;
2375         case DESC_RATE24M:
2376         case DESC_RATE36M:
2377         case DESC_RATE48M:
2378         case DESC_RATE54M:
2379                 rate_section = 2;
2380                 break;
2381         case DESC_RATEMCS0:
2382         case DESC_RATEMCS1:
2383         case DESC_RATEMCS2:
2384         case DESC_RATEMCS3:
2385                 rate_section = 3;
2386                 break;
2387         case DESC_RATEMCS4:
2388         case DESC_RATEMCS5:
2389         case DESC_RATEMCS6:
2390         case DESC_RATEMCS7:
2391                 rate_section = 4;
2392                 break;
2393         case DESC_RATEMCS8:
2394         case DESC_RATEMCS9:
2395         case DESC_RATEMCS10:
2396         case DESC_RATEMCS11:
2397                 rate_section = 5;
2398                 break;
2399         case DESC_RATEMCS12:
2400         case DESC_RATEMCS13:
2401         case DESC_RATEMCS14:
2402         case DESC_RATEMCS15:
2403                 rate_section = 6;
2404                 break;
2405         case DESC_RATEVHT1SS_MCS0:
2406         case DESC_RATEVHT1SS_MCS1:
2407         case DESC_RATEVHT1SS_MCS2:
2408         case DESC_RATEVHT1SS_MCS3:
2409                 rate_section = 7;
2410                 break;
2411         case DESC_RATEVHT1SS_MCS4:
2412         case DESC_RATEVHT1SS_MCS5:
2413         case DESC_RATEVHT1SS_MCS6:
2414         case DESC_RATEVHT1SS_MCS7:
2415                 rate_section = 8;
2416                 break;
2417         case DESC_RATEVHT1SS_MCS8:
2418         case DESC_RATEVHT1SS_MCS9:
2419         case DESC_RATEVHT2SS_MCS0:
2420         case DESC_RATEVHT2SS_MCS1:
2421                 rate_section = 9;
2422                 break;
2423         case DESC_RATEVHT2SS_MCS2:
2424         case DESC_RATEVHT2SS_MCS3:
2425         case DESC_RATEVHT2SS_MCS4:
2426         case DESC_RATEVHT2SS_MCS5:
2427                 rate_section = 10;
2428                 break;
2429         case DESC_RATEVHT2SS_MCS6:
2430         case DESC_RATEVHT2SS_MCS7:
2431         case DESC_RATEVHT2SS_MCS8:
2432         case DESC_RATEVHT2SS_MCS9:
2433                 rate_section = 11;
2434                 break;
2435         default:
2436                 RT_ASSERT(true, "Rate_Section is Illegal\n");
2437                 break;
2438         }
2439
2440         return rate_section;
2441 }
2442
2443 static char _rtl8812ae_phy_get_world_wide_limit(char  *limit_table)
2444 {
2445         char min = limit_table[0];
2446         u8 i = 0;
2447
2448         for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2449                 if (limit_table[i] < min)
2450                         min = limit_table[i];
2451         }
2452         return min;
2453 }
2454
2455 static char _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2456                                              u8 band,
2457                                              enum ht_channel_width bandwidth,
2458                                              enum radio_path rf_path,
2459                                              u8 rate, u8 channel)
2460 {
2461         struct rtl_priv *rtlpriv = rtl_priv(hw);
2462         struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2463         struct rtl_phy *rtlphy = &rtlpriv->phy;
2464         short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2465                  rate_section = -1, channel_temp = -1;
2466         u16 bd, regu, bdwidth, sec, chnl;
2467         char power_limit = MAX_POWER_INDEX;
2468
2469         if (rtlefuse->eeprom_regulatory == 2)
2470                 return MAX_POWER_INDEX;
2471
2472         regulation = TXPWR_LMT_WW;
2473
2474         if (band == BAND_ON_2_4G)
2475                 band_temp = 0;
2476         else if (band == BAND_ON_5G)
2477                 band_temp = 1;
2478
2479         if (bandwidth == HT_CHANNEL_WIDTH_20)
2480                 bandwidth_temp = 0;
2481         else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2482                 bandwidth_temp = 1;
2483         else if (bandwidth == HT_CHANNEL_WIDTH_80)
2484                 bandwidth_temp = 2;
2485
2486         switch (rate) {
2487         case DESC_RATE1M:
2488         case DESC_RATE2M:
2489         case DESC_RATE5_5M:
2490         case DESC_RATE11M:
2491                 rate_section = 0;
2492                 break;
2493         case DESC_RATE6M:
2494         case DESC_RATE9M:
2495         case DESC_RATE12M:
2496         case DESC_RATE18M:
2497         case DESC_RATE24M:
2498         case DESC_RATE36M:
2499         case DESC_RATE48M:
2500         case DESC_RATE54M:
2501                 rate_section = 1;
2502                 break;
2503         case DESC_RATEMCS0:
2504         case DESC_RATEMCS1:
2505         case DESC_RATEMCS2:
2506         case DESC_RATEMCS3:
2507         case DESC_RATEMCS4:
2508         case DESC_RATEMCS5:
2509         case DESC_RATEMCS6:
2510         case DESC_RATEMCS7:
2511                 rate_section = 2;
2512                 break;
2513         case DESC_RATEMCS8:
2514         case DESC_RATEMCS9:
2515         case DESC_RATEMCS10:
2516         case DESC_RATEMCS11:
2517         case DESC_RATEMCS12:
2518         case DESC_RATEMCS13:
2519         case DESC_RATEMCS14:
2520         case DESC_RATEMCS15:
2521                 rate_section = 3;
2522                 break;
2523         case DESC_RATEVHT1SS_MCS0:
2524         case DESC_RATEVHT1SS_MCS1:
2525         case DESC_RATEVHT1SS_MCS2:
2526         case DESC_RATEVHT1SS_MCS3:
2527         case DESC_RATEVHT1SS_MCS4:
2528         case DESC_RATEVHT1SS_MCS5:
2529         case DESC_RATEVHT1SS_MCS6:
2530         case DESC_RATEVHT1SS_MCS7:
2531         case DESC_RATEVHT1SS_MCS8:
2532         case DESC_RATEVHT1SS_MCS9:
2533                 rate_section = 4;
2534                 break;
2535         case DESC_RATEVHT2SS_MCS0:
2536         case DESC_RATEVHT2SS_MCS1:
2537         case DESC_RATEVHT2SS_MCS2:
2538         case DESC_RATEVHT2SS_MCS3:
2539         case DESC_RATEVHT2SS_MCS4:
2540         case DESC_RATEVHT2SS_MCS5:
2541         case DESC_RATEVHT2SS_MCS6:
2542         case DESC_RATEVHT2SS_MCS7:
2543         case DESC_RATEVHT2SS_MCS8:
2544         case DESC_RATEVHT2SS_MCS9:
2545                 rate_section = 5;
2546                 break;
2547         default:
2548                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2549                         "Wrong rate 0x%x\n", rate);
2550                 break;
2551         }
2552
2553         if (band_temp == BAND_ON_5G  && rate_section == 0)
2554                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2555                          "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2556
2557         /*workaround for wrong index combination to obtain tx power limit,
2558           OFDM only exists in BW 20M*/
2559         if (rate_section == 1)
2560                 bandwidth_temp = 0;
2561
2562         /*workaround for wrong index combination to obtain tx power limit,
2563          *HT on 80M will reference to HT on 40M
2564          */
2565         if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2566             bandwidth_temp == 2)
2567                 bandwidth_temp = 1;
2568
2569         if (band == BAND_ON_2_4G)
2570                 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2571                 BAND_ON_2_4G, channel);
2572         else if (band == BAND_ON_5G)
2573                 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2574                 BAND_ON_5G, channel);
2575         else if (band == BAND_ON_BOTH)
2576                 ;/* BAND_ON_BOTH don't care temporarily */
2577
2578         if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2579                 rate_section == -1 || channel_temp == -1) {
2580                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2581                          "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2582                          band_temp, regulation, bandwidth_temp, rf_path,
2583                          rate_section, channel_temp);
2584                 return MAX_POWER_INDEX;
2585         }
2586
2587         bd = band_temp;
2588         regu = regulation;
2589         bdwidth = bandwidth_temp;
2590         sec = rate_section;
2591         chnl = channel_temp;
2592
2593         if (band == BAND_ON_2_4G) {
2594                 char limits[10] = {0};
2595                 u8 i;
2596
2597                 for (i = 0; i < 4; ++i)
2598                         limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2599                         [sec][chnl][rf_path];
2600
2601                 power_limit = (regulation == TXPWR_LMT_WW) ?
2602                         _rtl8812ae_phy_get_world_wide_limit(limits) :
2603                         rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2604                                         [sec][chnl][rf_path];
2605         } else if (band == BAND_ON_5G) {
2606                 char limits[10] = {0};
2607                 u8 i;
2608
2609                 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2610                         limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2611                         [sec][chnl][rf_path];
2612
2613                 power_limit = (regulation == TXPWR_LMT_WW) ?
2614                         _rtl8812ae_phy_get_world_wide_limit(limits) :
2615                         rtlphy->txpwr_limit_5g[regu][chnl]
2616                         [sec][chnl][rf_path];
2617         } else {
2618                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2619                          "No power limit table of the specified band\n");
2620         }
2621         return power_limit;
2622 }
2623
2624 static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2625                                         u8 band, u8 path, u8 rate)
2626 {
2627         struct rtl_priv *rtlpriv = rtl_priv(hw);
2628         struct rtl_phy *rtlphy = &rtlpriv->phy;
2629         u8 shift = 0, rate_section, tx_num;
2630         char tx_pwr_diff = 0;
2631         char limit = 0;
2632
2633         rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2634         tx_num = RF_TX_NUM_NONIMPLEMENT;
2635
2636         if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2637                 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2638                         (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2639                         tx_num = RF_2TX;
2640                 else
2641                         tx_num = RF_1TX;
2642         }
2643
2644         switch (rate) {
2645         case DESC_RATE1M:
2646         case DESC_RATE6M:
2647         case DESC_RATE24M:
2648         case DESC_RATEMCS0:
2649         case DESC_RATEMCS4:
2650         case DESC_RATEMCS8:
2651         case DESC_RATEMCS12:
2652         case DESC_RATEVHT1SS_MCS0:
2653         case DESC_RATEVHT1SS_MCS4:
2654         case DESC_RATEVHT1SS_MCS8:
2655         case DESC_RATEVHT2SS_MCS2:
2656         case DESC_RATEVHT2SS_MCS6:
2657                 shift = 0;
2658                 break;
2659         case DESC_RATE2M:
2660         case DESC_RATE9M:
2661         case DESC_RATE36M:
2662         case DESC_RATEMCS1:
2663         case DESC_RATEMCS5:
2664         case DESC_RATEMCS9:
2665         case DESC_RATEMCS13:
2666         case DESC_RATEVHT1SS_MCS1:
2667         case DESC_RATEVHT1SS_MCS5:
2668         case DESC_RATEVHT1SS_MCS9:
2669         case DESC_RATEVHT2SS_MCS3:
2670         case DESC_RATEVHT2SS_MCS7:
2671                 shift = 8;
2672                 break;
2673         case DESC_RATE5_5M:
2674         case DESC_RATE12M:
2675         case DESC_RATE48M:
2676         case DESC_RATEMCS2:
2677         case DESC_RATEMCS6:
2678         case DESC_RATEMCS10:
2679         case DESC_RATEMCS14:
2680         case DESC_RATEVHT1SS_MCS2:
2681         case DESC_RATEVHT1SS_MCS6:
2682         case DESC_RATEVHT2SS_MCS0:
2683         case DESC_RATEVHT2SS_MCS4:
2684         case DESC_RATEVHT2SS_MCS8:
2685                 shift = 16;
2686                 break;
2687         case DESC_RATE11M:
2688         case DESC_RATE18M:
2689         case DESC_RATE54M:
2690         case DESC_RATEMCS3:
2691         case DESC_RATEMCS7:
2692         case DESC_RATEMCS11:
2693         case DESC_RATEMCS15:
2694         case DESC_RATEVHT1SS_MCS3:
2695         case DESC_RATEVHT1SS_MCS7:
2696         case DESC_RATEVHT2SS_MCS1:
2697         case DESC_RATEVHT2SS_MCS5:
2698         case DESC_RATEVHT2SS_MCS9:
2699                 shift = 24;
2700                 break;
2701         default:
2702                 RT_ASSERT(true, "Rate_Section is Illegal\n");
2703                 break;
2704         }
2705
2706         tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2707                 [tx_num][rate_section] >> shift) & 0xff;
2708
2709         /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2710         if (rtlpriv->efuse.eeprom_regulatory != 2) {
2711                 limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2712                         rtlphy->current_chan_bw, path, rate,
2713                         rtlphy->current_channel);
2714
2715                 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9  ||
2716                          rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2717                         if (limit < 0) {
2718                                 if (tx_pwr_diff < (-limit))
2719                                         tx_pwr_diff = -limit;
2720                         }
2721                 } else {
2722                         if (limit < 0)
2723                                 tx_pwr_diff = limit;
2724                         else
2725                                 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2726                 }
2727                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2728                         "Maximum power by rate %d, final power by rate %d\n",
2729                         limit, tx_pwr_diff);
2730         }
2731
2732         return  tx_pwr_diff;
2733 }
2734
2735 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2736                                         u8 rate, u8 bandwidth, u8 channel)
2737 {
2738         struct rtl_priv *rtlpriv = rtl_priv(hw);
2739         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2740         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2741         u8 index = (channel - 1);
2742         u8 txpower = 0;
2743         bool in_24g = false;
2744         char powerdiff_byrate = 0;
2745
2746         if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2747             (channel > 14 || channel < 1)) ||
2748             ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2749                 index = 0;
2750                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2751                         "Illegal channel!!\n");
2752         }
2753
2754         in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2755         if (in_24g) {
2756                 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2757                         txpower = rtlefuse->txpwrlevel_cck[path][index];
2758                 else if (DESC_RATE6M <= rate)
2759                         txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2760                 else
2761                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2762
2763                 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2764                     !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2765                         txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2766
2767                 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2768                         if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2769                                 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2770                                 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2771                         if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2772                                 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2773                                 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2774                 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2775                         if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2776                                 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2777                                 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2778                         if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2779                                 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2780                                 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2781                 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2782                         if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2783                             (DESC_RATEVHT1SS_MCS0 <= rate &&
2784                              rate <= DESC_RATEVHT2SS_MCS9))
2785                                 txpower += rtlefuse->txpwr_ht40diff[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_ht40diff[path][TX_2S];
2790                 }
2791         } else {
2792                 if (DESC_RATE6M <= rate)
2793                         txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2794                 else
2795                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2796                                  "INVALID Rate.\n");
2797
2798                 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2799                     !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2800                         txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2801
2802                 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2803                         if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2804                             (DESC_RATEVHT1SS_MCS0 <= rate &&
2805                              rate <= DESC_RATEVHT2SS_MCS9))
2806                                 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2807                         if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2808                             (DESC_RATEVHT2SS_MCS0 <= rate &&
2809                              rate <= DESC_RATEVHT2SS_MCS9))
2810                                 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2811                 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2812                         if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2813                             (DESC_RATEVHT1SS_MCS0 <= rate &&
2814                              rate <= DESC_RATEVHT2SS_MCS9))
2815                                 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2816                         if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2817                             (DESC_RATEVHT2SS_MCS0 <= rate &&
2818                              rate <= DESC_RATEVHT2SS_MCS9))
2819                                 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2820                 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2821                         u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2822                                 42, 58, 106, 122, 138, 155, 171
2823                         };
2824                         u8 i;
2825
2826                         for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i)
2827                                 if (channel_5g_80m[i] == channel)
2828                                         index = i;
2829
2830                         if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2831                             (DESC_RATEVHT1SS_MCS0 <= rate &&
2832                              rate <= DESC_RATEVHT2SS_MCS9))
2833                                 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2834                                         + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2835                         if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2836                             (DESC_RATEVHT2SS_MCS0 <= rate &&
2837                              rate <= DESC_RATEVHT2SS_MCS9))
2838                                 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2839                                         + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2840                                         + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2841                     }
2842         }
2843         if (rtlefuse->eeprom_regulatory != 2)
2844                 powerdiff_byrate =
2845                   _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2846                                                      path, rate);
2847
2848         if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2849             rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2850                 txpower -= powerdiff_byrate;
2851         else
2852                 txpower += powerdiff_byrate;
2853
2854         if (rate > DESC_RATE11M)
2855                 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2856         else
2857                 txpower += rtlpriv->dm.remnant_cck_idx;
2858
2859         if (txpower > MAX_POWER_INDEX)
2860                 txpower = MAX_POWER_INDEX;
2861
2862         return txpower;
2863 }
2864
2865 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2866                                              u8 power_index, u8 path, u8 rate)
2867 {
2868         struct rtl_priv *rtlpriv = rtl_priv(hw);
2869
2870         if (path == RF90_PATH_A) {
2871                 switch (rate) {
2872                 case DESC_RATE1M:
2873                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2874                                       MASKBYTE0, power_index);
2875                         break;
2876                 case DESC_RATE2M:
2877                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2878                                       MASKBYTE1, power_index);
2879                         break;
2880                 case DESC_RATE5_5M:
2881                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2882                                       MASKBYTE2, power_index);
2883                         break;
2884                 case DESC_RATE11M:
2885                         rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2886                                       MASKBYTE3, power_index);
2887                         break;
2888                 case DESC_RATE6M:
2889                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2890                                       MASKBYTE0, power_index);
2891                         break;
2892                 case DESC_RATE9M:
2893                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2894                                       MASKBYTE1, power_index);
2895                         break;
2896                 case DESC_RATE12M:
2897                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2898                                       MASKBYTE2, power_index);
2899                         break;
2900                 case DESC_RATE18M:
2901                         rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2902                                       MASKBYTE3, power_index);
2903                         break;
2904                 case DESC_RATE24M:
2905                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2906                                       MASKBYTE0, power_index);
2907                         break;
2908                 case DESC_RATE36M:
2909                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2910                                       MASKBYTE1, power_index);
2911                         break;
2912                 case DESC_RATE48M:
2913                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2914                                       MASKBYTE2, power_index);
2915                         break;
2916                 case DESC_RATE54M:
2917                         rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2918                                       MASKBYTE3, power_index);
2919                         break;
2920                 case DESC_RATEMCS0:
2921                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2922                                       MASKBYTE0, power_index);
2923                         break;
2924                 case DESC_RATEMCS1:
2925                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2926                                       MASKBYTE1, power_index);
2927                         break;
2928                 case DESC_RATEMCS2:
2929                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2930                                       MASKBYTE2, power_index);
2931                         break;
2932                 case DESC_RATEMCS3:
2933                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2934                                       MASKBYTE3, power_index);
2935                         break;
2936                 case DESC_RATEMCS4:
2937                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2938                                       MASKBYTE0, power_index);
2939                         break;
2940                 case DESC_RATEMCS5:
2941                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2942                                       MASKBYTE1, power_index);
2943                         break;
2944                 case DESC_RATEMCS6:
2945                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2946                                       MASKBYTE2, power_index);
2947                         break;
2948                 case DESC_RATEMCS7:
2949                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2950                                       MASKBYTE3, power_index);
2951                         break;
2952                 case DESC_RATEMCS8:
2953                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2954                                       MASKBYTE0, power_index);
2955                         break;
2956                 case DESC_RATEMCS9:
2957                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2958                                       MASKBYTE1, power_index);
2959                         break;
2960                 case DESC_RATEMCS10:
2961                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2962                                       MASKBYTE2, power_index);
2963                         break;
2964                 case DESC_RATEMCS11:
2965                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2966                                       MASKBYTE3, power_index);
2967                         break;
2968                 case DESC_RATEMCS12:
2969                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2970                                       MASKBYTE0, power_index);
2971                         break;
2972                 case DESC_RATEMCS13:
2973                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2974                                       MASKBYTE1, power_index);
2975                         break;
2976                 case DESC_RATEMCS14:
2977                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2978                                       MASKBYTE2, power_index);
2979                         break;
2980                 case DESC_RATEMCS15:
2981                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2982                                       MASKBYTE3, power_index);
2983                         break;
2984                 case DESC_RATEVHT1SS_MCS0:
2985                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2986                                       MASKBYTE0, power_index);
2987                         break;
2988                 case DESC_RATEVHT1SS_MCS1:
2989                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2990                                       MASKBYTE1, power_index);
2991                         break;
2992                 case DESC_RATEVHT1SS_MCS2:
2993                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2994                                       MASKBYTE2, power_index);
2995                         break;
2996                 case DESC_RATEVHT1SS_MCS3:
2997                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2998                                       MASKBYTE3, power_index);
2999                         break;
3000                 case DESC_RATEVHT1SS_MCS4:
3001                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3002                                       MASKBYTE0, power_index);
3003                         break;
3004                 case DESC_RATEVHT1SS_MCS5:
3005                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3006                                       MASKBYTE1, power_index);
3007                         break;
3008                 case DESC_RATEVHT1SS_MCS6:
3009                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3010                                       MASKBYTE2, power_index);
3011                         break;
3012                 case DESC_RATEVHT1SS_MCS7:
3013                         rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
3014                                       MASKBYTE3, power_index);
3015                         break;
3016                 case DESC_RATEVHT1SS_MCS8:
3017                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3018                                       MASKBYTE0, power_index);
3019                         break;
3020                 case DESC_RATEVHT1SS_MCS9:
3021                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3022                                       MASKBYTE1, power_index);
3023                         break;
3024                 case DESC_RATEVHT2SS_MCS0:
3025                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3026                                       MASKBYTE2, power_index);
3027                         break;
3028                 case DESC_RATEVHT2SS_MCS1:
3029                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
3030                                       MASKBYTE3, power_index);
3031                         break;
3032                 case DESC_RATEVHT2SS_MCS2:
3033                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3034                                       MASKBYTE0, power_index);
3035                         break;
3036                 case DESC_RATEVHT2SS_MCS3:
3037                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3038                                       MASKBYTE1, power_index);
3039                         break;
3040                 case DESC_RATEVHT2SS_MCS4:
3041                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3042                                       MASKBYTE2, power_index);
3043                         break;
3044                 case DESC_RATEVHT2SS_MCS5:
3045                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
3046                                       MASKBYTE3, power_index);
3047                         break;
3048                 case DESC_RATEVHT2SS_MCS6:
3049                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3050                                       MASKBYTE0, power_index);
3051                         break;
3052                 case DESC_RATEVHT2SS_MCS7:
3053                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3054                                       MASKBYTE1, power_index);
3055                         break;
3056                 case DESC_RATEVHT2SS_MCS8:
3057                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3058                                       MASKBYTE2, power_index);
3059                         break;
3060                 case DESC_RATEVHT2SS_MCS9:
3061                         rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
3062                                       MASKBYTE3, power_index);
3063                         break;
3064                 default:
3065                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3066                                 "Invalid Rate!!\n");
3067                         break;
3068                 }
3069         } else if (path == RF90_PATH_B) {
3070                 switch (rate) {
3071                 case DESC_RATE1M:
3072                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3073                                       MASKBYTE0, power_index);
3074                         break;
3075                 case DESC_RATE2M:
3076                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3077                                       MASKBYTE1, power_index);
3078                         break;
3079                 case DESC_RATE5_5M:
3080                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3081                                       MASKBYTE2, power_index);
3082                         break;
3083                 case DESC_RATE11M:
3084                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
3085                                       MASKBYTE3, power_index);
3086                         break;
3087                 case DESC_RATE6M:
3088                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3089                                       MASKBYTE0, power_index);
3090                         break;
3091                 case DESC_RATE9M:
3092                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3093                                       MASKBYTE1, power_index);
3094                         break;
3095                 case DESC_RATE12M:
3096                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3097                                       MASKBYTE2, power_index);
3098                         break;
3099                 case DESC_RATE18M:
3100                         rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3101                                       MASKBYTE3, power_index);
3102                         break;
3103                 case DESC_RATE24M:
3104                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3105                                       MASKBYTE0, power_index);
3106                         break;
3107                 case DESC_RATE36M:
3108                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3109                                       MASKBYTE1, power_index);
3110                         break;
3111                 case DESC_RATE48M:
3112                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3113                                       MASKBYTE2, power_index);
3114                         break;
3115                 case DESC_RATE54M:
3116                         rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3117                                       MASKBYTE3, power_index);
3118                         break;
3119                 case DESC_RATEMCS0:
3120                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3121                                       MASKBYTE0, power_index);
3122                         break;
3123                 case DESC_RATEMCS1:
3124                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3125                                       MASKBYTE1, power_index);
3126                         break;
3127                 case DESC_RATEMCS2:
3128                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3129                                       MASKBYTE2, power_index);
3130                         break;
3131                 case DESC_RATEMCS3:
3132                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3133                                       MASKBYTE3, power_index);
3134                         break;
3135                 case DESC_RATEMCS4:
3136                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3137                                       MASKBYTE0, power_index);
3138                         break;
3139                 case DESC_RATEMCS5:
3140                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3141                                       MASKBYTE1, power_index);
3142                         break;
3143                 case DESC_RATEMCS6:
3144                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3145                                       MASKBYTE2, power_index);
3146                         break;
3147                 case DESC_RATEMCS7:
3148                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3149                                       MASKBYTE3, power_index);
3150                         break;
3151                 case DESC_RATEMCS8:
3152                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3153                                       MASKBYTE0, power_index);
3154                         break;
3155                 case DESC_RATEMCS9:
3156                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3157                                       MASKBYTE1, power_index);
3158                         break;
3159                 case DESC_RATEMCS10:
3160                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3161                                       MASKBYTE2, power_index);
3162                         break;
3163                 case DESC_RATEMCS11:
3164                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3165                                       MASKBYTE3, power_index);
3166                         break;
3167                 case DESC_RATEMCS12:
3168                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3169                                       MASKBYTE0, power_index);
3170                         break;
3171                 case DESC_RATEMCS13:
3172                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3173                                       MASKBYTE1, power_index);
3174                         break;
3175                 case DESC_RATEMCS14:
3176                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3177                                       MASKBYTE2, power_index);
3178                         break;
3179                 case DESC_RATEMCS15:
3180                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3181                                       MASKBYTE3, power_index);
3182                         break;
3183                 case DESC_RATEVHT1SS_MCS0:
3184                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3185                                       MASKBYTE0, power_index);
3186                         break;
3187                 case DESC_RATEVHT1SS_MCS1:
3188                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3189                                       MASKBYTE1, power_index);
3190                         break;
3191                 case DESC_RATEVHT1SS_MCS2:
3192                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3193                                       MASKBYTE2, power_index);
3194                         break;
3195                 case DESC_RATEVHT1SS_MCS3:
3196                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3197                                       MASKBYTE3, power_index);
3198                         break;
3199                 case DESC_RATEVHT1SS_MCS4:
3200                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3201                                       MASKBYTE0, power_index);
3202                         break;
3203                 case DESC_RATEVHT1SS_MCS5:
3204                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3205                                       MASKBYTE1, power_index);
3206                         break;
3207                 case DESC_RATEVHT1SS_MCS6:
3208                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3209                                       MASKBYTE2, power_index);
3210                         break;
3211                 case DESC_RATEVHT1SS_MCS7:
3212                         rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3213                                       MASKBYTE3, power_index);
3214                         break;
3215                 case DESC_RATEVHT1SS_MCS8:
3216                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3217                                       MASKBYTE0, power_index);
3218                         break;
3219                 case DESC_RATEVHT1SS_MCS9:
3220                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3221                                       MASKBYTE1, power_index);
3222                         break;
3223                 case DESC_RATEVHT2SS_MCS0:
3224                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3225                                       MASKBYTE2, power_index);
3226                         break;
3227                 case DESC_RATEVHT2SS_MCS1:
3228                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3229                                       MASKBYTE3, power_index);
3230                         break;
3231                 case DESC_RATEVHT2SS_MCS2:
3232                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3233                                       MASKBYTE0, power_index);
3234                         break;
3235                 case DESC_RATEVHT2SS_MCS3:
3236                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3237                                       MASKBYTE1, power_index);
3238                         break;
3239                 case DESC_RATEVHT2SS_MCS4:
3240                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3241                                       MASKBYTE2, power_index);
3242                         break;
3243                 case DESC_RATEVHT2SS_MCS5:
3244                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3245                                       MASKBYTE3, power_index);
3246                         break;
3247                 case DESC_RATEVHT2SS_MCS6:
3248                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3249                                       MASKBYTE0, power_index);
3250                         break;
3251                 case DESC_RATEVHT2SS_MCS7:
3252                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3253                                       MASKBYTE1, power_index);
3254                         break;
3255                 case DESC_RATEVHT2SS_MCS8:
3256                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3257                                       MASKBYTE2, power_index);
3258                         break;
3259                 case DESC_RATEVHT2SS_MCS9:
3260                         rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3261                                       MASKBYTE3, power_index);
3262                         break;
3263                 default:
3264                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3265                                  "Invalid Rate!!\n");
3266                         break;
3267                 }
3268         } else {
3269                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3270                          "Invalid RFPath!!\n");
3271         }
3272 }
3273
3274 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3275                                                      u8 *array, u8 path,
3276                                                      u8 channel, u8 size)
3277 {
3278         struct rtl_priv *rtlpriv = rtl_priv(hw);
3279         struct rtl_phy *rtlphy = &rtlpriv->phy;
3280         u8 i;
3281         u8 power_index;
3282
3283         for (i = 0; i < size; i++) {
3284                 power_index =
3285                   _rtl8821ae_get_txpower_index(hw, path, array[i],
3286                                                rtlphy->current_chan_bw,
3287                                                channel);
3288                 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3289                                                  array[i]);
3290         }
3291 }
3292
3293 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3294                                                     u8 bw, u8 channel, u8 path)
3295 {
3296         struct rtl_priv *rtlpriv = rtl_priv(hw);
3297         struct rtl_phy *rtlphy = &rtlpriv->phy;
3298
3299         u8 i;
3300         u32 power_level, data, offset;
3301
3302         if (path >= rtlphy->num_total_rfpath)
3303                 return;
3304
3305         data = 0;
3306         if (path == RF90_PATH_A) {
3307                 power_level =
3308                         _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3309                         DESC_RATEMCS7, bw, channel);
3310                 offset =  RA_TXPWRTRAING;
3311         } else {
3312                 power_level =
3313                         _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3314                         DESC_RATEMCS7, bw, channel);
3315                 offset =  RB_TXPWRTRAING;
3316         }
3317
3318         for (i = 0; i < 3; i++) {
3319                 if (i == 0)
3320                         power_level = power_level - 10;
3321                 else if (i == 1)
3322                         power_level = power_level - 8;
3323                 else
3324                         power_level = power_level - 6;
3325
3326                 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3327         }
3328         rtl_set_bbreg(hw, offset, 0xffffff, data);
3329 }
3330
3331 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3332                                              u8 channel, u8 path)
3333 {
3334         /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3335         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3336         struct rtl_priv *rtlpriv = rtl_priv(hw);
3337         struct rtl_phy *rtlphy = &rtlpriv->phy;
3338         u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3339                               DESC_RATE11M};
3340         u8 sizes_of_cck_retes = 4;
3341         u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3342                                 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3343                                 DESC_RATE48M, DESC_RATE54M};
3344         u8 sizes_of_ofdm_retes = 8;
3345         u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3346                                 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3347                                 DESC_RATEMCS6, DESC_RATEMCS7};
3348         u8 sizes_of_ht_retes_1t = 8;
3349         u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9,
3350                                 DESC_RATEMCS10, DESC_RATEMCS11,
3351                                 DESC_RATEMCS12, DESC_RATEMCS13,
3352                                 DESC_RATEMCS14, DESC_RATEMCS15};
3353         u8 sizes_of_ht_retes_2t = 8;
3354         u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3355                                 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3356                                 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3357                                 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3358                              DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3359         u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3360                                 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3361                                 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3362                                 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3363                                 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3364         u8 sizes_of_vht_retes = 10;
3365
3366         if (rtlhal->current_bandtype == BAND_ON_2_4G)
3367                 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3368                                                          sizes_of_cck_retes);
3369
3370         _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3371                                                  sizes_of_ofdm_retes);
3372         _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3373                                                  sizes_of_ht_retes_1t);
3374         _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3375                                                  sizes_of_vht_retes);
3376
3377         if (rtlphy->num_total_rfpath >= 2) {
3378                 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3379                                                          channel,
3380                                                          sizes_of_ht_retes_2t);
3381                 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3382                                                          channel,
3383                                                          sizes_of_vht_retes);
3384         }
3385
3386         _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3387                                                 channel, path);
3388 }
3389
3390 /*just in case, write txpower in DW, to reduce time*/
3391 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3392 {
3393         struct rtl_priv *rtlpriv = rtl_priv(hw);
3394         struct rtl_phy *rtlphy = &rtlpriv->phy;
3395         u8 path = 0;
3396
3397         for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3398                 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3399 }
3400
3401 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3402                                             enum wireless_mode wirelessmode,
3403                                             u8 txpwridx)
3404 {
3405         long offset;
3406         long pwrout_dbm;
3407
3408         switch (wirelessmode) {
3409         case WIRELESS_MODE_B:
3410                 offset = -7;
3411                 break;
3412         case WIRELESS_MODE_G:
3413         case WIRELESS_MODE_N_24G:
3414                 offset = -8;
3415                 break;
3416         default:
3417                 offset = -8;
3418                 break;
3419         }
3420         pwrout_dbm = txpwridx / 2 + offset;
3421         return pwrout_dbm;
3422 }
3423
3424 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3425 {
3426         struct rtl_priv *rtlpriv = rtl_priv(hw);
3427         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3428         enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3429
3430         if (!is_hal_stop(rtlhal)) {
3431                 switch (operation) {
3432                 case SCAN_OPT_BACKUP_BAND0:
3433                         iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3434                         rtlpriv->cfg->ops->set_hw_reg(hw,
3435                                                       HW_VAR_IO_CMD,
3436                                                       (u8 *)&iotype);
3437
3438                         break;
3439                 case SCAN_OPT_BACKUP_BAND1:
3440                         iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3441                         rtlpriv->cfg->ops->set_hw_reg(hw,
3442                                                       HW_VAR_IO_CMD,
3443                                                       (u8 *)&iotype);
3444
3445                         break;
3446                 case SCAN_OPT_RESTORE:
3447                         iotype = IO_CMD_RESUME_DM_BY_SCAN;
3448                         rtlpriv->cfg->ops->set_hw_reg(hw,
3449                                                       HW_VAR_IO_CMD,
3450                                                       (u8 *)&iotype);
3451                         break;
3452                 default:
3453                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3454                                  "Unknown Scan Backup operation.\n");
3455                         break;
3456                 }
3457         }
3458 }
3459
3460 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3461 {
3462         u16 reg_rf_mode_bw, tmp = 0;
3463
3464         reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3465         switch (bw) {
3466         case HT_CHANNEL_WIDTH_20:
3467                 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3468                 break;
3469         case HT_CHANNEL_WIDTH_20_40:
3470                 tmp = reg_rf_mode_bw | BIT(7);
3471                 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3472                 break;
3473         case HT_CHANNEL_WIDTH_80:
3474                 tmp = reg_rf_mode_bw | BIT(8);
3475                 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3476                 break;
3477         default:
3478                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3479                 break;
3480         }
3481 }
3482
3483 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3484 {
3485         struct rtl_phy *rtlphy = &rtlpriv->phy;
3486         struct rtl_mac *mac = rtl_mac(rtlpriv);
3487         u8 sc_set_40 = 0, sc_set_20 = 0;
3488
3489         if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3490                 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3491                         sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3492                 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3493                         sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3494                 else
3495                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3496                                 "SCMapping: Not Correct Primary40MHz Setting\n");
3497
3498                 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3499                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3500                         sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3501                 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3502                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3503                         sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3504                 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3505                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3506                         sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3507                 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3508                         (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3509                         sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3510                 else
3511                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3512                                 "SCMapping: Not Correct Primary40MHz Setting\n");
3513         } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3514                 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3515                         sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3516                 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3517                         sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3518                 else
3519                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3520                          "SCMapping: Not Correct Primary40MHz Setting\n");
3521         }
3522         return (sc_set_40 << 4) | sc_set_20;
3523 }
3524
3525 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3526 {
3527         struct rtl_priv *rtlpriv = rtl_priv(hw);
3528         struct rtl_phy *rtlphy = &rtlpriv->phy;
3529         u8 sub_chnl = 0;
3530         u8 l1pk_val = 0;
3531
3532         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3533                  "Switch to %s bandwidth\n",
3534                   (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3535                   "20MHz" :
3536                   (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3537                   "40MHz" : "80MHz")));
3538
3539         _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3540         sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3541         rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3542
3543         switch (rtlphy->current_chan_bw) {
3544         case HT_CHANNEL_WIDTH_20:
3545                 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3546                 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3547
3548                 if (rtlphy->rf_type == RF_2T2R)
3549                         rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3550                 else
3551                         rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3552                 break;
3553         case HT_CHANNEL_WIDTH_20_40:
3554                 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3555                 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3556                 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3557                 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3558
3559                 if (rtlphy->reg_837 & BIT(2))
3560                         l1pk_val = 6;
3561                 else {
3562                         if (rtlphy->rf_type == RF_2T2R)
3563                                 l1pk_val = 7;
3564                         else
3565                                 l1pk_val = 8;
3566                 }
3567                 /* 0x848[25:22] = 0x6 */
3568                 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3569
3570                 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3571                         rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3572                 else
3573                         rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3574                 break;
3575
3576         case HT_CHANNEL_WIDTH_80:
3577                  /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3578                 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3579                 /* 0x8c4[30] = 1 */
3580                 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3581                 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3582                 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3583
3584                 if (rtlphy->reg_837 & BIT(2))
3585                         l1pk_val = 5;
3586                 else {
3587                         if (rtlphy->rf_type == RF_2T2R)
3588                                 l1pk_val = 6;
3589                         else
3590                                 l1pk_val = 7;
3591                 }
3592                 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3593
3594                 break;
3595         default:
3596                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3597                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3598                 break;
3599         }
3600
3601         rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3602
3603         rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3604         rtlphy->set_bwmode_inprogress = false;
3605
3606         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3607 }
3608
3609 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3610                             enum nl80211_channel_type ch_type)
3611 {
3612         struct rtl_priv *rtlpriv = rtl_priv(hw);
3613         struct rtl_phy *rtlphy = &rtlpriv->phy;
3614         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3615         u8 tmp_bw = rtlphy->current_chan_bw;
3616
3617         if (rtlphy->set_bwmode_inprogress)
3618                 return;
3619         rtlphy->set_bwmode_inprogress = true;
3620         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3621                 rtl8821ae_phy_set_bw_mode_callback(hw);
3622         else {
3623                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3624                          "FALSE driver sleep or unload\n");
3625                 rtlphy->set_bwmode_inprogress = false;
3626                 rtlphy->current_chan_bw = tmp_bw;
3627         }
3628 }
3629
3630 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3631 {
3632         struct rtl_priv *rtlpriv = rtl_priv(hw);
3633         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3634         struct rtl_phy *rtlphy = &rtlpriv->phy;
3635         u8 channel = rtlphy->current_channel;
3636         u8 path;
3637         u32 data;
3638
3639         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3640                  "switch to channel%d\n", rtlphy->current_channel);
3641         if (is_hal_stop(rtlhal))
3642                 return;
3643
3644         if (36 <= channel && channel <= 48)
3645                 data = 0x494;
3646         else if (50 <= channel && channel <= 64)
3647                 data = 0x453;
3648         else if (100 <= channel && channel <= 116)
3649                 data = 0x452;
3650         else if (118 <= channel)
3651                 data = 0x412;
3652         else
3653                 data = 0x96a;
3654         rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3655
3656         for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3657                 if (36 <= channel && channel <= 64)
3658                         data = 0x101;
3659                 else if (100 <= channel && channel <= 140)
3660                         data = 0x301;
3661                 else if (140 < channel)
3662                         data = 0x501;
3663                 else
3664                         data = 0x000;
3665                 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3666                         BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3667
3668                 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3669                         BMASKBYTE0, channel);
3670
3671                 if (channel > 14) {
3672                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3673                                 if (36 <= channel && channel <= 64)
3674                                         data = 0x114E9;
3675                                 else if (100 <= channel && channel <= 140)
3676                                         data = 0x110E9;
3677                                 else
3678                                         data = 0x110E9;
3679                                 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3680                                         BRFREGOFFSETMASK, data);
3681                         }
3682                 }
3683         }
3684         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3685 }
3686
3687 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3688 {
3689         struct rtl_priv *rtlpriv = rtl_priv(hw);
3690         struct rtl_phy *rtlphy = &rtlpriv->phy;
3691         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3692         u32 timeout = 1000, timecount = 0;
3693         u8 channel = rtlphy->current_channel;
3694
3695         if (rtlphy->sw_chnl_inprogress)
3696                 return 0;
3697         if (rtlphy->set_bwmode_inprogress)
3698                 return 0;
3699
3700         if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3701                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3702                          "sw_chnl_inprogress false driver sleep or unload\n");
3703                 return 0;
3704         }
3705         while (rtlphy->lck_inprogress && timecount < timeout) {
3706                 mdelay(50);
3707                 timecount += 50;
3708         }
3709
3710         if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3711                 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3712         else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3713                 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3714
3715         rtlphy->sw_chnl_inprogress = true;
3716         if (channel == 0)
3717                 channel = 1;
3718
3719         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3720                  "switch to channel%d, band type is %d\n",
3721                  rtlphy->current_channel, rtlhal->current_bandtype);
3722
3723         rtl8821ae_phy_sw_chnl_callback(hw);
3724
3725         rtl8821ae_dm_clear_txpower_tracking_state(hw);
3726         rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3727
3728         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3729         rtlphy->sw_chnl_inprogress = false;
3730         return 1;
3731 }
3732
3733 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3734 {
3735         u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3736                 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3737                 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3738                 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3739                 110, 112, 114, 116, 118, 120, 122, 124, 126,
3740                 128, 130, 132, 134, 136, 138, 140, 149, 151,
3741                 153, 155, 157, 159, 161, 163, 165};
3742         u8 place = chnl;
3743
3744         if (chnl > 14) {
3745                 for (place = 14; place < sizeof(channel_all); place++)
3746                         if (channel_all[place] == chnl)
3747                                 return place-13;
3748         }
3749
3750         return 0;
3751 }
3752
3753 #define MACBB_REG_NUM 10
3754 #define AFE_REG_NUM 14
3755 #define RF_REG_NUM 3
3756
3757 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3758                                         u32 *macbb_backup,
3759                                         u32 *backup_macbb_reg, u32 mac_bb_num)
3760 {
3761         struct rtl_priv *rtlpriv = rtl_priv(hw);
3762         u32 i;
3763
3764         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3765         /*save MACBB default value*/
3766         for (i = 0; i < mac_bb_num; i++)
3767                 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3768
3769         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3770 }
3771
3772 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3773                                       u32 *backup_afe_REG, u32 afe_num)
3774 {
3775         struct rtl_priv *rtlpriv = rtl_priv(hw);
3776         u32 i;
3777
3778         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3779         /*Save AFE Parameters */
3780         for (i = 0; i < afe_num; i++)
3781                 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3782         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3783 }
3784
3785 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3786                                      u32 *rfb_backup, u32 *backup_rf_reg,
3787                                      u32 rf_num)
3788 {
3789         struct rtl_priv *rtlpriv = rtl_priv(hw);
3790         u32 i;
3791
3792         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3793         /*Save RF Parameters*/
3794         for (i = 0; i < rf_num; i++) {
3795                 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3796                                               BMASKDWORD);
3797                 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3798                                               BMASKDWORD);
3799         }
3800         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3801 }
3802
3803 static void _rtl8821ae_iqk_configure_mac(
3804                 struct ieee80211_hw *hw
3805                 )
3806 {
3807         struct rtl_priv *rtlpriv = rtl_priv(hw);
3808         /* ========MAC register setting========*/
3809         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3810         rtl_write_byte(rtlpriv, 0x522, 0x3f);
3811         rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3812         rtl_write_byte(rtlpriv, 0x808, 0x00);           /*RX ante off*/
3813         rtl_set_bbreg(hw, 0x838, 0xf, 0xc);             /*CCA off*/
3814 }
3815
3816 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3817                                        enum radio_path path, u32 tx_x, u32 tx_y)
3818 {
3819         struct rtl_priv *rtlpriv = rtl_priv(hw);
3820         switch (path) {
3821         case RF90_PATH_A:
3822                 /* [31] = 1 --> Page C1 */
3823                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3824                 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3825                 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3826                 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3827                 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3828                 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3829                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3830                          "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3831                          tx_x, tx_y);
3832                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3833                          "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3834                          rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3835                          rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3836                 break;
3837         default:
3838                 break;
3839         }
3840 }
3841
3842 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3843                                        enum radio_path path, u32 rx_x, u32 rx_y)
3844 {
3845         struct rtl_priv *rtlpriv = rtl_priv(hw);
3846         switch (path) {
3847         case RF90_PATH_A:
3848                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3849                 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3850                 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3851                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3852                          "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3853                          rx_x>>1, rx_y>>1);
3854                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3855                          "0xc10 = %x ====>fill to IQC\n",
3856                          rtl_read_dword(rtlpriv, 0xc10));
3857                 break;
3858         default:
3859                 break;
3860         }
3861 }
3862
3863 #define cal_num 10
3864
3865 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3866 {
3867         struct rtl_priv *rtlpriv = rtl_priv(hw);
3868         struct rtl_phy *rtlphy = &rtlpriv->phy;
3869         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3870
3871         u32     tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3872         int     tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3873         int     tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3874                 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3875         bool    tx0iqkok = false, rx0iqkok = false;
3876         bool    vdf_enable = false;
3877         int     i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3878                 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3879
3880         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3881                         "BandWidth = %d.\n",
3882                          rtlphy->current_chan_bw);
3883         if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3884                 vdf_enable = true;
3885
3886         while (cal < cal_num) {
3887                 switch (path) {
3888                 case RF90_PATH_A:
3889                         temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3890                         /* Path-A LOK */
3891                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3892                         /*========Path-A AFE all on========*/
3893                         /*Port 0 DAC/ADC on*/
3894                         rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3895                         rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3896                         rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3897                         rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3898                         rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3899                         rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3900                         rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3901                         rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3902                         rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3903                         rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3904
3905                         rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3906
3907                         /* LOK Setting */
3908                         /* ====== LOK ====== */
3909                         /*DAC/ADC sampling rate (160 MHz)*/
3910                         rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3911
3912                         /* 2. LoK RF Setting (at BW = 20M) */
3913                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3914                         rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3);     /* BW 20M */
3915                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3916                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3917                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3918                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3919                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3920                         rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3921                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3922                         rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3923                         rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3924                         rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3925                         rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3926                         rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3927
3928                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3929                         rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3930
3931                         if (rtlhal->current_bandtype)
3932                                 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3933                         else
3934                                 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3935
3936                         rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3937                         rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3938                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3939                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3940                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3941
3942                         mdelay(10); /* Delay 10ms */
3943                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3944
3945                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3946                         rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3947
3948                         switch (rtlphy->current_chan_bw) {
3949                         case 1:
3950                                 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3951                                 break;
3952                         case 2:
3953                                 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3954                                 break;
3955                         default:
3956                                 break;
3957                         }
3958
3959                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3960
3961                         /* 3. TX RF Setting */
3962                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3963                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3964                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3965                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3966                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3967                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3968                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3969                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3970                         /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3971                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3972                         rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3973                         rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3974                         rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3975                         rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3976                         rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3977
3978                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3979                         rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3980                         if (rtlhal->current_bandtype)
3981                                 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3982                         else
3983                                 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3984
3985                         if (vdf_enable == 1) {
3986                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3987                                 for (k = 0; k <= 2; k++) {
3988                                         switch (k) {
3989                                         case 0:
3990                                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3991                                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3992                                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3993                                                 break;
3994                                         case 1:
3995                                                 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3996                                                 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3997                                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3998                                                 break;
3999                                         case 2:
4000                                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4001                                                         "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4002                                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4003                                                         "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4004                                                 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4005                                                 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
4006                                                 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
4007                                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4008                                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4009                                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
4010                                                 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
4011                                                 break;
4012                                         default:
4013                                                 break;
4014                                         }
4015                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4016                                         cal_retry = 0;
4017                                         while (1) {
4018                                                 /* one shot */
4019                                                 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4020                                                 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4021
4022                                                 mdelay(10); /* Delay 10ms */
4023                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4024                                                 delay_count = 0;
4025                                                 while (1) {
4026                                                         iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4027                                                         if ((~iqk_ready) || (delay_count > 20))
4028                                                                 break;
4029                                                         else{
4030                                                                 mdelay(1);
4031                                                                 delay_count++;
4032                                                         }
4033                                                 }
4034
4035                                                 if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4036                                                         /* ============TXIQK Check============== */
4037                                                         tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4038
4039                                                         if (~tx_fail) {
4040                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4041                                                                 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4042                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4043                                                                 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4044                                                                 tx0iqkok = true;
4045                                                                 break;
4046                                                         } else {
4047                                                                 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4048                                                                 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4049                                                                 tx0iqkok = false;
4050                                                                 cal_retry++;
4051                                                                 if (cal_retry == 10)
4052                                                                         break;
4053                                                         }
4054                                                 } else {
4055                                                         tx0iqkok = false;
4056                                                         cal_retry++;
4057                                                         if (cal_retry == 10)
4058                                                                 break;
4059                                                 }
4060                                         }
4061                                 }
4062                                 if (k == 3) {
4063                                         tx_x0[cal] = vdf_x[k-1];
4064                                         tx_y0[cal] = vdf_y[k-1];
4065                                 }
4066                         } else {
4067                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4068                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4069                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4070                                 cal_retry = 0;
4071                                 while (1) {
4072                                         /* one shot */
4073                                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4074                                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4075
4076                                         mdelay(10); /* Delay 10ms */
4077                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4078                                         delay_count = 0;
4079                                         while (1) {
4080                                                 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4081                                                 if ((~iqk_ready) || (delay_count > 20))
4082                                                         break;
4083                                                 else{
4084                                                         mdelay(1);
4085                                                         delay_count++;
4086                                                 }
4087                                         }
4088
4089                                         if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4090                                                 /* ============TXIQK Check============== */
4091                                                 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4092
4093                                                 if (~tx_fail) {
4094                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4095                                                         tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4096                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4097                                                         tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4098                                                         tx0iqkok = true;
4099                                                         break;
4100                                                 } else {
4101                                                         rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4102                                                         rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4103                                                         tx0iqkok = false;
4104                                                         cal_retry++;
4105                                                         if (cal_retry == 10)
4106                                                                 break;
4107                                                 }
4108                                         } else {
4109                                                 tx0iqkok = false;
4110                                                 cal_retry++;
4111                                                 if (cal_retry == 10)
4112                                                         break;
4113                                         }
4114                                 }
4115                         }
4116
4117                         if (tx0iqkok == false)
4118                                 break;                          /* TXK fail, Don't do RXK */
4119
4120                         if (vdf_enable == 1) {
4121                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);    /* TX VDF Disable */
4122                                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4123                                 for (k = 0; k <= 2; k++) {
4124                                         /* ====== RX mode TXK (RXK Step 1) ====== */
4125                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4126                                         /* 1. TX RF Setting */
4127                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4128                                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4129                                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4130                                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4131                                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4132                                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4133                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4134
4135                                         rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4136                                         rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4137                                         rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4138                                         rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4139                                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4140                                         rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4141                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4142                                         switch (k) {
4143                                         case 0:
4144                                                 {
4145                                                         rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4146                                                         rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4147                                                         rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4148                                                 }
4149                                                 break;
4150                                         case 1:
4151                                                 {
4152                                                         rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4153                                                         rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4154                                                         rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4155                                                 }
4156                                                 break;
4157                                         case 2:
4158                                                 {
4159                                                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4160                                                         "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4161                                                         vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4162                                                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4163                                                         "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4164                                                         vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4165                                                         rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4166                                                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4167                                                         rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4168                                                         rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4169                                                         rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4170                                                         rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4171                                                         rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4172                                                 }
4173                                                 break;
4174                                         default:
4175                                                 break;
4176                                         }
4177                                         rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4178                                         rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4179                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4180                                         cal_retry = 0;
4181                                         while (1) {
4182                                                 /* one shot */
4183                                                 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4184                                                 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4185
4186                                                 mdelay(10); /* Delay 10ms */
4187                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4188                                                 delay_count = 0;
4189                                                 while (1) {
4190                                                         iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4191                                                         if ((~iqk_ready) || (delay_count > 20))
4192                                                                 break;
4193                                                         else{
4194                                                                 mdelay(1);
4195                                                                 delay_count++;
4196                                                         }
4197                                                 }
4198
4199                                                 if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4200                                                         /* ============TXIQK Check============== */
4201                                                         tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4202
4203                                                         if (~tx_fail) {
4204                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4205                                                                 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4206                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4207                                                                 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4208                                                                 tx0iqkok = true;
4209                                                                 break;
4210                                                         } else{
4211                                                                 tx0iqkok = false;
4212                                                                 cal_retry++;
4213                                                                 if (cal_retry == 10)
4214                                                                         break;
4215                                                         }
4216                                                 } else {
4217                                                         tx0iqkok = false;
4218                                                         cal_retry++;
4219                                                         if (cal_retry == 10)
4220                                                                 break;
4221                                                 }
4222                                         }
4223
4224                                         if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4225                                                 tx_x0_rxk[cal] = tx_x0[cal];
4226                                                 tx_y0_rxk[cal] = tx_y0[cal];
4227                                                 tx0iqkok = true;
4228                                                 RT_TRACE(rtlpriv,
4229                                                          COMP_IQK,
4230                                                          DBG_LOUD,
4231                                                          "RXK Step 1 fail\n");
4232                                         }
4233
4234                                         /* ====== RX IQK ====== */
4235                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4236                                         /* 1. RX RF Setting */
4237                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4238                                         rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4239                                         rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4240                                         rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4241                                         rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4242                                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4243                                         rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4244
4245                                         rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4246                                         rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4247                                         rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4248                                         rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4249                                         rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4250                                         rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4251                                         rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4252
4253                                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4254                                         rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4255                                         rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4256                                         rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4257
4258                                         rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4259
4260                                         if (k == 2)
4261                                                 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1);  /* RX VDF Enable */
4262                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4263
4264                                         cal_retry = 0;
4265                                         while (1) {
4266                                                 /* one shot */
4267                                                 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4268                                                 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4269
4270                                                 mdelay(10); /* Delay 10ms */
4271                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4272                                                 delay_count = 0;
4273                                                 while (1) {
4274                                                         iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4275                                                         if ((~iqk_ready) || (delay_count > 20))
4276                                                                 break;
4277                                                         else{
4278                                                                 mdelay(1);
4279                                                                 delay_count++;
4280                                                         }
4281                                                 }
4282
4283                                                 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4284                                                         /* ============RXIQK Check============== */
4285                                                         rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4286                                                         if (rx_fail == 0) {
4287                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4288                                                                 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4289                                                                 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4290                                                                 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4291                                                                 rx0iqkok = true;
4292                                                                 break;
4293                                                         } else {
4294                                                                 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4295                                                                 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4296                                                                 rx0iqkok = false;
4297                                                                 cal_retry++;
4298                                                                 if (cal_retry == 10)
4299                                                                         break;
4300
4301                                                         }
4302                                                 } else{
4303                                                         rx0iqkok = false;
4304                                                         cal_retry++;
4305                                                         if (cal_retry == 10)
4306                                                                 break;
4307                                                 }
4308                                         }
4309
4310                                 }
4311                                 if (k == 3) {
4312                                         rx_x0[cal] = vdf_x[k-1];
4313                                         rx_y0[cal] = vdf_y[k-1];
4314                                 }
4315                                 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);    /* TX VDF Enable */
4316                         }
4317
4318                         else{
4319                                 /* ====== RX mode TXK (RXK Step 1) ====== */
4320                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4321                                 /* 1. TX RF Setting */
4322                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4323                                 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4324                                 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4325                                 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4326                                 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4327                                 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4328                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4329                                 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4330                                 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4331                                 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4332
4333                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4334                                 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4335                                 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4336                                 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4337                                 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4338                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4339                                 cal_retry = 0;
4340                                 while (1) {
4341                                         /* one shot */
4342                                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4343                                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4344
4345                                         mdelay(10); /* Delay 10ms */
4346                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4347                                         delay_count = 0;
4348                                         while (1) {
4349                                                 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4350                                                 if ((~iqk_ready) || (delay_count > 20))
4351                                                         break;
4352                                                 else{
4353                                                         mdelay(1);
4354                                                         delay_count++;
4355                                                 }
4356                                         }
4357
4358                                         if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4359                                                 /* ============TXIQK Check============== */
4360                                                 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4361
4362                                                 if (~tx_fail) {
4363                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4364                                                         tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4365                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4366                                                         tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4367                                                         tx0iqkok = true;
4368                                                         break;
4369                                                 } else {
4370                                                         tx0iqkok = false;
4371                                                         cal_retry++;
4372                                                         if (cal_retry == 10)
4373                                                                 break;
4374                                                 }
4375                                         } else{
4376                                                 tx0iqkok = false;
4377                                                 cal_retry++;
4378                                                 if (cal_retry == 10)
4379                                                         break;
4380                                         }
4381                                 }
4382
4383                                 if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4384                                         tx_x0_rxk[cal] = tx_x0[cal];
4385                                         tx_y0_rxk[cal] = tx_y0[cal];
4386                                         tx0iqkok = true;
4387                                         RT_TRACE(rtlpriv, COMP_IQK,
4388                                                  DBG_LOUD, "1");
4389                                 }
4390
4391                                 /* ====== RX IQK ====== */
4392                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4393                                 /* 1. RX RF Setting */
4394                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4395                                 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4396                                 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4397                                 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4398                                 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4399                                 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4400                                 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4401
4402                                 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4403                                 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4404                                 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4405                                 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4406                                 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4407                                 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4408                                 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4409
4410                                 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4411                                 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4412                                 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4413                                 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4414
4415                                 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4416
4417                                 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4418
4419                                 cal_retry = 0;
4420                                 while (1) {
4421                                         /* one shot */
4422                                         rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4423                                         rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4424
4425                                         mdelay(10); /* Delay 10ms */
4426                                         rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4427                                         delay_count = 0;
4428                                         while (1) {
4429                                                 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4430                                                 if ((~iqk_ready) || (delay_count > 20))
4431                                                         break;
4432                                                 else{
4433                                                         mdelay(1);
4434                                                         delay_count++;
4435                                                 }
4436                                         }
4437
4438                                         if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4439                                                 /* ============RXIQK Check============== */
4440                                                 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4441                                                 if (rx_fail == 0) {
4442                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4443                                                         rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4444                                                         rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4445                                                         rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4446                                                         rx0iqkok = true;
4447                                                         break;
4448                                                 } else{
4449                                                         rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4450                                                         rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4451                                                         rx0iqkok = false;
4452                                                         cal_retry++;
4453                                                         if (cal_retry == 10)
4454                                                                 break;
4455
4456                                                 }
4457                                         } else{
4458                                                 rx0iqkok = false;
4459                                                 cal_retry++;
4460                                                 if (cal_retry == 10)
4461                                                         break;
4462                                         }
4463                                 }
4464                         }
4465
4466                         if (tx0iqkok)
4467                                 tx_average++;
4468                         if (rx0iqkok)
4469                                 rx_average++;
4470                         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4471                         rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4472                         break;
4473                 default:
4474                         break;
4475                 }
4476                 cal++;
4477         }
4478
4479         /* FillIQK Result */
4480         switch (path) {
4481         case RF90_PATH_A:
4482                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4483                          "========Path_A =======\n");
4484                 if (tx_average == 0)
4485                         break;
4486
4487                 for (i = 0; i < tx_average; i++) {
4488                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4489                                  "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4490                                  (tx_x0_rxk[i])>>21&0x000007ff, i,
4491                                  (tx_y0_rxk[i])>>21&0x000007ff);
4492                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4493                                  "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4494                                  (tx_x0[i])>>21&0x000007ff, i,
4495                                  (tx_y0[i])>>21&0x000007ff);
4496                 }
4497                 for (i = 0; i < tx_average; i++) {
4498                         for (ii = i+1; ii < tx_average; ii++) {
4499                                 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4500                                 if (dx < 3 && dx > -3) {
4501                                         dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4502                                         if (dy < 3 && dy > -3) {
4503                                                 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4504                                                 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4505                                                 tx_finish = 1;
4506                                                 break;
4507                                         }
4508                                 }
4509                         }
4510                         if (tx_finish == 1)
4511                                 break;
4512                 }
4513
4514                 if (tx_finish == 1)
4515                         _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4516                 else
4517                         _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4518
4519                 if (rx_average == 0)
4520                         break;
4521
4522                 for (i = 0; i < rx_average; i++)
4523                         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4524                                 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4525                                 (rx_x0[i])>>21&0x000007ff, i,
4526                                 (rx_y0[i])>>21&0x000007ff);
4527                 for (i = 0; i < rx_average; i++) {
4528                         for (ii = i+1; ii < rx_average; ii++) {
4529                                 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4530                                 if (dx < 4 && dx > -4) {
4531                                         dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4532                                         if (dy < 4 && dy > -4) {
4533                                                 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4534                                                 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4535                                                 rx_finish = 1;
4536                                                 break;
4537                                         }
4538                                 }
4539                         }
4540                         if (rx_finish == 1)
4541                                 break;
4542                 }
4543
4544                 if (rx_finish == 1)
4545                         _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4546                 else
4547                         _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4548                 break;
4549         default:
4550                 break;
4551         }
4552 }
4553
4554 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4555                                       enum radio_path path,
4556                                       u32 *backup_rf_reg,
4557                                       u32 *rf_backup, u32 rf_reg_num)
4558 {
4559         struct rtl_priv *rtlpriv = rtl_priv(hw);
4560         u32 i;
4561
4562         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4563         for (i = 0; i < RF_REG_NUM; i++)
4564                 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4565                               rf_backup[i]);
4566
4567         switch (path) {
4568         case RF90_PATH_A:
4569                 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4570                          "RestoreRF Path A Success!!!!\n");
4571                 break;
4572         default:
4573                         break;
4574         }
4575 }
4576
4577 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4578                                        u32 *afe_backup, u32 *backup_afe_reg,
4579                                        u32 afe_num)
4580 {
4581         u32 i;
4582         struct rtl_priv *rtlpriv = rtl_priv(hw);
4583
4584         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4585         /* Reload AFE Parameters */
4586         for (i = 0; i < afe_num; i++)
4587                 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4588         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4589         rtl_write_dword(rtlpriv, 0xc80, 0x0);
4590         rtl_write_dword(rtlpriv, 0xc84, 0x0);
4591         rtl_write_dword(rtlpriv, 0xc88, 0x0);
4592         rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4593         rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4594         rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4595         rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4596         rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4597         rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4598         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4599 }
4600
4601 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4602                                          u32 *macbb_backup,
4603                                          u32 *backup_macbb_reg,
4604                                          u32 macbb_num)
4605 {
4606         u32 i;
4607         struct rtl_priv *rtlpriv = rtl_priv(hw);
4608
4609         rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4610         /* Reload MacBB Parameters */
4611         for (i = 0; i < macbb_num; i++)
4612                 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4613         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4614 }
4615
4616 #undef MACBB_REG_NUM
4617 #undef AFE_REG_NUM
4618 #undef RF_REG_NUM
4619
4620 #define MACBB_REG_NUM 11
4621 #define AFE_REG_NUM 12
4622 #define RF_REG_NUM 3
4623
4624 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4625 {
4626         u32     macbb_backup[MACBB_REG_NUM];
4627         u32 afe_backup[AFE_REG_NUM];
4628         u32 rfa_backup[RF_REG_NUM];
4629         u32 rfb_backup[RF_REG_NUM];
4630         u32 backup_macbb_reg[MACBB_REG_NUM] = {
4631                 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4632                 0xe00, 0xe50, 0x838, 0x82c
4633         };
4634         u32 backup_afe_reg[AFE_REG_NUM] = {
4635                 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4636                 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4637         };
4638         u32     backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4639
4640         _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4641                                     MACBB_REG_NUM);
4642         _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4643         _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4644                                  RF_REG_NUM);
4645
4646         _rtl8821ae_iqk_configure_mac(hw);
4647         _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4648         _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4649                                   RF_REG_NUM);
4650
4651         _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4652         _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4653                                      MACBB_REG_NUM);
4654 }
4655
4656 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4657 {
4658         struct rtl_priv *rtlpriv = rtl_priv(hw);
4659         /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4660         /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4661         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4662
4663         if (main)
4664                 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4665         else
4666                 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4667 }
4668
4669 #undef IQK_ADDA_REG_NUM
4670 #undef IQK_DELAY_TIME
4671
4672 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4673 {
4674 }
4675
4676 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4677                       u8 thermal_value, u8 threshold)
4678 {
4679         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4680
4681         rtldm->thermalvalue_iqk = thermal_value;
4682         rtl8812ae_phy_iq_calibrate(hw, false);
4683 }
4684
4685 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4686 {
4687         struct rtl_priv *rtlpriv = rtl_priv(hw);
4688         struct rtl_phy *rtlphy = &rtlpriv->phy;
4689
4690         if (!rtlphy->lck_inprogress) {
4691                 spin_lock(&rtlpriv->locks.iqk_lock);
4692                 rtlphy->lck_inprogress = true;
4693                 spin_unlock(&rtlpriv->locks.iqk_lock);
4694
4695                 _rtl8821ae_phy_iq_calibrate(hw);
4696
4697                 spin_lock(&rtlpriv->locks.iqk_lock);
4698                 rtlphy->lck_inprogress = false;
4699                 spin_unlock(&rtlpriv->locks.iqk_lock);
4700         }
4701 }
4702
4703 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4704 {
4705         struct rtl_priv *rtlpriv = rtl_priv(hw);
4706         struct rtl_phy *rtlphy = &rtlpriv->phy;
4707         u8 i;
4708
4709         RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4710                  "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4711                  (int)(sizeof(rtlphy->iqk_matrix) /
4712                  sizeof(struct iqk_matrix_regs)),
4713                  IQK_MATRIX_SETTINGS_NUM);
4714
4715         for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4716                 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4717                 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4718                 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4719                 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4720
4721                 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4722                 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4723                 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4724                 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4725
4726                 rtlphy->iqk_matrix[i].iqk_done = false;
4727         }
4728 }
4729
4730 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4731                       u8 thermal_value, u8 threshold)
4732 {
4733         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4734
4735         rtl8821ae_reset_iqk_result(hw);
4736
4737         rtldm->thermalvalue_iqk = thermal_value;
4738         rtl8821ae_phy_iq_calibrate(hw, false);
4739 }
4740
4741 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4742 {
4743 }
4744
4745 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
4746 {
4747 }
4748
4749 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4750 {
4751         _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4752 }
4753
4754 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4755 {
4756         struct rtl_priv *rtlpriv = rtl_priv(hw);
4757         struct rtl_phy *rtlphy = &rtlpriv->phy;
4758         bool postprocessing = false;
4759
4760         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4761                  "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4762                   iotype, rtlphy->set_io_inprogress);
4763         do {
4764                 switch (iotype) {
4765                 case IO_CMD_RESUME_DM_BY_SCAN:
4766                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4767                                  "[IO CMD] Resume DM after scan.\n");
4768                         postprocessing = true;
4769                         break;
4770                 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4771                 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4772                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4773                                  "[IO CMD] Pause DM before scan.\n");
4774                         postprocessing = true;
4775                         break;
4776                 default:
4777                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4778                                  "switch case not process\n");
4779                         break;
4780                 }
4781         } while (false);
4782         if (postprocessing && !rtlphy->set_io_inprogress) {
4783                 rtlphy->set_io_inprogress = true;
4784                 rtlphy->current_io_type = iotype;
4785         } else {
4786                 return false;
4787         }
4788         rtl8821ae_phy_set_io(hw);
4789         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4790         return true;
4791 }
4792
4793 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4794 {
4795         struct rtl_priv *rtlpriv = rtl_priv(hw);
4796         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4797         struct rtl_phy *rtlphy = &rtlpriv->phy;
4798
4799         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4800                  "--->Cmd(%#x), set_io_inprogress(%d)\n",
4801                   rtlphy->current_io_type, rtlphy->set_io_inprogress);
4802         switch (rtlphy->current_io_type) {
4803         case IO_CMD_RESUME_DM_BY_SCAN:
4804                 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4805                         _rtl8821ae_resume_tx_beacon(hw);
4806                 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4807                 rtl8821ae_dm_write_cck_cca_thres(hw,
4808                                                  rtlphy->initgain_backup.cca);
4809                 break;
4810         case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4811                 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4812                         _rtl8821ae_stop_tx_beacon(hw);
4813                 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4814                 rtl8821ae_dm_write_dig(hw, 0x17);
4815                 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4816                 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4817                 break;
4818         case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4819                 break;
4820         default:
4821                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4822                          "switch case not process\n");
4823                 break;
4824         }
4825         rtlphy->set_io_inprogress = false;
4826         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4827                  "(%#x)\n", rtlphy->current_io_type);
4828 }
4829
4830 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4831 {
4832         struct rtl_priv *rtlpriv = rtl_priv(hw);
4833
4834         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4835         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4836         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4837         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4838         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4839 }
4840
4841 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4842                                               enum rf_pwrstate rfpwr_state)
4843 {
4844         struct rtl_priv *rtlpriv = rtl_priv(hw);
4845         struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4846         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4847         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4848         bool bresult = true;
4849         u8 i, queue_id;
4850         struct rtl8192_tx_ring *ring = NULL;
4851
4852         switch (rfpwr_state) {
4853         case ERFON:
4854                 if ((ppsc->rfpwr_state == ERFOFF) &&
4855                     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4856                         bool rtstatus = false;
4857                         u32 initializecount = 0;
4858
4859                         do {
4860                                 initializecount++;
4861                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4862                                          "IPS Set eRf nic enable\n");
4863                                 rtstatus = rtl_ps_enable_nic(hw);
4864                         } while (!rtstatus && (initializecount < 10));
4865                         RT_CLEAR_PS_LEVEL(ppsc,
4866                                           RT_RF_OFF_LEVL_HALT_NIC);
4867                 } else {
4868                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4869                                  "Set ERFON sleeped:%d ms\n",
4870                                   jiffies_to_msecs(jiffies -
4871                                                    ppsc->
4872                                                    last_sleep_jiffies));
4873                         ppsc->last_awake_jiffies = jiffies;
4874                         rtl8821ae_phy_set_rf_on(hw);
4875                 }
4876                 if (mac->link_state == MAC80211_LINKED) {
4877                         rtlpriv->cfg->ops->led_control(hw,
4878                                                        LED_CTL_LINK);
4879                 } else {
4880                         rtlpriv->cfg->ops->led_control(hw,
4881                                                        LED_CTL_NO_LINK);
4882                 }
4883                 break;
4884         case ERFOFF:
4885                 for (queue_id = 0, i = 0;
4886                      queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4887                         ring = &pcipriv->dev.tx_ring[queue_id];
4888                         if (queue_id == BEACON_QUEUE ||
4889                             skb_queue_len(&ring->queue) == 0) {
4890                                 queue_id++;
4891                                 continue;
4892                         } else {
4893                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4894                                          "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4895                                          (i + 1), queue_id,
4896                                          skb_queue_len(&ring->queue));
4897
4898                                 udelay(10);
4899                                 i++;
4900                         }
4901                         if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4902                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4903                                          "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4904                                           MAX_DOZE_WAITING_TIMES_9x,
4905                                           queue_id,
4906                                           skb_queue_len(&ring->queue));
4907                                 break;
4908                         }
4909                 }
4910
4911                 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4912                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4913                                  "IPS Set eRf nic disable\n");
4914                         rtl_ps_disable_nic(hw);
4915                         RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4916                 } else {
4917                         if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4918                                 rtlpriv->cfg->ops->led_control(hw,
4919                                                                LED_CTL_NO_LINK);
4920                         } else {
4921                                 rtlpriv->cfg->ops->led_control(hw,
4922                                                                LED_CTL_POWER_OFF);
4923                         }
4924                 }
4925                 break;
4926         default:
4927                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4928                          "switch case not process\n");
4929                 bresult = false;
4930                 break;
4931         }
4932         if (bresult)
4933                 ppsc->rfpwr_state = rfpwr_state;
4934         return bresult;
4935 }
4936
4937 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4938                                       enum rf_pwrstate rfpwr_state)
4939 {
4940         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4941
4942         bool bresult = false;
4943
4944         if (rfpwr_state == ppsc->rfpwr_state)
4945                 return bresult;
4946         bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
4947         return bresult;
4948 }