]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[karo-tx-linux.git] / drivers / net / wireless / realtek / rtlwifi / rtl8723be / 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 "../rtl8723com/phy_common.h"
33 #include "rf.h"
34 #include "dm.h"
35 #include "../rtl8723com/dm_common.h"
36 #include "table.h"
37 #include "trx.h"
38
39 static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
40 static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
41 static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
42                                                      u8 configtype);
43 static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
44                                                        u8 configtype);
45 static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
46                                                 u8 channel, u8 *stage,
47                                                 u8 *step, u32 *delay);
48
49 static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw);
50 static void rtl8723be_phy_set_io(struct ieee80211_hw *hw);
51
52 u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
53                                u32 regaddr, u32 bitmask)
54 {
55         struct rtl_priv *rtlpriv = rtl_priv(hw);
56         u32 original_value, readback_value, bitshift;
57         unsigned long flags;
58
59         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
60                  "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
61                   regaddr, rfpath, bitmask);
62
63         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
64
65         original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
66         bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
67         readback_value = (original_value & bitmask) >> bitshift;
68
69         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
70
71         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
72                  "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
73                  regaddr, rfpath, bitmask, original_value);
74
75         return readback_value;
76 }
77
78 void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
79                               u32 regaddr, u32 bitmask, u32 data)
80 {
81         struct rtl_priv *rtlpriv = rtl_priv(hw);
82         u32 original_value, bitshift;
83         unsigned long flags;
84
85         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
86                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
87                   regaddr, bitmask, data, path);
88
89         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
90
91         if (bitmask != RFREG_OFFSET_MASK) {
92                         original_value = rtl8723_phy_rf_serial_read(hw, path,
93                                                                     regaddr);
94                         bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
95                         data = ((original_value & (~bitmask)) |
96                                 (data << bitshift));
97                 }
98
99         rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
100
101         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
102
103         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
104                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
105                   regaddr, bitmask, data, path);
106
107 }
108
109 bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
110 {
111         struct rtl_priv *rtlpriv = rtl_priv(hw);
112         bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
113
114         rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
115         return rtstatus;
116 }
117
118 bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
119 {
120         bool rtstatus = true;
121         struct rtl_priv *rtlpriv = rtl_priv(hw);
122         u16 regval;
123         u8 b_reg_hwparafile = 1;
124         u32 tmp;
125         u8 crystalcap = rtlpriv->efuse.crystalcap;
126         rtl8723_phy_init_bb_rf_reg_def(hw);
127         regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
128         rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
129                        regval | BIT(13) | BIT(0) | BIT(1));
130
131         rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
132         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
133                        FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
134                        FEN_BB_GLB_RSTN | FEN_BBRSTB);
135         tmp = rtl_read_dword(rtlpriv, 0x4c);
136         rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
137
138         rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
139
140         if (b_reg_hwparafile == 1)
141                 rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
142
143         crystalcap = crystalcap & 0x3F;
144         rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
145                       (crystalcap | crystalcap << 6));
146
147         return rtstatus;
148 }
149
150 bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
151 {
152         return rtl8723be_phy_rf6052_config(hw);
153 }
154
155 static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
156                                        const u32  condition)
157 {
158         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
159         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
160         u32 _board = rtlefuse->board_type; /*need efuse define*/
161         u32 _interface = rtlhal->interface;
162         u32 _platform = 0x08;/*SupportPlatform */
163         u32 cond = condition;
164
165         if (condition == 0xCDCDCDCD)
166                 return true;
167
168         cond = condition & 0xFF;
169         if ((_board & cond) == 0 && cond != 0x1F)
170                 return false;
171
172         cond = condition & 0xFF00;
173         cond = cond >> 8;
174         if ((_interface & cond) == 0 && cond != 0x07)
175                 return false;
176
177         cond = condition & 0xFF0000;
178         cond = cond >> 16;
179         if ((_platform & cond) == 0 && cond != 0x0F)
180                 return false;
181         return true;
182 }
183
184 static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
185                                      u32 data, enum radio_path rfpath,
186                                      u32 regaddr)
187 {
188         if (addr == 0xfe || addr == 0xffe) {
189                 /* In order not to disturb BT music
190                  *      when wifi init.(1ant NIC only)
191                  */
192                 mdelay(50);
193         } else {
194                 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
195                 udelay(1);
196         }
197 }
198 static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
199                                          u32 addr, u32 data)
200 {
201         u32 content = 0x1000; /*RF Content: radio_a_txt*/
202         u32 maskforphyset = (u32)(content & 0xE000);
203
204         _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
205                                  addr | maskforphyset);
206
207 }
208
209 static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
210 {
211         struct rtl_priv *rtlpriv = rtl_priv(hw);
212         struct rtl_phy *rtlphy = &rtlpriv->phy;
213
214         u8 band, path, txnum, section;
215
216         for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
217                 for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
218                         for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
219                                 for (section = 0;
220                                      section < TX_PWR_BY_RATE_NUM_SECTION;
221                                      ++section)
222                                         rtlphy->tx_power_by_rate_offset
223                                           [band][path][txnum][section] = 0;
224 }
225
226 static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
227                                      u32 addr, u32 data)
228 {
229         if (addr == 0xfe) {
230                 mdelay(50);
231         } else if (addr == 0xfd) {
232                 mdelay(5);
233         } else if (addr == 0xfc) {
234                 mdelay(1);
235         } else if (addr == 0xfb) {
236                 udelay(50);
237         } else if (addr == 0xfa) {
238                 udelay(5);
239         } else if (addr == 0xf9) {
240                 udelay(1);
241         } else {
242                 rtl_set_bbreg(hw, addr, MASKDWORD, data);
243                 udelay(1);
244         }
245 }
246
247 static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
248                                                     u8 band,
249                                                     u8 path, u8 rate_section,
250                                                     u8 txnum, u8 value)
251 {
252         struct rtl_priv *rtlpriv = rtl_priv(hw);
253         struct rtl_phy *rtlphy = &rtlpriv->phy;
254
255         if (path > RF90_PATH_D) {
256                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
257                          "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
258                           path);
259                 return;
260         }
261
262         if (band == BAND_ON_2_4G) {
263                 switch (rate_section) {
264                 case CCK:
265                         rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
266                         break;
267                 case OFDM:
268                         rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
269                         break;
270                 case HT_MCS0_MCS7:
271                         rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
272                         break;
273                 case HT_MCS8_MCS15:
274                         rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
275                         break;
276                 default:
277                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
278                                  "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
279                                  rate_section, path, txnum);
280                         break;
281                 };
282         } else {
283                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
284                          "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
285                          band);
286         }
287
288 }
289
290 static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
291                                                   u8 band, u8 path, u8 txnum,
292                                                   u8 rate_section)
293 {
294         struct rtl_priv *rtlpriv = rtl_priv(hw);
295         struct rtl_phy *rtlphy = &rtlpriv->phy;
296         u8 value = 0;
297         if (path > RF90_PATH_D) {
298                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
299                          "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
300                           path);
301                 return 0;
302         }
303
304         if (band == BAND_ON_2_4G) {
305                 switch (rate_section) {
306                 case CCK:
307                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
308                         break;
309                 case OFDM:
310                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
311                         break;
312                 case HT_MCS0_MCS7:
313                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
314                         break;
315                 case HT_MCS8_MCS15:
316                         value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
317                         break;
318                 default:
319                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
320                                  "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
321                                  rate_section, path, txnum);
322                         break;
323                 };
324         } else {
325                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
326                          "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
327                          band);
328         }
329
330         return value;
331 }
332
333 static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
334 {
335         struct rtl_priv *rtlpriv = rtl_priv(hw);
336         struct rtl_phy *rtlphy = &rtlpriv->phy;
337         u16 rawvalue = 0;
338         u8 base = 0, path = 0;
339
340         for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
341                 if (path == RF90_PATH_A) {
342                         rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
343                                 [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
344                         base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
345                         _rtl8723be_phy_set_txpower_by_rate_base(hw,
346                                 BAND_ON_2_4G, path, CCK, RF_1TX, base);
347                 } else if (path == RF90_PATH_B) {
348                         rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
349                                 [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
350                         base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
351                         _rtl8723be_phy_set_txpower_by_rate_base(hw,
352                                                                 BAND_ON_2_4G,
353                                                                 path, CCK,
354                                                                 RF_1TX, base);
355                 }
356                 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
357                                 [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
358                 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
359                 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
360                                                         path, OFDM, RF_1TX,
361                                                         base);
362
363                 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
364                                 [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
365                 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
366                 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
367                                                         path, HT_MCS0_MCS7,
368                                                         RF_1TX, base);
369
370                 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
371                                 [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
372                 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
373                 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
374                                                         path, HT_MCS8_MCS15,
375                                                         RF_2TX, base);
376         }
377 }
378
379 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
380                                                 u8 end, u8 base_val)
381 {
382         char i = 0;
383         u8 temp_value = 0;
384         u32 temp_data = 0;
385
386         for (i = 3; i >= 0; --i) {
387                 if (i >= start && i <= end) {
388                         /* Get the exact value */
389                         temp_value = (u8)(*data >> (i * 8)) & 0xF;
390                         temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10;
391
392                         /* Change the value to a relative value */
393                         temp_value = (temp_value > base_val) ?
394                                      temp_value - base_val :
395                                      base_val - temp_value;
396                 } else {
397                         temp_value = (u8)(*data >> (i * 8)) & 0xFF;
398                 }
399                 temp_data <<= 8;
400                 temp_data |= temp_value;
401         }
402         *data = temp_data;
403 }
404
405 static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value(
406                                                         struct ieee80211_hw *hw)
407 {
408         struct rtl_priv *rtlpriv = rtl_priv(hw);
409         struct rtl_phy *rtlphy = &rtlpriv->phy;
410         u8 base = 0, rfpath = RF90_PATH_A;
411
412         base = _rtl8723be_phy_get_txpower_by_rate_base(hw,
413                         BAND_ON_2_4G, rfpath, RF_1TX, CCK);
414         _phy_convert_txpower_dbm_to_relative_value(
415             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2],
416             1, 1, base);
417         _phy_convert_txpower_dbm_to_relative_value(
418             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3],
419             1, 3, base);
420
421         base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath,
422                                                        RF_1TX, OFDM);
423         _phy_convert_txpower_dbm_to_relative_value(
424             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0],
425             0, 3, base);
426         _phy_convert_txpower_dbm_to_relative_value(
427             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1],
428             0, 3, base);
429
430         base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
431                                                 rfpath, RF_1TX, HT_MCS0_MCS7);
432         _phy_convert_txpower_dbm_to_relative_value(
433             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4],
434             0, 3, base);
435         _phy_convert_txpower_dbm_to_relative_value(
436             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5],
437             0, 3, base);
438
439         base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
440                                                        rfpath, RF_2TX,
441                                                        HT_MCS8_MCS15);
442         _phy_convert_txpower_dbm_to_relative_value(
443             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6],
444             0, 3, base);
445
446         _phy_convert_txpower_dbm_to_relative_value(
447             &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7],
448             0, 3, base);
449
450         RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
451             "<===_rtl8723be_phy_convert_txpower_dbm_to_relative_value()\n");
452 }
453
454 static void phy_txpower_by_rate_config(struct ieee80211_hw *hw)
455 {
456         _rtl8723be_phy_store_txpower_by_rate_base(hw);
457         _rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw);
458 }
459
460 static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
461 {
462         struct rtl_priv *rtlpriv = rtl_priv(hw);
463         struct rtl_phy *rtlphy = &rtlpriv->phy;
464         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
465         bool rtstatus;
466
467         rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
468                                                 BASEBAND_CONFIG_PHY_REG);
469         if (!rtstatus) {
470                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
471                 return false;
472         }
473         _rtl8723be_phy_init_tx_power_by_rate(hw);
474         if (!rtlefuse->autoload_failflag) {
475                 rtlphy->pwrgroup_cnt = 0;
476                 rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
477                                                 BASEBAND_CONFIG_PHY_REG);
478         }
479         phy_txpower_by_rate_config(hw);
480         if (!rtstatus) {
481                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
482                 return false;
483         }
484         rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
485                                                 BASEBAND_CONFIG_AGC_TAB);
486         if (!rtstatus) {
487                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
488                 return false;
489         }
490         rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
491                                                       RFPGA0_XA_HSSIPARAMETER2,
492                                                       0x200));
493         return true;
494 }
495
496 static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
497 {
498         struct rtl_priv *rtlpriv = rtl_priv(hw);
499         u32 i;
500         u32 arraylength;
501         u32 *ptrarray;
502
503         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
504         arraylength = RTL8723BEMAC_1T_ARRAYLEN;
505         ptrarray = RTL8723BEMAC_1T_ARRAY;
506         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
507                  "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
508         for (i = 0; i < arraylength; i = i + 2)
509                 rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
510         return true;
511 }
512
513 static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
514                                                      u8 configtype)
515 {
516         #define READ_NEXT_PAIR(v1, v2, i) \
517                 do { \
518                         i += 2; \
519                         v1 = array_table[i];\
520                         v2 = array_table[i+1]; \
521                 } while (0)
522
523         int i;
524         u32 *array_table;
525         u16 arraylen;
526         struct rtl_priv *rtlpriv = rtl_priv(hw);
527         u32 v1 = 0, v2 = 0;
528
529         if (configtype == BASEBAND_CONFIG_PHY_REG) {
530                 arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
531                 array_table = RTL8723BEPHY_REG_1TARRAY;
532
533                 for (i = 0; i < arraylen; i = i + 2) {
534                         v1 = array_table[i];
535                         v2 = array_table[i+1];
536                         if (v1 < 0xcdcdcdcd) {
537                                 _rtl8723be_config_bb_reg(hw, v1, v2);
538                         } else {/*This line is the start line of branch.*/
539                                 /* to protect READ_NEXT_PAIR not overrun */
540                                 if (i >= arraylen - 2)
541                                         break;
542
543                                 if (!_rtl8723be_check_condition(hw,
544                                                 array_table[i])) {
545                                         /*Discard the following
546                                          *(offset, data) pairs
547                                          */
548                                         READ_NEXT_PAIR(v1, v2, i);
549                                         while (v2 != 0xDEAD &&
550                                                v2 != 0xCDEF &&
551                                                v2 != 0xCDCD &&
552                                                i < arraylen - 2) {
553                                                 READ_NEXT_PAIR(v1, v2, i);
554                                         }
555                                         i -= 2; /* prevent from for-loop += 2*/
556                                 /*Configure matched pairs and
557                                  *skip to end of if-else.
558                                  */
559                                 } else {
560                                         READ_NEXT_PAIR(v1, v2, i);
561                                         while (v2 != 0xDEAD &&
562                                                v2 != 0xCDEF &&
563                                                v2 != 0xCDCD &&
564                                                i < arraylen - 2) {
565                                                 _rtl8723be_config_bb_reg(hw,
566                                                                     v1, v2);
567                                                 READ_NEXT_PAIR(v1, v2, i);
568                                         }
569
570                                         while (v2 != 0xDEAD && i < arraylen - 2)
571                                                 READ_NEXT_PAIR(v1, v2, i);
572                                 }
573                         }
574                 }
575         } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
576                 arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
577                 array_table = RTL8723BEAGCTAB_1TARRAY;
578
579                 for (i = 0; i < arraylen; i = i + 2) {
580                         v1 = array_table[i];
581                         v2 = array_table[i+1];
582                         if (v1 < 0xCDCDCDCD) {
583                                 rtl_set_bbreg(hw, array_table[i],
584                                               MASKDWORD,
585                                               array_table[i + 1]);
586                                 udelay(1);
587                                 continue;
588                         } else {/*This line is the start line of branch.*/
589                                 /* to protect READ_NEXT_PAIR not overrun */
590                                 if (i >= arraylen - 2)
591                                         break;
592
593                                 if (!_rtl8723be_check_condition(hw,
594                                         array_table[i])) {
595                                         /*Discard the following
596                                          *(offset, data) pairs
597                                          */
598                                         READ_NEXT_PAIR(v1, v2, i);
599                                         while (v2 != 0xDEAD &&
600                                                v2 != 0xCDEF &&
601                                                v2 != 0xCDCD &&
602                                                i < arraylen - 2) {
603                                                 READ_NEXT_PAIR(v1, v2, i);
604                                         }
605                                         i -= 2; /* prevent from for-loop += 2*/
606                                 /*Configure matched pairs and
607                                  *skip to end of if-else.
608                                  */
609                                 } else {
610                                         READ_NEXT_PAIR(v1, v2, i);
611                                         while (v2 != 0xDEAD &&
612                                                v2 != 0xCDEF &&
613                                                v2 != 0xCDCD &&
614                                                i < arraylen - 2) {
615                                                 rtl_set_bbreg(hw, array_table[i],
616                                                               MASKDWORD,
617                                                               array_table[i + 1]);
618                                                 udelay(1);
619                                                 READ_NEXT_PAIR(v1, v2, i);
620                                         }
621
622                                         while (v2 != 0xDEAD && i < arraylen - 2)
623                                                 READ_NEXT_PAIR(v1, v2, i);
624                                 }
625                         }
626                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
627                                  "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
628                                  array_table[i], array_table[i + 1]);
629                 }
630         }
631         return true;
632 }
633
634 static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
635 {
636         u8 index = 0;
637
638         switch (regaddr) {
639         case RTXAGC_A_RATE18_06:
640                 index = 0;
641         break;
642         case RTXAGC_A_RATE54_24:
643                 index = 1;
644         break;
645         case RTXAGC_A_CCK1_MCS32:
646                 index = 2;
647         break;
648         case RTXAGC_B_CCK11_A_CCK2_11:
649                 index = 3;
650         break;
651         case RTXAGC_A_MCS03_MCS00:
652                 index = 4;
653         break;
654         case RTXAGC_A_MCS07_MCS04:
655                 index = 5;
656         break;
657         case RTXAGC_A_MCS11_MCS08:
658                 index = 6;
659         break;
660         case RTXAGC_A_MCS15_MCS12:
661                 index = 7;
662         break;
663         case RTXAGC_B_RATE18_06:
664                 index = 0;
665         break;
666         case RTXAGC_B_RATE54_24:
667                 index = 1;
668         break;
669         case RTXAGC_B_CCK1_55_MCS32:
670                 index = 2;
671         break;
672         case RTXAGC_B_MCS03_MCS00:
673                 index = 4;
674         break;
675         case RTXAGC_B_MCS07_MCS04:
676                 index = 5;
677         break;
678         case RTXAGC_B_MCS11_MCS08:
679                 index = 6;
680         break;
681         case RTXAGC_B_MCS15_MCS12:
682                 index = 7;
683         break;
684         default:
685                 regaddr &= 0xFFF;
686                 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
687                         index = (u8)((regaddr - 0xC20) / 4);
688                 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
689                         index = (u8)((regaddr - 0xE20) / 4);
690                 break;
691         };
692         return index;
693 }
694
695 static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
696                                               u32 band, u32 rfpath,
697                                               u32 txnum, u32 regaddr,
698                                               u32 bitmask, u32 data)
699 {
700         struct rtl_priv *rtlpriv = rtl_priv(hw);
701         struct rtl_phy *rtlphy = &rtlpriv->phy;
702         u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
703
704         if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
705                 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
706                 return;
707         }
708         if (rfpath > MAX_RF_PATH - 1) {
709                 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
710                          "Invalid RfPath %d\n", rfpath);
711                 return;
712         }
713         if (txnum > MAX_RF_PATH - 1) {
714                 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
715                 return;
716         }
717
718         rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
719                                                                         data;
720
721 }
722
723 static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
724                                                        u8 configtype)
725 {
726         struct rtl_priv *rtlpriv = rtl_priv(hw);
727         int i;
728         u32 *phy_regarray_table_pg;
729         u16 phy_regarray_pg_len;
730         u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
731
732         phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
733         phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
734
735         if (configtype == BASEBAND_CONFIG_PHY_REG) {
736                 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
737                         v1 = phy_regarray_table_pg[i];
738                         v2 = phy_regarray_table_pg[i+1];
739                         v3 = phy_regarray_table_pg[i+2];
740                         v4 = phy_regarray_table_pg[i+3];
741                         v5 = phy_regarray_table_pg[i+4];
742                         v6 = phy_regarray_table_pg[i+5];
743
744                         if (v1 < 0xcdcdcdcd) {
745                                 if (phy_regarray_table_pg[i] == 0xfe ||
746                                     phy_regarray_table_pg[i] == 0xffe)
747                                         mdelay(50);
748                                 else
749                                         _rtl8723be_store_tx_power_by_rate(hw,
750                                                         v1, v2, v3, v4, v5, v6);
751                                 continue;
752                         }
753                 }
754         } else {
755                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
756                          "configtype != BaseBand_Config_PHY_REG\n");
757         }
758         return true;
759 }
760
761 bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
762                                              enum radio_path rfpath)
763 {
764         #define READ_NEXT_RF_PAIR(v1, v2, i) \
765                 do { \
766                         i += 2; \
767                         v1 = radioa_array_table[i]; \
768                         v2 = radioa_array_table[i+1]; \
769                 } while (0)
770
771         int i;
772         bool rtstatus = true;
773         u32 *radioa_array_table;
774         u16 radioa_arraylen;
775         struct rtl_priv *rtlpriv = rtl_priv(hw);
776         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
777         u32 v1 = 0, v2 = 0;
778
779         radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
780         radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
781         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
782                  "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
783         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
784         rtstatus = true;
785         switch (rfpath) {
786         case RF90_PATH_A:
787                 for (i = 0; i < radioa_arraylen; i = i + 2) {
788                         v1 = radioa_array_table[i];
789                         v2 = radioa_array_table[i+1];
790                         if (v1 < 0xcdcdcdcd) {
791                                 _rtl8723be_config_rf_radio_a(hw, v1, v2);
792                         } else {/*This line is the start line of branch.*/
793                                 /* to protect READ_NEXT_PAIR not overrun */
794                                 if (i >= radioa_arraylen - 2)
795                                         break;
796
797                                 if (!_rtl8723be_check_condition(hw,
798                                                 radioa_array_table[i])) {
799                                         /*Discard the following
800                                          *(offset, data) pairs
801                                          */
802                                         READ_NEXT_RF_PAIR(v1, v2, i);
803                                         while (v2 != 0xDEAD &&
804                                                v2 != 0xCDEF &&
805                                                v2 != 0xCDCD &&
806                                                i < radioa_arraylen - 2) {
807                                                 READ_NEXT_RF_PAIR(v1, v2, i);
808                                         }
809                                         i -= 2; /* prevent from for-loop += 2*/
810                                 } else {
811                                         /*Configure matched pairs
812                                          *and skip to end of if-else.
813                                          */
814                                         READ_NEXT_RF_PAIR(v1, v2, i);
815                                         while (v2 != 0xDEAD &&
816                                                v2 != 0xCDEF &&
817                                                v2 != 0xCDCD &&
818                                                i < radioa_arraylen - 2) {
819                                                 _rtl8723be_config_rf_radio_a(hw,
820                                                                         v1, v2);
821                                                 READ_NEXT_RF_PAIR(v1, v2, i);
822                                         }
823
824                                         while (v2 != 0xDEAD &&
825                                                i < radioa_arraylen - 2) {
826                                                 READ_NEXT_RF_PAIR(v1, v2, i);
827                                         }
828                                 }
829                         }
830                 }
831
832                 if (rtlhal->oem_id == RT_CID_819X_HP)
833                         _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
834                 break;
835         case RF90_PATH_B:
836         case RF90_PATH_C:
837                 break;
838         case RF90_PATH_D:
839                 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
840                          "switch case not process\n");
841                 break;
842         }
843         return true;
844 }
845
846 void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
847 {
848         struct rtl_priv *rtlpriv = rtl_priv(hw);
849         struct rtl_phy *rtlphy = &rtlpriv->phy;
850
851         rtlphy->default_initialgain[0] =
852             (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
853         rtlphy->default_initialgain[1] =
854             (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
855         rtlphy->default_initialgain[2] =
856             (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
857         rtlphy->default_initialgain[3] =
858             (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
859
860         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
861                  "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
862                  rtlphy->default_initialgain[0],
863                  rtlphy->default_initialgain[1],
864                  rtlphy->default_initialgain[2],
865                  rtlphy->default_initialgain[3]);
866
867         rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
868                                                MASKBYTE0);
869         rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
870                                               MASKDWORD);
871
872         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
873                  "Default framesync (0x%x) = 0x%x\n",
874                   ROFDM0_RXDETECTOR3, rtlphy->framesync);
875 }
876
877 static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
878                                                           u8 rate)
879 {
880         u8 rate_section = 0;
881
882         switch (rate) {
883         case DESC92C_RATE1M:
884                 rate_section = 2;
885                 break;
886
887         case DESC92C_RATE2M:
888         case DESC92C_RATE5_5M:
889                 if (path == RF90_PATH_A)
890                         rate_section = 3;
891                 else if (path == RF90_PATH_B)
892                         rate_section = 2;
893                 break;
894
895         case DESC92C_RATE11M:
896                 rate_section = 3;
897                 break;
898
899         case DESC92C_RATE6M:
900         case DESC92C_RATE9M:
901         case DESC92C_RATE12M:
902         case DESC92C_RATE18M:
903                 rate_section = 0;
904                 break;
905
906         case DESC92C_RATE24M:
907         case DESC92C_RATE36M:
908         case DESC92C_RATE48M:
909         case DESC92C_RATE54M:
910                 rate_section = 1;
911                 break;
912
913         case DESC92C_RATEMCS0:
914         case DESC92C_RATEMCS1:
915         case DESC92C_RATEMCS2:
916         case DESC92C_RATEMCS3:
917                 rate_section = 4;
918                 break;
919
920         case DESC92C_RATEMCS4:
921         case DESC92C_RATEMCS5:
922         case DESC92C_RATEMCS6:
923         case DESC92C_RATEMCS7:
924                 rate_section = 5;
925                 break;
926
927         case DESC92C_RATEMCS8:
928         case DESC92C_RATEMCS9:
929         case DESC92C_RATEMCS10:
930         case DESC92C_RATEMCS11:
931                 rate_section = 6;
932                 break;
933
934         case DESC92C_RATEMCS12:
935         case DESC92C_RATEMCS13:
936         case DESC92C_RATEMCS14:
937         case DESC92C_RATEMCS15:
938                 rate_section = 7;
939                 break;
940
941         default:
942                 RT_ASSERT(true, "Rate_Section is Illegal\n");
943                 break;
944         }
945
946         return rate_section;
947 }
948
949 static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
950                                          enum band_type band,
951                                          enum radio_path rfpath, u8 rate)
952 {
953         struct rtl_priv *rtlpriv = rtl_priv(hw);
954         struct rtl_phy *rtlphy = &rtlpriv->phy;
955         u8 shift = 0, rate_section, tx_num;
956         char tx_pwr_diff = 0;
957
958         rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
959                                                                        rate);
960         tx_num = RF_TX_NUM_NONIMPLEMENT;
961
962         if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
963                 if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
964                         tx_num = RF_2TX;
965                 else
966                         tx_num = RF_1TX;
967         }
968
969         switch (rate) {
970         case DESC92C_RATE6M:
971         case DESC92C_RATE24M:
972         case DESC92C_RATEMCS0:
973         case DESC92C_RATEMCS4:
974         case DESC92C_RATEMCS8:
975         case DESC92C_RATEMCS12:
976                 shift = 0;
977                 break;
978         case DESC92C_RATE1M:
979         case DESC92C_RATE2M:
980         case DESC92C_RATE9M:
981         case DESC92C_RATE36M:
982         case DESC92C_RATEMCS1:
983         case DESC92C_RATEMCS5:
984         case DESC92C_RATEMCS9:
985         case DESC92C_RATEMCS13:
986                 shift = 8;
987                 break;
988         case DESC92C_RATE5_5M:
989         case DESC92C_RATE12M:
990         case DESC92C_RATE48M:
991         case DESC92C_RATEMCS2:
992         case DESC92C_RATEMCS6:
993         case DESC92C_RATEMCS10:
994         case DESC92C_RATEMCS14:
995                 shift = 16;
996                 break;
997         case DESC92C_RATE11M:
998         case DESC92C_RATE18M:
999         case DESC92C_RATE54M:
1000         case DESC92C_RATEMCS3:
1001         case DESC92C_RATEMCS7:
1002         case DESC92C_RATEMCS11:
1003         case DESC92C_RATEMCS15:
1004                 shift = 24;
1005                 break;
1006         default:
1007                 RT_ASSERT(true, "Rate_Section is Illegal\n");
1008                 break;
1009         }
1010         tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
1011                                           [rate_section] >> shift) & 0xff;
1012
1013         return  tx_pwr_diff;
1014 }
1015
1016 static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
1017                                        u8 rate, u8 bandwidth, u8 channel)
1018 {
1019         struct rtl_priv *rtlpriv = rtl_priv(hw);
1020         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1021         u8 index = (channel - 1);
1022         u8 txpower;
1023         u8 power_diff_byrate = 0;
1024
1025         if (channel > 14 || channel < 1) {
1026                 index = 0;
1027                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1028                          "Illegal channel!\n");
1029         }
1030         if (RX_HAL_IS_CCK_RATE(rate))
1031                 txpower = rtlefuse->txpwrlevel_cck[path][index];
1032         else if (DESC92C_RATE6M <= rate)
1033                 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1034         else
1035                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1036                          "invalid rate\n");
1037
1038         if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1039             !RX_HAL_IS_CCK_RATE(rate))
1040                 txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1041
1042         if (bandwidth == HT_CHANNEL_WIDTH_20) {
1043                 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1044                         txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1045                 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1046                         txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1047         } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1048                 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1049                         txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1050                 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1051                         txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1052         }
1053
1054         if (rtlefuse->eeprom_regulatory != 2)
1055                 power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1056                                                                    BAND_ON_2_4G,
1057                                                                    path, rate);
1058
1059         txpower += power_diff_byrate;
1060
1061         if (txpower > MAX_POWER_INDEX)
1062                 txpower = MAX_POWER_INDEX;
1063
1064         return txpower;
1065 }
1066
1067 static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1068                                              u8 power_index, u8 path, u8 rate)
1069 {
1070         struct rtl_priv *rtlpriv = rtl_priv(hw);
1071         if (path == RF90_PATH_A) {
1072                 switch (rate) {
1073                 case DESC92C_RATE1M:
1074                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1075                                                MASKBYTE1, power_index);
1076                         break;
1077                 case DESC92C_RATE2M:
1078                         rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1079                                                MASKBYTE1, power_index);
1080                         break;
1081                 case DESC92C_RATE5_5M:
1082                         rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1083                                                MASKBYTE2, power_index);
1084                         break;
1085                 case DESC92C_RATE11M:
1086                         rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1087                                                MASKBYTE3, power_index);
1088                         break;
1089
1090                 case DESC92C_RATE6M:
1091                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1092                                                MASKBYTE0, power_index);
1093                         break;
1094                 case DESC92C_RATE9M:
1095                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1096                                                MASKBYTE1, power_index);
1097                         break;
1098                 case DESC92C_RATE12M:
1099                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1100                                                MASKBYTE2, power_index);
1101                         break;
1102                 case DESC92C_RATE18M:
1103                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1104                                                MASKBYTE3, power_index);
1105                         break;
1106
1107                 case DESC92C_RATE24M:
1108                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1109                                                MASKBYTE0, power_index);
1110                         break;
1111                 case DESC92C_RATE36M:
1112                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1113                                                MASKBYTE1, power_index);
1114                         break;
1115                 case DESC92C_RATE48M:
1116                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1117                                                MASKBYTE2, power_index);
1118                         break;
1119                 case DESC92C_RATE54M:
1120                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1121                                                MASKBYTE3, power_index);
1122                         break;
1123
1124                 case DESC92C_RATEMCS0:
1125                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1126                                                MASKBYTE0, power_index);
1127                         break;
1128                 case DESC92C_RATEMCS1:
1129                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1130                                                MASKBYTE1, power_index);
1131                         break;
1132                 case DESC92C_RATEMCS2:
1133                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1134                                                MASKBYTE2, power_index);
1135                         break;
1136                 case DESC92C_RATEMCS3:
1137                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1138                                                MASKBYTE3, power_index);
1139                         break;
1140
1141                 case DESC92C_RATEMCS4:
1142                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1143                                                MASKBYTE0, power_index);
1144                         break;
1145                 case DESC92C_RATEMCS5:
1146                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1147                                                MASKBYTE1, power_index);
1148                         break;
1149                 case DESC92C_RATEMCS6:
1150                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1151                                                MASKBYTE2, power_index);
1152                         break;
1153                 case DESC92C_RATEMCS7:
1154                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1155                                                MASKBYTE3, power_index);
1156                         break;
1157
1158                 case DESC92C_RATEMCS8:
1159                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1160                                                MASKBYTE0, power_index);
1161                         break;
1162                 case DESC92C_RATEMCS9:
1163                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1164                                                MASKBYTE1, power_index);
1165                         break;
1166                 case DESC92C_RATEMCS10:
1167                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1168                                                MASKBYTE2, power_index);
1169                         break;
1170                 case DESC92C_RATEMCS11:
1171                         rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1172                                                MASKBYTE3, power_index);
1173                         break;
1174
1175                 default:
1176                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n");
1177                         break;
1178                 }
1179         } else {
1180                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1181         }
1182 }
1183
1184 void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1185 {
1186         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1187         u8 cck_rates[]  = {DESC92C_RATE1M, DESC92C_RATE2M,
1188                            DESC92C_RATE5_5M, DESC92C_RATE11M};
1189         u8 ofdm_rates[]  = {DESC92C_RATE6M, DESC92C_RATE9M,
1190                             DESC92C_RATE12M, DESC92C_RATE18M,
1191                             DESC92C_RATE24M, DESC92C_RATE36M,
1192                             DESC92C_RATE48M, DESC92C_RATE54M};
1193         u8 ht_rates_1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1194                              DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1195                              DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1196                              DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1197         u8 i, size;
1198         u8 power_index;
1199
1200         if (!rtlefuse->txpwr_fromeprom)
1201                 return;
1202
1203         size = sizeof(cck_rates) / sizeof(u8);
1204         for (i = 0; i < size; i++) {
1205                 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1206                                         cck_rates[i],
1207                                         rtl_priv(hw)->phy.current_chan_bw,
1208                                         channel);
1209                 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1210                                                  cck_rates[i]);
1211         }
1212         size = sizeof(ofdm_rates) / sizeof(u8);
1213         for (i = 0; i < size; i++) {
1214                 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1215                                         ofdm_rates[i],
1216                                         rtl_priv(hw)->phy.current_chan_bw,
1217                                         channel);
1218                 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1219                                                  ofdm_rates[i]);
1220         }
1221         size = sizeof(ht_rates_1t) / sizeof(u8);
1222         for (i = 0; i < size; i++) {
1223                 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1224                                         ht_rates_1t[i],
1225                                         rtl_priv(hw)->phy.current_chan_bw,
1226                                         channel);
1227                 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1228                                                  ht_rates_1t[i]);
1229         }
1230 }
1231
1232 void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1233 {
1234         struct rtl_priv *rtlpriv = rtl_priv(hw);
1235         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1236         enum io_type iotype;
1237
1238         if (!is_hal_stop(rtlhal)) {
1239                 switch (operation) {
1240                 case SCAN_OPT_BACKUP_BAND0:
1241                         iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1242                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1243                                                       (u8 *)&iotype);
1244
1245                         break;
1246                 case SCAN_OPT_RESTORE:
1247                         iotype = IO_CMD_RESUME_DM_BY_SCAN;
1248                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1249                                                       (u8 *)&iotype);
1250                         break;
1251                 default:
1252                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1253                                  "Unknown Scan Backup operation.\n");
1254                         break;
1255                 }
1256         }
1257 }
1258
1259 void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1260 {
1261         struct rtl_priv *rtlpriv = rtl_priv(hw);
1262         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1263         struct rtl_phy *rtlphy = &rtlpriv->phy;
1264         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1265         u8 reg_bw_opmode;
1266         u8 reg_prsr_rsc;
1267
1268         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1269                  "Switch to %s bandwidth\n",
1270                   rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1271                   "20MHz" : "40MHz");
1272
1273         if (is_hal_stop(rtlhal)) {
1274                 rtlphy->set_bwmode_inprogress = false;
1275                 return;
1276         }
1277
1278         reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1279         reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1280
1281         switch (rtlphy->current_chan_bw) {
1282         case HT_CHANNEL_WIDTH_20:
1283                 reg_bw_opmode |= BW_OPMODE_20MHZ;
1284                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1285                 break;
1286         case HT_CHANNEL_WIDTH_20_40:
1287                 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1288                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1289                 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1290                                (mac->cur_40_prime_sc << 5);
1291                 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1292                 break;
1293         default:
1294                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1295                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1296                 break;
1297         }
1298
1299         switch (rtlphy->current_chan_bw) {
1300         case HT_CHANNEL_WIDTH_20:
1301                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1302                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1303         /*      rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1304                 break;
1305         case HT_CHANNEL_WIDTH_20_40:
1306                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1307                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1308
1309                 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1310                               (mac->cur_40_prime_sc >> 1));
1311                 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1312                 /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1313
1314                 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1315                               (mac->cur_40_prime_sc ==
1316                                HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1317                 break;
1318         default:
1319                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1320                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1321                 break;
1322         }
1323         rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1324         rtlphy->set_bwmode_inprogress = false;
1325         RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1326 }
1327
1328 void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1329                             enum nl80211_channel_type ch_type)
1330 {
1331         struct rtl_priv *rtlpriv = rtl_priv(hw);
1332         struct rtl_phy *rtlphy = &rtlpriv->phy;
1333         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1334         u8 tmp_bw = rtlphy->current_chan_bw;
1335
1336         if (rtlphy->set_bwmode_inprogress)
1337                 return;
1338         rtlphy->set_bwmode_inprogress = true;
1339         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1340                 rtl8723be_phy_set_bw_mode_callback(hw);
1341         } else {
1342                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1343                          "false driver sleep or unload\n");
1344                 rtlphy->set_bwmode_inprogress = false;
1345                 rtlphy->current_chan_bw = tmp_bw;
1346         }
1347 }
1348
1349 void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1350 {
1351         struct rtl_priv *rtlpriv = rtl_priv(hw);
1352         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1353         struct rtl_phy *rtlphy = &rtlpriv->phy;
1354         u32 delay;
1355
1356         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1357                  "switch to channel%d\n", rtlphy->current_channel);
1358         if (is_hal_stop(rtlhal))
1359                 return;
1360         do {
1361                 if (!rtlphy->sw_chnl_inprogress)
1362                         break;
1363                 if (!_rtl8723be_phy_sw_chnl_step_by_step(hw,
1364                                                          rtlphy->current_channel,
1365                                                          &rtlphy->sw_chnl_stage,
1366                                                          &rtlphy->sw_chnl_step,
1367                                                          &delay)) {
1368                         if (delay > 0)
1369                                 mdelay(delay);
1370                         else
1371                                 continue;
1372                 } else {
1373                         rtlphy->sw_chnl_inprogress = false;
1374                 }
1375                 break;
1376         } while (true);
1377         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1378 }
1379
1380 u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1381 {
1382         struct rtl_priv *rtlpriv = rtl_priv(hw);
1383         struct rtl_phy *rtlphy = &rtlpriv->phy;
1384         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1385
1386         if (rtlphy->sw_chnl_inprogress)
1387                 return 0;
1388         if (rtlphy->set_bwmode_inprogress)
1389                 return 0;
1390         RT_ASSERT((rtlphy->current_channel <= 14),
1391                   "WIRELESS_MODE_G but channel>14");
1392         rtlphy->sw_chnl_inprogress = true;
1393         rtlphy->sw_chnl_stage = 0;
1394         rtlphy->sw_chnl_step = 0;
1395         if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1396                 rtl8723be_phy_sw_chnl_callback(hw);
1397                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1398                          "sw_chnl_inprogress false schdule workitem current channel %d\n",
1399                          rtlphy->current_channel);
1400                 rtlphy->sw_chnl_inprogress = false;
1401         } else {
1402                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1403                          "sw_chnl_inprogress false driver sleep or unload\n");
1404                 rtlphy->sw_chnl_inprogress = false;
1405         }
1406         return 1;
1407 }
1408
1409 static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1410                                                 u8 channel, u8 *stage,
1411                                                 u8 *step, u32 *delay)
1412 {
1413         struct rtl_priv *rtlpriv = rtl_priv(hw);
1414         struct rtl_phy *rtlphy = &rtlpriv->phy;
1415         struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1416         u32 precommoncmdcnt;
1417         struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1418         u32 postcommoncmdcnt;
1419         struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1420         u32 rfdependcmdcnt;
1421         struct swchnlcmd *currentcmd = NULL;
1422         u8 rfpath;
1423         u8 num_total_rfpath = rtlphy->num_total_rfpath;
1424
1425         precommoncmdcnt = 0;
1426         rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1427                                          MAX_PRECMD_CNT,
1428                                          CMDID_SET_TXPOWEROWER_LEVEL,
1429                                          0, 0, 0);
1430         rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1431                                          MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1432
1433         postcommoncmdcnt = 0;
1434
1435         rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1436                                          MAX_POSTCMD_CNT, CMDID_END,
1437                                             0, 0, 0);
1438
1439         rfdependcmdcnt = 0;
1440
1441         RT_ASSERT((channel >= 1 && channel <= 14),
1442                   "illegal channel for Zebra: %d\n", channel);
1443
1444         rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1445                                          MAX_RFDEPENDCMD_CNT,
1446                                          CMDID_RF_WRITEREG,
1447                                          RF_CHNLBW, channel, 10);
1448
1449         rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1450                                          MAX_RFDEPENDCMD_CNT,
1451                                             CMDID_END, 0, 0, 0);
1452
1453         do {
1454                 switch (*stage) {
1455                 case 0:
1456                         currentcmd = &precommoncmd[*step];
1457                         break;
1458                 case 1:
1459                         currentcmd = &rfdependcmd[*step];
1460                         break;
1461                 case 2:
1462                         currentcmd = &postcommoncmd[*step];
1463                         break;
1464                 default:
1465                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1466                                  "Invalid 'stage' = %d, Check it!\n", *stage);
1467                         return true;
1468                 }
1469
1470                 if (currentcmd->cmdid == CMDID_END) {
1471                         if ((*stage) == 2) {
1472                                 return true;
1473                         } else {
1474                                 (*stage)++;
1475                                 (*step) = 0;
1476                                 continue;
1477                         }
1478                 }
1479
1480                 switch (currentcmd->cmdid) {
1481                 case CMDID_SET_TXPOWEROWER_LEVEL:
1482                         rtl8723be_phy_set_txpower_level(hw, channel);
1483                         break;
1484                 case CMDID_WRITEPORT_ULONG:
1485                         rtl_write_dword(rtlpriv, currentcmd->para1,
1486                                         currentcmd->para2);
1487                         break;
1488                 case CMDID_WRITEPORT_USHORT:
1489                         rtl_write_word(rtlpriv, currentcmd->para1,
1490                                        (u16)currentcmd->para2);
1491                         break;
1492                 case CMDID_WRITEPORT_UCHAR:
1493                         rtl_write_byte(rtlpriv, currentcmd->para1,
1494                                        (u8)currentcmd->para2);
1495                         break;
1496                 case CMDID_RF_WRITEREG:
1497                         for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1498                                 rtlphy->rfreg_chnlval[rfpath] =
1499                                     ((rtlphy->rfreg_chnlval[rfpath] &
1500                                       0xfffffc00) | currentcmd->para2);
1501
1502                                 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1503                                               currentcmd->para1,
1504                                               RFREG_OFFSET_MASK,
1505                                               rtlphy->rfreg_chnlval[rfpath]);
1506                         }
1507                         break;
1508                 default:
1509                         RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1510                                  "switch case not process\n");
1511                         break;
1512                 }
1513
1514                 break;
1515         } while (true);
1516
1517         (*delay) = currentcmd->msdelay;
1518         (*step)++;
1519         return false;
1520 }
1521
1522 static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1523 {
1524         u32 reg_eac, reg_e94, reg_e9c, tmp;
1525         u8 result = 0x00;
1526
1527         /* leave IQK mode */
1528         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1529         /* switch to path A */
1530         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1531         /* enable path A PA in TXIQK mode */
1532         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1533         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1534         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1535         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1536
1537         /* 1. TX IQK */
1538         /* path-A IQK setting */
1539         /* IQK setting */
1540         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1541         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1542         /* path-A IQK setting */
1543         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1544         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1545         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1546         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1547
1548         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1549         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1550         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1551         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1552         /* LO calibration setting */
1553         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1554         /* enter IQK mode */
1555         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1556
1557         /* One shot, path A LOK & IQK */
1558         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1559         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1560
1561         mdelay(IQK_DELAY_TIME);
1562
1563         /* leave IQK mode */
1564         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1565
1566         /* Check failed */
1567         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1568         reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1569         reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1570
1571         if (!(reg_eac & BIT(28)) &&
1572             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1573             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1574                 result |= 0x01;
1575         else /* if Tx not OK, ignore Rx */
1576                 return result;
1577
1578         /* Allen 20131125 */
1579         tmp = (reg_e9c & 0x03FF0000) >> 16;
1580         if ((tmp & 0x200) > 0)
1581                 tmp = 0x400 - tmp;
1582
1583         if (!(reg_eac & BIT(28)) &&
1584             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1585             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1586             (tmp < 0xf))
1587                 result |= 0x01;
1588         else /* if Tx not OK, ignore Rx */
1589                 return result;
1590
1591         return result;
1592 }
1593
1594 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1595 static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1596 {
1597         u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1598         u8 result = 0x00;
1599
1600         /* leave IQK mode */
1601         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1602
1603         /* switch to path A */
1604         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1605
1606         /* 1 Get TXIMR setting */
1607         /* modify RXIQK mode table */
1608         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1609         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1610         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1611         /* LNA2 off, PA on for Dcut */
1612         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1613         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1614
1615         /* IQK setting */
1616         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1617         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1618
1619         /* path-A IQK setting */
1620         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1621         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1622         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1623         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1624
1625         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1626         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1627         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1628         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1629
1630         /* LO calibration setting */
1631         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1632
1633         /* enter IQK mode */
1634         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1635
1636         /* One shot, path A LOK & IQK */
1637         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1638         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1639
1640         mdelay(IQK_DELAY_TIME);
1641
1642         /* leave IQK mode */
1643         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1644
1645         /* Check failed */
1646         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1647         reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1648         reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1649
1650         if (!(reg_eac & BIT(28)) &&
1651             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1652             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1653                 result |= 0x01;
1654         else /* if Tx not OK, ignore Rx */
1655                 return result;
1656
1657         /* Allen 20131125 */
1658         tmp = (reg_e9c & 0x03FF0000) >> 16;
1659         if ((tmp & 0x200) > 0)
1660                 tmp = 0x400 - tmp;
1661
1662         if (!(reg_eac & BIT(28)) &&
1663             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1664             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1665             (tmp < 0xf))
1666                 result |= 0x01;
1667         else /* if Tx not OK, ignore Rx */
1668                 return result;
1669
1670         u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1671                  ((reg_e9c & 0x3FF0000) >> 16);
1672         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1673
1674         /* 1 RX IQK */
1675         /* modify RXIQK mode table */
1676         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1677         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1678         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1679         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1680         /* LAN2 on, PA off for Dcut */
1681         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1682
1683         /* PA, PAD setting */
1684         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1685         rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1686
1687         /* IQK setting */
1688         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1689
1690         /* path-A IQK setting */
1691         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1692         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1693         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1694         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1695
1696         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1697         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1698         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1699         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1700
1701         /* LO calibration setting */
1702         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1703
1704         /* enter IQK mode */
1705         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1706
1707         /* One shot, path A LOK & IQK */
1708         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1709         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1710
1711         mdelay(IQK_DELAY_TIME);
1712
1713         /* leave IQK mode */
1714         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1715
1716         /* Check failed */
1717         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1718         reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1719
1720         /* leave IQK mode */
1721         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1722         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1723
1724         /* Allen 20131125 */
1725         tmp = (reg_eac & 0x03FF0000) >> 16;
1726                 if ((tmp & 0x200) > 0)
1727                         tmp = 0x400 - tmp;
1728         /* if Tx is OK, check whether Rx is OK */
1729         if (!(reg_eac & BIT(27)) &&
1730             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1731             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1732                 result |= 0x02;
1733         else if (!(reg_eac & BIT(27)) &&
1734                  (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1735                  (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1736                  (tmp < 0xf))
1737                 result |= 0x02;
1738
1739         return result;
1740 }
1741
1742 static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1743 {
1744         u32 reg_eac, reg_e94, reg_e9c, tmp;
1745         u8 result = 0x00;
1746
1747         /* leave IQK mode */
1748         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1749         /* switch to path B */
1750         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1751
1752         /* enable path B PA in TXIQK mode */
1753         rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1754         rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1755
1756         /* 1 Tx IQK */
1757         /* IQK setting */
1758         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1759         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1760         /* path-A IQK setting */
1761         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1762         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1763         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1764         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1765
1766         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1767         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1768         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1769         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1770
1771         /* LO calibration setting */
1772         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1773
1774         /* enter IQK mode */
1775         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1776
1777         /* One shot, path B LOK & IQK */
1778         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1779         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1780
1781         mdelay(IQK_DELAY_TIME);
1782
1783         /* leave IQK mode */
1784         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1785
1786         /* Check failed */
1787         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1788         reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1789         reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1790
1791         if (!(reg_eac & BIT(28)) &&
1792             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1793             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1794                 result |= 0x01;
1795         else
1796                 return result;
1797
1798         /* Allen 20131125 */
1799         tmp = (reg_e9c & 0x03FF0000) >> 16;
1800         if ((tmp & 0x200) > 0)
1801                 tmp = 0x400 - tmp;
1802
1803         if (!(reg_eac & BIT(28)) &&
1804             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1805             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1806             (tmp < 0xf))
1807                 result |= 0x01;
1808         else
1809                 return result;
1810
1811         return result;
1812 }
1813
1814 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1815 static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1816 {
1817         u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1818         u8 result = 0x00;
1819
1820         /* leave IQK mode */
1821         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1822         /* switch to path B */
1823         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1824
1825         /* 1 Get TXIMR setting */
1826         /* modify RXIQK mode table */
1827         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1828         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1829         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1830         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1831
1832         /* open PA S1 & SMIXER */
1833         rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1834         rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1835
1836         /* IQK setting */
1837         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1838         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1839
1840         /* path-B IQK setting */
1841         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1842         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1843         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1844         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1845
1846         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1847         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1848         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1849         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1850
1851         /* LO calibration setting */
1852         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1853         /* enter IQK mode */
1854         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1855
1856         /* One shot, path B TXIQK @ RXIQK */
1857         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1858         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1859
1860         mdelay(IQK_DELAY_TIME);
1861
1862         /* leave IQK mode */
1863         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1864         /* Check failed */
1865         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1866         reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1867         reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1868
1869         if (!(reg_eac & BIT(28)) &&
1870             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1871             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1872                 result |= 0x01;
1873         else    /* if Tx not OK, ignore Rx */
1874                 return result;
1875
1876         /* Allen 20131125 */
1877         tmp = (reg_e9c & 0x03FF0000) >> 16;
1878         if ((tmp & 0x200) > 0)
1879                 tmp = 0x400 - tmp;
1880
1881         if (!(reg_eac & BIT(28)) &&
1882             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1883             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1884             (tmp < 0xf))
1885                 result |= 0x01;
1886         else
1887                 return result;
1888
1889         u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
1890                  ((reg_e9c & 0x3FF0000) >> 16);
1891         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1892
1893         /* 1 RX IQK */
1894
1895         /* <20121009, Kordan> RF Mode = 3 */
1896         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1897         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1898         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1899         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1900         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1901         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1902
1903         /* open PA S1 & close SMIXER */
1904         rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1905         rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1906
1907         /* IQK setting */
1908         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1909
1910         /* path-B IQK setting */
1911         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1912         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1913         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1914         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1915
1916         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1917         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1918         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1919         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1920
1921         /* LO calibration setting */
1922         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1923         /* enter IQK mode */
1924         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1925
1926         /* One shot, path B LOK & IQK */
1927         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1928         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1929
1930         mdelay(IQK_DELAY_TIME);
1931
1932         /* leave IQK mode */
1933         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1934         /* Check failed */
1935         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1936         reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1937
1938         /* Allen 20131125 */
1939         tmp = (reg_eac & 0x03FF0000) >> 16;
1940         if ((tmp & 0x200) > 0)
1941                 tmp = 0x400 - tmp;
1942
1943         /* if Tx is OK, check whether Rx is OK */
1944         if (!(reg_eac & BIT(27)) &&
1945             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1946             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1947                 result |= 0x02;
1948         else if (!(reg_eac & BIT(27)) &&
1949                  (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1950                  (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1951                  (tmp < 0xf))
1952                 result |= 0x02;
1953         else
1954                 return result;
1955
1956         return result;
1957 }
1958
1959 static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1960                                                   bool b_iqk_ok,
1961                                                   long result[][8],
1962                                                   u8 final_candidate,
1963                                                   bool btxonly)
1964 {
1965         u32 oldval_1, x, tx1_a, reg;
1966         long y, tx1_c;
1967
1968         if (final_candidate == 0xFF) {
1969                 return;
1970         } else if (b_iqk_ok) {
1971                 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1972                                           MASKDWORD) >> 22) & 0x3FF;
1973                 x = result[final_candidate][4];
1974                 if ((x & 0x00000200) != 0)
1975                         x = x | 0xFFFFFC00;
1976                 tx1_a = (x * oldval_1) >> 8;
1977                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1978                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1979                               ((x * oldval_1 >> 7) & 0x1));
1980                 y = result[final_candidate][5];
1981                 if ((y & 0x00000200) != 0)
1982                         y = y | 0xFFFFFC00;
1983                 tx1_c = (y * oldval_1) >> 8;
1984                 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1985                               ((tx1_c & 0x3C0) >> 6));
1986                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1987                               (tx1_c & 0x3F));
1988                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1989                               ((y * oldval_1 >> 7) & 0x1));
1990                 if (btxonly)
1991                         return;
1992                 reg = result[final_candidate][6];
1993                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1994                 reg = result[final_candidate][7] & 0x3F;
1995                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1996                 reg = (result[final_candidate][7] >> 6) & 0xF;
1997                 /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1998         }
1999 }
2000
2001 static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
2002                                               long result[][8], u8 c1, u8 c2)
2003 {
2004         u32 i, j, diff, simularity_bitmap, bound = 0;
2005
2006         u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2007         bool bresult = true; /* is2t = true*/
2008         s32 tmp1 = 0, tmp2 = 0;
2009
2010         bound = 8;
2011
2012         simularity_bitmap = 0;
2013
2014         for (i = 0; i < bound; i++) {
2015                 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2016                         if ((result[c1][i] & 0x00000200) != 0)
2017                                 tmp1 = result[c1][i] | 0xFFFFFC00;
2018                         else
2019                                 tmp1 = result[c1][i];
2020
2021                         if ((result[c2][i] & 0x00000200) != 0)
2022                                 tmp2 = result[c2][i] | 0xFFFFFC00;
2023                         else
2024                                 tmp2 = result[c2][i];
2025                 } else {
2026                         tmp1 = result[c1][i];
2027                         tmp2 = result[c2][i];
2028                 }
2029
2030                 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2031
2032                 if (diff > MAX_TOLERANCE) {
2033                         if ((i == 2 || i == 6) && !simularity_bitmap) {
2034                                 if (result[c1][i] + result[c1][i + 1] == 0)
2035                                         final_candidate[(i / 4)] = c2;
2036                                 else if (result[c2][i] + result[c2][i + 1] == 0)
2037                                         final_candidate[(i / 4)] = c1;
2038                                 else
2039                                         simularity_bitmap |= (1 << i);
2040                         } else
2041                                 simularity_bitmap |= (1 << i);
2042                 }
2043         }
2044
2045         if (simularity_bitmap == 0) {
2046                 for (i = 0; i < (bound / 4); i++) {
2047                         if (final_candidate[i] != 0xFF) {
2048                                 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2049                                         result[3][j] =
2050                                                 result[final_candidate[i]][j];
2051                                 bresult = false;
2052                         }
2053                 }
2054                 return bresult;
2055         } else {
2056                 if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
2057                         for (i = 0; i < 2; i++)
2058                                 result[3][i] = result[c1][i];
2059                 }
2060                 if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
2061                         for (i = 2; i < 4; i++)
2062                                 result[3][i] = result[c1][i];
2063                 }
2064                 if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
2065                         for (i = 4; i < 6; i++)
2066                                 result[3][i] = result[c1][i];
2067                 }
2068                 if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
2069                         for (i = 6; i < 8; i++)
2070                                 result[3][i] = result[c1][i];
2071                 }
2072                 return false;
2073         }
2074 }
2075
2076 static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2077                                         long result[][8], u8 t, bool is2t)
2078 {
2079         struct rtl_priv *rtlpriv = rtl_priv(hw);
2080         struct rtl_phy *rtlphy = &rtlpriv->phy;
2081         u32 i;
2082         u8 patha_ok, pathb_ok;
2083         u32 adda_reg[IQK_ADDA_REG_NUM] = {
2084                 0x85c, 0xe6c, 0xe70, 0xe74,
2085                 0xe78, 0xe7c, 0xe80, 0xe84,
2086                 0xe88, 0xe8c, 0xed0, 0xed4,
2087                 0xed8, 0xedc, 0xee0, 0xeec
2088         };
2089
2090         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2091                 0x522, 0x550, 0x551, 0x040
2092         };
2093         u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2094                 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2095                 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2096                 0x870, 0x860,
2097                 0x864, 0xa04
2098         };
2099         const u32 retrycount = 2;
2100
2101         u32 path_sel_bb;/* path_sel_rf */
2102
2103         u8 tmp_reg_c50, tmp_reg_c58;
2104
2105         tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2106         tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2107
2108         if (t == 0) {
2109                 rtl8723_save_adda_registers(hw, adda_reg,
2110                                             rtlphy->adda_backup, 16);
2111                 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2112                                                rtlphy->iqk_mac_backup);
2113                 rtl8723_save_adda_registers(hw, iqk_bb_reg,
2114                                             rtlphy->iqk_bb_backup,
2115                                             IQK_BB_REG_NUM);
2116         }
2117         rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2118         if (t == 0) {
2119                 rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2120                                                 RFPGA0_XA_HSSIPARAMETER1,
2121                                                 BIT(8));
2122         }
2123
2124         path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2125
2126         rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2127                                             rtlphy->iqk_mac_backup);
2128         /*BB Setting*/
2129         rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2130         rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2131         rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2132         rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2133
2134         /* path A TX IQK */
2135         for (i = 0; i < retrycount; i++) {
2136                 patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2137                 if (patha_ok == 0x01) {
2138                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2139                                 "Path A Tx IQK Success!!\n");
2140                         result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2141                                         0x3FF0000) >> 16;
2142                         result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2143                                         0x3FF0000) >> 16;
2144                         break;
2145                 } else {
2146                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2147                                  "Path A Tx IQK Fail!!\n");
2148                 }
2149         }
2150         /* path A RX IQK */
2151         for (i = 0; i < retrycount; i++) {
2152                 patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2153                 if (patha_ok == 0x03) {
2154                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2155                                  "Path A Rx IQK Success!!\n");
2156                         result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2157                                         0x3FF0000) >> 16;
2158                         result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2159                                         0x3FF0000) >> 16;
2160                         break;
2161                 }
2162                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2163                          "Path A Rx IQK Fail!!\n");
2164         }
2165
2166         if (0x00 == patha_ok)
2167                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2168
2169         if (is2t) {
2170                 /* path B TX IQK */
2171                 for (i = 0; i < retrycount; i++) {
2172                         pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2173                         if (pathb_ok == 0x01) {
2174                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2175                                          "Path B Tx IQK Success!!\n");
2176                                 result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2177                                                               MASKDWORD) &
2178                                                               0x3FF0000) >> 16;
2179                                 result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2180                                                               MASKDWORD) &
2181                                                               0x3FF0000) >> 16;
2182                                 break;
2183                         }
2184                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2185                                  "Path B Tx IQK Fail!!\n");
2186                 }
2187                 /* path B RX IQK */
2188                 for (i = 0; i < retrycount; i++) {
2189                         pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2190                         if (pathb_ok == 0x03) {
2191                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2192                                          "Path B Rx IQK Success!!\n");
2193                                 result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2194                                                               MASKDWORD) &
2195                                                               0x3FF0000) >> 16;
2196                                 result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2197                                                               MASKDWORD) &
2198                                                               0x3FF0000) >> 16;
2199                                 break;
2200                         }
2201                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2202                                  "Path B Rx IQK Fail!!\n");
2203                 }
2204         }
2205
2206         /* Back to BB mode, load original value */
2207         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2208
2209         if (t != 0) {
2210                 rtl8723_phy_reload_adda_registers(hw, adda_reg,
2211                                                   rtlphy->adda_backup, 16);
2212                 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2213                                                  rtlphy->iqk_mac_backup);
2214                 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2215                                                   rtlphy->iqk_bb_backup,
2216                                                   IQK_BB_REG_NUM);
2217
2218                 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2219                 /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2220
2221                 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2222                 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2223                 if (is2t) {
2224                         rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2225                         rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2226                 }
2227                 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2228                 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2229         }
2230         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2231 }
2232
2233 static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2234 {
2235         u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2236                         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2237                         13, 14, 36, 38, 40, 42, 44, 46,
2238                         48, 50, 52, 54, 56, 58, 60, 62, 64,
2239                         100, 102, 104, 106, 108, 110,
2240                         112, 114, 116, 118, 120, 122,
2241                         124, 126, 128, 130, 132, 134, 136,
2242                         138, 140, 149, 151, 153, 155, 157,
2243                         159, 161, 163, 165};
2244         u8 place = chnl;
2245
2246         if (chnl > 14) {
2247                 for (place = 14; place < sizeof(channel_all); place++) {
2248                         if (channel_all[place] == chnl)
2249                                 return place - 13;
2250                 }
2251         }
2252         return 0;
2253 }
2254
2255 static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2256 {
2257         u8 tmpreg;
2258         u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2259         struct rtl_priv *rtlpriv = rtl_priv(hw);
2260
2261         tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2262
2263         if ((tmpreg & 0x70) != 0)
2264                 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2265         else
2266                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2267
2268         if ((tmpreg & 0x70) != 0) {
2269                 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2270
2271                 if (is2t)
2272                         rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2273                                                   MASK12BITS);
2274
2275                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2276                               (rf_a_mode & 0x8FFFF) | 0x10000);
2277
2278                 if (is2t)
2279                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2280                                       (rf_b_mode & 0x8FFFF) | 0x10000);
2281         }
2282         lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2283
2284         rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2285         rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2286
2287         /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2288         /*mdelay(100);*/
2289         /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2290         mdelay(50);
2291
2292         rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2293
2294         if ((tmpreg & 0x70) != 0) {
2295                 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2296                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2297
2298                 if (is2t)
2299                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2300                                       MASK12BITS, rf_b_mode);
2301         } else {
2302                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2303         }
2304 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2305
2306 }
2307
2308 static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2309                                              bool bmain, bool is2t)
2310 {
2311         struct rtl_priv *rtlpriv = rtl_priv(hw);
2312         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2313
2314         if (bmain) /* left antenna */
2315                 rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1);
2316         else
2317                 rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2);
2318 }
2319
2320 #undef IQK_ADDA_REG_NUM
2321 #undef IQK_DELAY_TIME
2322 /* IQK is merge from Merge Temp */
2323 void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2324 {
2325         struct rtl_priv *rtlpriv = rtl_priv(hw);
2326         struct rtl_phy *rtlphy = &rtlpriv->phy;
2327         long result[4][8];
2328         u8 i, final_candidate, idx;
2329         bool b_patha_ok, b_pathb_ok;
2330         long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4;
2331         long reg_ecc, reg_tmp = 0;
2332         bool is12simular, is13simular, is23simular;
2333         u32 iqk_bb_reg[9] = {
2334                 ROFDM0_XARXIQIMBALANCE,
2335                 ROFDM0_XBRXIQIMBALANCE,
2336                 ROFDM0_ECCATHRESHOLD,
2337                 ROFDM0_AGCRSSITABLE,
2338                 ROFDM0_XATXIQIMBALANCE,
2339                 ROFDM0_XBTXIQIMBALANCE,
2340                 ROFDM0_XCTXAFE,
2341                 ROFDM0_XDTXAFE,
2342                 ROFDM0_RXIQEXTANTA
2343         };
2344         u32 path_sel_bb = 0; /* path_sel_rf = 0 */
2345
2346         if (rtlphy->lck_inprogress)
2347                 return;
2348
2349         spin_lock(&rtlpriv->locks.iqk_lock);
2350         rtlphy->lck_inprogress = true;
2351         spin_unlock(&rtlpriv->locks.iqk_lock);
2352
2353         if (b_recovery) {
2354                 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2355                                                   rtlphy->iqk_bb_backup, 9);
2356                 return;
2357         }
2358         /* Save RF Path */
2359         path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2360         /* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */
2361
2362         for (i = 0; i < 8; i++) {
2363                 result[0][i] = 0;
2364                 result[1][i] = 0;
2365                 result[2][i] = 0;
2366                 result[3][i] = 0;
2367         }
2368         final_candidate = 0xff;
2369         b_patha_ok = false;
2370         b_pathb_ok = false;
2371         is12simular = false;
2372         is23simular = false;
2373         is13simular = false;
2374         for (i = 0; i < 3; i++) {
2375                 _rtl8723be_phy_iq_calibrate(hw, result, i, true);
2376                 if (i == 1) {
2377                         is12simular = _rtl8723be_phy_simularity_compare(hw,
2378                                                                         result,
2379                                                                         0, 1);
2380                         if (is12simular) {
2381                                 final_candidate = 0;
2382                                 break;
2383                         }
2384                 }
2385                 if (i == 2) {
2386                         is13simular = _rtl8723be_phy_simularity_compare(hw,
2387                                                                         result,
2388                                                                         0, 2);
2389                         if (is13simular) {
2390                                 final_candidate = 0;
2391                                 break;
2392                         }
2393                         is23simular = _rtl8723be_phy_simularity_compare(hw,
2394                                                                         result,
2395                                                                         1, 2);
2396                         if (is23simular) {
2397                                 final_candidate = 1;
2398                         } else {
2399                                 for (i = 0; i < 8; i++)
2400                                         reg_tmp += result[3][i];
2401
2402                                 if (reg_tmp != 0)
2403                                         final_candidate = 3;
2404                                 else
2405                                         final_candidate = 0xFF;
2406                         }
2407                 }
2408         }
2409         for (i = 0; i < 4; i++) {
2410                 reg_e94 = result[i][0];
2411                 reg_e9c = result[i][1];
2412                 reg_ea4 = result[i][2];
2413                 reg_eac = result[i][3];
2414                 reg_eb4 = result[i][4];
2415                 reg_ebc = result[i][5];
2416                 reg_ec4 = result[i][6];
2417                 reg_ecc = result[i][7];
2418         }
2419         if (final_candidate != 0xff) {
2420                 reg_e94 = result[final_candidate][0];
2421                 rtlphy->reg_e94 = reg_e94;
2422                 reg_e9c = result[final_candidate][1];
2423                 rtlphy->reg_e9c = reg_e9c;
2424                 reg_ea4 = result[final_candidate][2];
2425                 reg_eac = result[final_candidate][3];
2426                 reg_eb4 = result[final_candidate][4];
2427                 rtlphy->reg_eb4 = reg_eb4;
2428                 reg_ebc = result[final_candidate][5];
2429                 rtlphy->reg_ebc = reg_ebc;
2430                 reg_ec4 = result[final_candidate][6];
2431                 reg_ecc = result[final_candidate][7];
2432                 b_patha_ok = true;
2433                 b_pathb_ok = true;
2434         } else {
2435                 rtlphy->reg_e94 = 0x100;
2436                 rtlphy->reg_eb4 = 0x100;
2437                 rtlphy->reg_e9c = 0x0;
2438                 rtlphy->reg_ebc = 0x0;
2439         }
2440         if (reg_e94 != 0)
2441                 rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2442                                                    final_candidate,
2443                                                    (reg_ea4 == 0));
2444         if (reg_eb4 != 0)
2445                 _rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2446                                                       final_candidate,
2447                                                       (reg_ec4 == 0));
2448
2449         idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel);
2450
2451         if (final_candidate < 4) {
2452                 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2453                         rtlphy->iqk_matrix[idx].value[0][i] =
2454                                                 result[final_candidate][i];
2455                 rtlphy->iqk_matrix[idx].iqk_done = true;
2456
2457         }
2458         rtl8723_save_adda_registers(hw, iqk_bb_reg,
2459                                     rtlphy->iqk_bb_backup, 9);
2460
2461         rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2462         /* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */
2463
2464         spin_lock(&rtlpriv->locks.iqk_lock);
2465         rtlphy->lck_inprogress = false;
2466         spin_unlock(&rtlpriv->locks.iqk_lock);
2467 }
2468
2469 void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
2470 {
2471         struct rtl_priv *rtlpriv = rtl_priv(hw);
2472         struct rtl_phy *rtlphy = &rtlpriv->phy;
2473         struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2474         u32 timeout = 2000, timecount = 0;
2475
2476         while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2477                 udelay(50);
2478                 timecount += 50;
2479         }
2480
2481         rtlphy->lck_inprogress = true;
2482         RTPRINT(rtlpriv, FINIT, INIT_IQK,
2483                 "LCK:Start!!! currentband %x delay %d ms\n",
2484                  rtlhal->current_bandtype, timecount);
2485
2486         _rtl8723be_phy_lc_calibrate(hw, false);
2487
2488         rtlphy->lck_inprogress = false;
2489 }
2490
2491 void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2492 {
2493         _rtl8723be_phy_set_rfpath_switch(hw, bmain, true);
2494 }
2495
2496 bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2497 {
2498         struct rtl_priv *rtlpriv = rtl_priv(hw);
2499         struct rtl_phy *rtlphy = &rtlpriv->phy;
2500         bool b_postprocessing = false;
2501
2502         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2503                  "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2504                   iotype, rtlphy->set_io_inprogress);
2505         do {
2506                 switch (iotype) {
2507                 case IO_CMD_RESUME_DM_BY_SCAN:
2508                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2509                                  "[IO CMD] Resume DM after scan.\n");
2510                         b_postprocessing = true;
2511                         break;
2512                 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2513                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2514                                  "[IO CMD] Pause DM before scan.\n");
2515                         b_postprocessing = true;
2516                         break;
2517                 default:
2518                         RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2519                                  "switch case not process\n");
2520                         break;
2521                 }
2522         } while (false);
2523         if (b_postprocessing && !rtlphy->set_io_inprogress) {
2524                 rtlphy->set_io_inprogress = true;
2525                 rtlphy->current_io_type = iotype;
2526         } else {
2527                 return false;
2528         }
2529         rtl8723be_phy_set_io(hw);
2530         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2531         return true;
2532 }
2533
2534 static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
2535 {
2536         struct rtl_priv *rtlpriv = rtl_priv(hw);
2537         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2538         struct rtl_phy *rtlphy = &rtlpriv->phy;
2539
2540         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2541                  "--->Cmd(%#x), set_io_inprogress(%d)\n",
2542                   rtlphy->current_io_type, rtlphy->set_io_inprogress);
2543         switch (rtlphy->current_io_type) {
2544         case IO_CMD_RESUME_DM_BY_SCAN:
2545                 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2546                 /*rtl92c_dm_write_dig(hw);*/
2547                 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
2548                 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2549                 break;
2550         case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2551                 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2552                 dm_digtable->cur_igvalue = 0x17;
2553                 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2554                 break;
2555         default:
2556                 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2557                          "switch case not process\n");
2558                 break;
2559         }
2560         rtlphy->set_io_inprogress = false;
2561         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2562                  "(%#x)\n", rtlphy->current_io_type);
2563 }
2564
2565 static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2566 {
2567         struct rtl_priv *rtlpriv = rtl_priv(hw);
2568
2569         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2570         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2571         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2572         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2573         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2574 }
2575
2576 static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2577 {
2578         struct rtl_priv *rtlpriv = rtl_priv(hw);
2579
2580         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2581         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2582         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2583         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2584 }
2585
2586 static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2587                                               enum rf_pwrstate rfpwr_state)
2588 {
2589         struct rtl_priv *rtlpriv = rtl_priv(hw);
2590         struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2591         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2592         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2593         bool bresult = true;
2594         u8 i, queue_id;
2595         struct rtl8192_tx_ring *ring = NULL;
2596
2597         switch (rfpwr_state) {
2598         case ERFON:
2599                 if ((ppsc->rfpwr_state == ERFOFF) &&
2600                      RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2601                         bool rtstatus;
2602                         u32 initializecount = 0;
2603                         do {
2604                                 initializecount++;
2605                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2606                                          "IPS Set eRf nic enable\n");
2607                                 rtstatus = rtl_ps_enable_nic(hw);
2608                         } while (!rtstatus && (initializecount < 10));
2609                                 RT_CLEAR_PS_LEVEL(ppsc,
2610                                                   RT_RF_OFF_LEVL_HALT_NIC);
2611                 } else {
2612                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2613                                  "Set ERFON sleeped:%d ms\n",
2614                                   jiffies_to_msecs(jiffies -
2615                                                    ppsc->last_sleep_jiffies));
2616                         ppsc->last_awake_jiffies = jiffies;
2617                         rtl8723be_phy_set_rf_on(hw);
2618                 }
2619                 if (mac->link_state == MAC80211_LINKED)
2620                         rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2621                 else
2622                         rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2623
2624                 break;
2625
2626         case ERFOFF:
2627                 for (queue_id = 0, i = 0;
2628                      queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2629                         ring = &pcipriv->dev.tx_ring[queue_id];
2630                         /* Don't check BEACON Q.
2631                          * BEACON Q is always not empty,
2632                          * because '_rtl8723be_cmd_send_packet'
2633                          */
2634                         if (queue_id == BEACON_QUEUE ||
2635                             skb_queue_len(&ring->queue) == 0) {
2636                                 queue_id++;
2637                                 continue;
2638                         } else {
2639                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2640                                          "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2641                                          (i + 1), queue_id,
2642                                          skb_queue_len(&ring->queue));
2643
2644                                 udelay(10);
2645                                 i++;
2646                         }
2647                         if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2648                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2649                                          "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2650                                           MAX_DOZE_WAITING_TIMES_9x,
2651                                           queue_id,
2652                                           skb_queue_len(&ring->queue));
2653                                 break;
2654                         }
2655                 }
2656
2657                 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2658                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2659                                  "IPS Set eRf nic disable\n");
2660                         rtl_ps_disable_nic(hw);
2661                         RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2662                 } else {
2663                         if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2664                                 rtlpriv->cfg->ops->led_control(hw,
2665                                                                LED_CTL_NO_LINK);
2666                         } else {
2667                                 rtlpriv->cfg->ops->led_control(hw,
2668                                                              LED_CTL_POWER_OFF);
2669                         }
2670                 }
2671                 break;
2672
2673         case ERFSLEEP:
2674                 if (ppsc->rfpwr_state == ERFOFF)
2675                         break;
2676                 for (queue_id = 0, i = 0;
2677                      queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2678                         ring = &pcipriv->dev.tx_ring[queue_id];
2679                         if (skb_queue_len(&ring->queue) == 0) {
2680                                 queue_id++;
2681                                 continue;
2682                         } else {
2683                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2684                                          "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2685                                          (i + 1), queue_id,
2686                                          skb_queue_len(&ring->queue));
2687
2688                                 udelay(10);
2689                                 i++;
2690                         }
2691                         if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2692                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2693                                          "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2694                                          MAX_DOZE_WAITING_TIMES_9x,
2695                                          queue_id,
2696                                          skb_queue_len(&ring->queue));
2697                                 break;
2698                         }
2699                 }
2700                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2701                          "Set ERFSLEEP awaked:%d ms\n",
2702                           jiffies_to_msecs(jiffies -
2703                                            ppsc->last_awake_jiffies));
2704                 ppsc->last_sleep_jiffies = jiffies;
2705                 _rtl8723be_phy_set_rf_sleep(hw);
2706                 break;
2707
2708         default:
2709                 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2710                          "switch case not process\n");
2711                 bresult = false;
2712                 break;
2713         }
2714         if (bresult)
2715                 ppsc->rfpwr_state = rfpwr_state;
2716         return bresult;
2717 }
2718
2719 bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2720                                       enum rf_pwrstate rfpwr_state)
2721 {
2722         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2723
2724         bool bresult = false;
2725
2726         if (rfpwr_state == ppsc->rfpwr_state)
2727                 return bresult;
2728         bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2729         return bresult;
2730 }