]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[karo-tx-linux.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192ee / phy.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2014  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
36 static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
37                                        enum radio_path rfpath, u32 offset);
38 static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
39                                          enum radio_path rfpath, u32 offset,
40                                          u32 data);
41 static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask);
42 static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw);
43 static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
44 static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
45                                         u8 configtype);
46 static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
47                                          u8 configtype);
48 static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw);
49 static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
50                                               u32 cmdtableidx, u32 cmdtablesz,
51                                               enum swchnlcmd_id cmdid,
52                                               u32 para1, u32 para2,
53                                               u32 msdelay);
54 static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
55                                               u8 channel, u8 *stage,
56                                               u8 *step, u32 *delay);
57 static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
58                                           enum wireless_mode wirelessmode,
59                                           u8 txpwridx);
60 static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw);
61 static void rtl92ee_phy_set_io(struct ieee80211_hw *hw);
62
63 u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
64 {
65         struct rtl_priv *rtlpriv = rtl_priv(hw);
66         u32 returnvalue, originalvalue, bitshift;
67
68         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
69                  "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
70         originalvalue = rtl_read_dword(rtlpriv, regaddr);
71         bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
72         returnvalue = (originalvalue & bitmask) >> bitshift;
73
74         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
75                  "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
76                   bitmask, regaddr, originalvalue);
77
78         return returnvalue;
79 }
80
81 void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
82                             u32 bitmask, u32 data)
83 {
84         struct rtl_priv *rtlpriv = rtl_priv(hw);
85         u32 originalvalue, bitshift;
86
87         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
88                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
89                   regaddr, bitmask, data);
90
91         if (bitmask != MASKDWORD) {
92                 originalvalue = rtl_read_dword(rtlpriv, regaddr);
93                 bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
94                 data = ((originalvalue & (~bitmask)) | (data << bitshift));
95         }
96
97         rtl_write_dword(rtlpriv, regaddr, data);
98
99         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
100                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
101                   regaddr, bitmask, data);
102 }
103
104 u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw,
105                              enum radio_path rfpath, u32 regaddr, u32 bitmask)
106 {
107         struct rtl_priv *rtlpriv = rtl_priv(hw);
108         u32 original_value, readback_value, bitshift;
109         unsigned long flags;
110
111         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
112                  "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
113                   regaddr, rfpath, bitmask);
114
115         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
116
117         original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr);
118         bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
119         readback_value = (original_value & bitmask) >> bitshift;
120
121         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
122
123         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
124                  "regaddr(%#x),rfpath(%#x),bitmask(%#x),original_value(%#x)\n",
125                   regaddr, rfpath, bitmask, original_value);
126
127         return readback_value;
128 }
129
130 void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw,
131                             enum radio_path rfpath,
132                             u32 addr, u32 bitmask, u32 data)
133 {
134         struct rtl_priv *rtlpriv = rtl_priv(hw);
135         u32 original_value, bitshift;
136         unsigned long flags;
137
138         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
139                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
140                   addr, bitmask, data, rfpath);
141
142         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
143
144         if (bitmask != RFREG_OFFSET_MASK) {
145                 original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr);
146                 bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
147                 data = (original_value & (~bitmask)) | (data << bitshift);
148         }
149
150         _rtl92ee_phy_rf_serial_write(hw, rfpath, addr, data);
151
152         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
153
154         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
155                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
156                   addr, bitmask, data, rfpath);
157 }
158
159 static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
160                                        enum radio_path rfpath, u32 offset)
161 {
162         struct rtl_priv *rtlpriv = rtl_priv(hw);
163         struct rtl_phy *rtlphy = &rtlpriv->phy;
164         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
165         u32 newoffset;
166         u32 tmplong, tmplong2;
167         u8 rfpi_enable = 0;
168         u32 retvalue;
169
170         offset &= 0xff;
171         newoffset = offset;
172         if (RT_CANNOT_IO(hw)) {
173                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
174                 return 0xFFFFFFFF;
175         }
176         tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
177         if (rfpath == RF90_PATH_A)
178                 tmplong2 = tmplong;
179         else
180                 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
181         tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
182                    (newoffset << 23) | BLSSIREADEDGE;
183         rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
184                       tmplong & (~BLSSIREADEDGE));
185         mdelay(1);
186         rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
187         mdelay(2);
188         if (rfpath == RF90_PATH_A)
189                 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
190                                                 BIT(8));
191         else if (rfpath == RF90_PATH_B)
192                 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
193                                                 BIT(8));
194         if (rfpi_enable)
195                 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
196                                          BLSSIREADBACKDATA);
197         else
198                 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
199                                          BLSSIREADBACKDATA);
200         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
201                  "RFR-%d Addr[0x%x]=0x%x\n",
202                   rfpath, pphyreg->rf_rb, retvalue);
203         return retvalue;
204 }
205
206 static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
207                                          enum radio_path rfpath, u32 offset,
208                                          u32 data)
209 {
210         u32 data_and_addr;
211         u32 newoffset;
212         struct rtl_priv *rtlpriv = rtl_priv(hw);
213         struct rtl_phy *rtlphy = &rtlpriv->phy;
214         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
215
216         if (RT_CANNOT_IO(hw)) {
217                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
218                 return;
219         }
220         offset &= 0xff;
221         newoffset = offset;
222         data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
223         rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
224         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
225                  "RFW-%d Addr[0x%x]=0x%x\n", rfpath,
226                  pphyreg->rf3wire_offset, data_and_addr);
227 }
228
229 static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask)
230 {
231         u32 i;
232
233         for (i = 0; i <= 31; i++) {
234                 if (((bitmask >> i) & 0x1) == 1)
235                         break;
236         }
237         return i;
238 }
239
240 bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw)
241 {
242         return _rtl92ee_phy_config_mac_with_headerfile(hw);
243 }
244
245 bool rtl92ee_phy_bb_config(struct ieee80211_hw *hw)
246 {
247         struct rtl_priv *rtlpriv = rtl_priv(hw);
248         bool rtstatus = true;
249         u16 regval;
250         u32 tmp;
251         u8 crystal_cap;
252
253         phy_init_bb_rf_register_def(hw);
254         regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
255         rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
256                        regval | BIT(13) | BIT(0) | BIT(1));
257
258         rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
259         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
260                        FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
261                        FEN_BB_GLB_RSTN | FEN_BBRSTB);
262
263         rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
264
265         tmp = rtl_read_dword(rtlpriv, 0x4c);
266         rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
267
268         rtstatus = _rtl92ee_phy_bb8192ee_config_parafile(hw);
269
270         crystal_cap = rtlpriv->efuse.eeprom_crystalcap & 0x3F;
271         rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
272                       (crystal_cap | (crystal_cap << 6)));
273         return rtstatus;
274 }
275
276 bool rtl92ee_phy_rf_config(struct ieee80211_hw *hw)
277 {
278         return rtl92ee_phy_rf6052_config(hw);
279 }
280
281 static bool _check_condition(struct ieee80211_hw *hw,
282                              const u32  condition)
283 {
284         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
285         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
286         u32 _board = rtlefuse->board_type; /*need efuse define*/
287         u32 _interface = rtlhal->interface;
288         u32 _platform = 0x08;/*SupportPlatform */
289         u32 cond = condition;
290
291         if (condition == 0xCDCDCDCD)
292                 return true;
293
294         cond = condition & 0xFF;
295         if ((_board != cond) && (cond != 0xFF))
296                 return false;
297
298         cond = condition & 0xFF00;
299         cond = cond >> 8;
300         if ((_interface & cond) == 0 && cond != 0x07)
301                 return false;
302
303         cond = condition & 0xFF0000;
304         cond = cond >> 16;
305         if ((_platform & cond) == 0 && cond != 0x0F)
306                 return false;
307
308         return true;
309 }
310
311 static void _rtl92ee_config_rf_reg(struct ieee80211_hw *hw, u32 addr, u32 data,
312                                    enum radio_path rfpath, u32 regaddr)
313 {
314         if (addr == 0xfe || addr == 0xffe) {
315                 mdelay(50);
316         } else {
317                 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
318                 udelay(1);
319
320                 if (addr == 0xb6) {
321                         u32 getvalue;
322                         u8 count = 0;
323
324                         getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
325                         udelay(1);
326
327                         while ((getvalue >> 8) != (data >> 8)) {
328                                 count++;
329                                 rtl_set_rfreg(hw, rfpath, regaddr,
330                                               RFREG_OFFSET_MASK, data);
331                                 udelay(1);
332                                 getvalue = rtl_get_rfreg(hw, rfpath, addr,
333                                                          MASKDWORD);
334                                 if (count > 5)
335                                         break;
336                         }
337                 }
338
339                 if (addr == 0xb2) {
340                         u32 getvalue;
341                         u8 count = 0;
342
343                         getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
344                         udelay(1);
345
346                         while (getvalue != data) {
347                                 count++;
348                                 rtl_set_rfreg(hw, rfpath, regaddr,
349                                               RFREG_OFFSET_MASK, data);
350                                 udelay(1);
351                                 rtl_set_rfreg(hw, rfpath, 0x18,
352                                               RFREG_OFFSET_MASK, 0x0fc07);
353                                 udelay(1);
354                                 getvalue = rtl_get_rfreg(hw, rfpath, addr,
355                                                          MASKDWORD);
356                                 if (count > 5)
357                                         break;
358                         }
359                 }
360         }
361 }
362
363 static void _rtl92ee_config_rf_radio_a(struct ieee80211_hw *hw,
364                                        u32 addr, u32 data)
365 {
366         u32 content = 0x1000; /*RF Content: radio_a_txt*/
367         u32 maskforphyset = (u32)(content & 0xE000);
368
369         _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_A,
370                                addr | maskforphyset);
371 }
372
373 static void _rtl92ee_config_rf_radio_b(struct ieee80211_hw *hw,
374                                        u32 addr, u32 data)
375 {
376         u32 content = 0x1001; /*RF Content: radio_b_txt*/
377         u32 maskforphyset = (u32)(content & 0xE000);
378
379         _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_B,
380                                addr | maskforphyset);
381 }
382
383 static void _rtl92ee_config_bb_reg(struct ieee80211_hw *hw,
384                                    u32 addr, u32 data)
385 {
386         if (addr == 0xfe)
387                 mdelay(50);
388         else if (addr == 0xfd)
389                 mdelay(5);
390         else if (addr == 0xfc)
391                 mdelay(1);
392         else if (addr == 0xfb)
393                 udelay(50);
394         else if (addr == 0xfa)
395                 udelay(5);
396         else if (addr == 0xf9)
397                 udelay(1);
398         else
399                 rtl_set_bbreg(hw, addr, MASKDWORD , data);
400
401         udelay(1);
402 }
403
404 static void _rtl92ee_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
405 {
406         struct rtl_priv *rtlpriv = rtl_priv(hw);
407         struct rtl_phy *rtlphy = &rtlpriv->phy;
408
409         u8 band = BAND_ON_2_4G, rf = 0, txnum = 0, sec = 0;
410
411         for (; band <= BAND_ON_5G; ++band)
412                 for (; rf < TX_PWR_BY_RATE_NUM_RF; ++rf)
413                         for (; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
414                                 for (; sec < TX_PWR_BY_RATE_NUM_SECTION; ++sec)
415                                         rtlphy->tx_power_by_rate_offset
416                                              [band][rf][txnum][sec] = 0;
417 }
418
419 static void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
420                                                   u8 band, u8 path,
421                                                   u8 rate_section, u8 txnum,
422                                                   u8 value)
423 {
424         struct rtl_priv *rtlpriv = rtl_priv(hw);
425         struct rtl_phy *rtlphy = &rtlpriv->phy;
426
427         if (path > RF90_PATH_D) {
428                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
429                          "Invalid Rf Path %d\n", path);
430                 return;
431         }
432
433         if (band == BAND_ON_2_4G) {
434                 switch (rate_section) {
435                 case CCK:
436                         rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
437                         break;
438                 case OFDM:
439                         rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
440                         break;
441                 case HT_MCS0_MCS7:
442                         rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
443                         break;
444                 case HT_MCS8_MCS15:
445                         rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
446                         break;
447                 default:
448                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
449                                  "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
450                                   rate_section, path, txnum);
451                         break;
452                 }
453         } else {
454                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
455                          "Invalid Band %d\n", band);
456         }
457 }
458
459 static u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
460                                                 u8 band, u8 path, u8 txnum,
461                                                 u8 rate_section)
462 {
463         struct rtl_priv *rtlpriv = rtl_priv(hw);
464         struct rtl_phy *rtlphy = &rtlpriv->phy;
465         u8 value = 0;
466
467         if (path > RF90_PATH_D) {
468                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
469                          "Invalid Rf Path %d\n", path);
470                 return 0;
471         }
472
473         if (band == BAND_ON_2_4G) {
474                 switch (rate_section) {
475                 case CCK:
476                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
477                         break;
478                 case OFDM:
479                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
480                         break;
481                 case HT_MCS0_MCS7:
482                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
483                         break;
484                 case HT_MCS8_MCS15:
485                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
486                         break;
487                 default:
488                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
489                                  "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
490                                   rate_section, path, txnum);
491                         break;
492                 }
493         } else {
494                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
495                          "Invalid Band %d()\n", band);
496         }
497         return value;
498 }
499
500 static void _rtl92ee_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
501 {
502         struct rtl_priv *rtlpriv = rtl_priv(hw);
503         struct rtl_phy *rtlphy = &rtlpriv->phy;
504         u16 raw = 0;
505         u8 base = 0, path = 0;
506
507         for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
508                 if (path == RF90_PATH_A) {
509                         raw = (u16)(rtlphy->tx_power_by_rate_offset
510                                     [BAND_ON_2_4G][path][RF_1TX][3] >> 24) &
511                                     0xFF;
512                         base = (raw >> 4) * 10 + (raw & 0xF);
513                         _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
514                                                               path, CCK, RF_1TX,
515                                                               base);
516                 } else if (path == RF90_PATH_B) {
517                         raw = (u16)(rtlphy->tx_power_by_rate_offset
518                                     [BAND_ON_2_4G][path][RF_1TX][3] >> 0) &
519                                     0xFF;
520                         base = (raw >> 4) * 10 + (raw & 0xF);
521                         _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
522                                                               path, CCK, RF_1TX,
523                                                               base);
524                 }
525                 raw = (u16)(rtlphy->tx_power_by_rate_offset
526                             [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
527                 base = (raw >> 4) * 10 + (raw & 0xF);
528                 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
529                                                       OFDM, RF_1TX, base);
530
531                 raw = (u16)(rtlphy->tx_power_by_rate_offset
532                             [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
533                 base = (raw >> 4) * 10 + (raw & 0xF);
534                 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
535                                                       HT_MCS0_MCS7, RF_1TX,
536                                                       base);
537
538                 raw = (u16)(rtlphy->tx_power_by_rate_offset
539                             [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
540                 base = (raw >> 4) * 10 + (raw & 0xF);
541                 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
542                                                       HT_MCS8_MCS15, RF_2TX,
543                                                       base);
544         }
545 }
546
547 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
548                                                        u8 end, u8 base)
549 {
550         char i = 0;
551         u8 tmp = 0;
552         u32 temp_data = 0;
553
554         for (i = 3; i >= 0; --i) {
555                 if (i >= start && i <= end) {
556                         /* Get the exact value */
557                         tmp = (u8)(*data >> (i * 8)) & 0xF;
558                         tmp += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
559
560                         /* Change the value to a relative value */
561                         tmp = (tmp > base) ? tmp - base : base - tmp;
562                 } else {
563                         tmp = (u8)(*data >> (i * 8)) & 0xFF;
564                 }
565                 temp_data <<= 8;
566                 temp_data |= tmp;
567         }
568         *data = temp_data;
569 }
570
571 static void phy_convert_txpwr_dbm_to_rel_val(struct ieee80211_hw *hw)
572 {
573         struct rtl_priv *rtlpriv = rtl_priv(hw);
574         struct rtl_phy *rtlphy = &rtlpriv->phy;
575         u8 base = 0, rf = 0, band = BAND_ON_2_4G;
576
577         for (rf = RF90_PATH_A; rf <= RF90_PATH_B; ++rf) {
578                 if (rf == RF90_PATH_A) {
579                         base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
580                                                                      rf, RF_1TX,
581                                                                      CCK);
582                         _phy_convert_txpower_dbm_to_relative_value(
583                                 &rtlphy->tx_power_by_rate_offset
584                                 [band][rf][RF_1TX][2],
585                                 1, 1, base);
586                         _phy_convert_txpower_dbm_to_relative_value(
587                                 &rtlphy->tx_power_by_rate_offset
588                                 [band][rf][RF_1TX][3],
589                                 1, 3, base);
590                 } else if (rf == RF90_PATH_B) {
591                         base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
592                                                                      rf, RF_1TX,
593                                                                      CCK);
594                         _phy_convert_txpower_dbm_to_relative_value(
595                                 &rtlphy->tx_power_by_rate_offset
596                                 [band][rf][RF_1TX][3],
597                                 0, 0, base);
598                         _phy_convert_txpower_dbm_to_relative_value(
599                                 &rtlphy->tx_power_by_rate_offset
600                                 [band][rf][RF_1TX][2],
601                                 1, 3, base);
602                 }
603                 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
604                                                              RF_1TX, OFDM);
605                 _phy_convert_txpower_dbm_to_relative_value(
606                         &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][0],
607                         0, 3, base);
608                 _phy_convert_txpower_dbm_to_relative_value(
609                         &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][1],
610                         0, 3, base);
611
612                 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
613                                                              RF_1TX,
614                                                              HT_MCS0_MCS7);
615                 _phy_convert_txpower_dbm_to_relative_value(
616                         &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][4],
617                         0, 3, base);
618                 _phy_convert_txpower_dbm_to_relative_value(
619                         &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][5],
620                         0, 3, base);
621
622                 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
623                                                              RF_2TX,
624                                                              HT_MCS8_MCS15);
625                 _phy_convert_txpower_dbm_to_relative_value(
626                         &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][6],
627                         0, 3, base);
628
629                 _phy_convert_txpower_dbm_to_relative_value(
630                         &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][7],
631                         0, 3, base);
632         }
633
634         RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
635                  "<==phy_convert_txpwr_dbm_to_rel_val()\n");
636 }
637
638 static void _rtl92ee_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
639 {
640         _rtl92ee_phy_store_txpower_by_rate_base(hw);
641         phy_convert_txpwr_dbm_to_rel_val(hw);
642 }
643
644 static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw)
645 {
646         struct rtl_priv *rtlpriv = rtl_priv(hw);
647         struct rtl_phy *rtlphy = &rtlpriv->phy;
648         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
649         bool rtstatus;
650
651         rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_PHY_REG);
652         if (!rtstatus) {
653                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
654                 return false;
655         }
656
657         _rtl92ee_phy_init_tx_power_by_rate(hw);
658         if (!rtlefuse->autoload_failflag) {
659                 rtlphy->pwrgroup_cnt = 0;
660                 rtstatus =
661                   phy_config_bb_with_pghdrfile(hw, BASEBAND_CONFIG_PHY_REG);
662         }
663         _rtl92ee_phy_txpower_by_rate_configuration(hw);
664         if (!rtstatus) {
665                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
666                 return false;
667         }
668         rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_AGC_TAB);
669         if (!rtstatus) {
670                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
671                 return false;
672         }
673         rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
674                                                       RFPGA0_XA_HSSIPARAMETER2,
675                                                       0x200));
676
677         return true;
678 }
679
680 static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
681 {
682         struct rtl_priv *rtlpriv = rtl_priv(hw);
683         u32 i;
684         u32 arraylength;
685         u32 *ptrarray;
686
687         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8192EMACPHY_Array\n");
688         arraylength = RTL8192EE_MAC_ARRAY_LEN;
689         ptrarray = RTL8192EE_MAC_ARRAY;
690         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
691                  "Img:RTL8192EE_MAC_ARRAY LEN %d\n" , arraylength);
692         for (i = 0; i < arraylength; i = i + 2)
693                 rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
694         return true;
695 }
696
697 #define READ_NEXT_PAIR(v1, v2, i) \
698         do { \
699                 i += 2; \
700                 v1 = array[i]; \
701                 v2 = array[i+1]; \
702         } while (0)
703
704 static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
705                                         u8 configtype)
706 {
707         int i;
708         u32 *array;
709         u16 len;
710         struct rtl_priv *rtlpriv = rtl_priv(hw);
711         u32 v1 = 0, v2 = 0;
712
713         if (configtype == BASEBAND_CONFIG_PHY_REG) {
714                 len = RTL8192EE_PHY_REG_ARRAY_LEN;
715                 array = RTL8192EE_PHY_REG_ARRAY;
716
717                 for (i = 0; i < len; i = i + 2) {
718                         v1 = array[i];
719                         v2 = array[i+1];
720                         if (v1 < 0xcdcdcdcd) {
721                                 _rtl92ee_config_bb_reg(hw, v1, v2);
722                         } else {/*This line is the start line of branch.*/
723                                 /* to protect READ_NEXT_PAIR not overrun */
724                                 if (i >= len - 2)
725                                         break;
726
727                                 if (!_check_condition(hw , array[i])) {
728                                         /*Discard the following pairs*/
729                                         READ_NEXT_PAIR(v1, v2, i);
730                                         while (v2 != 0xDEAD &&
731                                                v2 != 0xCDEF &&
732                                                v2 != 0xCDCD && i < len - 2) {
733                                                 READ_NEXT_PAIR(v1, v2, i);
734                                         }
735                                         i -= 2; /* prevent from for-loop += 2*/
736                                 } else {
737                                         /* Configure matched pairs and
738                                          * skip to end of if-else.
739                                          */
740                                         READ_NEXT_PAIR(v1, v2, i);
741                                         while (v2 != 0xDEAD &&
742                                                v2 != 0xCDEF &&
743                                                v2 != 0xCDCD && i < len - 2) {
744                                                 _rtl92ee_config_bb_reg(hw, v1,
745                                                                        v2);
746                                                 READ_NEXT_PAIR(v1, v2, i);
747                                         }
748
749                                         while (v2 != 0xDEAD && i < len - 2)
750                                                 READ_NEXT_PAIR(v1, v2, i);
751                                 }
752                         }
753                 }
754         } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
755                 len = RTL8192EE_AGC_TAB_ARRAY_LEN;
756                 array = RTL8192EE_AGC_TAB_ARRAY;
757
758                 for (i = 0; i < len; i = i + 2) {
759                         v1 = array[i];
760                         v2 = array[i+1];
761                         if (v1 < 0xCDCDCDCD) {
762                                 rtl_set_bbreg(hw, array[i], MASKDWORD,
763                                               array[i + 1]);
764                                 udelay(1);
765                                 continue;
766                     } else{/*This line is the start line of branch.*/
767                           /* to protect READ_NEXT_PAIR not overrun */
768                                 if (i >= len - 2)
769                                         break;
770
771                                 if (!_check_condition(hw , array[i])) {
772                                         /*Discard the following pairs*/
773                                         READ_NEXT_PAIR(v1, v2, i);
774                                         while (v2 != 0xDEAD &&
775                                                v2 != 0xCDEF &&
776                                                v2 != 0xCDCD &&
777                                                i < len - 2) {
778                                                 READ_NEXT_PAIR(v1, v2, i);
779                                         }
780                                         i -= 2; /* prevent from for-loop += 2*/
781                                 } else {
782                                         /* Configure matched pairs and
783                                          * skip to end of if-else.
784                                          */
785                                         READ_NEXT_PAIR(v1, v2, i);
786                                         while (v2 != 0xDEAD &&
787                                                v2 != 0xCDEF &&
788                                                v2 != 0xCDCD &&
789                                                i < len - 2) {
790                                                 rtl_set_bbreg(hw,
791                                                               array[i],
792                                                               MASKDWORD,
793                                                               array[i + 1]);
794                                                 udelay(1);
795                                                 READ_NEXT_PAIR(v1 , v2 , i);
796                                         }
797
798                                         while (v2 != 0xDEAD &&
799                                                i < len - 2) {
800                                                 READ_NEXT_PAIR(v1 , v2 , i);
801                                         }
802                                 }
803                         }
804                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
805                                  "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
806                                  array[i],
807                                  array[i + 1]);
808                 }
809         }
810         return true;
811 }
812
813 static u8 _rtl92ee_get_rate_section_index(u32 regaddr)
814 {
815         u8 index = 0;
816
817         switch (regaddr) {
818         case RTXAGC_A_RATE18_06:
819         case RTXAGC_B_RATE18_06:
820                 index = 0;
821                 break;
822         case RTXAGC_A_RATE54_24:
823         case RTXAGC_B_RATE54_24:
824                 index = 1;
825                 break;
826         case RTXAGC_A_CCK1_MCS32:
827         case RTXAGC_B_CCK1_55_MCS32:
828                 index = 2;
829                 break;
830         case RTXAGC_B_CCK11_A_CCK2_11:
831                 index = 3;
832                 break;
833         case RTXAGC_A_MCS03_MCS00:
834         case RTXAGC_B_MCS03_MCS00:
835                 index = 4;
836                 break;
837         case RTXAGC_A_MCS07_MCS04:
838         case RTXAGC_B_MCS07_MCS04:
839                 index = 5;
840                 break;
841         case RTXAGC_A_MCS11_MCS08:
842         case RTXAGC_B_MCS11_MCS08:
843                 index = 6;
844                 break;
845         case RTXAGC_A_MCS15_MCS12:
846         case RTXAGC_B_MCS15_MCS12:
847                 index = 7;
848                 break;
849         default:
850                 regaddr &= 0xFFF;
851                 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
852                         index = (u8)((regaddr - 0xC20) / 4);
853                 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
854                         index = (u8)((regaddr - 0xE20) / 4);
855                 break;
856         }
857         return index;
858 }
859
860 static void _rtl92ee_store_tx_power_by_rate(struct ieee80211_hw *hw,
861                                             enum band_type band,
862                                             enum radio_path rfpath,
863                                             u32 txnum, u32 regaddr,
864                                             u32 bitmask, u32 data)
865 {
866         struct rtl_priv *rtlpriv = rtl_priv(hw);
867         struct rtl_phy *rtlphy = &rtlpriv->phy;
868         u8 section = _rtl92ee_get_rate_section_index(regaddr);
869
870         if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
871                 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
872                 return;
873         }
874
875         if (rfpath > MAX_RF_PATH - 1) {
876                 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
877                          "Invalid RfPath %d\n", rfpath);
878                 return;
879         }
880         if (txnum > MAX_RF_PATH - 1) {
881                 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
882                 return;
883         }
884
885         rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][section] = data;
886 }
887
888 static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
889                                          u8 configtype)
890 {
891         struct rtl_priv *rtlpriv = rtl_priv(hw);
892         int i;
893         u32 *phy_regarray_table_pg;
894         u16 phy_regarray_pg_len;
895         u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
896
897         phy_regarray_pg_len = RTL8192EE_PHY_REG_ARRAY_PG_LEN;
898         phy_regarray_table_pg = RTL8192EE_PHY_REG_ARRAY_PG;
899
900         if (configtype == BASEBAND_CONFIG_PHY_REG) {
901                 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
902                         v1 = phy_regarray_table_pg[i];
903                         v2 = phy_regarray_table_pg[i+1];
904                         v3 = phy_regarray_table_pg[i+2];
905                         v4 = phy_regarray_table_pg[i+3];
906                         v5 = phy_regarray_table_pg[i+4];
907                         v6 = phy_regarray_table_pg[i+5];
908
909                         if (v1 < 0xcdcdcdcd) {
910                                 _rtl92ee_store_tx_power_by_rate(hw, v1, v2, v3,
911                                                                 v4, v5, v6);
912                                 continue;
913                         }
914                 }
915         } else {
916                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
917                          "configtype != BaseBand_Config_PHY_REG\n");
918         }
919         return true;
920 }
921
922 #define READ_NEXT_RF_PAIR(v1, v2, i) \
923         do { \
924                 i += 2; \
925                 v1 = array[i]; \
926                 v2 = array[i+1]; \
927         } while (0)
928
929 bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw  *hw,
930                                            enum radio_path rfpath)
931 {
932         struct rtl_priv *rtlpriv = rtl_priv(hw);
933         int i;
934         u32 *array;
935         u16 len;
936         u32 v1 = 0, v2 = 0;
937
938         switch (rfpath) {
939         case RF90_PATH_A:
940                 len = RTL8192EE_RADIOA_ARRAY_LEN;
941                 array = RTL8192EE_RADIOA_ARRAY;
942                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
943                          "Radio_A:RTL8192EE_RADIOA_ARRAY %d\n" , len);
944                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
945                 for (i = 0; i < len; i = i + 2) {
946                         v1 = array[i];
947                         v2 = array[i+1];
948                         if (v1 < 0xcdcdcdcd) {
949                                 _rtl92ee_config_rf_radio_a(hw, v1, v2);
950                                 continue;
951                         } else {/*This line is the start line of branch.*/
952                                 /* to protect READ_NEXT_PAIR not overrun */
953                                 if (i >= len - 2)
954                                         break;
955
956                                 if (!_check_condition(hw , array[i])) {
957                                         /*Discard the following pairs*/
958                                         READ_NEXT_RF_PAIR(v1, v2, i);
959                                         while (v2 != 0xDEAD &&
960                                                v2 != 0xCDEF &&
961                                                v2 != 0xCDCD && i < len - 2) {
962                                                 READ_NEXT_RF_PAIR(v1, v2, i);
963                                         }
964                                         i -= 2; /* prevent from for-loop += 2*/
965                                 } else {
966                                         /* Configure matched pairs and
967                                          * skip to end of if-else.
968                                          */
969                                         READ_NEXT_RF_PAIR(v1, v2, i);
970                                         while (v2 != 0xDEAD &&
971                                                v2 != 0xCDEF &&
972                                                v2 != 0xCDCD && i < len - 2) {
973                                                 _rtl92ee_config_rf_radio_a(hw,
974                                                                            v1,
975                                                                            v2);
976                                                 READ_NEXT_RF_PAIR(v1, v2, i);
977                                         }
978
979                                         while (v2 != 0xDEAD && i < len - 2)
980                                                 READ_NEXT_RF_PAIR(v1, v2, i);
981                                 }
982                         }
983                 }
984                 break;
985
986         case RF90_PATH_B:
987                 len = RTL8192EE_RADIOB_ARRAY_LEN;
988                 array = RTL8192EE_RADIOB_ARRAY;
989                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
990                          "Radio_A:RTL8192EE_RADIOB_ARRAY %d\n" , len);
991                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
992                 for (i = 0; i < len; i = i + 2) {
993                         v1 = array[i];
994                         v2 = array[i+1];
995                         if (v1 < 0xcdcdcdcd) {
996                                 _rtl92ee_config_rf_radio_b(hw, v1, v2);
997                                 continue;
998                         } else {/*This line is the start line of branch.*/
999                                 /* to protect READ_NEXT_PAIR not overrun */
1000                                 if (i >= len - 2)
1001                                         break;
1002
1003                                 if (!_check_condition(hw , array[i])) {
1004                                         /*Discard the following pairs*/
1005                                         READ_NEXT_RF_PAIR(v1, v2, i);
1006                                         while (v2 != 0xDEAD &&
1007                                                v2 != 0xCDEF &&
1008                                                v2 != 0xCDCD && i < len - 2) {
1009                                                 READ_NEXT_RF_PAIR(v1, v2, i);
1010                                         }
1011                                         i -= 2; /* prevent from for-loop += 2*/
1012                                 } else {
1013                                         /* Configure matched pairs and
1014                                          * skip to end of if-else.
1015                                          */
1016                                         READ_NEXT_RF_PAIR(v1, v2, i);
1017                                         while (v2 != 0xDEAD &&
1018                                                v2 != 0xCDEF &&
1019                                                v2 != 0xCDCD && i < len - 2) {
1020                                                 _rtl92ee_config_rf_radio_b(hw,
1021                                                                            v1,
1022                                                                            v2);
1023                                                 READ_NEXT_RF_PAIR(v1, v2, i);
1024                                         }
1025
1026                                         while (v2 != 0xDEAD && i < len - 2)
1027                                                 READ_NEXT_RF_PAIR(v1, v2, i);
1028                                 }
1029                         }
1030                 }
1031                 break;
1032         case RF90_PATH_C:
1033         case RF90_PATH_D:
1034                 break;
1035         }
1036         return true;
1037 }
1038
1039 void rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1040 {
1041         struct rtl_priv *rtlpriv = rtl_priv(hw);
1042         struct rtl_phy *rtlphy = &rtlpriv->phy;
1043
1044         rtlphy->default_initialgain[0] =
1045                 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1046         rtlphy->default_initialgain[1] =
1047                 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1048         rtlphy->default_initialgain[2] =
1049                 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
1050         rtlphy->default_initialgain[3] =
1051                 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
1052
1053         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1054                  "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
1055                   rtlphy->default_initialgain[0],
1056                   rtlphy->default_initialgain[1],
1057                   rtlphy->default_initialgain[2],
1058                   rtlphy->default_initialgain[3]);
1059
1060         rtlphy->framesync = (u8)rtl_get_bbreg(hw,
1061                                               ROFDM0_RXDETECTOR3, MASKBYTE0);
1062         rtlphy->framesync_c34 = rtl_get_bbreg(hw,
1063                                               ROFDM0_RXDETECTOR2, MASKDWORD);
1064
1065         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1066                  "Default framesync (0x%x) = 0x%x\n",
1067                   ROFDM0_RXDETECTOR3, rtlphy->framesync);
1068 }
1069
1070 static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw)
1071 {
1072         struct rtl_priv *rtlpriv = rtl_priv(hw);
1073         struct rtl_phy *rtlphy = &rtlpriv->phy;
1074
1075         rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1076         rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1077
1078         rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
1079         rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
1080
1081         rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
1082         rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
1083
1084         rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
1085                                                         RFPGA0_XA_LSSIPARAMETER;
1086         rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
1087                                                         RFPGA0_XB_LSSIPARAMETER;
1088
1089         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
1090         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
1091
1092         rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
1093         rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
1094
1095         rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
1096         rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
1097 }
1098
1099 void rtl92ee_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1100 {
1101         struct rtl_priv *rtlpriv = rtl_priv(hw);
1102         struct rtl_phy *rtlphy = &rtlpriv->phy;
1103         u8 txpwr_level;
1104         long txpwr_dbm;
1105
1106         txpwr_level = rtlphy->cur_cck_txpwridx;
1107         txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
1108                                                   txpwr_level);
1109         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1110         if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
1111             txpwr_dbm)
1112                 txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
1113                                                           txpwr_level);
1114         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1115         if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
1116                                           txpwr_level) > txpwr_dbm)
1117                 txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw,
1118                                                           WIRELESS_MODE_N_24G,
1119                                                           txpwr_level);
1120         *powerlevel = txpwr_dbm;
1121 }
1122
1123 static u8 _rtl92ee_phy_get_ratesection_intxpower_byrate(enum radio_path path,
1124                                                         u8 rate)
1125 {
1126         u8 rate_section = 0;
1127
1128         switch (rate) {
1129         case DESC92C_RATE1M:
1130                 rate_section = 2;
1131                 break;
1132         case DESC92C_RATE2M:
1133         case DESC92C_RATE5_5M:
1134                 if (path == RF90_PATH_A)
1135                         rate_section = 3;
1136                 else if (path == RF90_PATH_B)
1137                         rate_section = 2;
1138                 break;
1139         case DESC92C_RATE11M:
1140                 rate_section = 3;
1141                 break;
1142         case DESC92C_RATE6M:
1143         case DESC92C_RATE9M:
1144         case DESC92C_RATE12M:
1145         case DESC92C_RATE18M:
1146                 rate_section = 0;
1147                 break;
1148         case DESC92C_RATE24M:
1149         case DESC92C_RATE36M:
1150         case DESC92C_RATE48M:
1151         case DESC92C_RATE54M:
1152                 rate_section = 1;
1153                 break;
1154         case DESC92C_RATEMCS0:
1155         case DESC92C_RATEMCS1:
1156         case DESC92C_RATEMCS2:
1157         case DESC92C_RATEMCS3:
1158                 rate_section = 4;
1159                 break;
1160         case DESC92C_RATEMCS4:
1161         case DESC92C_RATEMCS5:
1162         case DESC92C_RATEMCS6:
1163         case DESC92C_RATEMCS7:
1164                 rate_section = 5;
1165                 break;
1166         case DESC92C_RATEMCS8:
1167         case DESC92C_RATEMCS9:
1168         case DESC92C_RATEMCS10:
1169         case DESC92C_RATEMCS11:
1170                 rate_section = 6;
1171                 break;
1172         case DESC92C_RATEMCS12:
1173         case DESC92C_RATEMCS13:
1174         case DESC92C_RATEMCS14:
1175         case DESC92C_RATEMCS15:
1176                 rate_section = 7;
1177                 break;
1178         default:
1179                 RT_ASSERT(true, "Rate_Section is Illegal\n");
1180                 break;
1181         }
1182         return rate_section;
1183 }
1184
1185 static u8 _rtl92ee_get_txpower_by_rate(struct ieee80211_hw *hw,
1186                                        enum band_type band,
1187                                        enum radio_path rf, u8 rate)
1188 {
1189         struct rtl_priv *rtlpriv = rtl_priv(hw);
1190         struct rtl_phy *rtlphy = &rtlpriv->phy;
1191         u8 shift = 0, sec, tx_num;
1192         char diff = 0;
1193
1194         sec = _rtl92ee_phy_get_ratesection_intxpower_byrate(rf, rate);
1195         tx_num = RF_TX_NUM_NONIMPLEMENT;
1196
1197         if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
1198                 if ((rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15))
1199                         tx_num = RF_2TX;
1200                 else
1201                         tx_num = RF_1TX;
1202         }
1203
1204         switch (rate) {
1205         case DESC92C_RATE1M:
1206         case DESC92C_RATE6M:
1207         case DESC92C_RATE24M:
1208         case DESC92C_RATEMCS0:
1209         case DESC92C_RATEMCS4:
1210         case DESC92C_RATEMCS8:
1211         case DESC92C_RATEMCS12:
1212                 shift = 0;
1213                 break;
1214         case DESC92C_RATE2M:
1215         case DESC92C_RATE9M:
1216         case DESC92C_RATE36M:
1217         case DESC92C_RATEMCS1:
1218         case DESC92C_RATEMCS5:
1219         case DESC92C_RATEMCS9:
1220         case DESC92C_RATEMCS13:
1221                 shift = 8;
1222                 break;
1223         case DESC92C_RATE5_5M:
1224         case DESC92C_RATE12M:
1225         case DESC92C_RATE48M:
1226         case DESC92C_RATEMCS2:
1227         case DESC92C_RATEMCS6:
1228         case DESC92C_RATEMCS10:
1229         case DESC92C_RATEMCS14:
1230                 shift = 16;
1231                 break;
1232         case DESC92C_RATE11M:
1233         case DESC92C_RATE18M:
1234         case DESC92C_RATE54M:
1235         case DESC92C_RATEMCS3:
1236         case DESC92C_RATEMCS7:
1237         case DESC92C_RATEMCS11:
1238         case DESC92C_RATEMCS15:
1239                 shift = 24;
1240                 break;
1241         default:
1242                 RT_ASSERT(true, "Rate_Section is Illegal\n");
1243                 break;
1244         }
1245
1246         diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rf][tx_num][sec] >>
1247                     shift) & 0xff;
1248
1249         return  diff;
1250 }
1251
1252 static u8 _rtl92ee_get_txpower_index(struct ieee80211_hw *hw,
1253                                      enum radio_path rfpath, u8 rate,
1254                                      u8 bw, u8 channel)
1255 {
1256         struct rtl_priv *rtlpriv = rtl_priv(hw);
1257         struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
1258         u8 index = (channel - 1);
1259         u8 tx_power = 0;
1260         u8 diff = 0;
1261
1262         if (channel < 1 || channel > 14) {
1263                 index = 0;
1264                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_DMESG,
1265                          "Illegal channel!!\n");
1266         }
1267
1268         if (IS_CCK_RATE(rate))
1269                 tx_power = rtlefuse->txpwrlevel_cck[rfpath][index];
1270         else if (DESC92C_RATE6M <= rate)
1271                 tx_power = rtlefuse->txpwrlevel_ht40_1s[rfpath][index];
1272
1273         /* OFDM-1T*/
1274         if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1275             !IS_CCK_RATE(rate))
1276                 tx_power += rtlefuse->txpwr_legacyhtdiff[rfpath][TX_1S];
1277
1278         /* BW20-1S, BW20-2S */
1279         if (bw == HT_CHANNEL_WIDTH_20) {
1280                 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1281                         tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_1S];
1282                 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1283                         tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_2S];
1284         } else if (bw == HT_CHANNEL_WIDTH_20_40) {/* BW40-1S, BW40-2S */
1285                 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1286                         tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_1S];
1287                 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1288                         tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_2S];
1289         }
1290
1291         if (rtlefuse->eeprom_regulatory != 2)
1292                 diff = _rtl92ee_get_txpower_by_rate(hw, BAND_ON_2_4G,
1293                                                     rfpath, rate);
1294
1295         tx_power += diff;
1296
1297         if (tx_power > MAX_POWER_INDEX)
1298                 tx_power = MAX_POWER_INDEX;
1299
1300         return tx_power;
1301 }
1302
1303 static void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx,
1304                                        enum radio_path rfpath, u8 rate)
1305 {
1306         struct rtl_priv *rtlpriv = rtl_priv(hw);
1307
1308         if (rfpath == RF90_PATH_A) {
1309                 switch (rate) {
1310                 case DESC92C_RATE1M:
1311                         rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1,
1312                                       pwr_idx);
1313                         break;
1314                 case DESC92C_RATE2M:
1315                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE1,
1316                                       pwr_idx);
1317                         break;
1318                 case DESC92C_RATE5_5M:
1319                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE2,
1320                                       pwr_idx);
1321                         break;
1322                 case DESC92C_RATE11M:
1323                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE3,
1324                                       pwr_idx);
1325                         break;
1326                 case DESC92C_RATE6M:
1327                         rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE0,
1328                                       pwr_idx);
1329                         break;
1330                 case DESC92C_RATE9M:
1331                         rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE1,
1332                                       pwr_idx);
1333                         break;
1334                 case DESC92C_RATE12M:
1335                         rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE2,
1336                                       pwr_idx);
1337                         break;
1338                 case DESC92C_RATE18M:
1339                         rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE3,
1340                                       pwr_idx);
1341                         break;
1342                 case DESC92C_RATE24M:
1343                         rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE0,
1344                                       pwr_idx);
1345                         break;
1346                 case DESC92C_RATE36M:
1347                         rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE1,
1348                                       pwr_idx);
1349                         break;
1350                 case DESC92C_RATE48M:
1351                         rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE2,
1352                                       pwr_idx);
1353                         break;
1354                 case DESC92C_RATE54M:
1355                         rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE3,
1356                                       pwr_idx);
1357                         break;
1358                 case DESC92C_RATEMCS0:
1359                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0,
1360                                       pwr_idx);
1361                         break;
1362                 case DESC92C_RATEMCS1:
1363                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE1,
1364                                       pwr_idx);
1365                         break;
1366                 case DESC92C_RATEMCS2:
1367                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE2,
1368                                       pwr_idx);
1369                         break;
1370                 case DESC92C_RATEMCS3:
1371                         rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3,
1372                                       pwr_idx);
1373                         break;
1374                 case DESC92C_RATEMCS4:
1375                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0,
1376                                       pwr_idx);
1377                         break;
1378                 case DESC92C_RATEMCS5:
1379                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE1,
1380                                       pwr_idx);
1381                         break;
1382                 case DESC92C_RATEMCS6:
1383                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE2,
1384                                       pwr_idx);
1385                         break;
1386                 case DESC92C_RATEMCS7:
1387                         rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3,
1388                                       pwr_idx);
1389                         break;
1390                 case DESC92C_RATEMCS8:
1391                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0,
1392                                       pwr_idx);
1393                         break;
1394                 case DESC92C_RATEMCS9:
1395                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE1,
1396                                       pwr_idx);
1397                         break;
1398                 case DESC92C_RATEMCS10:
1399                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE2,
1400                                       pwr_idx);
1401                         break;
1402                 case DESC92C_RATEMCS11:
1403                         rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3,
1404                                       pwr_idx);
1405                         break;
1406                 case DESC92C_RATEMCS12:
1407                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE0,
1408                                       pwr_idx);
1409                         break;
1410                 case DESC92C_RATEMCS13:
1411                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE1,
1412                                       pwr_idx);
1413                         break;
1414                 case DESC92C_RATEMCS14:
1415                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE2,
1416                                       pwr_idx);
1417                         break;
1418                 case DESC92C_RATEMCS15:
1419                         rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE3,
1420                                       pwr_idx);
1421                         break;
1422                 default:
1423                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1424                                  "Invalid Rate!!\n");
1425                         break;
1426                 }
1427         } else if (rfpath == RF90_PATH_B) {
1428                 switch (rate) {
1429                 case DESC92C_RATE1M:
1430                         rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE1,
1431                                       pwr_idx);
1432                         break;
1433                 case DESC92C_RATE2M:
1434                         rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE2,
1435                                       pwr_idx);
1436                         break;
1437                 case DESC92C_RATE5_5M:
1438                         rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE3,
1439                                       pwr_idx);
1440                         break;
1441                 case DESC92C_RATE11M:
1442                         rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0,
1443                                       pwr_idx);
1444                         break;
1445                 case DESC92C_RATE6M:
1446                         rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE0,
1447                                       pwr_idx);
1448                         break;
1449                 case DESC92C_RATE9M:
1450                         rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE1,
1451                                       pwr_idx);
1452                         break;
1453                 case DESC92C_RATE12M:
1454                         rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE2,
1455                                       pwr_idx);
1456                         break;
1457                 case DESC92C_RATE18M:
1458                         rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE3,
1459                                       pwr_idx);
1460                         break;
1461                 case DESC92C_RATE24M:
1462                         rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE0,
1463                                       pwr_idx);
1464                         break;
1465                 case DESC92C_RATE36M:
1466                         rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE1,
1467                                       pwr_idx);
1468                         break;
1469                 case DESC92C_RATE48M:
1470                         rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE2,
1471                                       pwr_idx);
1472                         break;
1473                 case DESC92C_RATE54M:
1474                         rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE3,
1475                                       pwr_idx);
1476                         break;
1477                 case DESC92C_RATEMCS0:
1478                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE0,
1479                                       pwr_idx);
1480                         break;
1481                 case DESC92C_RATEMCS1:
1482                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE1,
1483                                       pwr_idx);
1484                         break;
1485                 case DESC92C_RATEMCS2:
1486                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE2,
1487                                       pwr_idx);
1488                         break;
1489                 case DESC92C_RATEMCS3:
1490                         rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE3,
1491                                       pwr_idx);
1492                         break;
1493                 case DESC92C_RATEMCS4:
1494                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE0,
1495                                       pwr_idx);
1496                         break;
1497                 case DESC92C_RATEMCS5:
1498                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE1,
1499                                       pwr_idx);
1500                         break;
1501                 case DESC92C_RATEMCS6:
1502                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE2,
1503                                       pwr_idx);
1504                         break;
1505                 case DESC92C_RATEMCS7:
1506                         rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE3,
1507                                       pwr_idx);
1508                         break;
1509                 case DESC92C_RATEMCS8:
1510                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE0,
1511                                       pwr_idx);
1512                         break;
1513                 case DESC92C_RATEMCS9:
1514                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE1,
1515                                       pwr_idx);
1516                         break;
1517                 case DESC92C_RATEMCS10:
1518                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE2,
1519                                       pwr_idx);
1520                         break;
1521                 case DESC92C_RATEMCS11:
1522                         rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE3,
1523                                       pwr_idx);
1524                         break;
1525                 case DESC92C_RATEMCS12:
1526                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE0,
1527                                       pwr_idx);
1528                         break;
1529                 case DESC92C_RATEMCS13:
1530                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE1,
1531                                       pwr_idx);
1532                         break;
1533                 case DESC92C_RATEMCS14:
1534                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE2,
1535                                       pwr_idx);
1536                         break;
1537                 case DESC92C_RATEMCS15:
1538                         rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE3,
1539                                       pwr_idx);
1540                         break;
1541                 default:
1542                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1543                                  "Invalid Rate!!\n");
1544                         break;
1545                 }
1546         } else {
1547                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1548         }
1549 }
1550
1551 static void phy_set_txpower_index_by_rate_array(struct ieee80211_hw *hw,
1552                                                 enum radio_path rfpath, u8 bw,
1553                                                 u8 channel, u8 *rates, u8 size)
1554 {
1555         u8 i;
1556         u8 power_index;
1557
1558         for (i = 0; i < size; i++) {
1559                 power_index = _rtl92ee_get_txpower_index(hw, rfpath, rates[i],
1560                                                          bw, channel);
1561                 _rtl92ee_set_txpower_index(hw, power_index, rfpath, rates[i]);
1562         }
1563 }
1564
1565 static void phy_set_txpower_index_by_rate_section(struct ieee80211_hw *hw,
1566                                                   enum radio_path rfpath,
1567                                                   u8 channel,
1568                                                   enum rate_section section)
1569 {
1570         struct rtl_priv *rtlpriv = rtl_priv(hw);
1571         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1572         struct rtl_phy *rtlphy = &rtlpriv->phy;
1573
1574         if (section == CCK) {
1575                 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1576                                   DESC92C_RATE5_5M, DESC92C_RATE11M};
1577                 if (rtlhal->current_bandtype == BAND_ON_2_4G)
1578                         phy_set_txpower_index_by_rate_array(hw, rfpath,
1579                                                         rtlphy->current_chan_bw,
1580                                                         channel, cck_rates, 4);
1581         } else if (section == OFDM) {
1582                 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1583                                    DESC92C_RATE12M, DESC92C_RATE18M,
1584                                    DESC92C_RATE24M, DESC92C_RATE36M,
1585                                    DESC92C_RATE48M, DESC92C_RATE54M};
1586                 phy_set_txpower_index_by_rate_array(hw, rfpath,
1587                                                     rtlphy->current_chan_bw,
1588                                                     channel, ofdm_rates, 8);
1589         } else if (section == HT_MCS0_MCS7) {
1590                 u8 ht_rates1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1591                                     DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1592                                     DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1593                                     DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1594                 phy_set_txpower_index_by_rate_array(hw, rfpath,
1595                                                     rtlphy->current_chan_bw,
1596                                                     channel, ht_rates1t, 8);
1597         } else if (section == HT_MCS8_MCS15) {
1598                 u8 ht_rates2t[]  = {DESC92C_RATEMCS8, DESC92C_RATEMCS9,
1599                                     DESC92C_RATEMCS10, DESC92C_RATEMCS11,
1600                                     DESC92C_RATEMCS12, DESC92C_RATEMCS13,
1601                                     DESC92C_RATEMCS14, DESC92C_RATEMCS15};
1602                 phy_set_txpower_index_by_rate_array(hw, rfpath,
1603                                                     rtlphy->current_chan_bw,
1604                                                     channel, ht_rates2t, 8);
1605         } else
1606                 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
1607                          "Invalid RateSection %d\n", section);
1608 }
1609
1610 void rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1611 {
1612         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1613         struct rtl_phy *rtlphy = &rtl_priv(hw)->phy;
1614         enum radio_path rfpath;
1615
1616         if (!rtlefuse->txpwr_fromeprom)
1617                 return;
1618         for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
1619              rfpath++) {
1620                 phy_set_txpower_index_by_rate_section(hw, rfpath,
1621                                                       channel, CCK);
1622                 phy_set_txpower_index_by_rate_section(hw, rfpath,
1623                                                       channel, OFDM);
1624                 phy_set_txpower_index_by_rate_section(hw, rfpath,
1625                                                       channel,
1626                                                       HT_MCS0_MCS7);
1627
1628                 if (rtlphy->num_total_rfpath >= 2)
1629                         phy_set_txpower_index_by_rate_section(hw,
1630                                                               rfpath, channel,
1631                                                               HT_MCS8_MCS15);
1632         }
1633 }
1634
1635 static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1636                                           enum wireless_mode wirelessmode,
1637                                           u8 txpwridx)
1638 {
1639         long offset;
1640         long pwrout_dbm;
1641
1642         switch (wirelessmode) {
1643         case WIRELESS_MODE_B:
1644                 offset = -7;
1645                 break;
1646         case WIRELESS_MODE_G:
1647         case WIRELESS_MODE_N_24G:
1648                 offset = -8;
1649                 break;
1650         default:
1651                 offset = -8;
1652                 break;
1653         }
1654         pwrout_dbm = txpwridx / 2 + offset;
1655         return pwrout_dbm;
1656 }
1657
1658 void rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1659 {
1660         struct rtl_priv *rtlpriv = rtl_priv(hw);
1661         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1662         enum io_type iotype;
1663
1664         if (!is_hal_stop(rtlhal)) {
1665                 switch (operation) {
1666                 case SCAN_OPT_BACKUP_BAND0:
1667                         iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1668                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1669                                                       (u8 *)&iotype);
1670
1671                         break;
1672                 case SCAN_OPT_RESTORE:
1673                         iotype = IO_CMD_RESUME_DM_BY_SCAN;
1674                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1675                                                       (u8 *)&iotype);
1676                         break;
1677                 default:
1678                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1679                                  "Unknown Scan Backup operation.\n");
1680                         break;
1681                 }
1682         }
1683 }
1684
1685 void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1686 {
1687         struct rtl_priv *rtlpriv = rtl_priv(hw);
1688         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1689         struct rtl_phy *rtlphy = &rtlpriv->phy;
1690         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1691         u8 reg_bw_opmode;
1692         u8 reg_prsr_rsc;
1693
1694         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1695                  "Switch to %s bandwidth\n",
1696                   rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1697                   "20MHz" : "40MHz");
1698
1699         if (is_hal_stop(rtlhal)) {
1700                 rtlphy->set_bwmode_inprogress = false;
1701                 return;
1702         }
1703
1704         reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1705         reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1706
1707         switch (rtlphy->current_chan_bw) {
1708         case HT_CHANNEL_WIDTH_20:
1709                 reg_bw_opmode |= BW_OPMODE_20MHZ;
1710                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1711                 break;
1712         case HT_CHANNEL_WIDTH_20_40:
1713                 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1714                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1715                 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1716                                (mac->cur_40_prime_sc << 5);
1717                 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1718                 break;
1719         default:
1720                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1721                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1722                 break;
1723         }
1724
1725         switch (rtlphy->current_chan_bw) {
1726         case HT_CHANNEL_WIDTH_20:
1727                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1728                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1729                 rtl_set_bbreg(hw, ROFDM0_TXPSEUDONOISEWGT,
1730                               (BIT(31) | BIT(30)), 0);
1731                 break;
1732         case HT_CHANNEL_WIDTH_20_40:
1733                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1734                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1735                 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1736                               (mac->cur_40_prime_sc >> 1));
1737                 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00,
1738                               mac->cur_40_prime_sc);
1739
1740                 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1741                               (mac->cur_40_prime_sc ==
1742                                HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1743                 break;
1744         default:
1745                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1746                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1747                 break;
1748         }
1749         rtl92ee_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1750         rtlphy->set_bwmode_inprogress = false;
1751         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1752 }
1753
1754 void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw,
1755                              enum nl80211_channel_type ch_type)
1756 {
1757         struct rtl_priv *rtlpriv = rtl_priv(hw);
1758         struct rtl_phy *rtlphy = &rtlpriv->phy;
1759         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1760         u8 tmp_bw = rtlphy->current_chan_bw;
1761
1762         if (rtlphy->set_bwmode_inprogress)
1763                 return;
1764         rtlphy->set_bwmode_inprogress = true;
1765         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1766                 rtl92ee_phy_set_bw_mode_callback(hw);
1767         } else {
1768                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1769                          "false driver sleep or unload\n");
1770                 rtlphy->set_bwmode_inprogress = false;
1771                 rtlphy->current_chan_bw = tmp_bw;
1772         }
1773 }
1774
1775 void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1776 {
1777         struct rtl_priv *rtlpriv = rtl_priv(hw);
1778         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1779         struct rtl_phy *rtlphy = &rtlpriv->phy;
1780         u32 delay;
1781
1782         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1783                  "switch to channel%d\n", rtlphy->current_channel);
1784         if (is_hal_stop(rtlhal))
1785                 return;
1786         do {
1787                 if (!rtlphy->sw_chnl_inprogress)
1788                         break;
1789                 if (!_rtl92ee_phy_sw_chnl_step_by_step
1790                     (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1791                      &rtlphy->sw_chnl_step, &delay)) {
1792                         if (delay > 0)
1793                                 mdelay(delay);
1794                         else
1795                                 continue;
1796                 } else {
1797                         rtlphy->sw_chnl_inprogress = false;
1798                 }
1799                 break;
1800         } while (true);
1801         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1802 }
1803
1804 u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw)
1805 {
1806         struct rtl_priv *rtlpriv = rtl_priv(hw);
1807         struct rtl_phy *rtlphy = &rtlpriv->phy;
1808         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1809
1810         if (rtlphy->sw_chnl_inprogress)
1811                 return 0;
1812         if (rtlphy->set_bwmode_inprogress)
1813                 return 0;
1814         RT_ASSERT((rtlphy->current_channel <= 14),
1815                   "WIRELESS_MODE_G but channel>14");
1816         rtlphy->sw_chnl_inprogress = true;
1817         rtlphy->sw_chnl_stage = 0;
1818         rtlphy->sw_chnl_step = 0;
1819         if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1820                 rtl92ee_phy_sw_chnl_callback(hw);
1821                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1822                          "sw_chnl_inprogress false schdule workitem current channel %d\n",
1823                          rtlphy->current_channel);
1824                 rtlphy->sw_chnl_inprogress = false;
1825         } else {
1826                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1827                          "sw_chnl_inprogress false driver sleep or unload\n");
1828                 rtlphy->sw_chnl_inprogress = false;
1829         }
1830         return 1;
1831 }
1832
1833 static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1834                                               u8 channel, u8 *stage, u8 *step,
1835                                               u32 *delay)
1836 {
1837         struct rtl_priv *rtlpriv = rtl_priv(hw);
1838         struct rtl_phy *rtlphy = &rtlpriv->phy;
1839         struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1840         u32 precommoncmdcnt;
1841         struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1842         u32 postcommoncmdcnt;
1843         struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1844         u32 rfdependcmdcnt;
1845         struct swchnlcmd *currentcmd = NULL;
1846         u8 rfpath;
1847         u8 num_total_rfpath = rtlphy->num_total_rfpath;
1848
1849         precommoncmdcnt = 0;
1850         _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1851                                           MAX_PRECMD_CNT,
1852                                           CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
1853         _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1854                                           MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1855
1856         postcommoncmdcnt = 0;
1857
1858         _rtl92ee_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1859                                           MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1860
1861         rfdependcmdcnt = 0;
1862
1863         RT_ASSERT((channel >= 1 && channel <= 14),
1864                   "illegal channel for Zebra: %d\n", channel);
1865
1866         _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1867                                           MAX_RFDEPENDCMD_CNT,
1868                                           CMDID_RF_WRITEREG,
1869                                           RF_CHNLBW, channel, 10);
1870
1871         _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1872                                           MAX_RFDEPENDCMD_CNT, CMDID_END,
1873                                           0, 0, 0);
1874
1875         do {
1876                 switch (*stage) {
1877                 case 0:
1878                         currentcmd = &precommoncmd[*step];
1879                         break;
1880                 case 1:
1881                         currentcmd = &rfdependcmd[*step];
1882                         break;
1883                 case 2:
1884                         currentcmd = &postcommoncmd[*step];
1885                         break;
1886                 default:
1887                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1888                                  "Invalid 'stage' = %d, Check it!\n" , *stage);
1889                         return true;
1890                 }
1891
1892                 if (currentcmd->cmdid == CMDID_END) {
1893                         if ((*stage) == 2)
1894                                 return true;
1895                         (*stage)++;
1896                         (*step) = 0;
1897                         continue;
1898                 }
1899
1900                 switch (currentcmd->cmdid) {
1901                 case CMDID_SET_TXPOWEROWER_LEVEL:
1902                         rtl92ee_phy_set_txpower_level(hw, channel);
1903                         break;
1904                 case CMDID_WRITEPORT_ULONG:
1905                         rtl_write_dword(rtlpriv, currentcmd->para1,
1906                                         currentcmd->para2);
1907                         break;
1908                 case CMDID_WRITEPORT_USHORT:
1909                         rtl_write_word(rtlpriv, currentcmd->para1,
1910                                        (u16)currentcmd->para2);
1911                         break;
1912                 case CMDID_WRITEPORT_UCHAR:
1913                         rtl_write_byte(rtlpriv, currentcmd->para1,
1914                                        (u8)currentcmd->para2);
1915                         break;
1916                 case CMDID_RF_WRITEREG:
1917                         for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1918                                 rtlphy->rfreg_chnlval[rfpath] =
1919                                         ((rtlphy->rfreg_chnlval[rfpath] &
1920                                           0xfffff00) | currentcmd->para2);
1921
1922                                 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1923                                               currentcmd->para1,
1924                                               0x3ff,
1925                                               rtlphy->rfreg_chnlval[rfpath]);
1926                         }
1927                         break;
1928                 default:
1929                         RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1930                                  "switch case not process\n");
1931                         break;
1932                 }
1933
1934                 break;
1935         } while (true);
1936
1937         (*delay) = currentcmd->msdelay;
1938         (*step)++;
1939         return false;
1940 }
1941
1942 static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1943                                               u32 cmdtableidx, u32 cmdtablesz,
1944                                               enum swchnlcmd_id cmdid,
1945                                               u32 para1, u32 para2, u32 msdelay)
1946 {
1947         struct swchnlcmd *pcmd;
1948
1949         if (cmdtable == NULL) {
1950                 RT_ASSERT(false, "cmdtable cannot be NULL.\n");
1951                 return false;
1952         }
1953
1954         if (cmdtableidx >= cmdtablesz)
1955                 return false;
1956
1957         pcmd = cmdtable + cmdtableidx;
1958         pcmd->cmdid = cmdid;
1959         pcmd->para1 = para1;
1960         pcmd->para2 = para2;
1961         pcmd->msdelay = msdelay;
1962         return true;
1963 }
1964
1965 static u8 _rtl92ee_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1966 {
1967         u32 reg_eac, reg_e94, reg_e9c;
1968         u8 result = 0x00;
1969         /* path-A IQK setting */
1970         /* PA/PAD controlled by 0x0 */
1971         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1972         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
1973         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1974
1975         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1976         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1977         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1978         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1979
1980         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140303);
1981         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160000);
1982
1983         /*LO calibration setting*/
1984         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1985
1986         /*One shot, path A LOK & IQK*/
1987         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1988         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1989
1990         mdelay(IQK_DELAY_TIME);
1991
1992         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1993         reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1994         reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1995
1996         if (!(reg_eac & BIT(28)) &&
1997             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1998             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1999                 result |= 0x01;
2000         else
2001                 return result;
2002
2003         return result;
2004 }
2005
2006 static u8 _rtl92ee_phy_path_b_iqk(struct ieee80211_hw *hw)
2007 {
2008         u32 reg_eac, reg_eb4, reg_ebc;
2009         u8 result = 0x00;
2010
2011         /* PA/PAD controlled by 0x0 */
2012         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2013         rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2014         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2015
2016         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2017         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2018
2019         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2020         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2021         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2022         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2023
2024         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x821403e2);
2025         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160000);
2026
2027         /* LO calibration setting */
2028         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
2029
2030         /*One shot, path B LOK & IQK*/
2031         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2032         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2033
2034         mdelay(IQK_DELAY_TIME);
2035
2036         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
2037         reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
2038         reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
2039
2040         if (!(reg_eac & BIT(31)) &&
2041             (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2042             (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
2043                 result |= 0x01;
2044         else
2045                 return result;
2046
2047         return result;
2048 }
2049
2050 static u8 _rtl92ee_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2051 {
2052         u32 reg_eac, reg_e94, reg_e9c, reg_ea4 , u32temp;
2053         u8 result = 0x00;
2054
2055         /*Get TXIMR Setting*/
2056         /*Modify RX IQK mode table*/
2057         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2058
2059         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2060         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2061         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2062         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2063
2064         /*PA/PAD control by 0x56, and set = 0x0*/
2065         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2066         rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2067
2068         /*enter IQK mode*/
2069         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2070
2071         /*IQK Setting*/
2072         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2073         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2074
2075         /*path a IQK setting*/
2076         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2077         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2078         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2079         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2080
2081         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2082         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160c1f);
2083
2084         /*LO calibration Setting*/
2085         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2086
2087         /*one shot,path A LOK & iqk*/
2088         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2089         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2090
2091         mdelay(IQK_DELAY_TIME);
2092
2093         /* Check failed */
2094         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2095         reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
2096         reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
2097
2098         if (!(reg_eac & BIT(28)) &&
2099             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
2100             (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) {
2101                 result |= 0x01;
2102         } else {
2103                 /*      PA/PAD controlled by 0x0 */
2104                 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2105                 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2106                 return result;
2107         }
2108
2109         u32temp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
2110                   ((reg_e9c & 0x3FF0000) >> 16);
2111         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2112         /*RX IQK*/
2113         /*Modify RX IQK mode table*/
2114         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2115
2116         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2117
2118         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2119         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2120         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2121
2122         /*PA/PAD control by 0x56, and set = 0x0*/
2123         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2124         rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2125
2126         /*enter IQK mode*/
2127         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2128
2129         /*IQK Setting*/
2130         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2131
2132         /*path a IQK setting*/
2133         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2134         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2135         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2136         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2137
2138         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2139         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c1f);
2140
2141         /*LO calibration Setting*/
2142         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2143         /*one shot,path A LOK & iqk*/
2144         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2145         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2146
2147         mdelay(IQK_DELAY_TIME);
2148         /*Check failed*/
2149         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2150         reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
2151
2152         /*PA/PAD controlled by 0x0*/
2153         /*leave IQK mode*/
2154         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2155         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2156         /*if Tx is OK, check whether Rx is OK*/
2157         if (!(reg_eac & BIT(27)) &&
2158             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
2159             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
2160                 result |= 0x02;
2161
2162         return result;
2163 }
2164
2165 static u8 _rtl92ee_phy_path_b_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2166 {
2167         struct rtl_priv *rtlpriv = rtl_priv(hw);
2168         u32 reg_eac, reg_eb4, reg_ebc, reg_ecc, reg_ec4, u32temp;
2169         u8 result = 0x00;
2170
2171         /*Get TXIMR Setting*/
2172         /*Modify RX IQK mode table*/
2173         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2174
2175         rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2176         rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2177         rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2178         rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2179
2180         /*PA/PAD all off*/
2181         rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2182         rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2183
2184         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2185
2186         /*IQK Setting*/
2187         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2188         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2189
2190         /*path a IQK setting*/
2191         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2192         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2193         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2194         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2195
2196         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2197         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160c1f);
2198
2199         /*LO calibration Setting*/
2200         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2201
2202         /*one shot,path A LOK & iqk*/
2203         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2204         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2205
2206         mdelay(IQK_DELAY_TIME);
2207
2208         /* Check failed */
2209         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2210         reg_eb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD);
2211         reg_ebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD);
2212
2213         if (!(reg_eac & BIT(31)) &&
2214             (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2215             (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) {
2216                 result |= 0x01;
2217         } else {
2218                 /*      PA/PAD controlled by 0x0 */
2219                 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2220                 rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2221                 return result;
2222         }
2223
2224         u32temp = 0x80007C00 | (reg_eb4 & 0x3FF0000) |
2225                   ((reg_ebc & 0x3FF0000) >> 16);
2226         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2227         /*RX IQK*/
2228         /*Modify RX IQK mode table*/
2229         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2230         rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2231
2232         rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2233         rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2234         rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2235
2236         /*PA/PAD all off*/
2237         rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2238         rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2239
2240         /*enter IQK mode*/
2241         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2242
2243         /*IQK Setting*/
2244         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2245
2246         /*path b IQK setting*/
2247         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2248         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2249         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2250         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2251
2252         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2253         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160c1f);
2254
2255         /*LO calibration Setting*/
2256         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2257         /*one shot,path A LOK & iqk*/
2258         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2259         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2260
2261         mdelay(IQK_DELAY_TIME);
2262         /*Check failed*/
2263         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2264         reg_ec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD);
2265         reg_ecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD);
2266         /*PA/PAD controlled by 0x0*/
2267         /*leave IQK mode*/
2268         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2269         rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2270         /*if Tx is OK, check whether Rx is OK*/
2271         if (!(reg_eac & BIT(30)) &&
2272             (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
2273             (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
2274                 result |= 0x02;
2275         else
2276                 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "Path B Rx IQK fail!!\n");
2277
2278         return result;
2279 }
2280
2281 static void _rtl92ee_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
2282                                                 bool b_iqk_ok, long result[][8],
2283                                                 u8 final_candidate,
2284                                                 bool btxonly)
2285 {
2286         u32 oldval_0, x, tx0_a, reg;
2287         long y, tx0_c;
2288
2289         if (final_candidate == 0xFF) {
2290                 return;
2291         } else if (b_iqk_ok) {
2292                 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2293                                           MASKDWORD) >> 22) & 0x3FF;
2294                 x = result[final_candidate][0];
2295                 if ((x & 0x00000200) != 0)
2296                         x = x | 0xFFFFFC00;
2297                 tx0_a = (x * oldval_0) >> 8;
2298                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
2299                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
2300                               ((x * oldval_0 >> 7) & 0x1));
2301                 y = result[final_candidate][1];
2302                 if ((y & 0x00000200) != 0)
2303                         y = y | 0xFFFFFC00;
2304                 tx0_c = (y * oldval_0) >> 8;
2305                 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
2306                               ((tx0_c & 0x3C0) >> 6));
2307                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
2308                               (tx0_c & 0x3F));
2309                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
2310                               ((y * oldval_0 >> 7) & 0x1));
2311
2312                 if (btxonly)
2313                         return;
2314
2315                 reg = result[final_candidate][2];
2316                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
2317
2318                 reg = result[final_candidate][3] & 0x3F;
2319                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
2320
2321                 reg = (result[final_candidate][3] >> 6) & 0xF;
2322                 rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg);
2323         }
2324 }
2325
2326 static void _rtl92ee_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
2327                                                 bool b_iqk_ok, long result[][8],
2328                                                 u8 final_candidate,
2329                                                 bool btxonly)
2330 {
2331         u32 oldval_1, x, tx1_a, reg;
2332         long y, tx1_c;
2333
2334         if (final_candidate == 0xFF) {
2335                 return;
2336         } else if (b_iqk_ok) {
2337                 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2338                                           MASKDWORD) >> 22) & 0x3FF;
2339                 x = result[final_candidate][4];
2340                 if ((x & 0x00000200) != 0)
2341                         x = x | 0xFFFFFC00;
2342                 tx1_a = (x * oldval_1) >> 8;
2343                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx1_a);
2344                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
2345                               ((x * oldval_1 >> 7) & 0x1));
2346                 y = result[final_candidate][5];
2347                 if ((y & 0x00000200) != 0)
2348                         y = y | 0xFFFFFC00;
2349                 tx1_c = (y * oldval_1) >> 8;
2350                 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
2351                               ((tx1_c & 0x3C0) >> 6));
2352                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
2353                               (tx1_c & 0x3F));
2354                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
2355                               ((y * oldval_1 >> 7) & 0x1));
2356
2357                 if (btxonly)
2358                         return;
2359
2360                 reg = result[final_candidate][6];
2361                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2362
2363                 reg = result[final_candidate][7] & 0x3F;
2364                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2365
2366                 reg = (result[final_candidate][7] >> 6) & 0xF;
2367                 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0xF0000000, reg);
2368         }
2369 }
2370
2371 static void _rtl92ee_phy_save_adda_registers(struct ieee80211_hw *hw,
2372                                              u32 *addareg, u32 *addabackup,
2373                                              u32 registernum)
2374 {
2375         u32 i;
2376
2377         for (i = 0; i < registernum; i++)
2378                 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
2379 }
2380
2381 static void _rtl92ee_phy_save_mac_registers(struct ieee80211_hw *hw,
2382                                             u32 *macreg, u32 *macbackup)
2383 {
2384         struct rtl_priv *rtlpriv = rtl_priv(hw);
2385         u32 i;
2386
2387         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2388                 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
2389
2390         macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
2391 }
2392
2393 static void _rtl92ee_phy_reload_adda_registers(struct ieee80211_hw *hw,
2394                                                u32 *addareg, u32 *addabackup,
2395                                                u32 regiesternum)
2396 {
2397         u32 i;
2398
2399         for (i = 0; i < regiesternum; i++)
2400                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
2401 }
2402
2403 static void _rtl92ee_phy_reload_mac_registers(struct ieee80211_hw *hw,
2404                                               u32 *macreg, u32 *macbackup)
2405 {
2406         struct rtl_priv *rtlpriv = rtl_priv(hw);
2407         u32 i;
2408
2409         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2410                 rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]);
2411         rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
2412 }
2413
2414 static void _rtl92ee_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
2415                                       bool is_patha_on, bool is2t)
2416 {
2417         u32 pathon;
2418         u32 i;
2419
2420         pathon = is_patha_on ? 0x0fc01616 : 0x0fc01616;
2421         if (!is2t) {
2422                 pathon = 0x0fc01616;
2423                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0fc01616);
2424         } else {
2425                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
2426         }
2427
2428         for (i = 1; i < IQK_ADDA_REG_NUM; i++)
2429                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
2430 }
2431
2432 static void _rtl92ee_phy_mac_setting_calibration(struct ieee80211_hw *hw,
2433                                                  u32 *macreg, u32 *macbackup)
2434 {
2435         rtl_set_bbreg(hw, 0x520, 0x00ff0000, 0xff);
2436 }
2437
2438 static void _rtl92ee_phy_path_a_standby(struct ieee80211_hw *hw)
2439 {
2440         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
2441         rtl_set_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK, 0x10000);
2442         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2443 }
2444
2445 static bool _rtl92ee_phy_simularity_compare(struct ieee80211_hw *hw,
2446                                             long result[][8], u8 c1, u8 c2)
2447 {
2448         u32 i, j, diff, simularity_bitmap, bound;
2449
2450         u8 final_candidate[2] = { 0xFF, 0xFF };
2451         bool bresult = true/*, is2t = true*/;
2452         s32 tmp1, tmp2;
2453
2454         bound = 8;
2455
2456         simularity_bitmap = 0;
2457
2458         for (i = 0; i < bound; i++) {
2459                 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2460                         if ((result[c1][i] & 0x00000200) != 0)
2461                                 tmp1 = result[c1][i] | 0xFFFFFC00;
2462                         else
2463                                 tmp1 = result[c1][i];
2464
2465                         if ((result[c2][i] & 0x00000200) != 0)
2466                                 tmp2 = result[c2][i] | 0xFFFFFC00;
2467                         else
2468                                 tmp2 = result[c2][i];
2469                 } else {
2470                         tmp1 = result[c1][i];
2471                         tmp2 = result[c2][i];
2472                 }
2473
2474                 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2475
2476                 if (diff > MAX_TOLERANCE) {
2477                         if ((i == 2 || i == 6) && !simularity_bitmap) {
2478                                 if (result[c1][i] + result[c1][i + 1] == 0)
2479                                         final_candidate[(i / 4)] = c2;
2480                                 else if (result[c2][i] + result[c2][i + 1] == 0)
2481                                         final_candidate[(i / 4)] = c1;
2482                                 else
2483                                         simularity_bitmap |= (1 << i);
2484                         } else {
2485                                 simularity_bitmap |= (1 << i);
2486                         }
2487                 }
2488         }
2489
2490         if (simularity_bitmap == 0) {
2491                 for (i = 0; i < (bound / 4); i++) {
2492                         if (final_candidate[i] != 0xFF) {
2493                                 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2494                                         result[3][j] =
2495                                                 result[final_candidate[i]][j];
2496                                 bresult = false;
2497                         }
2498                 }
2499                 return bresult;
2500         }
2501         if (!(simularity_bitmap & 0x03)) {/*path A TX OK*/
2502                 for (i = 0; i < 2; i++)
2503                         result[3][i] = result[c1][i];
2504         }
2505         if (!(simularity_bitmap & 0x0c)) {/*path A RX OK*/
2506                 for (i = 2; i < 4; i++)
2507                         result[3][i] = result[c1][i];
2508         }
2509         if (!(simularity_bitmap & 0x30)) {/*path B TX OK*/
2510                 for (i = 4; i < 6; i++)
2511                         result[3][i] = result[c1][i];
2512         }
2513         if (!(simularity_bitmap & 0xc0)) {/*path B RX OK*/
2514                 for (i = 6; i < 8; i++)
2515                         result[3][i] = result[c1][i];
2516         }
2517         return false;
2518 }
2519
2520 static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw,
2521                                       long result[][8], u8 t, bool is2t)
2522 {
2523         struct rtl_priv *rtlpriv = rtl_priv(hw);
2524         struct rtl_phy *rtlphy = &rtlpriv->phy;
2525         u32 i;
2526         u8 patha_ok, pathb_ok;
2527         u8 tmp_0xc50 = (u8)rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2528         u8 tmp_0xc58 = (u8)rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2529         u32 adda_reg[IQK_ADDA_REG_NUM] = {
2530                 0x85c, 0xe6c, 0xe70, 0xe74,
2531                 0xe78, 0xe7c, 0xe80, 0xe84,
2532                 0xe88, 0xe8c, 0xed0, 0xed4,
2533                 0xed8, 0xedc, 0xee0, 0xeec
2534         };
2535         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2536                 0x522, 0x550, 0x551, 0x040
2537         };
2538         u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2539                 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2540                 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2541                 0x870, 0x860,
2542                 0x864, 0x800
2543         };
2544         const u32 retrycount = 2;
2545
2546         if (t == 0) {
2547                 _rtl92ee_phy_save_adda_registers(hw, adda_reg,
2548                                                  rtlphy->adda_backup,
2549                                                  IQK_ADDA_REG_NUM);
2550                 _rtl92ee_phy_save_mac_registers(hw, iqk_mac_reg,
2551                                                 rtlphy->iqk_mac_backup);
2552                 _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2553                                                  rtlphy->iqk_bb_backup,
2554                                                  IQK_BB_REG_NUM);
2555         }
2556
2557         _rtl92ee_phy_path_adda_on(hw, adda_reg, true, is2t);
2558
2559         /*BB setting*/
2560         rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2561         rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
2562         rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
2563         rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208200);
2564
2565         rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(10), 0x01);
2566         rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(26), 0x01);
2567         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), 0x01);
2568         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), 0x01);
2569
2570         _rtl92ee_phy_mac_setting_calibration(hw, iqk_mac_reg,
2571                                              rtlphy->iqk_mac_backup);
2572         /* Page B init*/
2573         /* IQ calibration setting*/
2574         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2575         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2576         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2577
2578         for (i = 0 ; i < retrycount ; i++) {
2579                 patha_ok = _rtl92ee_phy_path_a_iqk(hw, is2t);
2580
2581                 if (patha_ok == 0x01) {
2582                         RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2583                                  "Path A Tx IQK Success!!\n");
2584                         result[t][0] = (rtl_get_bbreg(hw,
2585                                                       RTX_POWER_BEFORE_IQK_A,
2586                                                       MASKDWORD) & 0x3FF0000)
2587                                                       >> 16;
2588                         result[t][1] = (rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
2589                                                       MASKDWORD) & 0x3FF0000)
2590                                                       >> 16;
2591                         break;
2592                 }
2593                 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2594                          "Path A Tx IQK Fail!!, ret = 0x%x\n",
2595                          patha_ok);
2596         }
2597
2598         for (i = 0 ; i < retrycount ; i++) {
2599                 patha_ok = _rtl92ee_phy_path_a_rx_iqk(hw, is2t);
2600
2601                 if (patha_ok == 0x03) {
2602                         RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2603                                  "Path A Rx IQK Success!!\n");
2604                         result[t][2] = (rtl_get_bbreg(hw,
2605                                                       RRX_POWER_BEFORE_IQK_A_2,
2606                                                       MASKDWORD) & 0x3FF0000)
2607                                                       >> 16;
2608                         result[t][3] = (rtl_get_bbreg(hw,
2609                                                       RRX_POWER_AFTER_IQK_A_2,
2610                                                       MASKDWORD) & 0x3FF0000)
2611                                                       >> 16;
2612                         break;
2613                 }
2614                 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2615                          "Path A Rx IQK Fail!!, ret = 0x%x\n",
2616                           patha_ok);
2617         }
2618
2619         if (0x00 == patha_ok)
2620                 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2621                          "Path A IQK failed!!, ret = 0\n");
2622         if (is2t) {
2623                 _rtl92ee_phy_path_a_standby(hw);
2624                 /* Turn Path B ADDA on */
2625                 _rtl92ee_phy_path_adda_on(hw, adda_reg, false, is2t);
2626
2627                 /* IQ calibration setting */
2628                 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2629                 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2630                 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2631
2632                 for (i = 0 ; i < retrycount ; i++) {
2633                         pathb_ok = _rtl92ee_phy_path_b_iqk(hw);
2634                         if (pathb_ok == 0x01) {
2635                                 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2636                                          "Path B Tx IQK Success!!\n");
2637                                 result[t][4] = (rtl_get_bbreg(hw,
2638                                                         RTX_POWER_BEFORE_IQK_B,
2639                                                         MASKDWORD) & 0x3FF0000)
2640                                                         >> 16;
2641                                 result[t][5] = (rtl_get_bbreg(hw,
2642                                                         RTX_POWER_AFTER_IQK_B,
2643                                                         MASKDWORD) & 0x3FF0000)
2644                                                         >> 16;
2645                                 break;
2646                         }
2647                         RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2648                                  "Path B Tx IQK Fail!!, ret = 0x%x\n",
2649                                  pathb_ok);
2650                 }
2651
2652                 for (i = 0 ; i < retrycount ; i++) {
2653                         pathb_ok = _rtl92ee_phy_path_b_rx_iqk(hw, is2t);
2654                         if (pathb_ok == 0x03) {
2655                                 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2656                                          "Path B Rx IQK Success!!\n");
2657                                 result[t][6] = (rtl_get_bbreg(hw,
2658                                                        RRX_POWER_BEFORE_IQK_B_2,
2659                                                        MASKDWORD) & 0x3FF0000)
2660                                                        >> 16;
2661                                 result[t][7] = (rtl_get_bbreg(hw,
2662                                                        RRX_POWER_AFTER_IQK_B_2,
2663                                                        MASKDWORD) & 0x3FF0000)
2664                                                        >> 16;
2665                                 break;
2666                         }
2667                         RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2668                                  "Path B Rx IQK Fail!!, ret = 0x%x\n",
2669                                  pathb_ok);
2670                 }
2671
2672                 if (0x00 == pathb_ok)
2673                         RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2674                                  "Path B IQK failed!!, ret = 0\n");
2675         }
2676         /* Back to BB mode, load original value */
2677         RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2678                  "IQK:Back to BB mode, load original value!\n");
2679         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2680
2681         if (t != 0) {
2682                 /* Reload ADDA power saving parameters */
2683                 _rtl92ee_phy_reload_adda_registers(hw, adda_reg,
2684                                                    rtlphy->adda_backup,
2685                                                    IQK_ADDA_REG_NUM);
2686
2687                 /* Reload MAC parameters */
2688                 _rtl92ee_phy_reload_mac_registers(hw, iqk_mac_reg,
2689                                                   rtlphy->iqk_mac_backup);
2690
2691                 _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2692                                                    rtlphy->iqk_bb_backup,
2693                                                    IQK_BB_REG_NUM);
2694
2695                 /* Restore RX initial gain */
2696                 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2697                 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_0xc50);
2698                 if (is2t) {
2699                         rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2700                         rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_0xc58);
2701                 }
2702
2703                 /* load 0xe30 IQC default value */
2704                 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2705                 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2706         }
2707 }
2708
2709 static void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2710 {
2711         u8 tmpreg;
2712         u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2713         struct rtl_priv *rtlpriv = rtl_priv(hw);
2714
2715         tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2716
2717         if ((tmpreg & 0x70) != 0)
2718                 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2719         else
2720                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2721
2722         if ((tmpreg & 0x70) != 0) {
2723                 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2724
2725                 if (is2t)
2726                         rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2727                                                   MASK12BITS);
2728
2729                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2730                               (rf_a_mode & 0x8FFFF) | 0x10000);
2731
2732                 if (is2t)
2733                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2734                                       (rf_b_mode & 0x8FFFF) | 0x10000);
2735         }
2736         lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2737
2738         rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
2739
2740         mdelay(100);
2741
2742         if ((tmpreg & 0x70) != 0) {
2743                 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2744                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2745
2746                 if (is2t)
2747                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2748                                       rf_b_mode);
2749         } else {
2750                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2751         }
2752 }
2753
2754 static void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2755                                            bool bmain, bool is2t)
2756 {
2757         struct rtl_priv *rtlpriv = rtl_priv(hw);
2758         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2759         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2760
2761         RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD , "\n");
2762
2763         if (is_hal_stop(rtlhal)) {
2764                 u8 u1btmp;
2765
2766                 u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
2767                 rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
2768                 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
2769         }
2770         if (is2t) {
2771                 if (bmain)
2772                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2773                                       BIT(5) | BIT(6), 0x1);
2774                 else
2775                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2776                                       BIT(5) | BIT(6), 0x2);
2777         } else {
2778                 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
2779                 rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
2780
2781                 /* We use the RF definition of MAIN and AUX,
2782                  * left antenna and right antenna repectively.
2783                  * Default output at AUX.
2784                  */
2785                 if (bmain) {
2786                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2787                                       BIT(14) | BIT(13) | BIT(12), 0);
2788                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2789                                       BIT(5) | BIT(4) | BIT(3), 0);
2790                         if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2791                                 rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0);
2792                 } else {
2793                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2794                                       BIT(14) | BIT(13) | BIT(12), 1);
2795                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2796                                       BIT(5) | BIT(4) | BIT(3), 1);
2797                         if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2798                                 rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1);
2799                 }
2800         }
2801 }
2802
2803 #undef IQK_ADDA_REG_NUM
2804 #undef IQK_DELAY_TIME
2805
2806 static u8 rtl92ee_get_rightchnlplace_for_iqk(u8 chnl)
2807 {
2808         u8 channel_all[59] = {
2809                 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
2810                 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
2811                 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
2812                 114, 116, 118, 120, 122, 124, 126, 128, 130,
2813                 132, 134, 136, 138, 140, 149, 151, 153, 155,
2814                 157, 159, 161, 163, 165
2815         };
2816         u8 place = chnl;
2817
2818         if (chnl > 14) {
2819                 for (place = 14; place < sizeof(channel_all); place++) {
2820                         if (channel_all[place] == chnl)
2821                                 return place - 13;
2822                 }
2823         }
2824
2825         return 0;
2826 }
2827
2828 void rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2829 {
2830         struct rtl_priv *rtlpriv = rtl_priv(hw);
2831         struct rtl_phy *rtlphy = &rtlpriv->phy;
2832         long result[4][8];
2833         u8 i, final_candidate;
2834         bool b_patha_ok, b_pathb_ok;
2835         long reg_e94, reg_e9c, reg_ea4, reg_eac;
2836         long reg_eb4, reg_ebc, reg_ec4, reg_ecc;
2837         bool is12simular, is13simular, is23simular;
2838         u8 idx;
2839         u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2840                 ROFDM0_XARXIQIMBALANCE,
2841                 ROFDM0_XBRXIQIMBALANCE,
2842                 ROFDM0_ECCATHRESHOLD,
2843                 ROFDM0_AGCRSSITABLE,
2844                 ROFDM0_XATXIQIMBALANCE,
2845                 ROFDM0_XBTXIQIMBALANCE,
2846                 ROFDM0_XCTXAFE,
2847                 ROFDM0_XDTXAFE,
2848                 ROFDM0_RXIQEXTANTA
2849         };
2850
2851         if (b_recovery) {
2852                 _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2853                                                    rtlphy->iqk_bb_backup, 9);
2854                 return;
2855         }
2856
2857         for (i = 0; i < 8; i++) {
2858                 result[0][i] = 0;
2859                 result[1][i] = 0;
2860                 result[2][i] = 0;
2861
2862                 if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
2863                         result[3][i] = 0x100;
2864                 else
2865                         result[3][i] = 0;
2866         }
2867         final_candidate = 0xff;
2868         b_patha_ok = false;
2869         b_pathb_ok = false;
2870         is12simular = false;
2871         is23simular = false;
2872         is13simular = false;
2873         for (i = 0; i < 3; i++) {
2874                 _rtl92ee_phy_iq_calibrate(hw, result, i, true);
2875                 if (i == 1) {
2876                         is12simular = _rtl92ee_phy_simularity_compare(hw,
2877                                                                       result,
2878                                                                       0, 1);
2879                         if (is12simular) {
2880                                 final_candidate = 0;
2881                                 break;
2882                         }
2883                 }
2884
2885                 if (i == 2) {
2886                         is13simular = _rtl92ee_phy_simularity_compare(hw,
2887                                                                       result,
2888                                                                       0, 2);
2889                         if (is13simular) {
2890                                 final_candidate = 0;
2891                                 break;
2892                         }
2893                         is23simular = _rtl92ee_phy_simularity_compare(hw,
2894                                                                       result,
2895                                                                       1, 2);
2896                         if (is23simular)
2897                                 final_candidate = 1;
2898                         else
2899                                 final_candidate = 3;
2900                 }
2901         }
2902
2903         for (i = 0; i < 4; i++) {
2904                 reg_e94 = result[i][0];
2905                 reg_e9c = result[i][1];
2906                 reg_ea4 = result[i][2];
2907                 reg_eac = result[i][3];
2908                 reg_eb4 = result[i][4];
2909                 reg_ebc = result[i][5];
2910                 reg_ec4 = result[i][6];
2911                 reg_ecc = result[i][7];
2912         }
2913
2914         if (final_candidate != 0xff) {
2915                 reg_e94 = result[final_candidate][0];
2916                 rtlphy->reg_e94 = reg_e94;
2917                 reg_e9c = result[final_candidate][1];
2918                 rtlphy->reg_e9c = reg_e9c;
2919                 reg_ea4 = result[final_candidate][2];
2920                 reg_eac = result[final_candidate][3];
2921                 reg_eb4 = result[final_candidate][4];
2922                 rtlphy->reg_eb4 = reg_eb4;
2923                 reg_ebc = result[final_candidate][5];
2924                 rtlphy->reg_ebc = reg_ebc;
2925                 reg_ec4 = result[final_candidate][6];
2926                 reg_ecc = result[final_candidate][7];
2927                 b_patha_ok = true;
2928                 b_pathb_ok = true;
2929         } else {
2930                 rtlphy->reg_e94 = 0x100;
2931                 rtlphy->reg_eb4 = 0x100;
2932                 rtlphy->reg_e9c = 0x0;
2933                 rtlphy->reg_ebc = 0x0;
2934         }
2935
2936         if (reg_e94 != 0)
2937                 _rtl92ee_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2938                                                     final_candidate,
2939                                                     (reg_ea4 == 0));
2940
2941         _rtl92ee_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2942                                             final_candidate,
2943                                             (reg_ec4 == 0));
2944
2945         idx = rtl92ee_get_rightchnlplace_for_iqk(rtlphy->current_channel);
2946
2947         /* To Fix BSOD when final_candidate is 0xff */
2948         if (final_candidate < 4) {
2949                 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2950                         rtlphy->iqk_matrix[idx].value[0][i] =
2951                                 result[final_candidate][i];
2952
2953                 rtlphy->iqk_matrix[idx].iqk_done = true;
2954         }
2955         _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2956                                          rtlphy->iqk_bb_backup, 9);
2957 }
2958
2959 void rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw)
2960 {
2961         struct rtl_priv *rtlpriv = rtl_priv(hw);
2962         struct rtl_phy *rtlphy = &rtlpriv->phy;
2963         struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2964         u32 timeout = 2000, timecount = 0;
2965
2966         while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2967                 udelay(50);
2968                 timecount += 50;
2969         }
2970
2971         rtlphy->lck_inprogress = true;
2972         RTPRINT(rtlpriv, FINIT, INIT_IQK,
2973                 "LCK:Start!!! currentband %x delay %d ms\n",
2974                  rtlhal->current_bandtype, timecount);
2975
2976         _rtl92ee_phy_lc_calibrate(hw, false);
2977
2978         rtlphy->lck_inprogress = false;
2979 }
2980
2981 void rtl92ee_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
2982 {
2983 }
2984
2985 void rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2986 {
2987         _rtl92ee_phy_set_rfpath_switch(hw, bmain, false);
2988 }
2989
2990 bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2991 {
2992         struct rtl_priv *rtlpriv = rtl_priv(hw);
2993         struct rtl_phy *rtlphy = &rtlpriv->phy;
2994         bool postprocessing = false;
2995
2996         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2997                  "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2998                   iotype, rtlphy->set_io_inprogress);
2999         do {
3000                 switch (iotype) {
3001                 case IO_CMD_RESUME_DM_BY_SCAN:
3002                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3003                                  "[IO CMD] Resume DM after scan.\n");
3004                         postprocessing = true;
3005                         break;
3006                 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
3007                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3008                                  "[IO CMD] Pause DM before scan.\n");
3009                         postprocessing = true;
3010                         break;
3011                 default:
3012                         RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3013                                  "switch case not process\n");
3014                         break;
3015                 }
3016         } while (false);
3017         if (postprocessing && !rtlphy->set_io_inprogress) {
3018                 rtlphy->set_io_inprogress = true;
3019                 rtlphy->current_io_type = iotype;
3020         } else {
3021                 return false;
3022         }
3023         rtl92ee_phy_set_io(hw);
3024         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
3025         return true;
3026 }
3027
3028 static void rtl92ee_phy_set_io(struct ieee80211_hw *hw)
3029 {
3030         struct rtl_priv *rtlpriv = rtl_priv(hw);
3031         struct rtl_phy *rtlphy = &rtlpriv->phy;
3032         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
3033
3034         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3035                  "--->Cmd(%#x), set_io_inprogress(%d)\n",
3036                   rtlphy->current_io_type, rtlphy->set_io_inprogress);
3037         switch (rtlphy->current_io_type) {
3038         case IO_CMD_RESUME_DM_BY_SCAN:
3039                 rtl92ee_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
3040                 rtl92ee_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca);
3041                 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE , "no set txpower\n");
3042                 rtl92ee_phy_set_txpower_level(hw, rtlphy->current_channel);
3043                 break;
3044         case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
3045                 /* 8192eebt */
3046                 rtlphy->initgain_backup.xaagccore1 = dm_dig->cur_igvalue;
3047                 rtl92ee_dm_write_dig(hw, 0x17);
3048                 rtlphy->initgain_backup.cca = dm_dig->cur_cck_cca_thres;
3049                 rtl92ee_dm_write_cck_cca_thres(hw, 0x40);
3050                 break;
3051         default:
3052                 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3053                          "switch case not process\n");
3054                 break;
3055         }
3056         rtlphy->set_io_inprogress = false;
3057         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3058                  "(%#x)\n", rtlphy->current_io_type);
3059 }
3060
3061 static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw)
3062 {
3063         struct rtl_priv *rtlpriv = rtl_priv(hw);
3064
3065         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
3066         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3067         /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/
3068         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3069         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3070         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3071 }
3072
3073 static void _rtl92ee_phy_set_rf_sleep(struct ieee80211_hw *hw)
3074 {
3075         struct rtl_priv *rtlpriv = rtl_priv(hw);
3076
3077         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3078         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
3079
3080         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3081         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
3082 }
3083
3084 static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3085                                             enum rf_pwrstate rfpwr_state)
3086 {
3087         struct rtl_priv *rtlpriv = rtl_priv(hw);
3088         struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
3089         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3090         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3091         bool bresult = true;
3092         u8 i, queue_id;
3093         struct rtl8192_tx_ring *ring = NULL;
3094
3095         switch (rfpwr_state) {
3096         case ERFON:
3097                 if ((ppsc->rfpwr_state == ERFOFF) &&
3098                     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
3099                         bool rtstatus;
3100                         u32 initializecount = 0;
3101
3102                         do {
3103                                 initializecount++;
3104                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3105                                          "IPS Set eRf nic enable\n");
3106                                 rtstatus = rtl_ps_enable_nic(hw);
3107                         } while (!rtstatus && (initializecount < 10));
3108                         RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3109                 } else {
3110                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3111                                  "Set ERFON sleeping:%d ms\n",
3112                                   jiffies_to_msecs(jiffies -
3113                                                    ppsc->last_sleep_jiffies));
3114                         ppsc->last_awake_jiffies = jiffies;
3115                         rtl92ee_phy_set_rf_on(hw);
3116                 }
3117                 if (mac->link_state == MAC80211_LINKED)
3118                         rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
3119                 else
3120                         rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
3121                 break;
3122         case ERFOFF:
3123                 for (queue_id = 0, i = 0;
3124                      queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3125                         ring = &pcipriv->dev.tx_ring[queue_id];
3126                         if (queue_id == BEACON_QUEUE ||
3127                             skb_queue_len(&ring->queue) == 0) {
3128                                 queue_id++;
3129                                 continue;
3130                         } else {
3131                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3132                                          "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3133                                          (i + 1), queue_id,
3134                                          skb_queue_len(&ring->queue));
3135
3136                                 udelay(10);
3137                                 i++;
3138                         }
3139                         if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3140                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3141                                          "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3142                                           MAX_DOZE_WAITING_TIMES_9x,
3143                                           queue_id,
3144                                           skb_queue_len(&ring->queue));
3145                                 break;
3146                         }
3147                 }
3148
3149                 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
3150                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3151                                  "IPS Set eRf nic disable\n");
3152                         rtl_ps_disable_nic(hw);
3153                         RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3154                 } else {
3155                         if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
3156                                 rtlpriv->cfg->ops->led_control(hw,
3157                                                         LED_CTL_NO_LINK);
3158                         } else {
3159                                 rtlpriv->cfg->ops->led_control(hw,
3160                                                         LED_CTL_POWER_OFF);
3161                         }
3162                 }
3163                 break;
3164         case ERFSLEEP:
3165                 if (ppsc->rfpwr_state == ERFOFF)
3166                         break;
3167                 for (queue_id = 0, i = 0;
3168                      queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3169                         ring = &pcipriv->dev.tx_ring[queue_id];
3170                         if (skb_queue_len(&ring->queue) == 0) {
3171                                 queue_id++;
3172                                 continue;
3173                         } else {
3174                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3175                                          "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3176                                          (i + 1), queue_id,
3177                                          skb_queue_len(&ring->queue));
3178                                 udelay(10);
3179                                 i++;
3180                         }
3181                         if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3182                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3183                                          "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3184                                           MAX_DOZE_WAITING_TIMES_9x,
3185                                           queue_id,
3186                                           skb_queue_len(&ring->queue));
3187                                 break;
3188                         }
3189                 }
3190                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3191                          "Set ERFSLEEP awaked:%d ms\n",
3192                           jiffies_to_msecs(jiffies -
3193                                            ppsc->last_awake_jiffies));
3194                 ppsc->last_sleep_jiffies = jiffies;
3195                 _rtl92ee_phy_set_rf_sleep(hw);
3196                 break;
3197         default:
3198                 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3199                          "switch case not process\n");
3200                 bresult = false;
3201                 break;
3202         }
3203         if (bresult)
3204                 ppsc->rfpwr_state = rfpwr_state;
3205         return bresult;
3206 }
3207
3208 bool rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3209                                     enum rf_pwrstate rfpwr_state)
3210 {
3211         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3212
3213         bool bresult = false;
3214
3215         if (rfpwr_state == ppsc->rfpwr_state)
3216                 return bresult;
3217         bresult = _rtl92ee_phy_set_rf_power_state(hw, rfpwr_state);
3218         return bresult;
3219 }