]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
rtl8192c_common: Update copyright dates
[mv-sheeva.git] / drivers / net / wireless / rtlwifi / rtl8192c / phy_common.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 <wlanfae@realtek.com>
23  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24  * Hsinchu 300, Taiwan.
25  *
26  * Larry Finger <Larry.Finger@lwfinger.net>
27  *
28  *****************************************************************************/
29
30 #include <linux/export.h>
31 #include "../wifi.h"
32 #include "../rtl8192ce/reg.h"
33 #include "../rtl8192ce/def.h"
34 #include "dm_common.h"
35 #include "phy_common.h"
36
37 /* Define macro to shorten lines */
38 #define MCS_TXPWR       mcs_txpwrlevel_origoffset
39
40 u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
41 {
42         struct rtl_priv *rtlpriv = rtl_priv(hw);
43         u32 returnvalue, originalvalue, bitshift;
44
45         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
46                  regaddr, bitmask);
47         originalvalue = rtl_read_dword(rtlpriv, regaddr);
48         bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
49         returnvalue = (originalvalue & bitmask) >> bitshift;
50
51         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
52                  "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
53                  bitmask, regaddr, originalvalue);
54
55         return returnvalue;
56
57 }
58 EXPORT_SYMBOL(rtl92c_phy_query_bb_reg);
59
60 void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
61                            u32 regaddr, u32 bitmask, u32 data)
62 {
63         struct rtl_priv *rtlpriv = rtl_priv(hw);
64         u32 originalvalue, bitshift;
65
66         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
67                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
68                  regaddr, bitmask, data);
69
70         if (bitmask != MASKDWORD) {
71                 originalvalue = rtl_read_dword(rtlpriv, regaddr);
72                 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
73                 data = ((originalvalue & (~bitmask)) | (data << bitshift));
74         }
75
76         rtl_write_dword(rtlpriv, regaddr, data);
77
78         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
79                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
80                  regaddr, bitmask, data);
81
82 }
83 EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
84
85 u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
86                                   enum radio_path rfpath, u32 offset)
87 {
88         RT_ASSERT(false, "deprecated!\n");
89         return 0;
90
91 }
92 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read);
93
94 void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
95                                     enum radio_path rfpath, u32 offset,
96                                     u32 data)
97 {
98         RT_ASSERT(false, "deprecated!\n");
99 }
100 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
101
102 u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
103                                enum radio_path rfpath, u32 offset)
104 {
105         struct rtl_priv *rtlpriv = rtl_priv(hw);
106         struct rtl_phy *rtlphy = &(rtlpriv->phy);
107         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
108         u32 newoffset;
109         u32 tmplong, tmplong2;
110         u8 rfpi_enable = 0;
111         u32 retvalue;
112
113         offset &= 0x3f;
114         newoffset = offset;
115         if (RT_CANNOT_IO(hw)) {
116                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
117                 return 0xFFFFFFFF;
118         }
119         tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
120         if (rfpath == RF90_PATH_A)
121                 tmplong2 = tmplong;
122         else
123                 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
124         tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
125             (newoffset << 23) | BLSSIREADEDGE;
126         rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
127                       tmplong & (~BLSSIREADEDGE));
128         mdelay(1);
129         rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
130         mdelay(1);
131         rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
132                       tmplong | BLSSIREADEDGE);
133         mdelay(1);
134         if (rfpath == RF90_PATH_A)
135                 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
136                                                  BIT(8));
137         else if (rfpath == RF90_PATH_B)
138                 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
139                                                  BIT(8));
140         if (rfpi_enable)
141                 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
142                                          BLSSIREADBACKDATA);
143         else
144                 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
145                                          BLSSIREADBACKDATA);
146         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
147                  rfpath, pphyreg->rflssi_readback, retvalue);
148         return retvalue;
149 }
150 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
151
152 void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
153                                  enum radio_path rfpath, u32 offset,
154                                  u32 data)
155 {
156         u32 data_and_addr;
157         u32 newoffset;
158         struct rtl_priv *rtlpriv = rtl_priv(hw);
159         struct rtl_phy *rtlphy = &(rtlpriv->phy);
160         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
161
162         if (RT_CANNOT_IO(hw)) {
163                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
164                 return;
165         }
166         offset &= 0x3f;
167         newoffset = offset;
168         data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
169         rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
170         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
171                  rfpath, pphyreg->rf3wire_offset, data_and_addr);
172 }
173 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write);
174
175 u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
176 {
177         u32 i;
178
179         for (i = 0; i <= 31; i++) {
180                 if (((bitmask >> i) & 0x1) == 1)
181                         break;
182         }
183         return i;
184 }
185 EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift);
186
187 static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
188 {
189         rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
190         rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
191         rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
192         rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
193         rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
194         rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
195         rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
196         rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
197         rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
198         rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
199 }
200
201 bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
202 {
203         struct rtl_priv *rtlpriv = rtl_priv(hw);
204
205         return rtlpriv->cfg->ops->phy_rf6052_config(hw);
206 }
207 EXPORT_SYMBOL(rtl92c_phy_rf_config);
208
209 bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
210 {
211         struct rtl_priv *rtlpriv = rtl_priv(hw);
212         struct rtl_phy *rtlphy = &(rtlpriv->phy);
213         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
214         bool rtstatus;
215
216         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
217         rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
218                                                  BASEBAND_CONFIG_PHY_REG);
219         if (rtstatus != true) {
220                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
221                 return false;
222         }
223         if (rtlphy->rf_type == RF_1T2R) {
224                 _rtl92c_phy_bb_config_1t(hw);
225                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
226         }
227         if (rtlefuse->autoload_failflag == false) {
228                 rtlphy->pwrgroup_cnt = 0;
229                 rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw,
230                                                    BASEBAND_CONFIG_PHY_REG);
231         }
232         if (rtstatus != true) {
233                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
234                 return false;
235         }
236         rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
237                                                  BASEBAND_CONFIG_AGC_TAB);
238         if (rtstatus != true) {
239                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
240                 return false;
241         }
242         rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
243                                                 RFPGA0_XA_HSSIPARAMETER2,
244                                                 0x200));
245
246         return true;
247 }
248 EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile);
249
250 void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
251                                             u32 regaddr, u32 bitmask,
252                                             u32 data)
253 {
254         struct rtl_priv *rtlpriv = rtl_priv(hw);
255         struct rtl_phy *rtlphy = &(rtlpriv->phy);
256
257         if (regaddr == RTXAGC_A_RATE18_06) {
258                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data;
259                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
260                          "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
261                          rtlphy->pwrgroup_cnt,
262                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]);
263         }
264         if (regaddr == RTXAGC_A_RATE54_24) {
265                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data;
266                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
267                          "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
268                          rtlphy->pwrgroup_cnt,
269                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]);
270         }
271         if (regaddr == RTXAGC_A_CCK1_MCS32) {
272                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data;
273                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
274                          "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
275                          rtlphy->pwrgroup_cnt,
276                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]);
277         }
278         if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
279                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data;
280                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
281                          "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
282                          rtlphy->pwrgroup_cnt,
283                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]);
284         }
285         if (regaddr == RTXAGC_A_MCS03_MCS00) {
286                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data;
287                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
288                          "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
289                          rtlphy->pwrgroup_cnt,
290                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]);
291         }
292         if (regaddr == RTXAGC_A_MCS07_MCS04) {
293                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data;
294                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
295                          "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
296                          rtlphy->pwrgroup_cnt,
297                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]);
298         }
299         if (regaddr == RTXAGC_A_MCS11_MCS08) {
300                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data;
301                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
302                          "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
303                          rtlphy->pwrgroup_cnt,
304                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]);
305         }
306         if (regaddr == RTXAGC_A_MCS15_MCS12) {
307                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data;
308                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
309                          "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
310                          rtlphy->pwrgroup_cnt,
311                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]);
312         }
313         if (regaddr == RTXAGC_B_RATE18_06) {
314                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data;
315                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
316                          "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
317                          rtlphy->pwrgroup_cnt,
318                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]);
319         }
320         if (regaddr == RTXAGC_B_RATE54_24) {
321                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
322                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
323                          "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
324                          rtlphy->pwrgroup_cnt,
325                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]);
326         }
327         if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
328                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
329                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
330                          "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
331                          rtlphy->pwrgroup_cnt,
332                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]);
333         }
334         if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
335                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
336                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
337                          "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
338                          rtlphy->pwrgroup_cnt,
339                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]);
340         }
341         if (regaddr == RTXAGC_B_MCS03_MCS00) {
342                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
343                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
344                          "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
345                          rtlphy->pwrgroup_cnt,
346                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]);
347         }
348         if (regaddr == RTXAGC_B_MCS07_MCS04) {
349                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
350                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
351                          "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
352                          rtlphy->pwrgroup_cnt,
353                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]);
354         }
355         if (regaddr == RTXAGC_B_MCS11_MCS08) {
356                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
357                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
358                          "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
359                          rtlphy->pwrgroup_cnt,
360                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]);
361         }
362         if (regaddr == RTXAGC_B_MCS15_MCS12) {
363                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
364                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
365                          "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
366                          rtlphy->pwrgroup_cnt,
367                          rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]);
368
369                 rtlphy->pwrgroup_cnt++;
370         }
371 }
372 EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset);
373
374 void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
375 {
376         struct rtl_priv *rtlpriv = rtl_priv(hw);
377         struct rtl_phy *rtlphy = &(rtlpriv->phy);
378
379         rtlphy->default_initialgain[0] =
380             (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
381         rtlphy->default_initialgain[1] =
382             (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
383         rtlphy->default_initialgain[2] =
384             (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
385         rtlphy->default_initialgain[3] =
386             (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
387
388         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
389                  "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
390                  rtlphy->default_initialgain[0],
391                  rtlphy->default_initialgain[1],
392                  rtlphy->default_initialgain[2],
393                  rtlphy->default_initialgain[3]);
394
395         rtlphy->framesync = (u8) rtl_get_bbreg(hw,
396                                                ROFDM0_RXDETECTOR3, MASKBYTE0);
397         rtlphy->framesync_c34 = rtl_get_bbreg(hw,
398                                               ROFDM0_RXDETECTOR2, MASKDWORD);
399
400         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
401                  "Default framesync (0x%x) = 0x%x\n",
402                  ROFDM0_RXDETECTOR3, rtlphy->framesync);
403 }
404
405 void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
406 {
407         struct rtl_priv *rtlpriv = rtl_priv(hw);
408         struct rtl_phy *rtlphy = &(rtlpriv->phy);
409
410         rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
411         rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
412         rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
413         rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
414
415         rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
416         rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
417         rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
418         rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
419
420         rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
421         rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
422
423         rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
424         rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
425
426         rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
427             RFPGA0_XA_LSSIPARAMETER;
428         rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
429             RFPGA0_XB_LSSIPARAMETER;
430
431         rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
432         rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
433         rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
434         rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
435
436         rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
437         rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
438         rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
439         rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
440
441         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
442         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
443
444         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
445         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
446
447         rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
448             RFPGA0_XAB_SWITCHCONTROL;
449         rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
450             RFPGA0_XAB_SWITCHCONTROL;
451         rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
452             RFPGA0_XCD_SWITCHCONTROL;
453         rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
454             RFPGA0_XCD_SWITCHCONTROL;
455
456         rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
457         rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
458         rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
459         rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
460
461         rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
462         rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
463         rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
464         rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
465
466         rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
467             ROFDM0_XARXIQIMBALANCE;
468         rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
469             ROFDM0_XBRXIQIMBALANCE;
470         rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
471             ROFDM0_XCRXIQIMBANLANCE;
472         rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
473             ROFDM0_XDRXIQIMBALANCE;
474
475         rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
476         rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
477         rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
478         rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
479
480         rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
481             ROFDM0_XATXIQIMBALANCE;
482         rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
483             ROFDM0_XBTXIQIMBALANCE;
484         rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
485             ROFDM0_XCTXIQIMBALANCE;
486         rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
487             ROFDM0_XDTXIQIMBALANCE;
488
489         rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
490         rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
491         rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
492         rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
493
494         rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
495             RFPGA0_XA_LSSIREADBACK;
496         rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
497             RFPGA0_XB_LSSIREADBACK;
498         rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
499             RFPGA0_XC_LSSIREADBACK;
500         rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
501             RFPGA0_XD_LSSIREADBACK;
502
503         rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
504             TRANSCEIVEA_HSPI_READBACK;
505         rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
506             TRANSCEIVEB_HSPI_READBACK;
507
508 }
509 EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition);
510
511 void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
512 {
513         struct rtl_priv *rtlpriv = rtl_priv(hw);
514         struct rtl_phy *rtlphy = &(rtlpriv->phy);
515         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
516         u8 txpwr_level;
517         long txpwr_dbm;
518
519         txpwr_level = rtlphy->cur_cck_txpwridx;
520         txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw,
521                                                  WIRELESS_MODE_B, txpwr_level);
522         txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
523             rtlefuse->legacy_ht_txpowerdiff;
524         if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
525                                          WIRELESS_MODE_G,
526                                          txpwr_level) > txpwr_dbm)
527                 txpwr_dbm =
528                     _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
529                                                  txpwr_level);
530         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
531         if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
532                                          WIRELESS_MODE_N_24G,
533                                          txpwr_level) > txpwr_dbm)
534                 txpwr_dbm =
535                     _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
536                                                  txpwr_level);
537         *powerlevel = txpwr_dbm;
538 }
539
540 static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
541                                       u8 *cckpowerlevel, u8 *ofdmpowerlevel)
542 {
543         struct rtl_priv *rtlpriv = rtl_priv(hw);
544         struct rtl_phy *rtlphy = &(rtlpriv->phy);
545         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
546         u8 index = (channel - 1);
547
548         cckpowerlevel[RF90_PATH_A] =
549             rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
550         cckpowerlevel[RF90_PATH_B] =
551             rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
552         if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
553                 ofdmpowerlevel[RF90_PATH_A] =
554                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
555                 ofdmpowerlevel[RF90_PATH_B] =
556                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
557         } else if (get_rf_type(rtlphy) == RF_2T2R) {
558                 ofdmpowerlevel[RF90_PATH_A] =
559                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
560                 ofdmpowerlevel[RF90_PATH_B] =
561                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
562         }
563 }
564
565 static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
566                                          u8 channel, u8 *cckpowerlevel,
567                                          u8 *ofdmpowerlevel)
568 {
569         struct rtl_priv *rtlpriv = rtl_priv(hw);
570         struct rtl_phy *rtlphy = &(rtlpriv->phy);
571
572         rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
573         rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
574
575 }
576
577 void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
578 {
579         struct rtl_priv *rtlpriv = rtl_priv(hw);
580         struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
581         u8 cckpowerlevel[2], ofdmpowerlevel[2];
582
583         if (rtlefuse->txpwr_fromeprom == false)
584                 return;
585         _rtl92c_get_txpower_index(hw, channel,
586                                   &cckpowerlevel[0], &ofdmpowerlevel[0]);
587         _rtl92c_ccxpower_index_check(hw,
588                                      channel, &cckpowerlevel[0],
589                                      &ofdmpowerlevel[0]);
590         rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
591         rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0],
592                                                        channel);
593 }
594 EXPORT_SYMBOL(rtl92c_phy_set_txpower_level);
595
596 bool rtl92c_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 = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
604                                                       WIRELESS_MODE_B,
605                                                       power_indbm);
606         u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
607                                                        WIRELESS_MODE_N_24G,
608                                                        power_indbm);
609         if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
610                 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
611         else
612                 ofdmtxpwridx = 0;
613         RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
614                  "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
615                  power_indbm, ccktxpwridx, ofdmtxpwridx);
616         for (idx = 0; idx < 14; idx++) {
617                 for (rf_path = 0; rf_path < 2; rf_path++) {
618                         rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
619                         rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
620                             ofdmtxpwridx;
621                         rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
622                             ofdmtxpwridx;
623                 }
624         }
625         rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
626         return true;
627 }
628 EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm);
629
630 u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
631                                 enum wireless_mode wirelessmode,
632                                 long power_indbm)
633 {
634         u8 txpwridx;
635         long offset;
636
637         switch (wirelessmode) {
638         case WIRELESS_MODE_B:
639                 offset = -7;
640                 break;
641         case WIRELESS_MODE_G:
642         case WIRELESS_MODE_N_24G:
643                 offset = -8;
644                 break;
645         default:
646                 offset = -8;
647                 break;
648         }
649
650         if ((power_indbm - offset) > 0)
651                 txpwridx = (u8) ((power_indbm - offset) * 2);
652         else
653                 txpwridx = 0;
654
655         if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
656                 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
657
658         return txpwridx;
659 }
660 EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_Idx);
661
662 long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
663                                   enum wireless_mode wirelessmode,
664                                   u8 txpwridx)
665 {
666         long offset;
667         long pwrout_dbm;
668
669         switch (wirelessmode) {
670         case WIRELESS_MODE_B:
671                 offset = -7;
672                 break;
673         case WIRELESS_MODE_G:
674         case WIRELESS_MODE_N_24G:
675                 offset = -8;
676                 break;
677         default:
678                 offset = -8;
679                 break;
680         }
681         pwrout_dbm = txpwridx / 2 + offset;
682         return pwrout_dbm;
683 }
684 EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm);
685
686 void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
687 {
688         struct rtl_priv *rtlpriv = rtl_priv(hw);
689         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
690         enum io_type iotype;
691
692         if (!is_hal_stop(rtlhal)) {
693                 switch (operation) {
694                 case SCAN_OPT_BACKUP:
695                         iotype = IO_CMD_PAUSE_DM_BY_SCAN;
696                         rtlpriv->cfg->ops->set_hw_reg(hw,
697                                                       HW_VAR_IO_CMD,
698                                                       (u8 *)&iotype);
699
700                         break;
701                 case SCAN_OPT_RESTORE:
702                         iotype = IO_CMD_RESUME_DM_BY_SCAN;
703                         rtlpriv->cfg->ops->set_hw_reg(hw,
704                                                       HW_VAR_IO_CMD,
705                                                       (u8 *)&iotype);
706                         break;
707                 default:
708                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
709                                  "Unknown Scan Backup operation\n");
710                         break;
711                 }
712         }
713 }
714 EXPORT_SYMBOL(rtl92c_phy_scan_operation_backup);
715
716 void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
717                             enum nl80211_channel_type ch_type)
718 {
719         struct rtl_priv *rtlpriv = rtl_priv(hw);
720         struct rtl_phy *rtlphy = &(rtlpriv->phy);
721         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
722         u8 tmp_bw = rtlphy->current_chan_bw;
723
724         if (rtlphy->set_bwmode_inprogress)
725                 return;
726         rtlphy->set_bwmode_inprogress = true;
727         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
728                 rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
729         } else {
730                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
731                          "FALSE driver sleep or unload\n");
732                 rtlphy->set_bwmode_inprogress = false;
733                 rtlphy->current_chan_bw = tmp_bw;
734         }
735 }
736 EXPORT_SYMBOL(rtl92c_phy_set_bw_mode);
737
738 void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
739 {
740         struct rtl_priv *rtlpriv = rtl_priv(hw);
741         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
742         struct rtl_phy *rtlphy = &(rtlpriv->phy);
743         u32 delay;
744
745         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
746                  "switch to channel%d\n", rtlphy->current_channel);
747         if (is_hal_stop(rtlhal))
748                 return;
749         do {
750                 if (!rtlphy->sw_chnl_inprogress)
751                         break;
752                 if (!_rtl92c_phy_sw_chnl_step_by_step
753                     (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
754                      &rtlphy->sw_chnl_step, &delay)) {
755                         if (delay > 0)
756                                 mdelay(delay);
757                         else
758                                 continue;
759                 } else {
760                         rtlphy->sw_chnl_inprogress = false;
761                 }
762                 break;
763         } while (true);
764         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
765 }
766 EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback);
767
768 u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
769 {
770         struct rtl_priv *rtlpriv = rtl_priv(hw);
771         struct rtl_phy *rtlphy = &(rtlpriv->phy);
772         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
773
774         if (rtlphy->sw_chnl_inprogress)
775                 return 0;
776         if (rtlphy->set_bwmode_inprogress)
777                 return 0;
778         RT_ASSERT((rtlphy->current_channel <= 14),
779                   "WIRELESS_MODE_G but channel>14\n");
780         rtlphy->sw_chnl_inprogress = true;
781         rtlphy->sw_chnl_stage = 0;
782         rtlphy->sw_chnl_step = 0;
783         if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
784                 rtl92c_phy_sw_chnl_callback(hw);
785                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
786                          "sw_chnl_inprogress false schdule workitem\n");
787                 rtlphy->sw_chnl_inprogress = false;
788         } else {
789                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
790                          "sw_chnl_inprogress false driver sleep or unload\n");
791                 rtlphy->sw_chnl_inprogress = false;
792         }
793         return 1;
794 }
795 EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
796
797 static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
798                                              u32 cmdtableidx, u32 cmdtablesz,
799                                              enum swchnlcmd_id cmdid,
800                                              u32 para1, u32 para2, u32 msdelay)
801 {
802         struct swchnlcmd *pcmd;
803
804         if (cmdtable == NULL) {
805                 RT_ASSERT(false, "cmdtable cannot be NULL\n");
806                 return false;
807         }
808
809         if (cmdtableidx >= cmdtablesz)
810                 return false;
811
812         pcmd = cmdtable + cmdtableidx;
813         pcmd->cmdid = cmdid;
814         pcmd->para1 = para1;
815         pcmd->para2 = para2;
816         pcmd->msdelay = msdelay;
817         return true;
818 }
819
820 bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
821                                       u8 channel, u8 *stage, u8 *step,
822                                       u32 *delay)
823 {
824         struct rtl_priv *rtlpriv = rtl_priv(hw);
825         struct rtl_phy *rtlphy = &(rtlpriv->phy);
826         struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
827         u32 precommoncmdcnt;
828         struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
829         u32 postcommoncmdcnt;
830         struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
831         u32 rfdependcmdcnt;
832         struct swchnlcmd *currentcmd = NULL;
833         u8 rfpath;
834         u8 num_total_rfpath = rtlphy->num_total_rfpath;
835
836         precommoncmdcnt = 0;
837         _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
838                                          MAX_PRECMD_CNT,
839                                          CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
840         _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
841                                          MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
842
843         postcommoncmdcnt = 0;
844
845         _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
846                                          MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
847
848         rfdependcmdcnt = 0;
849
850         RT_ASSERT((channel >= 1 && channel <= 14),
851                   "invalid channel for Zebra: %d\n", channel);
852
853         _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
854                                          MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
855                                          RF_CHNLBW, channel, 10);
856
857         _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
858                                          MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
859                                          0);
860
861         do {
862                 switch (*stage) {
863                 case 0:
864                         currentcmd = &precommoncmd[*step];
865                         break;
866                 case 1:
867                         currentcmd = &rfdependcmd[*step];
868                         break;
869                 case 2:
870                         currentcmd = &postcommoncmd[*step];
871                         break;
872                 }
873
874                 if (currentcmd->cmdid == CMDID_END) {
875                         if ((*stage) == 2) {
876                                 return true;
877                         } else {
878                                 (*stage)++;
879                                 (*step) = 0;
880                                 continue;
881                         }
882                 }
883
884                 switch (currentcmd->cmdid) {
885                 case CMDID_SET_TXPOWEROWER_LEVEL:
886                         rtl92c_phy_set_txpower_level(hw, channel);
887                         break;
888                 case CMDID_WRITEPORT_ULONG:
889                         rtl_write_dword(rtlpriv, currentcmd->para1,
890                                         currentcmd->para2);
891                         break;
892                 case CMDID_WRITEPORT_USHORT:
893                         rtl_write_word(rtlpriv, currentcmd->para1,
894                                        (u16) currentcmd->para2);
895                         break;
896                 case CMDID_WRITEPORT_UCHAR:
897                         rtl_write_byte(rtlpriv, currentcmd->para1,
898                                        (u8) currentcmd->para2);
899                         break;
900                 case CMDID_RF_WRITEREG:
901                         for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
902                                 rtlphy->rfreg_chnlval[rfpath] =
903                                     ((rtlphy->rfreg_chnlval[rfpath] &
904                                       0xfffffc00) | currentcmd->para2);
905
906                                 rtl_set_rfreg(hw, (enum radio_path)rfpath,
907                                               currentcmd->para1,
908                                               RFREG_OFFSET_MASK,
909                                               rtlphy->rfreg_chnlval[rfpath]);
910                         }
911                         break;
912                 default:
913                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
914                                  "switch case not processed\n");
915                         break;
916                 }
917
918                 break;
919         } while (true);
920
921         (*delay) = currentcmd->msdelay;
922         (*step)++;
923         return false;
924 }
925
926 bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
927 {
928         return true;
929 }
930 EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath);
931
932 static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
933 {
934         u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
935         u8 result = 0x00;
936
937         rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
938         rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
939         rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
940         rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
941                       config_pathb ? 0x28160202 : 0x28160502);
942
943         if (config_pathb) {
944                 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
945                 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
946                 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
947                 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
948         }
949
950         rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
951         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
952         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
953
954         mdelay(IQK_DELAY_TIME);
955
956         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
957         reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
958         reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
959         reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
960
961         if (!(reg_eac & BIT(28)) &&
962             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
963             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
964                 result |= 0x01;
965         else
966                 return result;
967
968         if (!(reg_eac & BIT(27)) &&
969             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
970             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
971                 result |= 0x02;
972         return result;
973 }
974
975 static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
976 {
977         u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
978         u8 result = 0x00;
979
980         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
981         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
982         mdelay(IQK_DELAY_TIME);
983         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
984         reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
985         reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
986         reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
987         reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
988
989         if (!(reg_eac & BIT(31)) &&
990             (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
991             (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
992                 result |= 0x01;
993         else
994                 return result;
995         if (!(reg_eac & BIT(30)) &&
996             (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
997             (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
998                 result |= 0x02;
999         return result;
1000 }
1001
1002 static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
1003                                                bool iqk_ok, long result[][8],
1004                                                u8 final_candidate, bool btxonly)
1005 {
1006         u32 oldval_0, x, tx0_a, reg;
1007         long y, tx0_c;
1008
1009         if (final_candidate == 0xFF) {
1010                 return;
1011         } else if (iqk_ok) {
1012                 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1013                                           MASKDWORD) >> 22) & 0x3FF;
1014                 x = result[final_candidate][0];
1015                 if ((x & 0x00000200) != 0)
1016                         x = x | 0xFFFFFC00;
1017                 tx0_a = (x * oldval_0) >> 8;
1018                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1019                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1020                               ((x * oldval_0 >> 7) & 0x1));
1021                 y = result[final_candidate][1];
1022                 if ((y & 0x00000200) != 0)
1023                         y = y | 0xFFFFFC00;
1024                 tx0_c = (y * oldval_0) >> 8;
1025                 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1026                               ((tx0_c & 0x3C0) >> 6));
1027                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1028                               (tx0_c & 0x3F));
1029                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1030                               ((y * oldval_0 >> 7) & 0x1));
1031                 if (btxonly)
1032                         return;
1033                 reg = result[final_candidate][2];
1034                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1035                 reg = result[final_candidate][3] & 0x3F;
1036                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1037                 reg = (result[final_candidate][3] >> 6) & 0xF;
1038                 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1039         }
1040 }
1041
1042 static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1043                                                bool iqk_ok, long result[][8],
1044                                                u8 final_candidate, bool btxonly)
1045 {
1046         u32 oldval_1, x, tx1_a, reg;
1047         long y, tx1_c;
1048
1049         if (final_candidate == 0xFF) {
1050                 return;
1051         } else if (iqk_ok) {
1052                 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1053                                           MASKDWORD) >> 22) & 0x3FF;
1054                 x = result[final_candidate][4];
1055                 if ((x & 0x00000200) != 0)
1056                         x = x | 0xFFFFFC00;
1057                 tx1_a = (x * oldval_1) >> 8;
1058                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1059                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1060                               ((x * oldval_1 >> 7) & 0x1));
1061                 y = result[final_candidate][5];
1062                 if ((y & 0x00000200) != 0)
1063                         y = y | 0xFFFFFC00;
1064                 tx1_c = (y * oldval_1) >> 8;
1065                 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1066                               ((tx1_c & 0x3C0) >> 6));
1067                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1068                               (tx1_c & 0x3F));
1069                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1070                               ((y * oldval_1 >> 7) & 0x1));
1071                 if (btxonly)
1072                         return;
1073                 reg = result[final_candidate][6];
1074                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1075                 reg = result[final_candidate][7] & 0x3F;
1076                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1077                 reg = (result[final_candidate][7] >> 6) & 0xF;
1078                 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
1079         }
1080 }
1081
1082 static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw,
1083                                             u32 *addareg, u32 *addabackup,
1084                                             u32 registernum)
1085 {
1086         u32 i;
1087
1088         for (i = 0; i < registernum; i++)
1089                 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1090 }
1091
1092 static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw,
1093                                            u32 *macreg, u32 *macbackup)
1094 {
1095         struct rtl_priv *rtlpriv = rtl_priv(hw);
1096         u32 i;
1097
1098         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1099                 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1100         macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1101 }
1102
1103 static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw,
1104                                               u32 *addareg, u32 *addabackup,
1105                                               u32 regiesternum)
1106 {
1107         u32 i;
1108
1109         for (i = 0; i < regiesternum; i++)
1110                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1111 }
1112
1113 static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw,
1114                                              u32 *macreg, u32 *macbackup)
1115 {
1116         struct rtl_priv *rtlpriv = rtl_priv(hw);
1117         u32 i;
1118
1119         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1120                 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1121         rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1122 }
1123
1124 static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw,
1125                                      u32 *addareg, bool is_patha_on, bool is2t)
1126 {
1127         u32 pathOn;
1128         u32 i;
1129
1130         pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1131         if (false == is2t) {
1132                 pathOn = 0x0bdb25a0;
1133                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1134         } else {
1135                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1136         }
1137
1138         for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1139                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1140 }
1141
1142 static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1143                                                 u32 *macreg, u32 *macbackup)
1144 {
1145         struct rtl_priv *rtlpriv = rtl_priv(hw);
1146         u32 i;
1147
1148         rtl_write_byte(rtlpriv, macreg[0], 0x3F);
1149
1150         for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1151                 rtl_write_byte(rtlpriv, macreg[i],
1152                                (u8) (macbackup[i] & (~BIT(3))));
1153         rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1154 }
1155
1156 static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw)
1157 {
1158         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1159         rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1160         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1161 }
1162
1163 static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1164 {
1165         u32 mode;
1166
1167         mode = pi_mode ? 0x01000100 : 0x01000000;
1168         rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1169         rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1170 }
1171
1172 static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw,
1173                                            long result[][8], u8 c1, u8 c2)
1174 {
1175         u32 i, j, diff, simularity_bitmap, bound;
1176         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1177
1178         u8 final_candidate[2] = { 0xFF, 0xFF };
1179         bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1180
1181         if (is2t)
1182                 bound = 8;
1183         else
1184                 bound = 4;
1185
1186         simularity_bitmap = 0;
1187
1188         for (i = 0; i < bound; i++) {
1189                 diff = (result[c1][i] > result[c2][i]) ?
1190                     (result[c1][i] - result[c2][i]) :
1191                     (result[c2][i] - result[c1][i]);
1192
1193                 if (diff > MAX_TOLERANCE) {
1194                         if ((i == 2 || i == 6) && !simularity_bitmap) {
1195                                 if (result[c1][i] + result[c1][i + 1] == 0)
1196                                         final_candidate[(i / 4)] = c2;
1197                                 else if (result[c2][i] + result[c2][i + 1] == 0)
1198                                         final_candidate[(i / 4)] = c1;
1199                                 else
1200                                         simularity_bitmap = simularity_bitmap |
1201                                             (1 << i);
1202                         } else
1203                                 simularity_bitmap =
1204                                     simularity_bitmap | (1 << i);
1205                 }
1206         }
1207
1208         if (simularity_bitmap == 0) {
1209                 for (i = 0; i < (bound / 4); i++) {
1210                         if (final_candidate[i] != 0xFF) {
1211                                 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1212                                         result[3][j] =
1213                                             result[final_candidate[i]][j];
1214                                 bresult = false;
1215                         }
1216                 }
1217                 return bresult;
1218         } else if (!(simularity_bitmap & 0x0F)) {
1219                 for (i = 0; i < 4; i++)
1220                         result[3][i] = result[c1][i];
1221                 return false;
1222         } else if (!(simularity_bitmap & 0xF0) && is2t) {
1223                 for (i = 4; i < 8; i++)
1224                         result[3][i] = result[c1][i];
1225                 return false;
1226         } else {
1227                 return false;
1228         }
1229
1230 }
1231
1232 static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1233                                      long result[][8], u8 t, bool is2t)
1234 {
1235         struct rtl_priv *rtlpriv = rtl_priv(hw);
1236         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1237         u32 i;
1238         u8 patha_ok, pathb_ok;
1239         u32 adda_reg[IQK_ADDA_REG_NUM] = {
1240                 0x85c, 0xe6c, 0xe70, 0xe74,
1241                 0xe78, 0xe7c, 0xe80, 0xe84,
1242                 0xe88, 0xe8c, 0xed0, 0xed4,
1243                 0xed8, 0xedc, 0xee0, 0xeec
1244         };
1245
1246         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1247                 0x522, 0x550, 0x551, 0x040
1248         };
1249
1250         const u32 retrycount = 2;
1251
1252         if (t == 0) {
1253                 /* dummy read */
1254                 rtl_get_bbreg(hw, 0x800, MASKDWORD);
1255
1256                 _rtl92c_phy_save_adda_registers(hw, adda_reg,
1257                                                 rtlphy->adda_backup, 16);
1258                 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1259                                                rtlphy->iqk_mac_backup);
1260         }
1261         _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1262         if (t == 0) {
1263                 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1264                                                    RFPGA0_XA_HSSIPARAMETER1,
1265                                                    BIT(8));
1266         }
1267
1268         if (!rtlphy->rfpi_enable)
1269                 _rtl92c_phy_pi_mode_switch(hw, true);
1270         if (t == 0) {
1271                 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1272                 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1273                 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1274         }
1275         rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1276         rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1277         rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1278         if (is2t) {
1279                 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1280                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1281         }
1282         _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg,
1283                                             rtlphy->iqk_mac_backup);
1284         rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1285         if (is2t)
1286                 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1287         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1288         rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1289         rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1290         for (i = 0; i < retrycount; i++) {
1291                 patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t);
1292                 if (patha_ok == 0x03) {
1293                         result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1294                                         0x3FF0000) >> 16;
1295                         result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1296                                         0x3FF0000) >> 16;
1297                         result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1298                                         0x3FF0000) >> 16;
1299                         result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1300                                         0x3FF0000) >> 16;
1301                         break;
1302                 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1303
1304                         result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1305                                                       MASKDWORD) & 0x3FF0000) >>
1306                             16;
1307                 result[t][1] =
1308                     (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1309
1310         }
1311
1312         if (is2t) {
1313                 _rtl92c_phy_path_a_standby(hw);
1314                 _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t);
1315                 for (i = 0; i < retrycount; i++) {
1316                         pathb_ok = _rtl92c_phy_path_b_iqk(hw);
1317                         if (pathb_ok == 0x03) {
1318                                 result[t][4] = (rtl_get_bbreg(hw,
1319                                                       0xeb4,
1320                                                       MASKDWORD) &
1321                                                 0x3FF0000) >> 16;
1322                                 result[t][5] =
1323                                     (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1324                                      0x3FF0000) >> 16;
1325                                 result[t][6] =
1326                                     (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1327                                      0x3FF0000) >> 16;
1328                                 result[t][7] =
1329                                     (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1330                                      0x3FF0000) >> 16;
1331                                 break;
1332                         } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1333                                 result[t][4] = (rtl_get_bbreg(hw,
1334                                                       0xeb4,
1335                                                       MASKDWORD) &
1336                                                 0x3FF0000) >> 16;
1337                         }
1338                         result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1339                                         0x3FF0000) >> 16;
1340                 }
1341         }
1342         rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1343         rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1344         rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1345         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1346         rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1347         if (is2t)
1348                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1349         if (t != 0) {
1350                 if (!rtlphy->rfpi_enable)
1351                         _rtl92c_phy_pi_mode_switch(hw, false);
1352                 _rtl92c_phy_reload_adda_registers(hw, adda_reg,
1353                                                   rtlphy->adda_backup, 16);
1354                 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1355                                                  rtlphy->iqk_mac_backup);
1356         }
1357 }
1358
1359 static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
1360                                      char delta, bool is2t)
1361 {
1362 #if 0 /* This routine is deliberately dummied out for later fixes */
1363         struct rtl_priv *rtlpriv = rtl_priv(hw);
1364         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1365         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1366
1367         u32 reg_d[PATH_NUM];
1368         u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound;
1369
1370         u32 bb_backup[APK_BB_REG_NUM];
1371         u32 bb_reg[APK_BB_REG_NUM] = {
1372                 0x904, 0xc04, 0x800, 0xc08, 0x874
1373         };
1374         u32 bb_ap_mode[APK_BB_REG_NUM] = {
1375                 0x00000020, 0x00a05430, 0x02040000,
1376                 0x000800e4, 0x00204000
1377         };
1378         u32 bb_normal_ap_mode[APK_BB_REG_NUM] = {
1379                 0x00000020, 0x00a05430, 0x02040000,
1380                 0x000800e4, 0x22204000
1381         };
1382
1383         u32 afe_backup[APK_AFE_REG_NUM];
1384         u32 afe_reg[APK_AFE_REG_NUM] = {
1385                 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78,
1386                 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
1387                 0xed0, 0xed4, 0xed8, 0xedc, 0xee0,
1388                 0xeec
1389         };
1390
1391         u32 mac_backup[IQK_MAC_REG_NUM];
1392         u32 mac_reg[IQK_MAC_REG_NUM] = {
1393                 0x522, 0x550, 0x551, 0x040
1394         };
1395
1396         u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1397                 {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
1398                 {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
1399         };
1400
1401         u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1402                 {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c},
1403                 {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
1404         };
1405
1406         u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1407                 {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
1408                 {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
1409         };
1410
1411         u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1412                 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a},
1413                 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
1414         };
1415
1416         u32 afe_on_off[PATH_NUM] = {
1417                 0x04db25a4, 0x0b1b25a4
1418         };
1419
1420         const u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
1421
1422         u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 };
1423
1424         u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 };
1425
1426         u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 };
1427
1428         const char apk_delta_mapping[APK_BB_REG_NUM][13] = {
1429                 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1430                 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1431                 {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1432                 {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1433                 {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
1434         };
1435
1436         const u32 apk_normal_setting_value_1[13] = {
1437                 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
1438                 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
1439                 0x12680000, 0x00880000, 0x00880000
1440         };
1441
1442         const u32 apk_normal_setting_value_2[16] = {
1443                 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
1444                 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
1445                 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
1446                 0x00050006
1447         };
1448
1449         u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
1450
1451         long bb_offset, delta_v, delta_offset;
1452
1453         if (!is2t)
1454                 pathbound = 1;
1455
1456         return;
1457
1458         for (index = 0; index < PATH_NUM; index++) {
1459                 apk_offset[index] = apk_normal_offset[index];
1460                 apk_value[index] = apk_normal_value[index];
1461                 afe_on_off[index] = 0x6fdb25a4;
1462         }
1463
1464         for (index = 0; index < APK_BB_REG_NUM; index++) {
1465                 for (path = 0; path < pathbound; path++) {
1466                         apk_rf_init_value[path][index] =
1467                             apk_normal_rf_init_value[path][index];
1468                         apk_rf_value_0[path][index] =
1469                             apk_normal_rf_value_0[path][index];
1470                 }
1471                 bb_ap_mode[index] = bb_normal_ap_mode[index];
1472
1473                 apkbound = 6;
1474         }
1475
1476         for (index = 0; index < APK_BB_REG_NUM; index++) {
1477                 if (index == 0)
1478                         continue;
1479                 bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD);
1480         }
1481
1482         _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup);
1483
1484         _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16);
1485
1486         for (path = 0; path < pathbound; path++) {
1487                 if (path == RF90_PATH_A) {
1488                         offset = 0xb00;
1489                         for (index = 0; index < 11; index++) {
1490                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1491                                               apk_normal_setting_value_1
1492                                               [index]);
1493
1494                                 offset += 0x04;
1495                         }
1496
1497                         rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
1498
1499                         offset = 0xb68;
1500                         for (; index < 13; index++) {
1501                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1502                                               apk_normal_setting_value_1
1503                                               [index]);
1504
1505                                 offset += 0x04;
1506                         }
1507
1508                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
1509
1510                         offset = 0xb00;
1511                         for (index = 0; index < 16; index++) {
1512                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1513                                               apk_normal_setting_value_2
1514                                               [index]);
1515
1516                                 offset += 0x04;
1517                         }
1518                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1519                 } else if (path == RF90_PATH_B) {
1520                         offset = 0xb70;
1521                         for (index = 0; index < 10; index++) {
1522                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1523                                               apk_normal_setting_value_1
1524                                               [index]);
1525
1526                                 offset += 0x04;
1527                         }
1528                         rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000);
1529                         rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
1530
1531                         offset = 0xb68;
1532                         index = 11;
1533                         for (; index < 13; index++) {
1534                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1535                                               apk_normal_setting_value_1
1536                                               [index]);
1537
1538                                 offset += 0x04;
1539                         }
1540
1541                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
1542
1543                         offset = 0xb60;
1544                         for (index = 0; index < 16; index++) {
1545                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1546                                               apk_normal_setting_value_2
1547                                               [index]);
1548
1549                                 offset += 0x04;
1550                         }
1551                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1552                 }
1553
1554                 reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path,
1555                                             0xd, MASKDWORD);
1556
1557                 for (index = 0; index < APK_AFE_REG_NUM; index++)
1558                         rtl_set_bbreg(hw, afe_reg[index], MASKDWORD,
1559                                       afe_on_off[path]);
1560
1561                 if (path == RF90_PATH_A) {
1562                         for (index = 0; index < APK_BB_REG_NUM; index++) {
1563                                 if (index == 0)
1564                                         continue;
1565                                 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD,
1566                                               bb_ap_mode[index]);
1567                         }
1568                 }
1569
1570                 _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup);
1571
1572                 if (path == 0) {
1573                         rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000);
1574                 } else {
1575                         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD,
1576                                       0x10000);
1577                         rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
1578                                       0x1000f);
1579                         rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
1580                                       0x20103);
1581                 }
1582
1583                 delta_offset = ((delta + 14) / 2);
1584                 if (delta_offset < 0)
1585                         delta_offset = 0;
1586                 else if (delta_offset > 12)
1587                         delta_offset = 12;
1588
1589                 for (index = 0; index < APK_BB_REG_NUM; index++) {
1590                         if (index != 1)
1591                                 continue;
1592
1593                         tmpreg = apk_rf_init_value[path][index];
1594
1595                         if (!rtlefuse->apk_thermalmeterignore) {
1596                                 bb_offset = (tmpreg & 0xF0000) >> 16;
1597
1598                                 if (!(tmpreg & BIT(15)))
1599                                         bb_offset = -bb_offset;
1600
1601                                 delta_v =
1602                                     apk_delta_mapping[index][delta_offset];
1603
1604                                 bb_offset += delta_v;
1605
1606                                 if (bb_offset < 0) {
1607                                         tmpreg = tmpreg & (~BIT(15));
1608                                         bb_offset = -bb_offset;
1609                                 } else {
1610                                         tmpreg = tmpreg | BIT(15);
1611                                 }
1612
1613                                 tmpreg =
1614                                     (tmpreg & 0xFFF0FFFF) | (bb_offset << 16);
1615                         }
1616
1617                         rtl_set_rfreg(hw, (enum radio_path)path, 0xc,
1618                                       MASKDWORD, 0x8992e);
1619                         rtl_set_rfreg(hw, (enum radio_path)path, 0x0,
1620                                       MASKDWORD, apk_rf_value_0[path][index]);
1621                         rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
1622                                       MASKDWORD, tmpreg);
1623
1624                         i = 0;
1625                         do {
1626                                 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000);
1627                                 rtl_set_bbreg(hw, apk_offset[path],
1628                                               MASKDWORD, apk_value[0]);
1629                                 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1630                                         ("PHY_APCalibrate() offset 0x%x "
1631                                          "value 0x%x\n",
1632                                          apk_offset[path],
1633                                          rtl_get_bbreg(hw, apk_offset[path],
1634                                                        MASKDWORD)));
1635
1636                                 mdelay(3);
1637
1638                                 rtl_set_bbreg(hw, apk_offset[path],
1639                                               MASKDWORD, apk_value[1]);
1640                                 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1641                                         ("PHY_APCalibrate() offset 0x%x "
1642                                          "value 0x%x\n",
1643                                          apk_offset[path],
1644                                          rtl_get_bbreg(hw, apk_offset[path],
1645                                                        MASKDWORD)));
1646
1647                                 mdelay(20);
1648
1649                                 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1650
1651                                 if (path == RF90_PATH_A)
1652                                         tmpreg = rtl_get_bbreg(hw, 0xbd8,
1653                                                                0x03E00000);
1654                                 else
1655                                         tmpreg = rtl_get_bbreg(hw, 0xbd8,
1656                                                                0xF8000000);
1657
1658                                 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1659                                         ("PHY_APCalibrate() offset "
1660                                          "0xbd8[25:21] %x\n", tmpreg));
1661
1662                                 i++;
1663
1664                         } while (tmpreg > apkbound && i < 4);
1665
1666                         apk_result[path][index] = tmpreg;
1667                 }
1668         }
1669
1670         _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup);
1671
1672         for (index = 0; index < APK_BB_REG_NUM; index++) {
1673                 if (index == 0)
1674                         continue;
1675                 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]);
1676         }
1677
1678         _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16);
1679
1680         for (path = 0; path < pathbound; path++) {
1681                 rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
1682                               MASKDWORD, reg_d[path]);
1683
1684                 if (path == RF90_PATH_B) {
1685                         rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
1686                                       0x1000f);
1687                         rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
1688                                       0x20101);
1689                 }
1690
1691                 if (apk_result[path][1] > 6)
1692                         apk_result[path][1] = 6;
1693         }
1694
1695         for (path = 0; path < pathbound; path++) {
1696                 rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD,
1697                               ((apk_result[path][1] << 15) |
1698                                (apk_result[path][1] << 10) |
1699                                (apk_result[path][1] << 5) |
1700                                apk_result[path][1]));
1701
1702                 if (path == RF90_PATH_A)
1703                         rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
1704                                       ((apk_result[path][1] << 15) |
1705                                        (apk_result[path][1] << 10) |
1706                                        (0x00 << 5) | 0x05));
1707                 else
1708                         rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
1709                                       ((apk_result[path][1] << 15) |
1710                                        (apk_result[path][1] << 10) |
1711                                        (0x02 << 5) | 0x05));
1712
1713                 rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD,
1714                               ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) |
1715                                0x08));
1716
1717         }
1718         rtlphy->b_apk_done = true;
1719 #endif
1720 }
1721
1722 static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1723                                           bool bmain, bool is2t)
1724 {
1725         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1726
1727         if (is_hal_stop(rtlhal)) {
1728                 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1729                 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1730         }
1731         if (is2t) {
1732                 if (bmain)
1733                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1734                                       BIT(5) | BIT(6), 0x1);
1735                 else
1736                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1737                                       BIT(5) | BIT(6), 0x2);
1738         } else {
1739                 if (bmain)
1740                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1741                 else
1742                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1743
1744         }
1745
1746 }
1747
1748 #undef IQK_ADDA_REG_NUM
1749 #undef IQK_DELAY_TIME
1750
1751 void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1752 {
1753         struct rtl_priv *rtlpriv = rtl_priv(hw);
1754         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1755         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1756
1757         long result[4][8];
1758         u8 i, final_candidate;
1759         bool patha_ok, pathb_ok;
1760         long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, reg_tmp = 0;
1761         bool is12simular, is13simular, is23simular;
1762         bool start_conttx = false, singletone = false;
1763         u32 iqk_bb_reg[10] = {
1764                 ROFDM0_XARXIQIMBALANCE,
1765                 ROFDM0_XBRXIQIMBALANCE,
1766                 ROFDM0_ECCATHRESHOLD,
1767                 ROFDM0_AGCRSSITABLE,
1768                 ROFDM0_XATXIQIMBALANCE,
1769                 ROFDM0_XBTXIQIMBALANCE,
1770                 ROFDM0_XCTXIQIMBALANCE,
1771                 ROFDM0_XCTXAFE,
1772                 ROFDM0_XDTXAFE,
1773                 ROFDM0_RXIQEXTANTA
1774         };
1775
1776         if (recovery) {
1777                 _rtl92c_phy_reload_adda_registers(hw,
1778                                                   iqk_bb_reg,
1779                                                   rtlphy->iqk_bb_backup, 10);
1780                 return;
1781         }
1782         if (start_conttx || singletone)
1783                 return;
1784         for (i = 0; i < 8; i++) {
1785                 result[0][i] = 0;
1786                 result[1][i] = 0;
1787                 result[2][i] = 0;
1788                 result[3][i] = 0;
1789         }
1790         final_candidate = 0xff;
1791         patha_ok = false;
1792         pathb_ok = false;
1793         is12simular = false;
1794         is23simular = false;
1795         is13simular = false;
1796         for (i = 0; i < 3; i++) {
1797                 if (IS_92C_SERIAL(rtlhal->version))
1798                         _rtl92c_phy_iq_calibrate(hw, result, i, true);
1799                 else
1800                         _rtl92c_phy_iq_calibrate(hw, result, i, false);
1801                 if (i == 1) {
1802                         is12simular = _rtl92c_phy_simularity_compare(hw,
1803                                                                      result, 0,
1804                                                                      1);
1805                         if (is12simular) {
1806                                 final_candidate = 0;
1807                                 break;
1808                         }
1809                 }
1810                 if (i == 2) {
1811                         is13simular = _rtl92c_phy_simularity_compare(hw,
1812                                                                      result, 0,
1813                                                                      2);
1814                         if (is13simular) {
1815                                 final_candidate = 0;
1816                                 break;
1817                         }
1818                         is23simular = _rtl92c_phy_simularity_compare(hw,
1819                                                                      result, 1,
1820                                                                      2);
1821                         if (is23simular)
1822                                 final_candidate = 1;
1823                         else {
1824                                 for (i = 0; i < 8; i++)
1825                                         reg_tmp += result[3][i];
1826
1827                                 if (reg_tmp != 0)
1828                                         final_candidate = 3;
1829                                 else
1830                                         final_candidate = 0xFF;
1831                         }
1832                 }
1833         }
1834         for (i = 0; i < 4; i++) {
1835                 reg_e94 = result[i][0];
1836                 reg_e9c = result[i][1];
1837                 reg_ea4 = result[i][2];
1838                 reg_eb4 = result[i][4];
1839                 reg_ebc = result[i][5];
1840                 reg_ec4 = result[i][6];
1841         }
1842         if (final_candidate != 0xff) {
1843                 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1844                 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1845                 reg_ea4 = result[final_candidate][2];
1846                 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1847                 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1848                 reg_ec4 = result[final_candidate][6];
1849                 patha_ok = pathb_ok = true;
1850         } else {
1851                 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1852                 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1853         }
1854         if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1855                 _rtl92c_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1856                                                    final_candidate,
1857                                                    (reg_ea4 == 0));
1858         if (IS_92C_SERIAL(rtlhal->version)) {
1859                 if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */
1860                         _rtl92c_phy_path_b_fill_iqk_matrix(hw, pathb_ok,
1861                                                            result,
1862                                                            final_candidate,
1863                                                            (reg_ec4 == 0));
1864         }
1865         _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg,
1866                                         rtlphy->iqk_bb_backup, 10);
1867 }
1868 EXPORT_SYMBOL(rtl92c_phy_iq_calibrate);
1869
1870 void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw)
1871 {
1872         struct rtl_priv *rtlpriv = rtl_priv(hw);
1873         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1874         bool start_conttx = false, singletone = false;
1875
1876         if (start_conttx || singletone)
1877                 return;
1878         if (IS_92C_SERIAL(rtlhal->version))
1879                 rtlpriv->cfg->ops->phy_lc_calibrate(hw, true);
1880         else
1881                 rtlpriv->cfg->ops->phy_lc_calibrate(hw, false);
1882 }
1883 EXPORT_SYMBOL(rtl92c_phy_lc_calibrate);
1884
1885 void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1886 {
1887         struct rtl_priv *rtlpriv = rtl_priv(hw);
1888         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1889         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1890
1891         if (rtlphy->apk_done)
1892                 return;
1893         if (IS_92C_SERIAL(rtlhal->version))
1894                 _rtl92c_phy_ap_calibrate(hw, delta, true);
1895         else
1896                 _rtl92c_phy_ap_calibrate(hw, delta, false);
1897 }
1898 EXPORT_SYMBOL(rtl92c_phy_ap_calibrate);
1899
1900 void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1901 {
1902         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1903
1904         if (IS_92C_SERIAL(rtlhal->version))
1905                 _rtl92c_phy_set_rfpath_switch(hw, bmain, true);
1906         else
1907                 _rtl92c_phy_set_rfpath_switch(hw, bmain, false);
1908 }
1909 EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch);
1910
1911 bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1912 {
1913         struct rtl_priv *rtlpriv = rtl_priv(hw);
1914         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1915         bool postprocessing = false;
1916
1917         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1918                  "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1919                  iotype, rtlphy->set_io_inprogress);
1920         do {
1921                 switch (iotype) {
1922                 case IO_CMD_RESUME_DM_BY_SCAN:
1923                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1924                                  "[IO CMD] Resume DM after scan\n");
1925                         postprocessing = true;
1926                         break;
1927                 case IO_CMD_PAUSE_DM_BY_SCAN:
1928                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1929                                  "[IO CMD] Pause DM before scan\n");
1930                         postprocessing = true;
1931                         break;
1932                 default:
1933                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1934                                  "switch case not processed\n");
1935                         break;
1936                 }
1937         } while (false);
1938         if (postprocessing && !rtlphy->set_io_inprogress) {
1939                 rtlphy->set_io_inprogress = true;
1940                 rtlphy->current_io_type = iotype;
1941         } else {
1942                 return false;
1943         }
1944         rtl92c_phy_set_io(hw);
1945         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
1946         return true;
1947 }
1948 EXPORT_SYMBOL(rtl92c_phy_set_io_cmd);
1949
1950 void rtl92c_phy_set_io(struct ieee80211_hw *hw)
1951 {
1952         struct rtl_priv *rtlpriv = rtl_priv(hw);
1953         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1954
1955         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1956                  "--->Cmd(%#x), set_io_inprogress(%d)\n",
1957                  rtlphy->current_io_type, rtlphy->set_io_inprogress);
1958         switch (rtlphy->current_io_type) {
1959         case IO_CMD_RESUME_DM_BY_SCAN:
1960                 dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1961                 rtl92c_dm_write_dig(hw);
1962                 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1963                 break;
1964         case IO_CMD_PAUSE_DM_BY_SCAN:
1965                 rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue;
1966                 dm_digtable.cur_igvalue = 0x17;
1967                 rtl92c_dm_write_dig(hw);
1968                 break;
1969         default:
1970                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1971                          "switch case not processed\n");
1972                 break;
1973         }
1974         rtlphy->set_io_inprogress = false;
1975         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
1976                  rtlphy->current_io_type);
1977 }
1978 EXPORT_SYMBOL(rtl92c_phy_set_io);
1979
1980 void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw)
1981 {
1982         struct rtl_priv *rtlpriv = rtl_priv(hw);
1983
1984         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1985         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1986         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1987         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1988         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1989         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1990 }
1991 EXPORT_SYMBOL(rtl92ce_phy_set_rf_on);
1992
1993 void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw)
1994 {
1995         u32 u4b_tmp;
1996         u8 delay = 5;
1997         struct rtl_priv *rtlpriv = rtl_priv(hw);
1998
1999         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2000         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2001         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2002         u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2003         while (u4b_tmp != 0 && delay > 0) {
2004                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
2005                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2006                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2007                 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2008                 delay--;
2009         }
2010         if (delay == 0) {
2011                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2012                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2013                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2014                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2015                 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
2016                          "Switch RF timeout !!!\n");
2017                 return;
2018         }
2019         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2020         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2021 }
2022 EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep);