Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192c / phy_common.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012  Realtek Corporation.*/
3
4 #include "../wifi.h"
5 #include "../rtl8192ce/reg.h"
6 #include "../rtl8192ce/def.h"
7 #include "dm_common.h"
8 #include "fw_common.h"
9 #include "phy_common.h"
10 #include <linux/export.h>
11
12 u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
13 {
14         struct rtl_priv *rtlpriv = rtl_priv(hw);
15         u32 returnvalue, originalvalue, bitshift;
16
17         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
18                  regaddr, bitmask);
19         originalvalue = rtl_read_dword(rtlpriv, regaddr);
20         bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
21         returnvalue = (originalvalue & bitmask) >> bitshift;
22
23         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
24                  "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
25                  bitmask, regaddr, originalvalue);
26
27         return returnvalue;
28 }
29 EXPORT_SYMBOL(rtl92c_phy_query_bb_reg);
30
31 void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
32                            u32 regaddr, u32 bitmask, u32 data)
33 {
34         struct rtl_priv *rtlpriv = rtl_priv(hw);
35         u32 originalvalue, bitshift;
36
37         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
38                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
39                  regaddr, bitmask, data);
40
41         if (bitmask != MASKDWORD) {
42                 originalvalue = rtl_read_dword(rtlpriv, regaddr);
43                 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
44                 data = ((originalvalue & (~bitmask)) | (data << bitshift));
45         }
46
47         rtl_write_dword(rtlpriv, regaddr, data);
48
49         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
50                  "regaddr(%#x), bitmask(%#x), data(%#x)\n",
51                  regaddr, bitmask, data);
52 }
53 EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
54
55 u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
56                                   enum radio_path rfpath, u32 offset)
57 {
58         WARN_ONCE(true, "rtl8192c-common: _rtl92c_phy_fw_rf_serial_read deprecated!\n");
59         return 0;
60 }
61 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read);
62
63 void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
64                                     enum radio_path rfpath, u32 offset,
65                                     u32 data)
66 {
67         WARN_ONCE(true, "rtl8192c-common: _rtl92c_phy_fw_rf_serial_write deprecated!\n");
68 }
69 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
70
71 u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
72                                enum radio_path rfpath, u32 offset)
73 {
74         struct rtl_priv *rtlpriv = rtl_priv(hw);
75         struct rtl_phy *rtlphy = &(rtlpriv->phy);
76         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
77         u32 newoffset;
78         u32 tmplong, tmplong2;
79         u8 rfpi_enable = 0;
80         u32 retvalue;
81
82         offset &= 0x3f;
83         newoffset = offset;
84         if (RT_CANNOT_IO(hw)) {
85                 pr_err("return all one\n");
86                 return 0xFFFFFFFF;
87         }
88         tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
89         if (rfpath == RF90_PATH_A)
90                 tmplong2 = tmplong;
91         else
92                 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
93         tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
94             (newoffset << 23) | BLSSIREADEDGE;
95         rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
96                       tmplong & (~BLSSIREADEDGE));
97         mdelay(1);
98         rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
99         mdelay(1);
100         rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
101                       tmplong | BLSSIREADEDGE);
102         mdelay(1);
103         if (rfpath == RF90_PATH_A)
104                 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
105                                                  BIT(8));
106         else if (rfpath == RF90_PATH_B)
107                 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
108                                                  BIT(8));
109         if (rfpi_enable)
110                 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
111                                          BLSSIREADBACKDATA);
112         else
113                 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
114                                          BLSSIREADBACKDATA);
115         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
116                                                rfpath, pphyreg->rf_rb,
117                                                retvalue);
118         return retvalue;
119 }
120 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
121
122 void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
123                                  enum radio_path rfpath, u32 offset,
124                                  u32 data)
125 {
126         u32 data_and_addr;
127         u32 newoffset;
128         struct rtl_priv *rtlpriv = rtl_priv(hw);
129         struct rtl_phy *rtlphy = &(rtlpriv->phy);
130         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
131
132         if (RT_CANNOT_IO(hw)) {
133                 pr_err("stop\n");
134                 return;
135         }
136         offset &= 0x3f;
137         newoffset = offset;
138         data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
139         rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
140         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
141                                                rfpath, pphyreg->rf3wire_offset,
142                                                data_and_addr);
143 }
144 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write);
145
146 u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
147 {
148         u32 i;
149
150         for (i = 0; i <= 31; i++) {
151                 if (((bitmask >> i) & 0x1) == 1)
152                         break;
153         }
154         return i;
155 }
156 EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift);
157
158 static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
159 {
160         rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
161         rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
162         rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
163         rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
164         rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
165         rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
166         rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
167         rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
168         rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
169         rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
170 }
171
172 bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
173 {
174         struct rtl_priv *rtlpriv = rtl_priv(hw);
175
176         return rtlpriv->cfg->ops->phy_rf6052_config(hw);
177 }
178 EXPORT_SYMBOL(rtl92c_phy_rf_config);
179
180 bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
181 {
182         struct rtl_priv *rtlpriv = rtl_priv(hw);
183         struct rtl_phy *rtlphy = &(rtlpriv->phy);
184         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
185         bool rtstatus;
186
187         rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
188                                                  BASEBAND_CONFIG_PHY_REG);
189         if (!rtstatus) {
190                 pr_err("Write BB Reg Fail!!\n");
191                 return false;
192         }
193         if (rtlphy->rf_type == RF_1T2R) {
194                 _rtl92c_phy_bb_config_1t(hw);
195                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
196         }
197         if (rtlefuse->autoload_failflag == false) {
198                 rtlphy->pwrgroup_cnt = 0;
199                 rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw,
200                                                    BASEBAND_CONFIG_PHY_REG);
201         }
202         if (!rtstatus) {
203                 pr_err("BB_PG Reg Fail!!\n");
204                 return false;
205         }
206         rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
207                                                  BASEBAND_CONFIG_AGC_TAB);
208         if (!rtstatus) {
209                 pr_err("AGC Table Fail\n");
210                 return false;
211         }
212         rtlphy->cck_high_power =
213                 (bool)(rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200));
214
215         return true;
216 }
217
218 EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile);
219
220 void _rtl92c_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
221                                             u32 regaddr, u32 bitmask,
222                                             u32 data)
223 {
224         struct rtl_priv *rtlpriv = rtl_priv(hw);
225         struct rtl_phy *rtlphy = &(rtlpriv->phy);
226
227         if (regaddr == RTXAGC_A_RATE18_06) {
228                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
229                     data;
230                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
231                          "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
232                           rtlphy->pwrgroup_cnt,
233                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
234                                                             pwrgroup_cnt][0]);
235         }
236         if (regaddr == RTXAGC_A_RATE54_24) {
237                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
238                     data;
239                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
240                          "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
241                           rtlphy->pwrgroup_cnt,
242                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
243                                                             pwrgroup_cnt][1]);
244         }
245         if (regaddr == RTXAGC_A_CCK1_MCS32) {
246                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
247                     data;
248                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
249                          "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
250                           rtlphy->pwrgroup_cnt,
251                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
252                                                             pwrgroup_cnt][6]);
253         }
254         if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
255                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
256                     data;
257                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
258                          "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
259                           rtlphy->pwrgroup_cnt,
260                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
261                                                             pwrgroup_cnt][7]);
262         }
263         if (regaddr == RTXAGC_A_MCS03_MCS00) {
264                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
265                     data;
266                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
267                          "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
268                           rtlphy->pwrgroup_cnt,
269                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
270                                                             pwrgroup_cnt][2]);
271         }
272         if (regaddr == RTXAGC_A_MCS07_MCS04) {
273                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
274                     data;
275                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
276                          "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
277                           rtlphy->pwrgroup_cnt,
278                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
279                                                             pwrgroup_cnt][3]);
280         }
281         if (regaddr == RTXAGC_A_MCS11_MCS08) {
282                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
283                     data;
284                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
285                          "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
286                           rtlphy->pwrgroup_cnt,
287                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
288                                                             pwrgroup_cnt][4]);
289         }
290         if (regaddr == RTXAGC_A_MCS15_MCS12) {
291                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
292                     data;
293                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
294                          "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
295                           rtlphy->pwrgroup_cnt,
296                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
297                                                             pwrgroup_cnt][5]);
298         }
299         if (regaddr == RTXAGC_B_RATE18_06) {
300                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
301                     data;
302                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
303                          "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
304                           rtlphy->pwrgroup_cnt,
305                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
306                                                             pwrgroup_cnt][8]);
307         }
308         if (regaddr == RTXAGC_B_RATE54_24) {
309                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
310                     data;
311                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
312                          "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
313                           rtlphy->pwrgroup_cnt,
314                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
315                                                             pwrgroup_cnt][9]);
316         }
317         if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
318                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
319                     data;
320                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
321                          "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
322                           rtlphy->pwrgroup_cnt,
323                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
324                                                             pwrgroup_cnt][14]);
325         }
326         if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
327                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
328                     data;
329                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
330                          "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
331                           rtlphy->pwrgroup_cnt,
332                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
333                                                             pwrgroup_cnt][15]);
334         }
335         if (regaddr == RTXAGC_B_MCS03_MCS00) {
336                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
337                     data;
338                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
339                          "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
340                           rtlphy->pwrgroup_cnt,
341                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
342                                                             pwrgroup_cnt][10]);
343         }
344         if (regaddr == RTXAGC_B_MCS07_MCS04) {
345                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
346                     data;
347                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
348                          "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
349                           rtlphy->pwrgroup_cnt,
350                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
351                                                             pwrgroup_cnt][11]);
352         }
353         if (regaddr == RTXAGC_B_MCS11_MCS08) {
354                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
355                     data;
356                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
357                          "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
358                           rtlphy->pwrgroup_cnt,
359                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
360                                                             pwrgroup_cnt][12]);
361         }
362         if (regaddr == RTXAGC_B_MCS15_MCS12) {
363                 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
364                     data;
365                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
366                          "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
367                           rtlphy->pwrgroup_cnt,
368                           rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
369                                                             pwrgroup_cnt][13]);
370
371                 rtlphy->pwrgroup_cnt++;
372         }
373 }
374 EXPORT_SYMBOL(_rtl92c_store_pwrindex_diffrate_offset);
375
376 void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
377 {
378         struct rtl_priv *rtlpriv = rtl_priv(hw);
379         struct rtl_phy *rtlphy = &(rtlpriv->phy);
380
381         rtlphy->default_initialgain[0] =
382             (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
383         rtlphy->default_initialgain[1] =
384             (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
385         rtlphy->default_initialgain[2] =
386             (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
387         rtlphy->default_initialgain[3] =
388             (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
389
390         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
391                  "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
392                   rtlphy->default_initialgain[0],
393                   rtlphy->default_initialgain[1],
394                   rtlphy->default_initialgain[2],
395                   rtlphy->default_initialgain[3]);
396
397         rtlphy->framesync = (u8)rtl_get_bbreg(hw,
398                                                ROFDM0_RXDETECTOR3, MASKBYTE0);
399         rtlphy->framesync_c34 = rtl_get_bbreg(hw,
400                                               ROFDM0_RXDETECTOR2, MASKDWORD);
401
402         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
403                  "Default framesync (0x%x) = 0x%x\n",
404                   ROFDM0_RXDETECTOR3, rtlphy->framesync);
405 }
406
407 void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
408 {
409         struct rtl_priv *rtlpriv = rtl_priv(hw);
410         struct rtl_phy *rtlphy = &(rtlpriv->phy);
411
412         rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
413         rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
414         rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
415         rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
416
417         rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
418         rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
419         rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
420         rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
421
422         rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
423         rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
424
425         rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
426         rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
427
428         rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
429             RFPGA0_XA_LSSIPARAMETER;
430         rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
431             RFPGA0_XB_LSSIPARAMETER;
432
433         rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
434         rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
435         rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
436         rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
437
438         rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
439         rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
440         rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
441         rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
442
443         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
444         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
445
446         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
447         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
448
449         rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
450         rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
451         rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
452         rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
453
454         rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
455         rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
456         rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
457         rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
458
459         rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
460         rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
461         rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
462         rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
463
464         rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
465         rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
466         rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
467         rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
468
469         rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
470         rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
471         rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
472         rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
473
474         rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
475         rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
476         rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
477         rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
478
479         rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
480         rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
481         rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
482         rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
483
484         rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
485         rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
486         rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
487         rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
488
489         rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
490         rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
491
492 }
493 EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition);
494
495 void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
496 {
497         struct rtl_priv *rtlpriv = rtl_priv(hw);
498         struct rtl_phy *rtlphy = &(rtlpriv->phy);
499         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
500         u8 txpwr_level;
501         long txpwr_dbm;
502
503         txpwr_level = rtlphy->cur_cck_txpwridx;
504         txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
505                                                  txpwr_level);
506         txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
507             rtlefuse->legacy_ht_txpowerdiff;
508         if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
509                                          txpwr_level) > txpwr_dbm)
510                 txpwr_dbm =
511                     _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
512                                                  txpwr_level);
513         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
514         if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
515                                          txpwr_level) > txpwr_dbm)
516                 txpwr_dbm =
517                     _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
518                                                  txpwr_level);
519         *powerlevel = txpwr_dbm;
520 }
521
522 static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
523                                       u8 *cckpowerlevel, u8 *ofdmpowerlevel)
524 {
525         struct rtl_priv *rtlpriv = rtl_priv(hw);
526         struct rtl_phy *rtlphy = &(rtlpriv->phy);
527         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
528         u8 index = (channel - 1);
529
530         cckpowerlevel[RF90_PATH_A] =
531             rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
532         cckpowerlevel[RF90_PATH_B] =
533             rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
534         if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
535                 ofdmpowerlevel[RF90_PATH_A] =
536                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
537                 ofdmpowerlevel[RF90_PATH_B] =
538                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
539         } else if (get_rf_type(rtlphy) == RF_2T2R) {
540                 ofdmpowerlevel[RF90_PATH_A] =
541                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
542                 ofdmpowerlevel[RF90_PATH_B] =
543                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
544         }
545 }
546
547 static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
548                                          u8 channel, u8 *cckpowerlevel,
549                                          u8 *ofdmpowerlevel)
550 {
551         struct rtl_priv *rtlpriv = rtl_priv(hw);
552         struct rtl_phy *rtlphy = &(rtlpriv->phy);
553
554         rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
555         rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
556 }
557
558 void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
559 {
560         struct rtl_priv *rtlpriv = rtl_priv(hw);
561         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
562         u8 cckpowerlevel[2], ofdmpowerlevel[2];
563
564         if (!rtlefuse->txpwr_fromeprom)
565                 return;
566         _rtl92c_get_txpower_index(hw, channel,
567                                   &cckpowerlevel[0], &ofdmpowerlevel[0]);
568         _rtl92c_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
569                                      &ofdmpowerlevel[0]);
570         rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
571         rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0],
572                                                        channel);
573 }
574 EXPORT_SYMBOL(rtl92c_phy_set_txpower_level);
575
576 bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
577 {
578         struct rtl_priv *rtlpriv = rtl_priv(hw);
579         struct rtl_phy *rtlphy = &(rtlpriv->phy);
580         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
581         u8 idx;
582         u8 rf_path;
583         u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_B,
584                                                       power_indbm);
585         u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_N_24G,
586                                                        power_indbm);
587         if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
588                 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
589         else
590                 ofdmtxpwridx = 0;
591         RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
592                  "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
593                   power_indbm, ccktxpwridx, ofdmtxpwridx);
594         for (idx = 0; idx < 14; idx++) {
595                 for (rf_path = 0; rf_path < 2; rf_path++) {
596                         rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
597                         rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
598                             ofdmtxpwridx;
599                         rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
600                             ofdmtxpwridx;
601                 }
602         }
603         rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
604         return true;
605 }
606 EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm);
607
608 u8 _rtl92c_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,
609                                 enum wireless_mode wirelessmode,
610                                 long power_indbm)
611 {
612         u8 txpwridx;
613         long offset;
614
615         switch (wirelessmode) {
616         case WIRELESS_MODE_B:
617                 offset = -7;
618                 break;
619         case WIRELESS_MODE_G:
620         case WIRELESS_MODE_N_24G:
621                 offset = -8;
622                 break;
623         default:
624                 offset = -8;
625                 break;
626         }
627
628         if ((power_indbm - offset) > 0)
629                 txpwridx = (u8)((power_indbm - offset) * 2);
630         else
631                 txpwridx = 0;
632
633         if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
634                 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
635
636         return txpwridx;
637 }
638 EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_idx);
639
640 long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
641                                   enum wireless_mode wirelessmode,
642                                   u8 txpwridx)
643 {
644         long offset;
645         long pwrout_dbm;
646
647         switch (wirelessmode) {
648         case WIRELESS_MODE_B:
649                 offset = -7;
650                 break;
651         case WIRELESS_MODE_G:
652         case WIRELESS_MODE_N_24G:
653                 offset = -8;
654                 break;
655         default:
656                 offset = -8;
657                 break;
658         }
659         pwrout_dbm = txpwridx / 2 + offset;
660         return pwrout_dbm;
661 }
662 EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm);
663
664 void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
665                             enum nl80211_channel_type ch_type)
666 {
667         struct rtl_priv *rtlpriv = rtl_priv(hw);
668         struct rtl_phy *rtlphy = &(rtlpriv->phy);
669         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
670         u8 tmp_bw = rtlphy->current_chan_bw;
671
672         if (rtlphy->set_bwmode_inprogress)
673                 return;
674         rtlphy->set_bwmode_inprogress = true;
675         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
676                 rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
677         } else {
678                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
679                          "false driver sleep or unload\n");
680                 rtlphy->set_bwmode_inprogress = false;
681                 rtlphy->current_chan_bw = tmp_bw;
682         }
683 }
684 EXPORT_SYMBOL(rtl92c_phy_set_bw_mode);
685
686 void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
687 {
688         struct rtl_priv *rtlpriv = rtl_priv(hw);
689         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
690         struct rtl_phy *rtlphy = &(rtlpriv->phy);
691         u32 delay;
692
693         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
694                  "switch to channel%d\n", rtlphy->current_channel);
695         if (is_hal_stop(rtlhal))
696                 return;
697         do {
698                 if (!rtlphy->sw_chnl_inprogress)
699                         break;
700                 if (!_rtl92c_phy_sw_chnl_step_by_step
701                     (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
702                      &rtlphy->sw_chnl_step, &delay)) {
703                         if (delay > 0)
704                                 mdelay(delay);
705                         else
706                                 continue;
707                 } else {
708                         rtlphy->sw_chnl_inprogress = false;
709                 }
710                 break;
711         } while (true);
712         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
713 }
714 EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback);
715
716 u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
717 {
718         struct rtl_priv *rtlpriv = rtl_priv(hw);
719         struct rtl_phy *rtlphy = &(rtlpriv->phy);
720         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
721
722         if (rtlphy->sw_chnl_inprogress)
723                 return 0;
724         if (rtlphy->set_bwmode_inprogress)
725                 return 0;
726         WARN_ONCE((rtlphy->current_channel > 14),
727                   "rtl8192c-common: WIRELESS_MODE_G but channel>14");
728         rtlphy->sw_chnl_inprogress = true;
729         rtlphy->sw_chnl_stage = 0;
730         rtlphy->sw_chnl_step = 0;
731         if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
732                 rtl92c_phy_sw_chnl_callback(hw);
733                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
734                          "sw_chnl_inprogress false schedule workitem\n");
735                 rtlphy->sw_chnl_inprogress = false;
736         } else {
737                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
738                          "sw_chnl_inprogress false driver sleep or unload\n");
739                 rtlphy->sw_chnl_inprogress = false;
740         }
741         return 1;
742 }
743 EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
744
745 static void _rtl92c_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
746 {
747         struct rtl_priv *rtlpriv = rtl_priv(hw);
748         struct rtl_phy *rtlphy = &(rtlpriv->phy);
749         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
750
751         if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) {
752                 if (channel == 6 &&
753                     rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
754                         rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,
755                                       MASKDWORD, 0x00255);
756                 } else {
757                         u32 backuprf0x1A =
758                           (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1,
759                                              RFREG_OFFSET_MASK);
760                         rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
761                                       backuprf0x1A);
762                 }
763         }
764 }
765
766 static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
767                                              u32 cmdtableidx, u32 cmdtablesz,
768                                              enum swchnlcmd_id cmdid,
769                                              u32 para1, u32 para2, u32 msdelay)
770 {
771         struct swchnlcmd *pcmd;
772
773         if (cmdtable == NULL) {
774                 WARN_ONCE(true, "rtl8192c-common: cmdtable cannot be NULL.\n");
775                 return false;
776         }
777
778         if (cmdtableidx >= cmdtablesz)
779                 return false;
780
781         pcmd = cmdtable + cmdtableidx;
782         pcmd->cmdid = cmdid;
783         pcmd->para1 = para1;
784         pcmd->para2 = para2;
785         pcmd->msdelay = msdelay;
786         return true;
787 }
788
789 bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
790                                       u8 channel, u8 *stage, u8 *step,
791                                       u32 *delay)
792 {
793         struct rtl_priv *rtlpriv = rtl_priv(hw);
794         struct rtl_phy *rtlphy = &(rtlpriv->phy);
795         struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
796         u32 precommoncmdcnt;
797         struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
798         u32 postcommoncmdcnt;
799         struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
800         u32 rfdependcmdcnt;
801         struct swchnlcmd *currentcmd = NULL;
802         u8 rfpath;
803         u8 num_total_rfpath = rtlphy->num_total_rfpath;
804
805         precommoncmdcnt = 0;
806         _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
807                                          MAX_PRECMD_CNT,
808                                          CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
809         _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
810                                          MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
811
812         postcommoncmdcnt = 0;
813
814         _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
815                                          MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
816
817         rfdependcmdcnt = 0;
818
819         WARN_ONCE((channel < 1 || channel > 14),
820                   "rtl8192c-common: illegal channel for Zebra: %d\n", channel);
821
822         _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
823                                          MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
824                                          RF_CHNLBW, channel, 10);
825
826         _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
827                                          MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
828                                          0);
829
830         do {
831                 switch (*stage) {
832                 case 0:
833                         currentcmd = &precommoncmd[*step];
834                         break;
835                 case 1:
836                         currentcmd = &rfdependcmd[*step];
837                         break;
838                 case 2:
839                         currentcmd = &postcommoncmd[*step];
840                         break;
841                 default:
842                         pr_err("Invalid 'stage' = %d, Check it!\n",
843                                *stage);
844                         return true;
845                 }
846
847                 if (currentcmd->cmdid == CMDID_END) {
848                         if ((*stage) == 2) {
849                                 return true;
850                         } else {
851                                 (*stage)++;
852                                 (*step) = 0;
853                                 continue;
854                         }
855                 }
856
857                 switch (currentcmd->cmdid) {
858                 case CMDID_SET_TXPOWEROWER_LEVEL:
859                         rtl92c_phy_set_txpower_level(hw, channel);
860                         break;
861                 case CMDID_WRITEPORT_ULONG:
862                         rtl_write_dword(rtlpriv, currentcmd->para1,
863                                         currentcmd->para2);
864                         break;
865                 case CMDID_WRITEPORT_USHORT:
866                         rtl_write_word(rtlpriv, currentcmd->para1,
867                                        (u16) currentcmd->para2);
868                         break;
869                 case CMDID_WRITEPORT_UCHAR:
870                         rtl_write_byte(rtlpriv, currentcmd->para1,
871                                        (u8)currentcmd->para2);
872                         break;
873                 case CMDID_RF_WRITEREG:
874                         for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
875                                 rtlphy->rfreg_chnlval[rfpath] =
876                                     ((rtlphy->rfreg_chnlval[rfpath] &
877                                       0xfffffc00) | currentcmd->para2);
878
879                                 rtl_set_rfreg(hw, (enum radio_path)rfpath,
880                                               currentcmd->para1,
881                                               RFREG_OFFSET_MASK,
882                                               rtlphy->rfreg_chnlval[rfpath]);
883                         }
884                         _rtl92c_phy_sw_rf_seting(hw, channel);
885                         break;
886                 default:
887                         RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
888                                  "switch case %#x not processed\n",
889                                  currentcmd->cmdid);
890                         break;
891                 }
892
893                 break;
894         } while (true);
895
896         (*delay) = currentcmd->msdelay;
897         (*step)++;
898         return false;
899 }
900
901 bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
902 {
903         return true;
904 }
905 EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath);
906
907 static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
908 {
909         u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
910         u8 result = 0x00;
911
912         rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
913         rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
914         rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
915         rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
916                       config_pathb ? 0x28160202 : 0x28160502);
917
918         if (config_pathb) {
919                 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
920                 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
921                 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
922                 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
923         }
924
925         rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
926         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
927         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
928
929         mdelay(IQK_DELAY_TIME);
930
931         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
932         reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
933         reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
934         reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
935
936         if (!(reg_eac & BIT(28)) &&
937             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
938             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
939                 result |= 0x01;
940         else
941                 return result;
942
943         if (!(reg_eac & BIT(27)) &&
944             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
945             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
946                 result |= 0x02;
947         return result;
948 }
949
950 static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
951 {
952         u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
953         u8 result = 0x00;
954
955         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
956         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
957         mdelay(IQK_DELAY_TIME);
958         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
959         reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
960         reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
961         reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
962         reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
963
964         if (!(reg_eac & BIT(31)) &&
965             (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
966             (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
967                 result |= 0x01;
968         else
969                 return result;
970         if (!(reg_eac & BIT(30)) &&
971             (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
972             (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
973                 result |= 0x02;
974         return result;
975 }
976
977 static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
978                                                bool b_iqk_ok, long result[][8],
979                                                u8 final_candidate, bool btxonly)
980 {
981         u32 oldval_0, x, tx0_a, reg;
982         long y, tx0_c;
983
984         if (final_candidate == 0xFF) {
985                 return;
986         } else if (b_iqk_ok) {
987                 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
988                                           MASKDWORD) >> 22) & 0x3FF;
989                 x = result[final_candidate][0];
990                 if ((x & 0x00000200) != 0)
991                         x = x | 0xFFFFFC00;
992                 tx0_a = (x * oldval_0) >> 8;
993                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
994                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
995                               ((x * oldval_0 >> 7) & 0x1));
996                 y = result[final_candidate][1];
997                 if ((y & 0x00000200) != 0)
998                         y = y | 0xFFFFFC00;
999                 tx0_c = (y * oldval_0) >> 8;
1000                 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1001                               ((tx0_c & 0x3C0) >> 6));
1002                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1003                               (tx0_c & 0x3F));
1004                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1005                               ((y * oldval_0 >> 7) & 0x1));
1006                 if (btxonly)
1007                         return;
1008                 reg = result[final_candidate][2];
1009                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1010                 reg = result[final_candidate][3] & 0x3F;
1011                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1012                 reg = (result[final_candidate][3] >> 6) & 0xF;
1013                 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1014         }
1015 }
1016
1017 static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1018                                                bool b_iqk_ok, long result[][8],
1019                                                u8 final_candidate, bool btxonly)
1020 {
1021         u32 oldval_1, x, tx1_a, reg;
1022         long y, tx1_c;
1023
1024         if (final_candidate == 0xFF) {
1025                 return;
1026         } else if (b_iqk_ok) {
1027                 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1028                                           MASKDWORD) >> 22) & 0x3FF;
1029                 x = result[final_candidate][4];
1030                 if ((x & 0x00000200) != 0)
1031                         x = x | 0xFFFFFC00;
1032                 tx1_a = (x * oldval_1) >> 8;
1033                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1034                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1035                               ((x * oldval_1 >> 7) & 0x1));
1036                 y = result[final_candidate][5];
1037                 if ((y & 0x00000200) != 0)
1038                         y = y | 0xFFFFFC00;
1039                 tx1_c = (y * oldval_1) >> 8;
1040                 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1041                               ((tx1_c & 0x3C0) >> 6));
1042                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1043                               (tx1_c & 0x3F));
1044                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1045                               ((y * oldval_1 >> 7) & 0x1));
1046                 if (btxonly)
1047                         return;
1048                 reg = result[final_candidate][6];
1049                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1050                 reg = result[final_candidate][7] & 0x3F;
1051                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1052                 reg = (result[final_candidate][7] >> 6) & 0xF;
1053                 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
1054         }
1055 }
1056
1057 static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw,
1058                                             u32 *addareg, u32 *addabackup,
1059                                             u32 registernum)
1060 {
1061         u32 i;
1062
1063         for (i = 0; i < registernum; i++)
1064                 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1065 }
1066
1067 static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw,
1068                                            u32 *macreg, u32 *macbackup)
1069 {
1070         struct rtl_priv *rtlpriv = rtl_priv(hw);
1071         u32 i;
1072
1073         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1074                 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1075         macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1076 }
1077
1078 static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw,
1079                                               u32 *addareg, u32 *addabackup,
1080                                               u32 regiesternum)
1081 {
1082         u32 i;
1083
1084         for (i = 0; i < regiesternum; i++)
1085                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1086 }
1087
1088 static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw,
1089                                              u32 *macreg, u32 *macbackup)
1090 {
1091         struct rtl_priv *rtlpriv = rtl_priv(hw);
1092         u32 i;
1093
1094         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1095                 rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]);
1096         rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1097 }
1098
1099 static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw,
1100                                      u32 *addareg, bool is_patha_on, bool is2t)
1101 {
1102         u32 pathon;
1103         u32 i;
1104
1105         pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1106         if (false == is2t) {
1107                 pathon = 0x0bdb25a0;
1108                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1109         } else {
1110                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
1111         }
1112
1113         for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1114                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
1115 }
1116
1117 static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1118                                                 u32 *macreg, u32 *macbackup)
1119 {
1120         struct rtl_priv *rtlpriv = rtl_priv(hw);
1121         u32 i = 0;
1122
1123         rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1124
1125         for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1126                 rtl_write_byte(rtlpriv, macreg[i],
1127                                (u8)(macbackup[i] & (~BIT(3))));
1128         rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & (~BIT(5))));
1129 }
1130
1131 static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw)
1132 {
1133         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1134         rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1135         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1136 }
1137
1138 static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1139 {
1140         u32 mode;
1141
1142         mode = pi_mode ? 0x01000100 : 0x01000000;
1143         rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1144         rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1145 }
1146
1147 static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw,
1148                                            long result[][8], u8 c1, u8 c2)
1149 {
1150         u32 i, j, diff, simularity_bitmap, bound;
1151         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1152
1153         u8 final_candidate[2] = { 0xFF, 0xFF };
1154         bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1155
1156         if (is2t)
1157                 bound = 8;
1158         else
1159                 bound = 4;
1160
1161         simularity_bitmap = 0;
1162
1163         for (i = 0; i < bound; i++) {
1164                 diff = (result[c1][i] > result[c2][i]) ?
1165                     (result[c1][i] - result[c2][i]) :
1166                     (result[c2][i] - result[c1][i]);
1167
1168                 if (diff > MAX_TOLERANCE) {
1169                         if ((i == 2 || i == 6) && !simularity_bitmap) {
1170                                 if (result[c1][i] + result[c1][i + 1] == 0)
1171                                         final_candidate[(i / 4)] = c2;
1172                                 else if (result[c2][i] + result[c2][i + 1] == 0)
1173                                         final_candidate[(i / 4)] = c1;
1174                                 else
1175                                         simularity_bitmap = simularity_bitmap |
1176                                             (1 << i);
1177                         } else
1178                                 simularity_bitmap =
1179                                     simularity_bitmap | (1 << i);
1180                 }
1181         }
1182
1183         if (simularity_bitmap == 0) {
1184                 for (i = 0; i < (bound / 4); i++) {
1185                         if (final_candidate[i] != 0xFF) {
1186                                 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1187                                         result[3][j] =
1188                                             result[final_candidate[i]][j];
1189                                 bresult = false;
1190                         }
1191                 }
1192                 return bresult;
1193         } else if (!(simularity_bitmap & 0x0F)) {
1194                 for (i = 0; i < 4; i++)
1195                         result[3][i] = result[c1][i];
1196                 return false;
1197         } else if (!(simularity_bitmap & 0xF0) && is2t) {
1198                 for (i = 4; i < 8; i++)
1199                         result[3][i] = result[c1][i];
1200                 return false;
1201         } else {
1202                 return false;
1203         }
1204 }
1205
1206 static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1207                                      long result[][8], u8 t, bool is2t)
1208 {
1209         struct rtl_priv *rtlpriv = rtl_priv(hw);
1210         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1211         u32 i;
1212         u8 patha_ok, pathb_ok;
1213         u32 adda_reg[IQK_ADDA_REG_NUM] = {
1214                 0x85c, 0xe6c, 0xe70, 0xe74,
1215                 0xe78, 0xe7c, 0xe80, 0xe84,
1216                 0xe88, 0xe8c, 0xed0, 0xed4,
1217                 0xed8, 0xedc, 0xee0, 0xeec
1218         };
1219         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1220                 0x522, 0x550, 0x551, 0x040
1221         };
1222         const u32 retrycount = 2;
1223         u32 bbvalue;
1224
1225         if (t == 0) {
1226                 bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
1227
1228                 _rtl92c_phy_save_adda_registers(hw, adda_reg,
1229                                                 rtlphy->adda_backup, 16);
1230                 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1231                                                rtlphy->iqk_mac_backup);
1232         }
1233         _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1234         if (t == 0) {
1235                 rtlphy->rfpi_enable =
1236                    (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
1237                                      BIT(8));
1238         }
1239
1240         if (!rtlphy->rfpi_enable)
1241                 _rtl92c_phy_pi_mode_switch(hw, true);
1242         if (t == 0) {
1243                 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1244                 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1245                 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1246         }
1247         rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1248         rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1249         rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1250         if (is2t) {
1251                 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1252                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1253         }
1254         _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg,
1255                                             rtlphy->iqk_mac_backup);
1256         rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1257         if (is2t)
1258                 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1259         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1260         rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1261         rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1262         for (i = 0; i < retrycount; i++) {
1263                 patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t);
1264                 if (patha_ok == 0x03) {
1265                         result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1266                                         0x3FF0000) >> 16;
1267                         result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1268                                         0x3FF0000) >> 16;
1269                         result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1270                                         0x3FF0000) >> 16;
1271                         result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1272                                         0x3FF0000) >> 16;
1273                         break;
1274                 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1275
1276                         result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1277                                                       MASKDWORD) & 0x3FF0000) >>
1278                             16;
1279                 result[t][1] =
1280                     (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1281
1282         }
1283
1284         if (is2t) {
1285                 _rtl92c_phy_path_a_standby(hw);
1286                 _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t);
1287                 for (i = 0; i < retrycount; i++) {
1288                         pathb_ok = _rtl92c_phy_path_b_iqk(hw);
1289                         if (pathb_ok == 0x03) {
1290                                 result[t][4] = (rtl_get_bbreg(hw,
1291                                                               0xeb4,
1292                                                               MASKDWORD) &
1293                                                 0x3FF0000) >> 16;
1294                                 result[t][5] =
1295                                     (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1296                                      0x3FF0000) >> 16;
1297                                 result[t][6] =
1298                                     (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1299                                      0x3FF0000) >> 16;
1300                                 result[t][7] =
1301                                     (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1302                                      0x3FF0000) >> 16;
1303                                 break;
1304                         } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1305                                 result[t][4] = (rtl_get_bbreg(hw,
1306                                                               0xeb4,
1307                                                               MASKDWORD) &
1308                                                 0x3FF0000) >> 16;
1309                         }
1310                         result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1311                                         0x3FF0000) >> 16;
1312                 }
1313         }
1314         rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1315         rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1316         rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1317         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1318         rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1319         if (is2t)
1320                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1321         if (t != 0) {
1322                 if (!rtlphy->rfpi_enable)
1323                         _rtl92c_phy_pi_mode_switch(hw, false);
1324                 _rtl92c_phy_reload_adda_registers(hw, adda_reg,
1325                                                   rtlphy->adda_backup, 16);
1326                 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1327                                                  rtlphy->iqk_mac_backup);
1328         }
1329 }
1330
1331 static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
1332                                      s8 delta, bool is2t)
1333 {
1334 }
1335
1336 static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1337                                           bool bmain, bool is2t)
1338 {
1339         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1340
1341         if (is_hal_stop(rtlhal)) {
1342                 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1343                 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1344         }
1345         if (is2t) {
1346                 if (bmain)
1347                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1348                                       BIT(5) | BIT(6), 0x1);
1349                 else
1350                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1351                                       BIT(5) | BIT(6), 0x2);
1352         } else {
1353                 if (bmain)
1354                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1355                 else
1356                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1357         }
1358 }
1359
1360 #undef IQK_ADDA_REG_NUM
1361 #undef IQK_DELAY_TIME
1362
1363 void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
1364 {
1365         struct rtl_priv *rtlpriv = rtl_priv(hw);
1366         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1367         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1368
1369         long result[4][8];
1370         u8 i, final_candidate;
1371         bool b_patha_ok, b_pathb_ok;
1372         long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4,
1373             reg_tmp = 0;
1374         bool is12simular, is13simular, is23simular;
1375         u32 iqk_bb_reg[10] = {
1376                 ROFDM0_XARXIQIMBALANCE,
1377                 ROFDM0_XBRXIQIMBALANCE,
1378                 ROFDM0_ECCATHRESHOLD,
1379                 ROFDM0_AGCRSSITABLE,
1380                 ROFDM0_XATXIQIMBALANCE,
1381                 ROFDM0_XBTXIQIMBALANCE,
1382                 ROFDM0_XCTXIQIMBALANCE,
1383                 ROFDM0_XCTXAFE,
1384                 ROFDM0_XDTXAFE,
1385                 ROFDM0_RXIQEXTANTA
1386         };
1387
1388         if (b_recovery) {
1389                 _rtl92c_phy_reload_adda_registers(hw,
1390                                                   iqk_bb_reg,
1391                                                   rtlphy->iqk_bb_backup, 10);
1392                 return;
1393         }
1394         for (i = 0; i < 8; i++) {
1395                 result[0][i] = 0;
1396                 result[1][i] = 0;
1397                 result[2][i] = 0;
1398                 result[3][i] = 0;
1399         }
1400         final_candidate = 0xff;
1401         b_patha_ok = false;
1402         b_pathb_ok = false;
1403         is12simular = false;
1404         is23simular = false;
1405         is13simular = false;
1406         for (i = 0; i < 3; i++) {
1407                 if (IS_92C_SERIAL(rtlhal->version))
1408                         _rtl92c_phy_iq_calibrate(hw, result, i, true);
1409                 else
1410                         _rtl92c_phy_iq_calibrate(hw, result, i, false);
1411                 if (i == 1) {
1412                         is12simular = _rtl92c_phy_simularity_compare(hw,
1413                                                                      result, 0,
1414                                                                      1);
1415                         if (is12simular) {
1416                                 final_candidate = 0;
1417                                 break;
1418                         }
1419                 }
1420                 if (i == 2) {
1421                         is13simular = _rtl92c_phy_simularity_compare(hw,
1422                                                                      result, 0,
1423                                                                      2);
1424                         if (is13simular) {
1425                                 final_candidate = 0;
1426                                 break;
1427                         }
1428                         is23simular = _rtl92c_phy_simularity_compare(hw,
1429                                                                      result, 1,
1430                                                                      2);
1431                         if (is23simular)
1432                                 final_candidate = 1;
1433                         else {
1434                                 for (i = 0; i < 8; i++)
1435                                         reg_tmp += result[3][i];
1436
1437                                 if (reg_tmp != 0)
1438                                         final_candidate = 3;
1439                                 else
1440                                         final_candidate = 0xFF;
1441                         }
1442                 }
1443         }
1444         for (i = 0; i < 4; i++) {
1445                 reg_e94 = result[i][0];
1446                 reg_e9c = result[i][1];
1447                 reg_ea4 = result[i][2];
1448                 reg_eb4 = result[i][4];
1449                 reg_ebc = result[i][5];
1450                 reg_ec4 = result[i][6];
1451         }
1452         if (final_candidate != 0xff) {
1453                 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1454                 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1455                 reg_ea4 = result[final_candidate][2];
1456                 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1457                 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1458                 reg_ec4 = result[final_candidate][6];
1459                 b_patha_ok = true;
1460                 b_pathb_ok = true;
1461         } else {
1462                 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1463                 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1464         }
1465         if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1466                 _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
1467                                                    final_candidate,
1468                                                    (reg_ea4 == 0));
1469         if (IS_92C_SERIAL(rtlhal->version)) {
1470                 if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */
1471                         _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok,
1472                                                            result,
1473                                                            final_candidate,
1474                                                            (reg_ec4 == 0));
1475         }
1476         _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg,
1477                                         rtlphy->iqk_bb_backup, 10);
1478 }
1479 EXPORT_SYMBOL(rtl92c_phy_iq_calibrate);
1480
1481 void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw)
1482 {
1483         struct rtl_priv *rtlpriv = rtl_priv(hw);
1484         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1485
1486         if (IS_92C_SERIAL(rtlhal->version))
1487                 rtlpriv->cfg->ops->phy_lc_calibrate(hw, true);
1488         else
1489                 rtlpriv->cfg->ops->phy_lc_calibrate(hw, false);
1490 }
1491 EXPORT_SYMBOL(rtl92c_phy_lc_calibrate);
1492
1493 void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
1494 {
1495         struct rtl_priv *rtlpriv = rtl_priv(hw);
1496         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1497         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1498
1499         if (rtlphy->apk_done)
1500                 return;
1501         if (IS_92C_SERIAL(rtlhal->version))
1502                 _rtl92c_phy_ap_calibrate(hw, delta, true);
1503         else
1504                 _rtl92c_phy_ap_calibrate(hw, delta, false);
1505 }
1506 EXPORT_SYMBOL(rtl92c_phy_ap_calibrate);
1507
1508 void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1509 {
1510         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1511
1512         if (IS_92C_SERIAL(rtlhal->version))
1513                 _rtl92c_phy_set_rfpath_switch(hw, bmain, true);
1514         else
1515                 _rtl92c_phy_set_rfpath_switch(hw, bmain, false);
1516 }
1517 EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch);
1518
1519 bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1520 {
1521         struct rtl_priv *rtlpriv = rtl_priv(hw);
1522         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1523         bool postprocessing = false;
1524
1525         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1526                  "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1527                   iotype, rtlphy->set_io_inprogress);
1528         do {
1529                 switch (iotype) {
1530                 case IO_CMD_RESUME_DM_BY_SCAN:
1531                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1532                                  "[IO CMD] Resume DM after scan.\n");
1533                         postprocessing = true;
1534                         break;
1535                 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1536                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1537                                  "[IO CMD] Pause DM before scan.\n");
1538                         postprocessing = true;
1539                         break;
1540                 default:
1541                         RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1542                                  "switch case %#x not processed\n", iotype);
1543                         break;
1544                 }
1545         } while (false);
1546         if (postprocessing && !rtlphy->set_io_inprogress) {
1547                 rtlphy->set_io_inprogress = true;
1548                 rtlphy->current_io_type = iotype;
1549         } else {
1550                 return false;
1551         }
1552         rtl92c_phy_set_io(hw);
1553         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
1554         return true;
1555 }
1556 EXPORT_SYMBOL(rtl92c_phy_set_io_cmd);
1557
1558 void rtl92c_phy_set_io(struct ieee80211_hw *hw)
1559 {
1560         struct rtl_priv *rtlpriv = rtl_priv(hw);
1561         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1562         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1563
1564         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1565                  "--->Cmd(%#x), set_io_inprogress(%d)\n",
1566                   rtlphy->current_io_type, rtlphy->set_io_inprogress);
1567         switch (rtlphy->current_io_type) {
1568         case IO_CMD_RESUME_DM_BY_SCAN:
1569                 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1570                 rtl92c_dm_write_dig(hw);
1571                 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1572                 break;
1573         case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1574                 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1575                 dm_digtable->cur_igvalue = 0x17;
1576                 rtl92c_dm_write_dig(hw);
1577                 break;
1578         default:
1579                 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1580                          "switch case %#x not processed\n",
1581                          rtlphy->current_io_type);
1582                 break;
1583         }
1584         rtlphy->set_io_inprogress = false;
1585         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1586                  "(%#x)\n", rtlphy->current_io_type);
1587 }
1588 EXPORT_SYMBOL(rtl92c_phy_set_io);
1589
1590 void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw)
1591 {
1592         struct rtl_priv *rtlpriv = rtl_priv(hw);
1593
1594         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1595         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1596         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1597         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1598         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1599         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1600 }
1601 EXPORT_SYMBOL(rtl92ce_phy_set_rf_on);
1602
1603 void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw)
1604 {
1605         u32 u4b_tmp;
1606         u8 delay = 5;
1607         struct rtl_priv *rtlpriv = rtl_priv(hw);
1608
1609         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1610         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1611         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1612         u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1613         while (u4b_tmp != 0 && delay > 0) {
1614                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1615                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1616                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1617                 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1618                 delay--;
1619         }
1620         if (delay == 0) {
1621                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1622                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1623                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1624                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1625                 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1626                          "Switch RF timeout !!!.\n");
1627                 return;
1628         }
1629         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1630         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1631 }
1632 EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep);