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