GNU Linux-libre 4.9.288-gnu1
[releases.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         s8 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!!\n");
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!!\n");
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 %#x not processed\n", rfpath);
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         s8 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 = 0;
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 schedule 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 %#x not processed\n",
1511                                  currentcmd->cmdid);
1512                         break;
1513                 }
1514
1515                 break;
1516         } while (true);
1517
1518         (*delay) = currentcmd->msdelay;
1519         (*step)++;
1520         return false;
1521 }
1522
1523 static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1524 {
1525         u32 reg_eac, reg_e94, reg_e9c, tmp;
1526         u8 result = 0x00;
1527
1528         /* leave IQK mode */
1529         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1530         /* switch to path A */
1531         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1532         /* enable path A PA in TXIQK mode */
1533         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1534         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1535         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1536         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1537
1538         /* 1. TX IQK */
1539         /* path-A IQK setting */
1540         /* IQK setting */
1541         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1542         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1543         /* path-A IQK setting */
1544         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1545         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1546         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1547         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1548
1549         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1550         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1551         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1552         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1553         /* LO calibration setting */
1554         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1555         /* enter IQK mode */
1556         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1557
1558         /* One shot, path A LOK & IQK */
1559         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1560         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1561
1562         mdelay(IQK_DELAY_TIME);
1563
1564         /* leave IQK mode */
1565         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1566
1567         /* Check failed */
1568         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1569         reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1570         reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1571
1572         if (!(reg_eac & BIT(28)) &&
1573             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1574             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1575                 result |= 0x01;
1576         else /* if Tx not OK, ignore Rx */
1577                 return result;
1578
1579         /* Allen 20131125 */
1580         tmp = (reg_e9c & 0x03FF0000) >> 16;
1581         if ((tmp & 0x200) > 0)
1582                 tmp = 0x400 - tmp;
1583
1584         if (!(reg_eac & BIT(28)) &&
1585             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1586             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1587             (tmp < 0xf))
1588                 result |= 0x01;
1589         else /* if Tx not OK, ignore Rx */
1590                 return result;
1591
1592         return result;
1593 }
1594
1595 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1596 static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1597 {
1598         u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1599         u8 result = 0x00;
1600
1601         /* leave IQK mode */
1602         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1603
1604         /* switch to path A */
1605         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1606
1607         /* 1 Get TXIMR setting */
1608         /* modify RXIQK mode table */
1609         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1610         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1611         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1612         /* LNA2 off, PA on for Dcut */
1613         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1614         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1615
1616         /* IQK setting */
1617         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1618         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1619
1620         /* path-A IQK setting */
1621         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1622         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1623         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1624         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1625
1626         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1627         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1628         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1629         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1630
1631         /* LO calibration setting */
1632         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1633
1634         /* enter IQK mode */
1635         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1636
1637         /* One shot, path A LOK & IQK */
1638         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1639         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1640
1641         mdelay(IQK_DELAY_TIME);
1642
1643         /* leave IQK mode */
1644         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1645
1646         /* Check failed */
1647         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1648         reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1649         reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1650
1651         if (!(reg_eac & BIT(28)) &&
1652             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1653             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1654                 result |= 0x01;
1655         else /* if Tx not OK, ignore Rx */
1656                 return result;
1657
1658         /* Allen 20131125 */
1659         tmp = (reg_e9c & 0x03FF0000) >> 16;
1660         if ((tmp & 0x200) > 0)
1661                 tmp = 0x400 - tmp;
1662
1663         if (!(reg_eac & BIT(28)) &&
1664             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1665             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1666             (tmp < 0xf))
1667                 result |= 0x01;
1668         else /* if Tx not OK, ignore Rx */
1669                 return result;
1670
1671         u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1672                  ((reg_e9c & 0x3FF0000) >> 16);
1673         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1674
1675         /* 1 RX IQK */
1676         /* modify RXIQK mode table */
1677         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1678         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1679         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1680         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1681         /* LAN2 on, PA off for Dcut */
1682         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1683
1684         /* PA, PAD setting */
1685         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1686         rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1687
1688         /* IQK setting */
1689         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1690
1691         /* path-A IQK setting */
1692         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1693         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1694         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1695         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1696
1697         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1698         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1699         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1700         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1701
1702         /* LO calibration setting */
1703         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1704
1705         /* enter IQK mode */
1706         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1707
1708         /* One shot, path A LOK & IQK */
1709         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1710         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1711
1712         mdelay(IQK_DELAY_TIME);
1713
1714         /* leave IQK mode */
1715         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1716
1717         /* Check failed */
1718         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1719         reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1720
1721         /* leave IQK mode */
1722         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1723         rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1724
1725         /* Allen 20131125 */
1726         tmp = (reg_eac & 0x03FF0000) >> 16;
1727         if ((tmp & 0x200) > 0)
1728                 tmp = 0x400 - tmp;
1729         /* if Tx is OK, check whether Rx is OK */
1730         if (!(reg_eac & BIT(27)) &&
1731             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1732             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1733                 result |= 0x02;
1734         else if (!(reg_eac & BIT(27)) &&
1735                  (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1736                  (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1737                  (tmp < 0xf))
1738                 result |= 0x02;
1739
1740         return result;
1741 }
1742
1743 static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1744 {
1745         u32 reg_eac, reg_e94, reg_e9c, tmp;
1746         u8 result = 0x00;
1747
1748         /* leave IQK mode */
1749         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1750         /* switch to path B */
1751         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1752
1753         /* enable path B PA in TXIQK mode */
1754         rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1755         rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1756
1757         /* 1 Tx IQK */
1758         /* IQK setting */
1759         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1760         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1761         /* path-A IQK setting */
1762         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1763         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1764         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1765         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1766
1767         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1768         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1769         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1770         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1771
1772         /* LO calibration setting */
1773         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1774
1775         /* enter IQK mode */
1776         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1777
1778         /* One shot, path B LOK & IQK */
1779         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1780         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1781
1782         mdelay(IQK_DELAY_TIME);
1783
1784         /* leave IQK mode */
1785         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1786
1787         /* Check failed */
1788         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1789         reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1790         reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1791
1792         if (!(reg_eac & BIT(28)) &&
1793             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1794             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1795                 result |= 0x01;
1796         else
1797                 return result;
1798
1799         /* Allen 20131125 */
1800         tmp = (reg_e9c & 0x03FF0000) >> 16;
1801         if ((tmp & 0x200) > 0)
1802                 tmp = 0x400 - tmp;
1803
1804         if (!(reg_eac & BIT(28)) &&
1805             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1806             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1807             (tmp < 0xf))
1808                 result |= 0x01;
1809         else
1810                 return result;
1811
1812         return result;
1813 }
1814
1815 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1816 static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1817 {
1818         u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1819         u8 result = 0x00;
1820
1821         /* leave IQK mode */
1822         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1823         /* switch to path B */
1824         rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1825
1826         /* 1 Get TXIMR setting */
1827         /* modify RXIQK mode table */
1828         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1829         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1830         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1831         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1832
1833         /* open PA S1 & SMIXER */
1834         rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1835         rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1836
1837         /* IQK setting */
1838         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1839         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1840
1841         /* path-B IQK setting */
1842         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1843         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1844         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1845         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1846
1847         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1848         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1849         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1850         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1851
1852         /* LO calibration setting */
1853         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1854         /* enter IQK mode */
1855         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1856
1857         /* One shot, path B TXIQK @ RXIQK */
1858         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1859         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1860
1861         mdelay(IQK_DELAY_TIME);
1862
1863         /* leave IQK mode */
1864         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1865         /* Check failed */
1866         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1867         reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1868         reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1869
1870         if (!(reg_eac & BIT(28)) &&
1871             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1872             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1873                 result |= 0x01;
1874         else    /* if Tx not OK, ignore Rx */
1875                 return result;
1876
1877         /* Allen 20131125 */
1878         tmp = (reg_e9c & 0x03FF0000) >> 16;
1879         if ((tmp & 0x200) > 0)
1880                 tmp = 0x400 - tmp;
1881
1882         if (!(reg_eac & BIT(28)) &&
1883             (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1884             (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1885             (tmp < 0xf))
1886                 result |= 0x01;
1887         else
1888                 return result;
1889
1890         u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
1891                  ((reg_e9c & 0x3FF0000) >> 16);
1892         rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1893
1894         /* 1 RX IQK */
1895
1896         /* <20121009, Kordan> RF Mode = 3 */
1897         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1898         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1899         rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1900         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1901         rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1902         rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1903
1904         /* open PA S1 & close SMIXER */
1905         rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1906         rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1907
1908         /* IQK setting */
1909         rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1910
1911         /* path-B IQK setting */
1912         rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1913         rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1914         rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1915         rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1916
1917         rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1918         rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1919         rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1920         rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1921
1922         /* LO calibration setting */
1923         rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1924         /* enter IQK mode */
1925         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1926
1927         /* One shot, path B LOK & IQK */
1928         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1929         rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1930
1931         mdelay(IQK_DELAY_TIME);
1932
1933         /* leave IQK mode */
1934         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1935         /* Check failed */
1936         reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1937         reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1938
1939         /* Allen 20131125 */
1940         tmp = (reg_eac & 0x03FF0000) >> 16;
1941         if ((tmp & 0x200) > 0)
1942                 tmp = 0x400 - tmp;
1943
1944         /* if Tx is OK, check whether Rx is OK */
1945         if (!(reg_eac & BIT(27)) &&
1946             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1947             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1948                 result |= 0x02;
1949         else if (!(reg_eac & BIT(27)) &&
1950                  (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1951                  (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1952                  (tmp < 0xf))
1953                 result |= 0x02;
1954         else
1955                 return result;
1956
1957         return result;
1958 }
1959
1960 static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1961                                                   bool b_iqk_ok,
1962                                                   long result[][8],
1963                                                   u8 final_candidate,
1964                                                   bool btxonly)
1965 {
1966         u32 oldval_1, x, tx1_a, reg;
1967         long y, tx1_c;
1968
1969         if (final_candidate == 0xFF) {
1970                 return;
1971         } else if (b_iqk_ok) {
1972                 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1973                                           MASKDWORD) >> 22) & 0x3FF;
1974                 x = result[final_candidate][4];
1975                 if ((x & 0x00000200) != 0)
1976                         x = x | 0xFFFFFC00;
1977                 tx1_a = (x * oldval_1) >> 8;
1978                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1979                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1980                               ((x * oldval_1 >> 7) & 0x1));
1981                 y = result[final_candidate][5];
1982                 if ((y & 0x00000200) != 0)
1983                         y = y | 0xFFFFFC00;
1984                 tx1_c = (y * oldval_1) >> 8;
1985                 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1986                               ((tx1_c & 0x3C0) >> 6));
1987                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1988                               (tx1_c & 0x3F));
1989                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1990                               ((y * oldval_1 >> 7) & 0x1));
1991                 if (btxonly)
1992                         return;
1993                 reg = result[final_candidate][6];
1994                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1995                 reg = result[final_candidate][7] & 0x3F;
1996                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1997                 reg = (result[final_candidate][7] >> 6) & 0xF;
1998                 /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1999         }
2000 }
2001
2002 static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
2003                                               long result[][8], u8 c1, u8 c2)
2004 {
2005         u32 i, j, diff, simularity_bitmap, bound = 0;
2006
2007         u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2008         bool bresult = true; /* is2t = true*/
2009         s32 tmp1 = 0, tmp2 = 0;
2010
2011         bound = 8;
2012
2013         simularity_bitmap = 0;
2014
2015         for (i = 0; i < bound; i++) {
2016                 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2017                         if ((result[c1][i] & 0x00000200) != 0)
2018                                 tmp1 = result[c1][i] | 0xFFFFFC00;
2019                         else
2020                                 tmp1 = result[c1][i];
2021
2022                         if ((result[c2][i] & 0x00000200) != 0)
2023                                 tmp2 = result[c2][i] | 0xFFFFFC00;
2024                         else
2025                                 tmp2 = result[c2][i];
2026                 } else {
2027                         tmp1 = result[c1][i];
2028                         tmp2 = result[c2][i];
2029                 }
2030
2031                 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2032
2033                 if (diff > MAX_TOLERANCE) {
2034                         if ((i == 2 || i == 6) && !simularity_bitmap) {
2035                                 if (result[c1][i] + result[c1][i + 1] == 0)
2036                                         final_candidate[(i / 4)] = c2;
2037                                 else if (result[c2][i] + result[c2][i + 1] == 0)
2038                                         final_candidate[(i / 4)] = c1;
2039                                 else
2040                                         simularity_bitmap |= (1 << i);
2041                         } else
2042                                 simularity_bitmap |= (1 << i);
2043                 }
2044         }
2045
2046         if (simularity_bitmap == 0) {
2047                 for (i = 0; i < (bound / 4); i++) {
2048                         if (final_candidate[i] != 0xFF) {
2049                                 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2050                                         result[3][j] =
2051                                                 result[final_candidate[i]][j];
2052                                 bresult = false;
2053                         }
2054                 }
2055                 return bresult;
2056         } else {
2057                 if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
2058                         for (i = 0; i < 2; i++)
2059                                 result[3][i] = result[c1][i];
2060                 }
2061                 if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
2062                         for (i = 2; i < 4; i++)
2063                                 result[3][i] = result[c1][i];
2064                 }
2065                 if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
2066                         for (i = 4; i < 6; i++)
2067                                 result[3][i] = result[c1][i];
2068                 }
2069                 if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
2070                         for (i = 6; i < 8; i++)
2071                                 result[3][i] = result[c1][i];
2072                 }
2073                 return false;
2074         }
2075 }
2076
2077 static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2078                                         long result[][8], u8 t, bool is2t)
2079 {
2080         struct rtl_priv *rtlpriv = rtl_priv(hw);
2081         struct rtl_phy *rtlphy = &rtlpriv->phy;
2082         u32 i;
2083         u8 patha_ok, pathb_ok;
2084         u32 adda_reg[IQK_ADDA_REG_NUM] = {
2085                 0x85c, 0xe6c, 0xe70, 0xe74,
2086                 0xe78, 0xe7c, 0xe80, 0xe84,
2087                 0xe88, 0xe8c, 0xed0, 0xed4,
2088                 0xed8, 0xedc, 0xee0, 0xeec
2089         };
2090
2091         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2092                 0x522, 0x550, 0x551, 0x040
2093         };
2094         u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2095                 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2096                 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2097                 0x870, 0x860,
2098                 0x864, 0xa04
2099         };
2100         const u32 retrycount = 2;
2101
2102         u32 path_sel_bb;/* path_sel_rf */
2103
2104         u8 tmp_reg_c50, tmp_reg_c58;
2105
2106         tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2107         tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2108
2109         if (t == 0) {
2110                 rtl8723_save_adda_registers(hw, adda_reg,
2111                                             rtlphy->adda_backup, 16);
2112                 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2113                                                rtlphy->iqk_mac_backup);
2114                 rtl8723_save_adda_registers(hw, iqk_bb_reg,
2115                                             rtlphy->iqk_bb_backup,
2116                                             IQK_BB_REG_NUM);
2117         }
2118         rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2119         if (t == 0) {
2120                 rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2121                                                 RFPGA0_XA_HSSIPARAMETER1,
2122                                                 BIT(8));
2123         }
2124
2125         path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2126
2127         rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2128                                             rtlphy->iqk_mac_backup);
2129         /*BB Setting*/
2130         rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2131         rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2132         rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2133         rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2134
2135         /* path A TX IQK */
2136         for (i = 0; i < retrycount; i++) {
2137                 patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2138                 if (patha_ok == 0x01) {
2139                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2140                                 "Path A Tx IQK Success!!\n");
2141                         result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2142                                         0x3FF0000) >> 16;
2143                         result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2144                                         0x3FF0000) >> 16;
2145                         break;
2146                 } else {
2147                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2148                                  "Path A Tx IQK Fail!!\n");
2149                 }
2150         }
2151         /* path A RX IQK */
2152         for (i = 0; i < retrycount; i++) {
2153                 patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2154                 if (patha_ok == 0x03) {
2155                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2156                                  "Path A Rx IQK Success!!\n");
2157                         result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2158                                         0x3FF0000) >> 16;
2159                         result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2160                                         0x3FF0000) >> 16;
2161                         break;
2162                 }
2163                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2164                          "Path A Rx IQK Fail!!\n");
2165         }
2166
2167         if (0x00 == patha_ok)
2168                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2169
2170         if (is2t) {
2171                 /* path B TX IQK */
2172                 for (i = 0; i < retrycount; i++) {
2173                         pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2174                         if (pathb_ok == 0x01) {
2175                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2176                                          "Path B Tx IQK Success!!\n");
2177                                 result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2178                                                               MASKDWORD) &
2179                                                               0x3FF0000) >> 16;
2180                                 result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2181                                                               MASKDWORD) &
2182                                                               0x3FF0000) >> 16;
2183                                 break;
2184                         }
2185                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2186                                  "Path B Tx IQK Fail!!\n");
2187                 }
2188                 /* path B RX IQK */
2189                 for (i = 0; i < retrycount; i++) {
2190                         pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2191                         if (pathb_ok == 0x03) {
2192                                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2193                                          "Path B Rx IQK Success!!\n");
2194                                 result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2195                                                               MASKDWORD) &
2196                                                               0x3FF0000) >> 16;
2197                                 result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2198                                                               MASKDWORD) &
2199                                                               0x3FF0000) >> 16;
2200                                 break;
2201                         }
2202                         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2203                                  "Path B Rx IQK Fail!!\n");
2204                 }
2205         }
2206
2207         /* Back to BB mode, load original value */
2208         rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2209
2210         if (t != 0) {
2211                 rtl8723_phy_reload_adda_registers(hw, adda_reg,
2212                                                   rtlphy->adda_backup, 16);
2213                 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2214                                                  rtlphy->iqk_mac_backup);
2215                 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2216                                                   rtlphy->iqk_bb_backup,
2217                                                   IQK_BB_REG_NUM);
2218
2219                 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2220                 /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2221
2222                 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2223                 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2224                 if (is2t) {
2225                         rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2226                         rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2227                 }
2228                 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2229                 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2230         }
2231         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2232 }
2233
2234 static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2235 {
2236         u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2237                         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2238                         13, 14, 36, 38, 40, 42, 44, 46,
2239                         48, 50, 52, 54, 56, 58, 60, 62, 64,
2240                         100, 102, 104, 106, 108, 110,
2241                         112, 114, 116, 118, 120, 122,
2242                         124, 126, 128, 130, 132, 134, 136,
2243                         138, 140, 149, 151, 153, 155, 157,
2244                         159, 161, 163, 165};
2245         u8 place = chnl;
2246
2247         if (chnl > 14) {
2248                 for (place = 14; place < sizeof(channel_all); place++) {
2249                         if (channel_all[place] == chnl)
2250                                 return place - 13;
2251                 }
2252         }
2253         return 0;
2254 }
2255
2256 static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2257 {
2258         u8 tmpreg;
2259         u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2260         struct rtl_priv *rtlpriv = rtl_priv(hw);
2261
2262         tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2263
2264         if ((tmpreg & 0x70) != 0)
2265                 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2266         else
2267                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2268
2269         if ((tmpreg & 0x70) != 0) {
2270                 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2271
2272                 if (is2t)
2273                         rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2274                                                   MASK12BITS);
2275
2276                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2277                               (rf_a_mode & 0x8FFFF) | 0x10000);
2278
2279                 if (is2t)
2280                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2281                                       (rf_b_mode & 0x8FFFF) | 0x10000);
2282         }
2283         lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2284
2285         rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2286         rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2287
2288         /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2289         /*mdelay(100);*/
2290         /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2291         mdelay(50);
2292
2293         rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2294
2295         if ((tmpreg & 0x70) != 0) {
2296                 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2297                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2298
2299                 if (is2t)
2300                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2301                                       MASK12BITS, rf_b_mode);
2302         } else {
2303                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2304         }
2305         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
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 %#x not processed\n", iotype);
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 %#x not processed\n",
2558                          rtlphy->current_io_type);
2559                 break;
2560         }
2561         rtlphy->set_io_inprogress = false;
2562         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2563                  "(%#x)\n", rtlphy->current_io_type);
2564 }
2565
2566 static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2567 {
2568         struct rtl_priv *rtlpriv = rtl_priv(hw);
2569
2570         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2571         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2572         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2573         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2574         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2575 }
2576
2577 static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2578 {
2579         struct rtl_priv *rtlpriv = rtl_priv(hw);
2580
2581         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2582         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2583         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2584         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2585 }
2586
2587 static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2588                                               enum rf_pwrstate rfpwr_state)
2589 {
2590         struct rtl_priv *rtlpriv = rtl_priv(hw);
2591         struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2592         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2593         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2594         bool bresult = true;
2595         u8 i, queue_id;
2596         struct rtl8192_tx_ring *ring = NULL;
2597
2598         switch (rfpwr_state) {
2599         case ERFON:
2600                 if ((ppsc->rfpwr_state == ERFOFF) &&
2601                      RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2602                         bool rtstatus;
2603                         u32 initializecount = 0;
2604                         do {
2605                                 initializecount++;
2606                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2607                                          "IPS Set eRf nic enable\n");
2608                                 rtstatus = rtl_ps_enable_nic(hw);
2609                         } while (!rtstatus && (initializecount < 10));
2610                         RT_CLEAR_PS_LEVEL(ppsc, 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 %#x not processed\n", rfpwr_state);
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 }