]> Git Repo - linux.git/blob - drivers/net/wireless/rtlwifi/rtl8723ae/phy.c
selinux: Remove security_ops extern
[linux.git] / drivers / net / wireless / rtlwifi / rtl8723ae / phy.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2012  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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  * The full GNU General Public License is included in this distribution in the
19  * file called LICENSE.
20  *
21  * Contact Information:
22  * wlanfae <[email protected]>
23  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24  * Hsinchu 300, Taiwan.
25  *
26  * Larry Finger <[email protected]>
27  *
28  *****************************************************************************/
29
30 #include "../wifi.h"
31 #include "../pci.h"
32 #include "../ps.h"
33 #include "../core.h"
34 #include "reg.h"
35 #include "def.h"
36 #include "phy.h"
37 #include "rf.h"
38 #include "dm.h"
39 #include "table.h"
40 #include "../rtl8723com/phy_common.h"
41
42 /* static forward definitions */
43 static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
44                                   enum radio_path rfpath, u32 offset);
45 static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
46                                     enum radio_path rfpath,
47                                     u32 offset, u32 data);
48 static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
49 static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw);
50 static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype);
51 static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype);
52 static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
53                                       u8 *stage, u8 *step, u32 *delay);
54 static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
55                                 enum wireless_mode wirelessmode,
56                                 long power_indbm);
57 static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw);
58
59 u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
60                                enum radio_path rfpath, u32 regaddr, u32 bitmask)
61 {
62         struct rtl_priv *rtlpriv = rtl_priv(hw);
63         u32 original_value, readback_value, bitshift;
64         struct rtl_phy *rtlphy = &(rtlpriv->phy);
65         unsigned long flags;
66
67         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
68                  "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
69                  regaddr, rfpath, bitmask);
70
71         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
72
73         if (rtlphy->rf_mode != RF_OP_BY_FW)
74                 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
75         else
76                 original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr);
77
78         bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
79         readback_value = (original_value & bitmask) >> bitshift;
80
81         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
82
83         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
84                  "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
85                  regaddr, rfpath, bitmask, original_value);
86
87         return readback_value;
88 }
89
90 void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
91                               enum radio_path rfpath,
92                               u32 regaddr, u32 bitmask, u32 data)
93 {
94         struct rtl_priv *rtlpriv = rtl_priv(hw);
95         struct rtl_phy *rtlphy = &(rtlpriv->phy);
96         u32 original_value, bitshift;
97         unsigned long flags;
98
99         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
100                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
101                  regaddr, bitmask, data, rfpath);
102
103         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
104
105         if (rtlphy->rf_mode != RF_OP_BY_FW) {
106                 if (bitmask != RFREG_OFFSET_MASK) {
107                         original_value = rtl8723_phy_rf_serial_read(hw, rfpath,
108                                                                     regaddr);
109                         bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
110                         data = ((original_value & (~bitmask)) |
111                                (data << bitshift));
112                 }
113
114                 rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);
115         } else {
116                 if (bitmask != RFREG_OFFSET_MASK) {
117                         original_value = _phy_fw_rf_serial_read(hw, rfpath,
118                                                                 regaddr);
119                         bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
120                         data = ((original_value & (~bitmask)) |
121                                (data << bitshift));
122                 }
123                 _phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
124         }
125
126         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
127
128         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
129                  "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
130                  regaddr, bitmask, data, rfpath);
131 }
132
133 static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
134                                             enum radio_path rfpath, u32 offset)
135 {
136         RT_ASSERT(false, "deprecated!\n");
137         return 0;
138 }
139
140 static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
141                                     enum radio_path rfpath,
142                                     u32 offset, u32 data)
143 {
144         RT_ASSERT(false, "deprecated!\n");
145 }
146
147 static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw)
148 {
149         rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
150         rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
151         rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
152         rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
153         rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
154         rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
155         rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
156         rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
157         rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
158         rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
159 }
160
161 bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw)
162 {
163         struct rtl_priv *rtlpriv = rtl_priv(hw);
164         bool rtstatus = _phy_cfg_mac_w_header(hw);
165         rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
166         return rtstatus;
167 }
168
169 bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw)
170 {
171         bool rtstatus = true;
172         struct rtl_priv *rtlpriv = rtl_priv(hw);
173         u8 tmpu1b;
174         u8 reg_hwparafile = 1;
175
176         rtl8723_phy_init_bb_rf_reg_def(hw);
177
178         /* 1. 0x28[1] = 1 */
179         tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
180         udelay(2);
181         rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));
182         udelay(2);
183         /* 2. 0x29[7:0] = 0xFF */
184         rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);
185         udelay(2);
186
187         /* 3. 0x02[1:0] = 2b'11 */
188         tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
189         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b |
190                        FEN_BB_GLB_RSTn | FEN_BBRSTB));
191
192         /* 4. 0x25[6] = 0 */
193         tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);
194         rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6))));
195
196         /* 5. 0x24[20] = 0      Advised by SD3 Alex Wang. 2011.02.09. */
197         tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);
198         rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4))));
199
200         /* 6. 0x1f[7:0] = 0x07 */
201         rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);
202
203         if (reg_hwparafile == 1)
204                 rtstatus = _phy_bb8192c_config_parafile(hw);
205         return rtstatus;
206 }
207
208 bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw)
209 {
210         return rtl8723ae_phy_rf6052_config(hw);
211 }
212
213 static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
214 {
215         struct rtl_priv *rtlpriv = rtl_priv(hw);
216         struct rtl_phy *rtlphy = &(rtlpriv->phy);
217         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
218         bool rtstatus;
219
220         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
221         rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG);
222         if (rtstatus != true) {
223                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
224                 return false;
225         }
226
227         if (rtlphy->rf_type == RF_1T2R) {
228                 _rtl8723ae_phy_bb_config_1t(hw);
229                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
230         }
231         if (rtlefuse->autoload_failflag == false) {
232                 rtlphy->pwrgroup_cnt = 0;
233                 rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG);
234         }
235         if (rtstatus != true) {
236                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
237                 return false;
238         }
239         rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB);
240         if (rtstatus != true) {
241                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
242                 return false;
243         }
244         rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
245                                          RFPGA0_XA_HSSIPARAMETER2, 0x200));
246         return true;
247 }
248
249 static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw)
250 {
251         struct rtl_priv *rtlpriv = rtl_priv(hw);
252         u32 i;
253         u32 arraylength;
254         u32 *ptrarray;
255
256         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");
257         arraylength = RTL8723E_MACARRAYLENGTH;
258         ptrarray = RTL8723EMAC_ARRAY;
259
260         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
261                  "Img:RTL8192CEMAC_2T_ARRAY\n");
262         for (i = 0; i < arraylength; i = i + 2)
263                 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
264         return true;
265 }
266
267 static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype)
268 {
269         int i;
270         u32 *phy_regarray_table;
271         u32 *agctab_array_table;
272         u16 phy_reg_arraylen, agctab_arraylen;
273         struct rtl_priv *rtlpriv = rtl_priv(hw);
274
275         agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;
276         agctab_array_table = RTL8723EAGCTAB_1TARRAY;
277         phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;
278         phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
279         if (configtype == BASEBAND_CONFIG_PHY_REG) {
280                 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
281                         rtl_addr_delay(phy_regarray_table[i]);
282                         rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
283                                       phy_regarray_table[i + 1]);
284                         udelay(1);
285                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
286                                  "The phy_regarray_table[0] is %x"
287                                  " Rtl819XPHY_REGArray[1] is %x\n",
288                                  phy_regarray_table[i],
289                                  phy_regarray_table[i + 1]);
290                 }
291         } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
292                 for (i = 0; i < agctab_arraylen; i = i + 2) {
293                         rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
294                                       agctab_array_table[i + 1]);
295                         udelay(1);
296                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
297                                  "The agctab_array_table[0] is "
298                                  "%x Rtl819XPHY_REGArray[1] is %x\n",
299                                  agctab_array_table[i],
300                                  agctab_array_table[i + 1]);
301                 }
302         }
303         return true;
304 }
305
306 static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr,
307                                   u32 bitmask, u32 data)
308 {
309         struct rtl_priv *rtlpriv = rtl_priv(hw);
310         struct rtl_phy *rtlphy = &(rtlpriv->phy);
311
312         switch (regaddr) {
313         case RTXAGC_A_RATE18_06:
314                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data;
315                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
316                          "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
317                          rtlphy->pwrgroup_cnt,
318                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]);
319                 break;
320         case RTXAGC_A_RATE54_24:
321                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data;
322                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
323                          "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
324                          rtlphy->pwrgroup_cnt,
325                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]);
326                 break;
327         case RTXAGC_A_CCK1_MCS32:
328                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data;
329                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
330                          "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
331                          rtlphy->pwrgroup_cnt,
332                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]);
333                 break;
334         case RTXAGC_B_CCK11_A_CCK2_11:
335                 if (bitmask == 0xffffff00) {
336                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data;
337                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
338                                  "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
339                                  rtlphy->pwrgroup_cnt,
340                                  rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]);
341                 }
342                 if (bitmask == 0x000000ff) {
343                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data;
344                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
345                                  "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
346                                  rtlphy->pwrgroup_cnt,
347                                  rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]);
348                 }
349                 break;
350         case RTXAGC_A_MCS03_MCS00:
351                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data;
352                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
353                          "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
354                          rtlphy->pwrgroup_cnt,
355                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]);
356                 break;
357         case RTXAGC_A_MCS07_MCS04:
358                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data;
359                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
360                          "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
361                          rtlphy->pwrgroup_cnt,
362                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]);
363                 break;
364         case RTXAGC_A_MCS11_MCS08:
365                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data;
366                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
367                          "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
368                          rtlphy->pwrgroup_cnt,
369                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]);
370                 break;
371         case RTXAGC_A_MCS15_MCS12:
372                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data;
373                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
374                          "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
375                          rtlphy->pwrgroup_cnt,
376                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]);
377                 break;
378         case RTXAGC_B_RATE18_06:
379                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data;
380                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
381                          "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
382                          rtlphy->pwrgroup_cnt,
383                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]);
384                 break;
385         case RTXAGC_B_RATE54_24:
386                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data;
387                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
388                          "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
389                          rtlphy->pwrgroup_cnt,
390                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]);
391                 break;
392         case RTXAGC_B_CCK1_55_MCS32:
393                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data;
394                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
395                          "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
396                          rtlphy->pwrgroup_cnt,
397                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]);
398                 break;
399         case RTXAGC_B_MCS03_MCS00:
400                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data;
401                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
402                          "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
403                          rtlphy->pwrgroup_cnt,
404                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]);
405                 break;
406         case RTXAGC_B_MCS07_MCS04:
407                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data;
408                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
409                          "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
410                          rtlphy->pwrgroup_cnt,
411                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]);
412                 break;
413         case RTXAGC_B_MCS11_MCS08:
414                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data;
415                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
416                          "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
417                          rtlphy->pwrgroup_cnt,
418                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]);
419                 break;
420         case RTXAGC_B_MCS15_MCS12:
421                 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data;
422                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
423                          "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
424                          rtlphy->pwrgroup_cnt,
425                          rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]);
426                 rtlphy->pwrgroup_cnt++;
427                 break;
428         }
429 }
430
431 static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype)
432 {
433         struct rtl_priv *rtlpriv = rtl_priv(hw);
434         int i;
435         u32 *phy_regarray_table_pg;
436         u16 phy_regarray_pg_len;
437
438         phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;
439         phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;
440
441         if (configtype == BASEBAND_CONFIG_PHY_REG) {
442                 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
443                         rtl_addr_delay(phy_regarray_table_pg[i]);
444
445                         _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i],
446                                               phy_regarray_table_pg[i + 1],
447                                               phy_regarray_table_pg[i + 2]);
448                 }
449         } else {
450                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
451                          "configtype != BaseBand_Config_PHY_REG\n");
452         }
453         return true;
454 }
455
456 bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
457                                              enum radio_path rfpath)
458 {
459         struct rtl_priv *rtlpriv = rtl_priv(hw);
460         int i;
461         u32 *radioa_array_table;
462         u16 radioa_arraylen;
463
464         radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH;
465         radioa_array_table = RTL8723E_RADIOA_1TARRAY;
466
467         switch (rfpath) {
468         case RF90_PATH_A:
469                 for (i = 0; i < radioa_arraylen; i = i + 2) {
470                         rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
471                                         RFREG_OFFSET_MASK,
472                                         radioa_array_table[i + 1]);
473                 }
474                 break;
475         case RF90_PATH_B:
476                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
477                          "switch case not process\n");
478                 break;
479         case RF90_PATH_C:
480                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
481                          "switch case not process\n");
482                 break;
483         case RF90_PATH_D:
484                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
485                          "switch case not process\n");
486                 break;
487         }
488         return true;
489 }
490
491 void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
492 {
493         struct rtl_priv *rtlpriv = rtl_priv(hw);
494         struct rtl_phy *rtlphy = &(rtlpriv->phy);
495
496         rtlphy->default_initialgain[0] =
497             (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
498         rtlphy->default_initialgain[1] =
499             (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
500         rtlphy->default_initialgain[2] =
501             (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
502         rtlphy->default_initialgain[3] =
503             (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
504
505         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
506                  "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
507                   rtlphy->default_initialgain[0],
508                   rtlphy->default_initialgain[1],
509                   rtlphy->default_initialgain[2],
510                   rtlphy->default_initialgain[3]);
511
512         rtlphy->framesync = (u8) rtl_get_bbreg(hw,
513                                                ROFDM0_RXDETECTOR3, MASKBYTE0);
514         rtlphy->framesync_c34 = rtl_get_bbreg(hw,
515                                               ROFDM0_RXDETECTOR2, MASKDWORD);
516
517         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
518                  "Default framesync (0x%x) = 0x%x\n",
519                  ROFDM0_RXDETECTOR3, rtlphy->framesync);
520 }
521
522 void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
523 {
524         struct rtl_priv *rtlpriv = rtl_priv(hw);
525         struct rtl_phy *rtlphy = &(rtlpriv->phy);
526         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
527         u8 txpwr_level;
528         long txpwr_dbm;
529
530         txpwr_level = rtlphy->cur_cck_txpwridx;
531         txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level);
532         txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
533             rtlefuse->legacy_ht_txpowerdiff;
534         if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm)
535                 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
536                                                   txpwr_level);
537         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
538         if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) >
539             txpwr_dbm)
540                 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
541                                                          txpwr_level);
542         *powerlevel = txpwr_dbm;
543 }
544
545 static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
546                                          u8 *cckpowerlevel, u8 *ofdmpowerlevel)
547 {
548         struct rtl_priv *rtlpriv = rtl_priv(hw);
549         struct rtl_phy *rtlphy = &(rtlpriv->phy);
550         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
551         u8 index = (channel - 1);
552
553         cckpowerlevel[RF90_PATH_A] =
554             rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
555         cckpowerlevel[RF90_PATH_B] =
556             rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
557         if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
558                 ofdmpowerlevel[RF90_PATH_A] =
559                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
560                 ofdmpowerlevel[RF90_PATH_B] =
561                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
562         } else if (get_rf_type(rtlphy) == RF_2T2R) {
563                 ofdmpowerlevel[RF90_PATH_A] =
564                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
565                 ofdmpowerlevel[RF90_PATH_B] =
566                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
567         }
568 }
569
570 static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw,
571                                             u8 channel, u8 *cckpowerlevel,
572                                             u8 *ofdmpowerlevel)
573 {
574         struct rtl_priv *rtlpriv = rtl_priv(hw);
575         struct rtl_phy *rtlphy = &(rtlpriv->phy);
576
577         rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
578         rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
579 }
580
581 void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
582 {
583         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
584         u8 cckpowerlevel[2], ofdmpowerlevel[2];
585
586         if (rtlefuse->txpwr_fromeprom == false)
587                 return;
588         _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0],
589                                      &ofdmpowerlevel[0]);
590         _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
591                                         &ofdmpowerlevel[0]);
592         rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
593         rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
594 }
595
596 bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
597 {
598         struct rtl_priv *rtlpriv = rtl_priv(hw);
599         struct rtl_phy *rtlphy = &(rtlpriv->phy);
600         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
601         u8 idx;
602         u8 rf_path;
603         u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B,
604                                                power_indbm);
605         u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G,
606                                                 power_indbm);
607         if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
608                 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
609         else
610                 ofdmtxpwridx = 0;
611         RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
612                  "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
613                  power_indbm, ccktxpwridx, ofdmtxpwridx);
614         for (idx = 0; idx < 14; idx++) {
615                 for (rf_path = 0; rf_path < 2; rf_path++) {
616                         rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
617                         rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
618                                                             ofdmtxpwridx;
619                         rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
620                                                             ofdmtxpwridx;
621                 }
622         }
623         rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
624         return true;
625 }
626
627 static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
628                                 enum wireless_mode wirelessmode,
629                                 long power_indbm)
630 {
631         u8 txpwridx;
632         long offset;
633
634         switch (wirelessmode) {
635         case WIRELESS_MODE_B:
636                 offset = -7;
637                 break;
638         case WIRELESS_MODE_G:
639         case WIRELESS_MODE_N_24G:
640                 offset = -8;
641                 break;
642         default:
643                 offset = -8;
644                 break;
645         }
646
647         if ((power_indbm - offset) > 0)
648                 txpwridx = (u8) ((power_indbm - offset) * 2);
649         else
650                 txpwridx = 0;
651
652         if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
653                 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
654
655         return txpwridx;
656 }
657
658 void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
659 {
660         struct rtl_priv *rtlpriv = rtl_priv(hw);
661         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
662         struct rtl_phy *rtlphy = &(rtlpriv->phy);
663         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
664         u8 reg_bw_opmode;
665         u8 reg_prsr_rsc;
666
667         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
668                  "Switch to %s bandwidth\n",
669                  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
670                  "20MHz" : "40MHz");
671
672         if (is_hal_stop(rtlhal)) {
673                 rtlphy->set_bwmode_inprogress = false;
674                 return;
675         }
676
677         reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
678         reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
679
680         switch (rtlphy->current_chan_bw) {
681         case HT_CHANNEL_WIDTH_20:
682                 reg_bw_opmode |= BW_OPMODE_20MHZ;
683                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
684                 break;
685         case HT_CHANNEL_WIDTH_20_40:
686                 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
687                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
688                 reg_prsr_rsc =
689                     (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
690                 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
691                 break;
692         default:
693                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
694                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
695                 break;
696         }
697
698         switch (rtlphy->current_chan_bw) {
699         case HT_CHANNEL_WIDTH_20:
700                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
701                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
702                 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
703                 break;
704         case HT_CHANNEL_WIDTH_20_40:
705                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
706                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
707
708                 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
709                               (mac->cur_40_prime_sc >> 1));
710                 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
711                 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
712
713                 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
714                               (mac->cur_40_prime_sc ==
715                                HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
716                 break;
717         default:
718                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
719                          "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
720                 break;
721         }
722         rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
723         rtlphy->set_bwmode_inprogress = false;
724         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
725 }
726
727 void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
728                                enum nl80211_channel_type ch_type)
729 {
730         struct rtl_priv *rtlpriv = rtl_priv(hw);
731         struct rtl_phy *rtlphy = &(rtlpriv->phy);
732         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
733         u8 tmp_bw = rtlphy->current_chan_bw;
734
735         if (rtlphy->set_bwmode_inprogress)
736                 return;
737         rtlphy->set_bwmode_inprogress = true;
738         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
739                 rtl8723ae_phy_set_bw_mode_callback(hw);
740         } else {
741                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
742                          "FALSE driver sleep or unload\n");
743                 rtlphy->set_bwmode_inprogress = false;
744                 rtlphy->current_chan_bw = tmp_bw;
745         }
746 }
747
748 void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
749 {
750         struct rtl_priv *rtlpriv = rtl_priv(hw);
751         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
752         struct rtl_phy *rtlphy = &(rtlpriv->phy);
753         u32 delay;
754
755         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
756                  "switch to channel%d\n", rtlphy->current_channel);
757         if (is_hal_stop(rtlhal))
758                 return;
759         do {
760                 if (!rtlphy->sw_chnl_inprogress)
761                         break;
762                 if (!_phy_sw_chnl_step_by_step
763                     (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
764                      &rtlphy->sw_chnl_step, &delay)) {
765                         if (delay > 0)
766                                 mdelay(delay);
767                         else
768                                 continue;
769                 } else {
770                         rtlphy->sw_chnl_inprogress = false;
771                 }
772                 break;
773         } while (true);
774         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
775 }
776
777 u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw)
778 {
779         struct rtl_priv *rtlpriv = rtl_priv(hw);
780         struct rtl_phy *rtlphy = &(rtlpriv->phy);
781         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
782
783         if (rtlphy->sw_chnl_inprogress)
784                 return 0;
785         if (rtlphy->set_bwmode_inprogress)
786                 return 0;
787         RT_ASSERT((rtlphy->current_channel <= 14),
788                   "WIRELESS_MODE_G but channel>14");
789         rtlphy->sw_chnl_inprogress = true;
790         rtlphy->sw_chnl_stage = 0;
791         rtlphy->sw_chnl_step = 0;
792         if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
793                 rtl8723ae_phy_sw_chnl_callback(hw);
794                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
795                          "sw_chnl_inprogress false schedule workitem\n");
796                 rtlphy->sw_chnl_inprogress = false;
797         } else {
798                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
799                          "sw_chnl_inprogress false driver sleep or unload\n");
800                 rtlphy->sw_chnl_inprogress = false;
801         }
802         return 1;
803 }
804
805 static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
806 {
807         struct rtl_priv *rtlpriv = rtl_priv(hw);
808         struct rtl_phy *rtlphy = &(rtlpriv->phy);
809         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
810
811         if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
812                 if (channel == 6 && rtlphy->current_chan_bw ==
813                     HT_CHANNEL_WIDTH_20)
814                         rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
815                                       0x00255);
816                 else{
817                         u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A,
818                                            RF_RX_G1, RFREG_OFFSET_MASK);
819                         rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
820                                       backupRF0x1A);
821                 }
822         }
823 }
824
825 static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
826                                       u8 *stage, u8 *step, u32 *delay)
827 {
828         struct rtl_priv *rtlpriv = rtl_priv(hw);
829         struct rtl_phy *rtlphy = &(rtlpriv->phy);
830         struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
831         u32 precommoncmdcnt;
832         struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
833         u32 postcommoncmdcnt;
834         struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
835         u32 rfdependcmdcnt;
836         struct swchnlcmd *currentcmd = NULL;
837         u8 rfpath;
838         u8 num_total_rfpath = rtlphy->num_total_rfpath;
839
840         precommoncmdcnt = 0;
841         rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
842                                          MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL,
843                                          0, 0, 0);
844         rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
845                                          MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
846         postcommoncmdcnt = 0;
847
848         rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
849                                          MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
850         rfdependcmdcnt = 0;
851
852         RT_ASSERT((channel >= 1 && channel <= 14),
853                   "illegal channel for Zebra: %d\n", channel);
854
855         rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
856                                          MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
857                                   RF_CHNLBW, channel, 10);
858
859         rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
860                                          MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
861
862         do {
863                 switch (*stage) {
864                 case 0:
865                         currentcmd = &precommoncmd[*step];
866                         break;
867                 case 1:
868                         currentcmd = &rfdependcmd[*step];
869                         break;
870                 case 2:
871                         currentcmd = &postcommoncmd[*step];
872                         break;
873                 }
874
875                 if (currentcmd->cmdid == CMDID_END) {
876                         if ((*stage) == 2) {
877                                 return true;
878                         } else {
879                                 (*stage)++;
880                                 (*step) = 0;
881                                 continue;
882                         }
883                 }
884
885                 switch (currentcmd->cmdid) {
886                 case CMDID_SET_TXPOWEROWER_LEVEL:
887                         rtl8723ae_phy_set_txpower_level(hw, channel);
888                         break;
889                 case CMDID_WRITEPORT_ULONG:
890                         rtl_write_dword(rtlpriv, currentcmd->para1,
891                                         currentcmd->para2);
892                         break;
893                 case CMDID_WRITEPORT_USHORT:
894                         rtl_write_word(rtlpriv, currentcmd->para1,
895                                        (u16) currentcmd->para2);
896                         break;
897                 case CMDID_WRITEPORT_UCHAR:
898                         rtl_write_byte(rtlpriv, currentcmd->para1,
899                                        (u8) currentcmd->para2);
900                         break;
901                 case CMDID_RF_WRITEREG:
902                         for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
903                                 rtlphy->rfreg_chnlval[rfpath] =
904                                     ((rtlphy->rfreg_chnlval[rfpath] &
905                                       0xfffffc00) | currentcmd->para2);
906
907                                 rtl_set_rfreg(hw, (enum radio_path)rfpath,
908                                               currentcmd->para1,
909                                               RFREG_OFFSET_MASK,
910                                               rtlphy->rfreg_chnlval[rfpath]);
911                         }
912                         _rtl8723ae_phy_sw_rf_seting(hw, channel);
913                         break;
914                 default:
915                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
916                                  "switch case not process\n");
917                         break;
918                 }
919
920                 break;
921         } while (true);
922
923         (*delay) = currentcmd->msdelay;
924         (*step)++;
925         return false;
926 }
927
928 static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
929 {
930         u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
931         u8 result = 0x00;
932
933         rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
934         rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
935         rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
936         rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
937                       config_pathb ? 0x28160202 : 0x28160502);
938
939         if (config_pathb) {
940                 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
941                 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
942                 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
943                 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
944         }
945
946         rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
947         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
948         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
949
950         mdelay(IQK_DELAY_TIME);
951
952         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
953         reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
954         reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
955         reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
956
957         if (!(reg_eac & BIT(28)) &&
958             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
959             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
960                 result |= 0x01;
961         else
962                 return result;
963
964         if (!(reg_eac & BIT(27)) &&
965             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
966             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
967                 result |= 0x02;
968         return result;
969 }
970
971 static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw)
972 {
973         u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
974         u8 result = 0x00;
975
976         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
977         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
978         mdelay(IQK_DELAY_TIME);
979         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
980         reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
981         reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
982         reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
983         reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
984
985         if (!(reg_eac & BIT(31)) &&
986             (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
987             (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
988                 result |= 0x01;
989         else
990                 return result;
991         if (!(reg_eac & BIT(30)) &&
992             (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
993             (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
994                 result |= 0x02;
995         return result;
996 }
997
998 static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8],
999                                 u8 c1, u8 c2)
1000 {
1001         u32 i, j, diff, simularity_bitmap, bound;
1002
1003         u8 final_candidate[2] = { 0xFF, 0xFF };
1004         bool bresult = true;
1005
1006         bound = 4;
1007
1008         simularity_bitmap = 0;
1009
1010         for (i = 0; i < bound; i++) {
1011                 diff = (result[c1][i] > result[c2][i]) ?
1012                     (result[c1][i] - result[c2][i]) :
1013                     (result[c2][i] - result[c1][i]);
1014
1015                 if (diff > MAX_TOLERANCE) {
1016                         if ((i == 2 || i == 6) && !simularity_bitmap) {
1017                                 if (result[c1][i] + result[c1][i + 1] == 0)
1018                                         final_candidate[(i / 4)] = c2;
1019                                 else if (result[c2][i] + result[c2][i + 1] == 0)
1020                                         final_candidate[(i / 4)] = c1;
1021                                 else
1022                                         simularity_bitmap = simularity_bitmap |
1023                                             (1 << i);
1024                         } else
1025                                 simularity_bitmap =
1026                                     simularity_bitmap | (1 << i);
1027                 }
1028         }
1029
1030         if (simularity_bitmap == 0) {
1031                 for (i = 0; i < (bound / 4); i++) {
1032                         if (final_candidate[i] != 0xFF) {
1033                                 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1034                                         result[3][j] =
1035                                             result[final_candidate[i]][j];
1036                                 bresult = false;
1037                         }
1038                 }
1039                 return bresult;
1040         } else if (!(simularity_bitmap & 0x0F)) {
1041                 for (i = 0; i < 4; i++)
1042                         result[3][i] = result[c1][i];
1043                 return false;
1044         } else {
1045                 return false;
1046         }
1047
1048 }
1049
1050 static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1051                                         long result[][8], u8 t, bool is2t)
1052 {
1053         struct rtl_priv *rtlpriv = rtl_priv(hw);
1054         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1055         u32 i;
1056         u8 patha_ok, pathb_ok;
1057         u32 adda_reg[IQK_ADDA_REG_NUM] = {
1058                 0x85c, 0xe6c, 0xe70, 0xe74,
1059                 0xe78, 0xe7c, 0xe80, 0xe84,
1060                 0xe88, 0xe8c, 0xed0, 0xed4,
1061                 0xed8, 0xedc, 0xee0, 0xeec
1062         };
1063         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1064                 0x522, 0x550, 0x551, 0x040
1065         };
1066         const u32 retrycount = 2;
1067
1068         if (t == 0) {
1069                 rtl8723_save_adda_registers(hw, adda_reg, rtlphy->adda_backup,
1070                                             16);
1071                 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1072                                                rtlphy->iqk_mac_backup);
1073         }
1074         rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1075         if (t == 0) {
1076                 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1077                                                  RFPGA0_XA_HSSIPARAMETER1,
1078                                                  BIT(8));
1079         }
1080
1081         if (!rtlphy->rfpi_enable)
1082                 rtl8723_phy_pi_mode_switch(hw, true);
1083         if (t == 0) {
1084                 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1085                 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1086                 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1087         }
1088         rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1089         rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1090         rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1091         if (is2t) {
1092                 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1093                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1094         }
1095         rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1096                                             rtlphy->iqk_mac_backup);
1097         rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1098         if (is2t)
1099                 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1100         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1101         rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1102         rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1103         for (i = 0; i < retrycount; i++) {
1104                 patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t);
1105                 if (patha_ok == 0x03) {
1106                         result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1107                                         0x3FF0000) >> 16;
1108                         result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1109                                         0x3FF0000) >> 16;
1110                         result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1111                                         0x3FF0000) >> 16;
1112                         result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1113                                         0x3FF0000) >> 16;
1114                         break;
1115                 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1116
1117                         result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1118                                         MASKDWORD) & 0x3FF0000) >> 16;
1119                 result[t][1] =
1120                     (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1121
1122         }
1123
1124         if (is2t) {
1125                 rtl8723_phy_path_a_standby(hw);
1126                 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1127                 for (i = 0; i < retrycount; i++) {
1128                         pathb_ok = _rtl8723ae_phy_path_b_iqk(hw);
1129                         if (pathb_ok == 0x03) {
1130                                 result[t][4] =
1131                                     (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1132                                      0x3FF0000) >> 16;
1133                                 result[t][5] =
1134                                     (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1135                                      0x3FF0000) >> 16;
1136                                 result[t][6] =
1137                                     (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1138                                      0x3FF0000) >> 16;
1139                                 result[t][7] =
1140                                     (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1141                                      0x3FF0000) >> 16;
1142                                 break;
1143                         } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1144                                 result[t][4] =
1145                                     (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1146                                      0x3FF0000) >> 16;
1147                         }
1148                         result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1149                                         0x3FF0000) >> 16;
1150                 }
1151         }
1152         rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1153         rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1154         rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1155         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1156         rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1157         if (is2t)
1158                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1159         if (t != 0) {
1160                 if (!rtlphy->rfpi_enable)
1161                         rtl8723_phy_pi_mode_switch(hw, false);
1162                 rtl8723_phy_reload_adda_registers(hw, adda_reg,
1163                                                   rtlphy->adda_backup, 16);
1164                 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1165                                                  rtlphy->iqk_mac_backup);
1166         }
1167 }
1168
1169 static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1170 {
1171         struct rtl_priv *rtlpriv = rtl_priv(hw);
1172         u8 tmpreg;
1173         u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1174
1175         tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1176
1177         if ((tmpreg & 0x70) != 0)
1178                 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1179         else
1180                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1181
1182         if ((tmpreg & 0x70) != 0) {
1183                 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1184
1185                 if (is2t)
1186                         rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1187                                                   MASK12BITS);
1188
1189                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1190                               (rf_a_mode & 0x8FFFF) | 0x10000);
1191
1192                 if (is2t)
1193                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1194                                       (rf_b_mode & 0x8FFFF) | 0x10000);
1195         }
1196         lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1197
1198         rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1199
1200         mdelay(100);
1201
1202         if ((tmpreg & 0x70) != 0) {
1203                 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1204                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1205
1206                 if (is2t)
1207                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1208                                       rf_b_mode);
1209         } else {
1210                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1211         }
1212 }
1213
1214 static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1215                                              bool bmain, bool is2t)
1216 {
1217         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1218
1219         if (is_hal_stop(rtlhal)) {
1220                 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1221                 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1222         }
1223         if (is2t) {
1224                 if (bmain)
1225                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1226                                       BIT(5) | BIT(6), 0x1);
1227                 else
1228                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1229                                       BIT(5) | BIT(6), 0x2);
1230         } else {
1231                 if (bmain)
1232                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1233                 else
1234                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1235
1236         }
1237 }
1238
1239 #undef IQK_ADDA_REG_NUM
1240 #undef IQK_DELAY_TIME
1241
1242 void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1243 {
1244         struct rtl_priv *rtlpriv = rtl_priv(hw);
1245         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1246         long result[4][8];
1247         u8 i, final_candidate;
1248         bool patha_ok, pathb_ok;
1249         long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_tmp = 0;
1250         bool is12simular, is13simular, is23simular;
1251         bool start_conttx = false, singletone = false;
1252         u32 iqk_bb_reg[10] = {
1253                 ROFDM0_XARXIQIMBALANCE,
1254                 ROFDM0_XBRXIQIMBALANCE,
1255                 ROFDM0_ECCATHRESHOLD,
1256                 ROFDM0_AGCRSSITABLE,
1257                 ROFDM0_XATXIQIMBALANCE,
1258                 ROFDM0_XBTXIQIMBALANCE,
1259                 ROFDM0_XCTXIQIMBALANCE,
1260                 ROFDM0_XCTXAFE,
1261                 ROFDM0_XDTXAFE,
1262                 ROFDM0_RXIQEXTANTA
1263         };
1264
1265         if (recovery) {
1266                 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1267                                                   rtlphy->iqk_bb_backup, 10);
1268                 return;
1269         }
1270         if (start_conttx || singletone)
1271                 return;
1272         for (i = 0; i < 8; i++) {
1273                 result[0][i] = 0;
1274                 result[1][i] = 0;
1275                 result[2][i] = 0;
1276                 result[3][i] = 0;
1277         }
1278         final_candidate = 0xff;
1279         patha_ok = false;
1280         pathb_ok = false;
1281         is12simular = false;
1282         is23simular = false;
1283         is13simular = false;
1284         for (i = 0; i < 3; i++) {
1285                 _rtl8723ae_phy_iq_calibrate(hw, result, i, false);
1286                 if (i == 1) {
1287                         is12simular = phy_simularity_comp(hw, result, 0, 1);
1288                         if (is12simular) {
1289                                 final_candidate = 0;
1290                                 break;
1291                         }
1292                 }
1293                 if (i == 2) {
1294                         is13simular = phy_simularity_comp(hw, result, 0, 2);
1295                         if (is13simular) {
1296                                 final_candidate = 0;
1297                                 break;
1298                         }
1299                         is23simular = phy_simularity_comp(hw, result, 1, 2);
1300                         if (is23simular) {
1301                                 final_candidate = 1;
1302                         } else {
1303                                 for (i = 0; i < 8; i++)
1304                                         reg_tmp += result[3][i];
1305
1306                                 if (reg_tmp != 0)
1307                                         final_candidate = 3;
1308                                 else
1309                                         final_candidate = 0xFF;
1310                         }
1311                 }
1312         }
1313         for (i = 0; i < 4; i++) {
1314                 reg_e94 = result[i][0];
1315                 reg_e9c = result[i][1];
1316                 reg_ea4 = result[i][2];
1317                 reg_eb4 = result[i][4];
1318                 reg_ebc = result[i][5];
1319         }
1320         if (final_candidate != 0xff) {
1321                 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1322                 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1323                 reg_ea4 = result[final_candidate][2];
1324                 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1325                 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1326                 patha_ok = pathb_ok = true;
1327         } else {
1328                 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1329                 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1330         }
1331         if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1332                 rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1333                                                    final_candidate,
1334                                                    (reg_ea4 == 0));
1335         rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
1336 }
1337
1338 void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw)
1339 {
1340         bool start_conttx = false, singletone = false;
1341
1342         if (start_conttx || singletone)
1343                 return;
1344         _rtl8723ae_phy_lc_calibrate(hw, false);
1345 }
1346
1347 void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1348 {
1349         _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false);
1350 }
1351
1352 bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1353 {
1354         struct rtl_priv *rtlpriv = rtl_priv(hw);
1355         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1356         bool postprocessing = false;
1357
1358         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1359                  "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1360                  iotype, rtlphy->set_io_inprogress);
1361         do {
1362                 switch (iotype) {
1363                 case IO_CMD_RESUME_DM_BY_SCAN:
1364                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1365                                  "[IO CMD] Resume DM after scan.\n");
1366                         postprocessing = true;
1367                         break;
1368                 case IO_CMD_PAUSE_DM_BY_SCAN:
1369                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1370                                  "[IO CMD] Pause DM before scan.\n");
1371                         postprocessing = true;
1372                         break;
1373                 default:
1374                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1375                                  "switch case not process\n");
1376                         break;
1377                 }
1378         } while (false);
1379         if (postprocessing && !rtlphy->set_io_inprogress) {
1380                 rtlphy->set_io_inprogress = true;
1381                 rtlphy->current_io_type = iotype;
1382         } else {
1383                 return false;
1384         }
1385         rtl8723ae_phy_set_io(hw);
1386         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
1387         return true;
1388 }
1389
1390 static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw)
1391 {
1392         struct rtl_priv *rtlpriv = rtl_priv(hw);
1393         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1394         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1395
1396         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1397                  "--->Cmd(%#x), set_io_inprogress(%d)\n",
1398                  rtlphy->current_io_type, rtlphy->set_io_inprogress);
1399         switch (rtlphy->current_io_type) {
1400         case IO_CMD_RESUME_DM_BY_SCAN:
1401                 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1402                 rtl8723ae_dm_write_dig(hw);
1403                 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
1404                 break;
1405         case IO_CMD_PAUSE_DM_BY_SCAN:
1406                 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1407                 dm_digtable->cur_igvalue = 0x17;
1408                 rtl8723ae_dm_write_dig(hw);
1409                 break;
1410         default:
1411                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1412                          "switch case not process\n");
1413                 break;
1414         }
1415         rtlphy->set_io_inprogress = false;
1416         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1417                  "<---(%#x)\n", rtlphy->current_io_type);
1418 }
1419
1420 static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw)
1421 {
1422         struct rtl_priv *rtlpriv = rtl_priv(hw);
1423
1424         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1425         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1426         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1427         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1428         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1429         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1430 }
1431
1432 static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw)
1433 {
1434         struct rtl_priv *rtlpriv = rtl_priv(hw);
1435         u32 u4b_tmp;
1436         u8 delay = 5;
1437
1438         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1439         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1440         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1441         u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1442         while (u4b_tmp != 0 && delay > 0) {
1443                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1444                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1445                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1446                 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1447                 delay--;
1448         }
1449         if (delay == 0) {
1450                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1451                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1452                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1453                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1454                 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1455                          "Switch RF timeout !!!.\n");
1456                 return;
1457         }
1458         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1459         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1460 }
1461
1462 static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
1463                                               enum rf_pwrstate rfpwr_state)
1464 {
1465         struct rtl_priv *rtlpriv = rtl_priv(hw);
1466         struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1467         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1468         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1469         struct rtl8192_tx_ring *ring = NULL;
1470         bool bresult = true;
1471         u8 i, queue_id;
1472
1473         switch (rfpwr_state) {
1474         case ERFON:
1475                 if ((ppsc->rfpwr_state == ERFOFF) &&
1476                     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
1477                         bool rtstatus;
1478                         u32 InitializeCount = 0;
1479                         do {
1480                                 InitializeCount++;
1481                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1482                                          "IPS Set eRf nic enable\n");
1483                                 rtstatus = rtl_ps_enable_nic(hw);
1484                         } while ((rtstatus != true) && (InitializeCount < 10));
1485                         RT_CLEAR_PS_LEVEL(ppsc,
1486                                           RT_RF_OFF_LEVL_HALT_NIC);
1487                 } else {
1488                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1489                                  "Set ERFON sleeped:%d ms\n",
1490                                  jiffies_to_msecs(jiffies -
1491                                  ppsc->last_sleep_jiffies));
1492                         ppsc->last_awake_jiffies = jiffies;
1493                         rtl8723ae_phy_set_rf_on(hw);
1494                 }
1495                 if (mac->link_state == MAC80211_LINKED) {
1496                         rtlpriv->cfg->ops->led_control(hw,
1497                                         LED_CTL_LINK);
1498                 } else {
1499                         rtlpriv->cfg->ops->led_control(hw,
1500                                         LED_CTL_NO_LINK);
1501                 }
1502                 break;
1503         case ERFOFF:
1504                 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
1505                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1506                                  "IPS Set eRf nic disable\n");
1507                         rtl_ps_disable_nic(hw);
1508                         RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1509                 } else {
1510                         if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
1511                                 rtlpriv->cfg->ops->led_control(hw,
1512                                         LED_CTL_NO_LINK);
1513                         } else {
1514                                 rtlpriv->cfg->ops->led_control(hw,
1515                                         LED_CTL_POWER_OFF);
1516                         }
1517                 }
1518                 break;
1519         case ERFSLEEP:
1520                 if (ppsc->rfpwr_state == ERFOFF)
1521                         break;
1522                 for (queue_id = 0, i = 0;
1523                      queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
1524                         ring = &pcipriv->dev.tx_ring[queue_id];
1525                         if (skb_queue_len(&ring->queue) == 0) {
1526                                 queue_id++;
1527                                 continue;
1528                         } else {
1529                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1530                                          "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
1531                                          (i + 1), queue_id,
1532                                          skb_queue_len(&ring->queue));
1533
1534                                 udelay(10);
1535                                 i++;
1536                         }
1537                         if (i >= MAX_DOZE_WAITING_TIMES_9x) {
1538                                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1539                                          "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
1540                                          MAX_DOZE_WAITING_TIMES_9x,
1541                                          queue_id,
1542                                          skb_queue_len(&ring->queue));
1543                                 break;
1544                         }
1545                 }
1546                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1547                          "Set ERFSLEEP awaked:%d ms\n",
1548                          jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
1549                 ppsc->last_sleep_jiffies = jiffies;
1550                 _rtl8723ae_phy_set_rf_sleep(hw);
1551                 break;
1552         default:
1553                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1554                          "switch case not processed\n");
1555                 bresult = false;
1556                 break;
1557         }
1558         if (bresult)
1559                 ppsc->rfpwr_state = rfpwr_state;
1560         return bresult;
1561 }
1562
1563 bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
1564                                       enum rf_pwrstate rfpwr_state)
1565 {
1566         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1567         bool bresult = false;
1568
1569         if (rfpwr_state == ppsc->rfpwr_state)
1570                 return bresult;
1571         bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state);
1572         return bresult;
1573 }
This page took 0.132562 seconds and 4 git commands to generate.