rtlwifi: rtl8192ce: Rework rtl8192ce/phy.c
[pandora-kernel.git] / drivers / net / wireless / rtlwifi / rtl8192ce / phy.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  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 "../wifi.h"
31 #include "../pci.h"
32 #include "../ps.h"
33 #include "reg.h"
34 #include "def.h"
35 #include "phy.h"
36 #include "rf.h"
37 #include "dm.h"
38 #include "table.h"
39
40 /* Define macro to shorten lines */
41 #define MCS_TXPWR       mcs_txpwrlevel_origoffset
42
43 static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
44                                          enum radio_path rfpath, u32 offset);
45 static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
46                                            enum radio_path rfpath, u32 offset,
47                                            u32 data);
48 static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
49                                       enum radio_path rfpath, u32 offset);
50 static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
51                                         enum radio_path rfpath, u32 offset,
52                                         u32 data);
53 static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);
54 static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
55 static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
56 static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
57                                                   u8 configtype);
58 static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
59                                                     u8 configtype);
60 static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
61 static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
62                                              u32 cmdtableidx, u32 cmdtablesz,
63                                              enum swchnlcmd_id cmdid, u32 para1,
64                                              u32 para2, u32 msdelay);
65 static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
66                                              u8 channel, u8 *stage, u8 *step,
67                                              u32 *delay);
68 static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
69                                        enum wireless_mode wirelessmode,
70                                        long power_indbm);
71 static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw,
72                                               enum radio_path rfpath);
73 static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
74                                          enum wireless_mode wirelessmode,
75                                          u8 txpwridx);
76 u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
77 {
78         struct rtl_priv *rtlpriv = rtl_priv(hw);
79         u32 returnvalue, originalvalue, bitshift;
80
81         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
82                                                "bitmask(%#x)\n", regaddr,
83                                                bitmask));
84         originalvalue = rtl_read_dword(rtlpriv, regaddr);
85         bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
86         returnvalue = (originalvalue & bitmask) >> bitshift;
87
88         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
89                                                "Addr[0x%x]=0x%x\n", bitmask,
90                                                regaddr, originalvalue));
91
92         return returnvalue;
93
94 }
95
96 void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
97                            u32 regaddr, u32 bitmask, u32 data)
98 {
99         struct rtl_priv *rtlpriv = rtl_priv(hw);
100         u32 originalvalue, bitshift;
101
102         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
103                                                " data(%#x)\n", regaddr, bitmask,
104                                                data));
105
106         if (bitmask != MASKDWORD) {
107                 originalvalue = rtl_read_dword(rtlpriv, regaddr);
108                 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
109                 data = ((originalvalue & (~bitmask)) | (data << bitshift));
110         }
111
112         rtl_write_dword(rtlpriv, regaddr, data);
113
114         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
115                                                " data(%#x)\n", regaddr, bitmask,
116                                                data));
117
118 }
119
120 u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
121                             enum radio_path rfpath, u32 regaddr, u32 bitmask)
122 {
123         struct rtl_priv *rtlpriv = rtl_priv(hw);
124         u32 original_value, readback_value, bitshift;
125         struct rtl_phy *rtlphy = &(rtlpriv->phy);
126         unsigned long flags;
127
128         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
129                                                "rfpath(%#x), bitmask(%#x)\n",
130                                                regaddr, rfpath, bitmask));
131
132         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
133
134         if (rtlphy->rf_mode != RF_OP_BY_FW) {
135                 original_value = _rtl92c_phy_rf_serial_read(hw,
136                                                             rfpath, regaddr);
137         } else {
138                 original_value = _rtl92c_phy_fw_rf_serial_read(hw,
139                                                                rfpath, regaddr);
140         }
141
142         bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
143         readback_value = (original_value & bitmask) >> bitshift;
144
145         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
146
147         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
148                  ("regaddr(%#x), rfpath(%#x), "
149                   "bitmask(%#x), original_value(%#x)\n",
150                   regaddr, rfpath, bitmask, original_value));
151
152         return readback_value;
153 }
154
155 void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
156                            enum radio_path rfpath,
157                            u32 regaddr, u32 bitmask, u32 data)
158 {
159         struct rtl_priv *rtlpriv = rtl_priv(hw);
160         struct rtl_phy *rtlphy = &(rtlpriv->phy);
161         u32 original_value, bitshift;
162         unsigned long flags;
163
164         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
165                  ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
166                   regaddr, bitmask, data, rfpath));
167
168         spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
169
170         if (rtlphy->rf_mode != RF_OP_BY_FW) {
171                 if (bitmask != RFREG_OFFSET_MASK) {
172                         original_value = _rtl92c_phy_rf_serial_read(hw,
173                                                                     rfpath,
174                                                                     regaddr);
175                         bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
176                         data =
177                             ((original_value & (~bitmask)) |
178                              (data << bitshift));
179                 }
180
181                 _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
182         } else {
183                 if (bitmask != RFREG_OFFSET_MASK) {
184                         original_value = _rtl92c_phy_fw_rf_serial_read(hw,
185                                                                        rfpath,
186                                                                        regaddr);
187                         bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
188                         data =
189                             ((original_value & (~bitmask)) |
190                              (data << bitshift));
191                 }
192                 _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
193         }
194
195         spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
196
197         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
198                                                "bitmask(%#x), data(%#x), "
199                                                "rfpath(%#x)\n", regaddr,
200                                                bitmask, data, rfpath));
201 }
202
203 static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
204                                          enum radio_path rfpath, u32 offset)
205 {
206         RT_ASSERT(false, ("deprecated!\n"));
207         return 0;
208 }
209
210 static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
211                                            enum radio_path rfpath, u32 offset,
212                                            u32 data)
213 {
214         RT_ASSERT(false, ("deprecated!\n"));
215 }
216
217 static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
218                                       enum radio_path rfpath, u32 offset)
219 {
220         struct rtl_priv *rtlpriv = rtl_priv(hw);
221         struct rtl_phy *rtlphy = &(rtlpriv->phy);
222         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
223         u32 newoffset;
224         u32 tmplong, tmplong2;
225         u8 rfpi_enable = 0;
226         u32 retvalue;
227
228         offset &= 0x3f;
229         newoffset = offset;
230         if (RT_CANNOT_IO(hw)) {
231                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n"));
232                 return 0xFFFFFFFF;
233         }
234         tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
235         if (rfpath == RF90_PATH_A)
236                 tmplong2 = tmplong;
237         else
238                 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
239         tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
240             (newoffset << 23) | BLSSIREADEDGE;
241         rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
242                       tmplong & (~BLSSIREADEDGE));
243         mdelay(1);
244         rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
245         mdelay(1);
246         rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
247                       tmplong | BLSSIREADEDGE);
248         mdelay(1);
249         if (rfpath == RF90_PATH_A)
250                 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
251                                                  BIT(8));
252         else if (rfpath == RF90_PATH_B)
253                 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
254                                                  BIT(8));
255         if (rfpi_enable)
256                 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
257                                          BLSSIREADBACKDATA);
258         else
259                 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
260                                          BLSSIREADBACKDATA);
261         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
262                                                rfpath, pphyreg->rflssi_readback,
263                                                retvalue));
264         return retvalue;
265 }
266
267 static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
268                                         enum radio_path rfpath, u32 offset,
269                                         u32 data)
270 {
271         u32 data_and_addr;
272         u32 newoffset;
273         struct rtl_priv *rtlpriv = rtl_priv(hw);
274         struct rtl_phy *rtlphy = &(rtlpriv->phy);
275         struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
276
277         if (RT_CANNOT_IO(hw)) {
278                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n"));
279                 return;
280         }
281         offset &= 0x3f;
282         newoffset = offset;
283         data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
284         rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
285         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
286                                                rfpath, pphyreg->rf3wire_offset,
287                                                data_and_addr));
288 }
289
290 static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
291 {
292         u32 i;
293
294         for (i = 0; i <= 31; i++) {
295                 if (((bitmask >> i) & 0x1) == 1)
296                         break;
297         }
298         return i;
299 }
300
301 static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
302 {
303         rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
304         rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
305         rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
306         rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
307         rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
308         rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
309         rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
310         rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
311         rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
312         rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
313 }
314
315 bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
316 {
317         struct rtl_priv *rtlpriv = rtl_priv(hw);
318         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
319         bool is92c = IS_92C_SERIAL(rtlhal->version);
320         bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
321
322         if (is92c)
323                 rtl_write_byte(rtlpriv, 0x14, 0x71);
324         return rtstatus;
325 }
326
327 bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
328 {
329         bool rtstatus = true;
330         struct rtl_priv *rtlpriv = rtl_priv(hw);
331         u16 regval;
332         u32 regvaldw;
333         u8 b_reg_hwparafile = 1;
334
335         _rtl92c_phy_init_bb_rf_register_definition(hw);
336         regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
337         rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
338                        regval | BIT(13) | BIT(0) | BIT(1));
339         rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
340         rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
341         rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
342         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
343                        FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
344                        FEN_BB_GLB_RSTn | FEN_BBRSTB);
345         rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
346         regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
347         rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
348         if (b_reg_hwparafile == 1)
349                 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
350         return rtstatus;
351 }
352
353 bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
354 {
355         return rtl92c_phy_rf6052_config(hw);
356 }
357
358 static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
359 {
360         struct rtl_priv *rtlpriv = rtl_priv(hw);
361         struct rtl_phy *rtlphy = &(rtlpriv->phy);
362         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
363         bool rtstatus;
364
365         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
366         rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw,
367                                                  BASEBAND_CONFIG_PHY_REG);
368         if (rtstatus != true) {
369                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
370                 return false;
371         }
372         if (rtlphy->rf_type == RF_1T2R) {
373                 _rtl92c_phy_bb_config_1t(hw);
374                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
375         }
376         if (rtlefuse->autoload_failflag == false) {
377                 rtlphy->pwrgroup_cnt = 0;
378                 rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw,
379                                                    BASEBAND_CONFIG_PHY_REG);
380         }
381         if (rtstatus != true) {
382                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
383                 return false;
384         }
385         rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw,
386                                                  BASEBAND_CONFIG_AGC_TAB);
387         if (rtstatus != true) {
388                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
389                 return false;
390         }
391         rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw,
392                                                 RFPGA0_XA_HSSIPARAMETER2,
393                                                 0x200));
394         return true;
395 }
396
397 static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
398 {
399         struct rtl_priv *rtlpriv = rtl_priv(hw);
400         u32 i;
401         u32 arraylength;
402         u32 *ptrarray;
403
404         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
405         arraylength = MAC_2T_ARRAYLENGTH;
406         ptrarray = RTL8192CEMAC_2T_ARRAY;
407         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
408                  ("Img:RTL8192CEMAC_2T_ARRAY\n"));
409         for (i = 0; i < arraylength; i = i + 2)
410                 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
411         return true;
412 }
413
414 void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw)
415 {
416 }
417
418 static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
419                                                   u8 configtype)
420 {
421         int i;
422         u32 *phy_regarray_table;
423         u32 *agctab_array_table;
424         u16 phy_reg_arraylen, agctab_arraylen;
425         struct rtl_priv *rtlpriv = rtl_priv(hw);
426         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
427
428         if (IS_92C_SERIAL(rtlhal->version)) {
429                 agctab_arraylen = AGCTAB_2TARRAYLENGTH;
430                 agctab_array_table = RTL8192CEAGCTAB_2TARRAY;
431                 phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH;
432                 phy_regarray_table = RTL8192CEPHY_REG_2TARRAY;
433         } else {
434                 agctab_arraylen = AGCTAB_1TARRAYLENGTH;
435                 agctab_array_table = RTL8192CEAGCTAB_1TARRAY;
436                 phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH;
437                 phy_regarray_table = RTL8192CEPHY_REG_1TARRAY;
438         }
439         if (configtype == BASEBAND_CONFIG_PHY_REG) {
440                 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
441                         if (phy_regarray_table[i] == 0xfe)
442                                 mdelay(50);
443                         else if (phy_regarray_table[i] == 0xfd)
444                                 mdelay(5);
445                         else if (phy_regarray_table[i] == 0xfc)
446                                 mdelay(1);
447                         else if (phy_regarray_table[i] == 0xfb)
448                                 udelay(50);
449                         else if (phy_regarray_table[i] == 0xfa)
450                                 udelay(5);
451                         else if (phy_regarray_table[i] == 0xf9)
452                                 udelay(1);
453                         rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
454                                       phy_regarray_table[i + 1]);
455                         udelay(1);
456                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
457                                  ("The phy_regarray_table[0] is %x"
458                                   " Rtl819XPHY_REGArray[1] is %x\n",
459                                   phy_regarray_table[i],
460                                   phy_regarray_table[i + 1]));
461                 }
462                 rtl92c_phy_config_bb_external_pa(hw);
463         } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
464                 for (i = 0; i < agctab_arraylen; i = i + 2) {
465                         rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
466                                       agctab_array_table[i + 1]);
467                         udelay(1);
468                         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
469                                  ("The agctab_array_table[0] is "
470                                   "%x Rtl819XPHY_REGArray[1] is %x\n",
471                                   agctab_array_table[i],
472                                   agctab_array_table[i + 1]));
473                 }
474         }
475         return true;
476 }
477
478 static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
479                                                    u32 regaddr, u32 bitmask,
480                                                    u32 data)
481 {
482         struct rtl_priv *rtlpriv = rtl_priv(hw);
483         struct rtl_phy *rtlphy = &(rtlpriv->phy);
484
485         if (regaddr == RTXAGC_A_RATE18_06) {
486                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data;
487                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
488                          ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
489                           rtlphy->pwrgroup_cnt,
490                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]));
491         }
492         if (regaddr == RTXAGC_A_RATE54_24) {
493                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data;
494                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
495                          ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
496                           rtlphy->pwrgroup_cnt,
497                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]));
498         }
499         if (regaddr == RTXAGC_A_CCK1_MCS32) {
500                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data;
501                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
502                          ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
503                           rtlphy->pwrgroup_cnt,
504                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]));
505         }
506         if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
507                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data;
508                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
509                          ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
510                           rtlphy->pwrgroup_cnt,
511                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]));
512         }
513         if (regaddr == RTXAGC_A_MCS03_MCS00) {
514                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data;
515                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
516                          ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
517                           rtlphy->pwrgroup_cnt,
518                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]));
519         }
520         if (regaddr == RTXAGC_A_MCS07_MCS04) {
521                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data;
522                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
523                          ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
524                           rtlphy->pwrgroup_cnt,
525                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]));
526         }
527         if (regaddr == RTXAGC_A_MCS11_MCS08) {
528                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data;
529                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
530                          ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
531                           rtlphy->pwrgroup_cnt,
532                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]));
533         }
534         if (regaddr == RTXAGC_A_MCS15_MCS12) {
535                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data;
536                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
537                          ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
538                           rtlphy->pwrgroup_cnt,
539                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]));
540         }
541         if (regaddr == RTXAGC_B_RATE18_06) {
542                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data;
543                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
544                          ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
545                           rtlphy->pwrgroup_cnt,
546                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]));
547         }
548         if (regaddr == RTXAGC_B_RATE54_24) {
549                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
550
551                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
552                          ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
553                           rtlphy->pwrgroup_cnt,
554                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));
555         }
556
557         if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
558                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
559
560                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
561                          ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
562                           rtlphy->pwrgroup_cnt,
563                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));
564         }
565
566         if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
567                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
568
569                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
570                          ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
571                           rtlphy->pwrgroup_cnt,
572                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));
573         }
574
575         if (regaddr == RTXAGC_B_MCS03_MCS00) {
576                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
577
578                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
579                          ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
580                           rtlphy->pwrgroup_cnt,
581                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));
582         }
583
584         if (regaddr == RTXAGC_B_MCS07_MCS04) {
585                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
586
587                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
588                          ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
589                           rtlphy->pwrgroup_cnt,
590                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));
591         }
592
593         if (regaddr == RTXAGC_B_MCS11_MCS08) {
594                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
595
596                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
597                          ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
598                           rtlphy->pwrgroup_cnt,
599                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));
600         }
601
602         if (regaddr == RTXAGC_B_MCS15_MCS12) {
603                 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
604
605                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
606                          ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
607                           rtlphy->pwrgroup_cnt,
608                           rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]));
609
610                 rtlphy->pwrgroup_cnt++;
611         }
612 }
613
614 static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
615                                                     u8 configtype)
616 {
617         struct rtl_priv *rtlpriv = rtl_priv(hw);
618         int i;
619         u32 *phy_regarray_table_pg;
620         u16 phy_regarray_pg_len;
621
622         phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH;
623         phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG;
624
625         if (configtype == BASEBAND_CONFIG_PHY_REG) {
626                 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
627                         if (phy_regarray_table_pg[i] == 0xfe)
628                                 mdelay(50);
629                         else if (phy_regarray_table_pg[i] == 0xfd)
630                                 mdelay(5);
631                         else if (phy_regarray_table_pg[i] == 0xfc)
632                                 mdelay(1);
633                         else if (phy_regarray_table_pg[i] == 0xfb)
634                                 udelay(50);
635                         else if (phy_regarray_table_pg[i] == 0xfa)
636                                 udelay(5);
637                         else if (phy_regarray_table_pg[i] == 0xf9)
638                                 udelay(1);
639
640                         _rtl92c_store_pwrIndex_diffrate_offset(hw,
641                                                phy_regarray_table_pg[i],
642                                                phy_regarray_table_pg[i + 1],
643                                                phy_regarray_table_pg[i + 2]);
644                 }
645         } else {
646
647                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
648                          ("configtype != BaseBand_Config_PHY_REG\n"));
649         }
650         return true;
651 }
652
653 static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw,
654                                               enum radio_path rfpath)
655 {
656         return true;
657 }
658
659 bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
660                                           enum radio_path rfpath)
661 {
662
663         int i;
664         bool rtstatus = true;
665         u32 *radioa_array_table;
666         u32 *radiob_array_table;
667         u16 radioa_arraylen, radiob_arraylen;
668         struct rtl_priv *rtlpriv = rtl_priv(hw);
669         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
670
671         if (IS_92C_SERIAL(rtlhal->version)) {
672                 radioa_arraylen = RADIOA_2TARRAYLENGTH;
673                 radioa_array_table = RTL8192CERADIOA_2TARRAY;
674                 radiob_arraylen = RADIOB_2TARRAYLENGTH;
675                 radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
676                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
677                          ("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
678                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
679                          ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
680         } else {
681                 radioa_arraylen = RADIOA_1TARRAYLENGTH;
682                 radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
683                 radiob_arraylen = RADIOB_1TARRAYLENGTH;
684                 radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
685                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
686                          ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
687                 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
688                          ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
689         }
690         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
691         rtstatus = true;
692         switch (rfpath) {
693         case RF90_PATH_A:
694                 for (i = 0; i < radioa_arraylen; i = i + 2) {
695                         if (radioa_array_table[i] == 0xfe)
696                                 mdelay(50);
697                         else if (radioa_array_table[i] == 0xfd)
698                                 mdelay(5);
699                         else if (radioa_array_table[i] == 0xfc)
700                                 mdelay(1);
701                         else if (radioa_array_table[i] == 0xfb)
702                                 udelay(50);
703                         else if (radioa_array_table[i] == 0xfa)
704                                 udelay(5);
705                         else if (radioa_array_table[i] == 0xf9)
706                                 udelay(1);
707                         else {
708                                 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
709                                               RFREG_OFFSET_MASK,
710                                               radioa_array_table[i + 1]);
711                                 udelay(1);
712                         }
713                 }
714                 _rtl92c_phy_config_rf_external_pa(hw, rfpath);
715                 break;
716         case RF90_PATH_B:
717                 for (i = 0; i < radiob_arraylen; i = i + 2) {
718                         if (radiob_array_table[i] == 0xfe) {
719                                 mdelay(50);
720                         } else if (radiob_array_table[i] == 0xfd)
721                                 mdelay(5);
722                         else if (radiob_array_table[i] == 0xfc)
723                                 mdelay(1);
724                         else if (radiob_array_table[i] == 0xfb)
725                                 udelay(50);
726                         else if (radiob_array_table[i] == 0xfa)
727                                 udelay(5);
728                         else if (radiob_array_table[i] == 0xf9)
729                                 udelay(1);
730                         else {
731                                 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
732                                               RFREG_OFFSET_MASK,
733                                               radiob_array_table[i + 1]);
734                                 udelay(1);
735                         }
736                 }
737                 break;
738         case RF90_PATH_C:
739                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
740                          ("switch case not process\n"));
741                 break;
742         case RF90_PATH_D:
743                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
744                          ("switch case not process\n"));
745                 break;
746         }
747         return true;
748 }
749
750 void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
751 {
752         struct rtl_priv *rtlpriv = rtl_priv(hw);
753         struct rtl_phy *rtlphy = &(rtlpriv->phy);
754
755         rtlphy->default_initialgain[0] =
756             (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
757         rtlphy->default_initialgain[1] =
758             (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
759         rtlphy->default_initialgain[2] =
760             (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
761         rtlphy->default_initialgain[3] =
762             (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
763
764         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
765                  ("Default initial gain (c50=0x%x, "
766                   "c58=0x%x, c60=0x%x, c68=0x%x\n",
767                   rtlphy->default_initialgain[0],
768                   rtlphy->default_initialgain[1],
769                   rtlphy->default_initialgain[2],
770                   rtlphy->default_initialgain[3]));
771
772         rtlphy->framesync = (u8) rtl_get_bbreg(hw,
773                                                ROFDM0_RXDETECTOR3, MASKBYTE0);
774         rtlphy->framesync_c34 = rtl_get_bbreg(hw,
775                                               ROFDM0_RXDETECTOR2, MASKDWORD);
776
777         RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
778                  ("Default framesync (0x%x) = 0x%x\n",
779                   ROFDM0_RXDETECTOR3, rtlphy->framesync));
780 }
781
782 static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
783 {
784         struct rtl_priv *rtlpriv = rtl_priv(hw);
785         struct rtl_phy *rtlphy = &(rtlpriv->phy);
786
787         rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
788         rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
789         rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
790         rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
791
792         rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
793         rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
794         rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
795         rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
796
797         rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
798         rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
799
800         rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
801         rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
802
803         rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
804             RFPGA0_XA_LSSIPARAMETER;
805         rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
806             RFPGA0_XB_LSSIPARAMETER;
807
808         rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
809         rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
810         rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
811         rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
812
813         rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
814         rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
815         rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
816         rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
817
818         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
819         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
820
821         rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
822         rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
823
824         rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
825             RFPGA0_XAB_SWITCHCONTROL;
826         rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
827             RFPGA0_XAB_SWITCHCONTROL;
828         rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
829             RFPGA0_XCD_SWITCHCONTROL;
830         rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
831             RFPGA0_XCD_SWITCHCONTROL;
832
833         rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
834         rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
835         rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
836         rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
837
838         rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
839         rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
840         rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
841         rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
842
843         rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
844             ROFDM0_XARXIQIMBALANCE;
845         rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
846             ROFDM0_XBRXIQIMBALANCE;
847         rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
848             ROFDM0_XCRXIQIMBANLANCE;
849         rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
850             ROFDM0_XDRXIQIMBALANCE;
851
852         rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
853         rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
854         rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
855         rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
856
857         rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
858             ROFDM0_XATXIQIMBALANCE;
859         rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
860             ROFDM0_XBTXIQIMBALANCE;
861         rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
862             ROFDM0_XCTXIQIMBALANCE;
863         rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
864             ROFDM0_XDTXIQIMBALANCE;
865
866         rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
867         rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
868         rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
869         rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
870
871         rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
872             RFPGA0_XA_LSSIREADBACK;
873         rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
874             RFPGA0_XB_LSSIREADBACK;
875         rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
876             RFPGA0_XC_LSSIREADBACK;
877         rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
878             RFPGA0_XD_LSSIREADBACK;
879
880         rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
881             TRANSCEIVEA_HSPI_READBACK;
882         rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
883             TRANSCEIVEB_HSPI_READBACK;
884
885 }
886
887 void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
888 {
889         struct rtl_priv *rtlpriv = rtl_priv(hw);
890         struct rtl_phy *rtlphy = &(rtlpriv->phy);
891         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
892         u8 txpwr_level;
893         long txpwr_dbm;
894
895         txpwr_level = rtlphy->cur_cck_txpwridx;
896         txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw,
897                                                  WIRELESS_MODE_B, txpwr_level);
898         txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
899             rtlefuse->legacy_ht_txpowerdiff;
900         if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
901                                          WIRELESS_MODE_G,
902                                          txpwr_level) > txpwr_dbm)
903                 txpwr_dbm =
904                     _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
905                                                  txpwr_level);
906         txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
907         if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
908                                          WIRELESS_MODE_N_24G,
909                                          txpwr_level) > txpwr_dbm)
910                 txpwr_dbm =
911                     _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
912                                                  txpwr_level);
913         *powerlevel = txpwr_dbm;
914 }
915
916 static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
917                                       u8 *cckpowerlevel, u8 *ofdmpowerlevel)
918 {
919         struct rtl_priv *rtlpriv = rtl_priv(hw);
920         struct rtl_phy *rtlphy = &(rtlpriv->phy);
921         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
922         u8 index = (channel - 1);
923
924         cckpowerlevel[RF90_PATH_A] =
925             rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
926         cckpowerlevel[RF90_PATH_B] =
927             rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
928         if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
929                 ofdmpowerlevel[RF90_PATH_A] =
930                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
931                 ofdmpowerlevel[RF90_PATH_B] =
932                     rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
933         } else if (get_rf_type(rtlphy) == RF_2T2R) {
934                 ofdmpowerlevel[RF90_PATH_A] =
935                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
936                 ofdmpowerlevel[RF90_PATH_B] =
937                     rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
938         }
939 }
940
941 static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
942                                          u8 channel, u8 *cckpowerlevel,
943                                          u8 *ofdmpowerlevel)
944 {
945         struct rtl_priv *rtlpriv = rtl_priv(hw);
946         struct rtl_phy *rtlphy = &(rtlpriv->phy);
947
948         rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
949         rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
950 }
951
952 void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
953 {
954         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
955         u8 cckpowerlevel[2], ofdmpowerlevel[2];
956
957         if (rtlefuse->b_txpwr_fromeprom == false)
958                 return;
959         _rtl92c_get_txpower_index(hw, channel,
960                                   &cckpowerlevel[0], &ofdmpowerlevel[0]);
961         _rtl92c_ccxpower_index_check(hw,
962                                      channel, &cckpowerlevel[0],
963                                      &ofdmpowerlevel[0]);
964         rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
965         rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
966 }
967
968 bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
969 {
970         struct rtl_priv *rtlpriv = rtl_priv(hw);
971         struct rtl_phy *rtlphy = &(rtlpriv->phy);
972         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
973         u8 idx;
974         u8 rf_path;
975
976         u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
977                                                       WIRELESS_MODE_B,
978                                                       power_indbm);
979         u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
980                                                        WIRELESS_MODE_N_24G,
981                                                        power_indbm);
982         if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
983                 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
984         else
985                 ofdmtxpwridx = 0;
986         RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
987                  ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
988                   power_indbm, ccktxpwridx, ofdmtxpwridx));
989         for (idx = 0; idx < 14; idx++) {
990                 for (rf_path = 0; rf_path < 2; rf_path++) {
991                         rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
992                         rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
993                             ofdmtxpwridx;
994                         rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
995                             ofdmtxpwridx;
996                 }
997         }
998         rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
999         return true;
1000 }
1001
1002 void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval)
1003 {
1004 }
1005
1006 static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
1007                                        enum wireless_mode wirelessmode,
1008                                        long power_indbm)
1009 {
1010         u8 txpwridx;
1011         long offset;
1012
1013         switch (wirelessmode) {
1014         case WIRELESS_MODE_B:
1015                 offset = -7;
1016                 break;
1017         case WIRELESS_MODE_G:
1018         case WIRELESS_MODE_N_24G:
1019                 offset = -8;
1020                 break;
1021         default:
1022                 offset = -8;
1023                 break;
1024         }
1025
1026         if ((power_indbm - offset) > 0)
1027                 txpwridx = (u8) ((power_indbm - offset) * 2);
1028         else
1029                 txpwridx = 0;
1030
1031         if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
1032                 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
1033
1034         return txpwridx;
1035 }
1036
1037 static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1038                                          enum wireless_mode wirelessmode,
1039                                          u8 txpwridx)
1040 {
1041         long offset;
1042         long pwrout_dbm;
1043
1044         switch (wirelessmode) {
1045         case WIRELESS_MODE_B:
1046                 offset = -7;
1047                 break;
1048         case WIRELESS_MODE_G:
1049         case WIRELESS_MODE_N_24G:
1050                 offset = -8;
1051                 break;
1052         default:
1053                 offset = -8;
1054                 break;
1055         }
1056         pwrout_dbm = txpwridx / 2 + offset;
1057         return pwrout_dbm;
1058 }
1059
1060 void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1061 {
1062         struct rtl_priv *rtlpriv = rtl_priv(hw);
1063         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1064         enum io_type iotype;
1065
1066         if (!is_hal_stop(rtlhal)) {
1067                 switch (operation) {
1068                 case SCAN_OPT_BACKUP:
1069                         iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1070                         rtlpriv->cfg->ops->set_hw_reg(hw,
1071                                                       HW_VAR_IO_CMD,
1072                                                       (u8 *)&iotype);
1073
1074                         break;
1075                 case SCAN_OPT_RESTORE:
1076                         iotype = IO_CMD_RESUME_DM_BY_SCAN;
1077                         rtlpriv->cfg->ops->set_hw_reg(hw,
1078                                                       HW_VAR_IO_CMD,
1079                                                       (u8 *)&iotype);
1080                         break;
1081                 default:
1082                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1083                                  ("Unknown Scan Backup operation.\n"));
1084                         break;
1085                 }
1086         }
1087 }
1088
1089 void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1090 {
1091         struct rtl_priv *rtlpriv = rtl_priv(hw);
1092         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1093         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1094         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1095         u8 reg_bw_opmode;
1096         u8 reg_prsr_rsc;
1097
1098         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1099                  ("Switch to %s bandwidth\n",
1100                   rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1101                   "20MHz" : "40MHz"))
1102
1103             if (is_hal_stop(rtlhal))
1104                 return;
1105
1106         reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1107         reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1108
1109         switch (rtlphy->current_chan_bw) {
1110         case HT_CHANNEL_WIDTH_20:
1111                 reg_bw_opmode |= BW_OPMODE_20MHZ;
1112                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1113                 break;
1114
1115         case HT_CHANNEL_WIDTH_20_40:
1116                 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1117                 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1118
1119                 reg_prsr_rsc =
1120                     (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
1121                 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1122                 break;
1123
1124         default:
1125                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1126                          ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
1127                 break;
1128         }
1129
1130         switch (rtlphy->current_chan_bw) {
1131         case HT_CHANNEL_WIDTH_20:
1132                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1133                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1134                 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
1135                 break;
1136         case HT_CHANNEL_WIDTH_20_40:
1137                 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1138                 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1139                 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1140                               (mac->cur_40_prime_sc >> 1));
1141                 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1142                 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
1143                 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1144                               (mac->cur_40_prime_sc ==
1145                                HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1146                 break;
1147         default:
1148                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1149                          ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
1150                 break;
1151         }
1152         rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1153         rtlphy->set_bwmode_inprogress = false;
1154         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
1155 }
1156
1157 void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
1158                             enum nl80211_channel_type ch_type)
1159 {
1160         struct rtl_priv *rtlpriv = rtl_priv(hw);
1161         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1162         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1163         u8 tmp_bw = rtlphy->current_chan_bw;
1164
1165         if (rtlphy->set_bwmode_inprogress)
1166                 return;
1167         rtlphy->set_bwmode_inprogress = true;
1168         if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
1169                 rtl92c_phy_set_bw_mode_callback(hw);
1170         else {
1171                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1172                          ("FALSE driver sleep or unload\n"));
1173                 rtlphy->set_bwmode_inprogress = false;
1174                 rtlphy->current_chan_bw = tmp_bw;
1175         }
1176 }
1177
1178 void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1179 {
1180         struct rtl_priv *rtlpriv = rtl_priv(hw);
1181         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1182         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1183         u32 delay;
1184
1185         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1186                  ("switch to channel%d\n", rtlphy->current_channel));
1187         if (is_hal_stop(rtlhal))
1188                 return;
1189         do {
1190                 if (!rtlphy->sw_chnl_inprogress)
1191                         break;
1192                 if (!_rtl92c_phy_sw_chnl_step_by_step
1193                     (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1194                      &rtlphy->sw_chnl_step, &delay)) {
1195                         if (delay > 0)
1196                                 mdelay(delay);
1197                         else
1198                                 continue;
1199                 } else
1200                         rtlphy->sw_chnl_inprogress = false;
1201                 break;
1202         } while (true);
1203         RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
1204 }
1205
1206 u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
1207 {
1208         struct rtl_priv *rtlpriv = rtl_priv(hw);
1209         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1210         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1211
1212         if (rtlphy->sw_chnl_inprogress)
1213                 return 0;
1214         if (rtlphy->set_bwmode_inprogress)
1215                 return 0;
1216         RT_ASSERT((rtlphy->current_channel <= 14),
1217                   ("WIRELESS_MODE_G but channel>14"));
1218         rtlphy->sw_chnl_inprogress = true;
1219         rtlphy->sw_chnl_stage = 0;
1220         rtlphy->sw_chnl_step = 0;
1221         if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1222                 rtl92c_phy_sw_chnl_callback(hw);
1223                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1224                          ("sw_chnl_inprogress false schdule workitem\n"));
1225                 rtlphy->sw_chnl_inprogress = false;
1226         } else {
1227                 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1228                          ("sw_chnl_inprogress false driver sleep or"
1229                           " unload\n"));
1230                 rtlphy->sw_chnl_inprogress = false;
1231         }
1232         return 1;
1233 }
1234
1235 static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1236                                              u8 channel, u8 *stage, u8 *step,
1237                                              u32 *delay)
1238 {
1239         struct rtl_priv *rtlpriv = rtl_priv(hw);
1240         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1241         struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1242         u32 precommoncmdcnt;
1243         struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1244         u32 postcommoncmdcnt;
1245         struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1246         u32 rfdependcmdcnt;
1247         struct swchnlcmd *currentcmd = NULL;
1248         u8 rfpath;
1249         u8 num_total_rfpath = rtlphy->num_total_rfpath;
1250
1251         precommoncmdcnt = 0;
1252         _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1253                                          MAX_PRECMD_CNT,
1254                                          CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
1255         _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1256                                          MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1257
1258         postcommoncmdcnt = 0;
1259
1260         _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1261                                          MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1262
1263         rfdependcmdcnt = 0;
1264
1265         RT_ASSERT((channel >= 1 && channel <= 14),
1266                   ("illegal channel for Zebra: %d\n", channel));
1267
1268         _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1269                                          MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
1270                                          RF_CHNLBW, channel, 10);
1271
1272         _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1273                                          MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
1274                                          0);
1275
1276         do {
1277                 switch (*stage) {
1278                 case 0:
1279                         currentcmd = &precommoncmd[*step];
1280                         break;
1281                 case 1:
1282                         currentcmd = &rfdependcmd[*step];
1283                         break;
1284                 case 2:
1285                         currentcmd = &postcommoncmd[*step];
1286                         break;
1287                 }
1288
1289                 if (currentcmd->cmdid == CMDID_END) {
1290                         if ((*stage) == 2) {
1291                                 return true;
1292                         } else {
1293                                 (*stage)++;
1294                                 (*step) = 0;
1295                                 continue;
1296                         }
1297                 }
1298
1299                 switch (currentcmd->cmdid) {
1300                 case CMDID_SET_TXPOWEROWER_LEVEL:
1301                         rtl92c_phy_set_txpower_level(hw, channel);
1302                         break;
1303                 case CMDID_WRITEPORT_ULONG:
1304                         rtl_write_dword(rtlpriv, currentcmd->para1,
1305                                         currentcmd->para2);
1306                         break;
1307                 case CMDID_WRITEPORT_USHORT:
1308                         rtl_write_word(rtlpriv, currentcmd->para1,
1309                                        (u16) currentcmd->para2);
1310                         break;
1311                 case CMDID_WRITEPORT_UCHAR:
1312                         rtl_write_byte(rtlpriv, currentcmd->para1,
1313                                        (u8) currentcmd->para2);
1314                         break;
1315                 case CMDID_RF_WRITEREG:
1316                         for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1317                                 rtlphy->rfreg_chnlval[rfpath] =
1318                                     ((rtlphy->rfreg_chnlval[rfpath] &
1319                                       0xfffffc00) | currentcmd->para2);
1320
1321                                 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1322                                               currentcmd->para1,
1323                                               RFREG_OFFSET_MASK,
1324                                               rtlphy->rfreg_chnlval[rfpath]);
1325                         }
1326                         break;
1327                 default:
1328                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1329                                  ("switch case not process\n"));
1330                         break;
1331                 }
1332
1333                 break;
1334         } while (true);
1335
1336         (*delay) = currentcmd->msdelay;
1337         (*step)++;
1338         return false;
1339 }
1340
1341 static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1342                                              u32 cmdtableidx, u32 cmdtablesz,
1343                                              enum swchnlcmd_id cmdid,
1344                                              u32 para1, u32 para2, u32 msdelay)
1345 {
1346         struct swchnlcmd *pcmd;
1347
1348         if (cmdtable == NULL) {
1349                 RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
1350                 return false;
1351         }
1352
1353         if (cmdtableidx >= cmdtablesz)
1354                 return false;
1355
1356         pcmd = cmdtable + cmdtableidx;
1357         pcmd->cmdid = cmdid;
1358         pcmd->para1 = para1;
1359         pcmd->para2 = para2;
1360         pcmd->msdelay = msdelay;
1361         return true;
1362 }
1363
1364 bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
1365 {
1366         return true;
1367 }
1368
1369 static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1370 {
1371         u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1372         u8 result = 0x00;
1373
1374         rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
1375         rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
1376         rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
1377         rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
1378                       config_pathb ? 0x28160202 : 0x28160502);
1379
1380         if (config_pathb) {
1381                 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
1382                 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
1383                 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
1384                 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
1385         }
1386
1387         rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
1388         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1389         rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1390
1391         mdelay(IQK_DELAY_TIME);
1392
1393         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1394         reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1395         reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1396         reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1397
1398         if (!(reg_eac & BIT(28)) &&
1399             (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1400             (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1401                 result |= 0x01;
1402         else
1403                 return result;
1404
1405         if (!(reg_eac & BIT(27)) &&
1406             (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1407             (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1408                 result |= 0x02;
1409         return result;
1410 }
1411
1412 static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
1413 {
1414         u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1415         u8 result = 0x00;
1416
1417         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1418         rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1419         mdelay(IQK_DELAY_TIME);
1420         reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1421         reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1422         reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1423         reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1424         reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1425         if (!(reg_eac & BIT(31)) &&
1426             (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1427             (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1428                 result |= 0x01;
1429         else
1430                 return result;
1431
1432         if (!(reg_eac & BIT(30)) &&
1433             (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1434             (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1435                 result |= 0x02;
1436         return result;
1437 }
1438
1439 static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
1440                                                bool b_iqk_ok, long result[][8],
1441                                                u8 final_candidate, bool btxonly)
1442 {
1443         u32 oldval_0, x, tx0_a, reg;
1444         long y, tx0_c;
1445
1446         if (final_candidate == 0xFF)
1447                 return;
1448         else if (b_iqk_ok) {
1449                 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1450                                           MASKDWORD) >> 22) & 0x3FF;
1451                 x = result[final_candidate][0];
1452                 if ((x & 0x00000200) != 0)
1453                         x = x | 0xFFFFFC00;
1454                 tx0_a = (x * oldval_0) >> 8;
1455                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1456                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1457                               ((x * oldval_0 >> 7) & 0x1));
1458                 y = result[final_candidate][1];
1459                 if ((y & 0x00000200) != 0)
1460                         y = y | 0xFFFFFC00;
1461                 tx0_c = (y * oldval_0) >> 8;
1462                 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1463                               ((tx0_c & 0x3C0) >> 6));
1464                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1465                               (tx0_c & 0x3F));
1466                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1467                               ((y * oldval_0 >> 7) & 0x1));
1468                 if (btxonly)
1469                         return;
1470                 reg = result[final_candidate][2];
1471                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1472                 reg = result[final_candidate][3] & 0x3F;
1473                 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1474                 reg = (result[final_candidate][3] >> 6) & 0xF;
1475                 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1476         }
1477 }
1478
1479 static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1480                                                bool b_iqk_ok, long result[][8],
1481                                                u8 final_candidate, bool btxonly)
1482 {
1483         u32 oldval_1, x, tx1_a, reg;
1484         long y, tx1_c;
1485
1486         if (final_candidate == 0xFF)
1487                 return;
1488         else if (b_iqk_ok) {
1489                 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1490                                           MASKDWORD) >> 22) & 0x3FF;
1491                 x = result[final_candidate][4];
1492                 if ((x & 0x00000200) != 0)
1493                         x = x | 0xFFFFFC00;
1494                 tx1_a = (x * oldval_1) >> 8;
1495                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1496                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1497                               ((x * oldval_1 >> 7) & 0x1));
1498                 y = result[final_candidate][5];
1499                 if ((y & 0x00000200) != 0)
1500                         y = y | 0xFFFFFC00;
1501                 tx1_c = (y * oldval_1) >> 8;
1502                 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1503                               ((tx1_c & 0x3C0) >> 6));
1504                 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1505                               (tx1_c & 0x3F));
1506                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1507                               ((y * oldval_1 >> 7) & 0x1));
1508                 if (btxonly)
1509                         return;
1510                 reg = result[final_candidate][6];
1511                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1512                 reg = result[final_candidate][7] & 0x3F;
1513                 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1514                 reg = (result[final_candidate][7] >> 6) & 0xF;
1515                 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
1516         }
1517 }
1518
1519 static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw,
1520                                             u32 *addareg, u32 *addabackup,
1521                                             u32 registernum)
1522 {
1523         u32 i;
1524
1525         for (i = 0; i < registernum; i++)
1526                 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1527 }
1528
1529 static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw,
1530                                            u32 *macreg, u32 *macbackup)
1531 {
1532         struct rtl_priv *rtlpriv = rtl_priv(hw);
1533         u32 i;
1534
1535         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1536                 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1537         macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1538 }
1539
1540 static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw,
1541                                               u32 *addareg, u32 *addabackup,
1542                                               u32 regiesternum)
1543 {
1544         u32 i;
1545
1546         for (i = 0; i < regiesternum; i++)
1547                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1548 }
1549
1550 static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw,
1551                                              u32 *macreg, u32 *macbackup)
1552 {
1553         struct rtl_priv *rtlpriv = rtl_priv(hw);
1554         u32 i;
1555
1556         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1557                 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1558         rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1559 }
1560
1561 static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw,
1562                                      u32 *addareg, bool is_patha_on, bool is2t)
1563 {
1564         u32 pathOn;
1565         u32 i;
1566
1567         pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1568         if (false == is2t) {
1569                 pathOn = 0x0bdb25a0;
1570                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1571         } else {
1572                 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1573         }
1574
1575         for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1576                 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1577 }
1578
1579 static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1580                                                 u32 *macreg, u32 *macbackup)
1581 {
1582         struct rtl_priv *rtlpriv = rtl_priv(hw);
1583         u32 i;
1584
1585         rtl_write_byte(rtlpriv, macreg[0], 0x3F);
1586
1587         for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1588                 rtl_write_byte(rtlpriv, macreg[i],
1589                                (u8) (macbackup[i] & (~BIT(3))));
1590         rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1591 }
1592
1593 static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw)
1594 {
1595         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1596         rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1597         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1598 }
1599
1600 static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1601 {
1602         u32 mode;
1603
1604         mode = pi_mode ? 0x01000100 : 0x01000000;
1605         rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1606         rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1607 }
1608
1609 static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw,
1610                                            long result[][8], u8 c1, u8 c2)
1611 {
1612         u32 i, j, diff, simularity_bitmap, bound;
1613         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1614
1615         u8 final_candidate[2] = { 0xFF, 0xFF };
1616         bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1617
1618         if (is2t)
1619                 bound = 8;
1620         else
1621                 bound = 4;
1622
1623         simularity_bitmap = 0;
1624
1625         for (i = 0; i < bound; i++) {
1626                 diff = (result[c1][i] > result[c2][i]) ?
1627                     (result[c1][i] - result[c2][i]) :
1628                     (result[c2][i] - result[c1][i]);
1629
1630                 if (diff > MAX_TOLERANCE) {
1631                         if ((i == 2 || i == 6) && !simularity_bitmap) {
1632                                 if (result[c1][i] + result[c1][i + 1] == 0)
1633                                         final_candidate[(i / 4)] = c2;
1634                                 else if (result[c2][i] + result[c2][i + 1] == 0)
1635                                         final_candidate[(i / 4)] = c1;
1636                                 else
1637                                         simularity_bitmap = simularity_bitmap |
1638                                             (1 << i);
1639                         } else
1640                                 simularity_bitmap =
1641                                     simularity_bitmap | (1 << i);
1642                 }
1643         }
1644
1645         if (simularity_bitmap == 0) {
1646                 for (i = 0; i < (bound / 4); i++) {
1647                         if (final_candidate[i] != 0xFF) {
1648                                 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1649                                         result[3][j] =
1650                                             result[final_candidate[i]][j];
1651                                 bresult = false;
1652                         }
1653                 }
1654                 return bresult;
1655         } else if (!(simularity_bitmap & 0x0F)) {
1656                 for (i = 0; i < 4; i++)
1657                         result[3][i] = result[c1][i];
1658                 return false;
1659         } else if (!(simularity_bitmap & 0xF0) && is2t) {
1660                 for (i = 4; i < 8; i++)
1661                         result[3][i] = result[c1][i];
1662                 return false;
1663         } else {
1664                 return false;
1665         }
1666
1667 }
1668
1669 static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1670                                      long result[][8], u8 t, bool is2t)
1671 {
1672         struct rtl_priv *rtlpriv = rtl_priv(hw);
1673         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1674         u32 i;
1675         u8 patha_ok, pathb_ok;
1676         u32 adda_reg[IQK_ADDA_REG_NUM] = {
1677                 0x85c, 0xe6c, 0xe70, 0xe74,
1678                 0xe78, 0xe7c, 0xe80, 0xe84,
1679                 0xe88, 0xe8c, 0xed0, 0xed4,
1680                 0xed8, 0xedc, 0xee0, 0xeec
1681         };
1682
1683         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1684                 0x522, 0x550, 0x551, 0x040
1685         };
1686
1687         const u32 retrycount = 2;
1688
1689         u32 bbvalue;
1690
1691         if (t == 0) {
1692                 bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
1693
1694                 _rtl92c_phy_save_adda_registers(hw, adda_reg,
1695                                                 rtlphy->adda_backup, 16);
1696                 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1697                                                rtlphy->iqk_mac_backup);
1698         }
1699         _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1700         if (t == 0) {
1701                 rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw,
1702                                                    RFPGA0_XA_HSSIPARAMETER1,
1703                                                    BIT(8));
1704         }
1705         if (!rtlphy->b_rfpi_enable)
1706                 _rtl92c_phy_pi_mode_switch(hw, true);
1707         if (t == 0) {
1708                 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1709                 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1710                 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1711         }
1712         rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1713         rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1714         rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1715         if (is2t) {
1716                 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1717                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1718         }
1719         _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg,
1720                                             rtlphy->iqk_mac_backup);
1721         rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1722         if (is2t)
1723                 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1724         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1725         rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1726         rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1727         for (i = 0; i < retrycount; i++) {
1728                 patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t);
1729                 if (patha_ok == 0x03) {
1730                         result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1731                                         0x3FF0000) >> 16;
1732                         result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1733                                         0x3FF0000) >> 16;
1734                         result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1735                                         0x3FF0000) >> 16;
1736                         result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1737                                         0x3FF0000) >> 16;
1738                         break;
1739                 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1740                         result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1741                                                       MASKDWORD) & 0x3FF0000) >>
1742                                                       16;
1743                 result[t][1] =
1744                     (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1745
1746         }
1747
1748         if (is2t) {
1749                 _rtl92c_phy_path_a_standby(hw);
1750                 _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t);
1751                 for (i = 0; i < retrycount; i++) {
1752                         pathb_ok = _rtl92c_phy_path_b_iqk(hw);
1753                         if (pathb_ok == 0x03) {
1754                                 result[t][4] = (rtl_get_bbreg(hw,
1755                                                       0xeb4,
1756                                                       MASKDWORD) &
1757                                                 0x3FF0000) >> 16;
1758                                 result[t][5] =
1759                                     (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1760                                      0x3FF0000) >> 16;
1761                                 result[t][6] =
1762                                     (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1763                                      0x3FF0000) >> 16;
1764                                 result[t][7] =
1765                                     (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1766                                      0x3FF0000) >> 16;
1767                                 break;
1768                         } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1769                                 result[t][4] = (rtl_get_bbreg(hw,
1770                                                       0xeb4,
1771                                                       MASKDWORD) &
1772                                                 0x3FF0000) >> 16;
1773                         }
1774                         result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1775                                         0x3FF0000) >> 16;
1776                 }
1777         }
1778         rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1779         rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1780         rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1781         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1782         rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1783         if (is2t)
1784                 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1785         if (t != 0) {
1786                 if (!rtlphy->b_rfpi_enable)
1787                         _rtl92c_phy_pi_mode_switch(hw, false);
1788                 _rtl92c_phy_reload_adda_registers(hw, adda_reg,
1789                                                   rtlphy->adda_backup, 16);
1790                 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1791                                                  rtlphy->iqk_mac_backup);
1792         }
1793 }
1794
1795 static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1796 {
1797         u8 tmpreg;
1798         u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1799         struct rtl_priv *rtlpriv = rtl_priv(hw);
1800
1801         tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1802
1803         if ((tmpreg & 0x70) != 0)
1804                 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1805         else
1806                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1807
1808         if ((tmpreg & 0x70) != 0) {
1809                 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1810
1811                 if (is2t)
1812                         rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1813                                                   MASK12BITS);
1814
1815                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1816                               (rf_a_mode & 0x8FFFF) | 0x10000);
1817
1818                 if (is2t)
1819                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1820                                       (rf_b_mode & 0x8FFFF) | 0x10000);
1821         }
1822         lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1823
1824         rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1825
1826         mdelay(100);
1827
1828         if ((tmpreg & 0x70) != 0) {
1829                 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1830                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1831
1832                 if (is2t)
1833                         rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1834                                       rf_b_mode);
1835         } else {
1836                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1837         }
1838 }
1839
1840 static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
1841                                      char delta, bool is2t)
1842 {
1843         /* This routine is deliberately dummied out for later fixes */
1844 #if 0
1845         struct rtl_priv *rtlpriv = rtl_priv(hw);
1846         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1847         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1848
1849         u32 reg_d[PATH_NUM];
1850         u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound;
1851
1852         u32 bb_backup[APK_BB_REG_NUM];
1853         u32 bb_reg[APK_BB_REG_NUM] = {
1854                 0x904, 0xc04, 0x800, 0xc08, 0x874
1855         };
1856         u32 bb_ap_mode[APK_BB_REG_NUM] = {
1857                 0x00000020, 0x00a05430, 0x02040000,
1858                 0x000800e4, 0x00204000
1859         };
1860         u32 bb_normal_ap_mode[APK_BB_REG_NUM] = {
1861                 0x00000020, 0x00a05430, 0x02040000,
1862                 0x000800e4, 0x22204000
1863         };
1864
1865         u32 afe_backup[APK_AFE_REG_NUM];
1866         u32 afe_reg[APK_AFE_REG_NUM] = {
1867                 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78,
1868                 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
1869                 0xed0, 0xed4, 0xed8, 0xedc, 0xee0,
1870                 0xeec
1871         };
1872
1873         u32 mac_backup[IQK_MAC_REG_NUM];
1874         u32 mac_reg[IQK_MAC_REG_NUM] = {
1875                 0x522, 0x550, 0x551, 0x040
1876         };
1877
1878         u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1879                 {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
1880                 {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
1881         };
1882
1883         u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1884                 {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c},
1885                 {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
1886         };
1887
1888         u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1889                 {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
1890                 {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
1891         };
1892
1893         u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1894                 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a},
1895                 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
1896         };
1897
1898         u32 afe_on_off[PATH_NUM] = {
1899                 0x04db25a4, 0x0b1b25a4
1900         };
1901
1902         u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
1903
1904         u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 };
1905
1906         u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 };
1907
1908         u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 };
1909
1910         const char apk_delta_mapping[APK_BB_REG_NUM][13] = {
1911                 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1912                 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1913                 {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1914                 {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1915                 {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
1916         };
1917
1918         const u32 apk_normal_setting_value_1[13] = {
1919                 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
1920                 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
1921                 0x12680000, 0x00880000, 0x00880000
1922         };
1923
1924         const u32 apk_normal_setting_value_2[16] = {
1925                 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
1926                 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
1927                 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
1928                 0x00050006
1929         };
1930
1931         const u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
1932
1933         long bb_offset, delta_v, delta_offset;
1934
1935         if (!is2t)
1936                 pathbound = 1;
1937
1938         for (index = 0; index < PATH_NUM; index++) {
1939                 apk_offset[index] = apk_normal_offset[index];
1940                 apk_value[index] = apk_normal_value[index];
1941                 afe_on_off[index] = 0x6fdb25a4;
1942         }
1943
1944         for (index = 0; index < APK_BB_REG_NUM; index++) {
1945                 for (path = 0; path < pathbound; path++) {
1946                         apk_rf_init_value[path][index] =
1947                             apk_normal_rf_init_value[path][index];
1948                         apk_rf_value_0[path][index] =
1949                             apk_normal_rf_value_0[path][index];
1950                 }
1951                 bb_ap_mode[index] = bb_normal_ap_mode[index];
1952
1953                 apkbound = 6;
1954         }
1955
1956         for (index = 0; index < APK_BB_REG_NUM; index++) {
1957                 if (index == 0)
1958                         continue;
1959                 bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD);
1960         }
1961
1962         _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup);
1963
1964         _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16);
1965
1966         for (path = 0; path < pathbound; path++) {
1967                 if (path == RF90_PATH_A) {
1968                         offset = 0xb00;
1969                         for (index = 0; index < 11; index++) {
1970                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1971                                               apk_normal_setting_value_1
1972                                               [index]);
1973
1974                                 offset += 0x04;
1975                         }
1976
1977                         rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
1978
1979                         offset = 0xb68;
1980                         for (; index < 13; index++) {
1981                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1982                                               apk_normal_setting_value_1
1983                                               [index]);
1984
1985                                 offset += 0x04;
1986                         }
1987
1988                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
1989
1990                         offset = 0xb00;
1991                         for (index = 0; index < 16; index++) {
1992                                 rtl_set_bbreg(hw, offset, MASKDWORD,
1993                                               apk_normal_setting_value_2
1994                                               [index]);
1995
1996                                 offset += 0x04;
1997                         }
1998                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1999                 } else if (path == RF90_PATH_B) {
2000                         offset = 0xb70;
2001                         for (index = 0; index < 10; index++) {
2002                                 rtl_set_bbreg(hw, offset, MASKDWORD,
2003                                               apk_normal_setting_value_1
2004                                               [index]);
2005
2006                                 offset += 0x04;
2007                         }
2008                         rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000);
2009                         rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
2010
2011                         offset = 0xb68;
2012                         index = 11;
2013                         for (; index < 13; index++) {
2014                                 rtl_set_bbreg(hw, offset, MASKDWORD,
2015                                               apk_normal_setting_value_1
2016                                               [index]);
2017
2018                                 offset += 0x04;
2019                         }
2020
2021                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
2022
2023                         offset = 0xb60;
2024                         for (index = 0; index < 16; index++) {
2025                                 rtl_set_bbreg(hw, offset, MASKDWORD,
2026                                               apk_normal_setting_value_2
2027                                               [index]);
2028
2029                                 offset += 0x04;
2030                         }
2031                         rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2032                 }
2033
2034                 reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path,
2035                                             0xd, MASKDWORD);
2036
2037                 for (index = 0; index < APK_AFE_REG_NUM; index++)
2038                         rtl_set_bbreg(hw, afe_reg[index], MASKDWORD,
2039                                       afe_on_off[path]);
2040
2041                 if (path == RF90_PATH_A) {
2042                         for (index = 0; index < APK_BB_REG_NUM; index++) {
2043                                 if (index == 0)
2044                                         continue;
2045                                 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD,
2046                                               bb_ap_mode[index]);
2047                         }
2048                 }
2049
2050                 _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup);
2051
2052                 if (path == 0) {
2053                         rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000);
2054                 } else {
2055                         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD,
2056                                       0x10000);
2057                         rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
2058                                       0x1000f);
2059                         rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
2060                                       0x20103);
2061                 }
2062
2063                 delta_offset = ((delta + 14) / 2);
2064                 if (delta_offset < 0)
2065                         delta_offset = 0;
2066                 else if (delta_offset > 12)
2067                         delta_offset = 12;
2068
2069                 for (index = 0; index < APK_BB_REG_NUM; index++) {
2070                         if (index != 1)
2071                                 continue;
2072
2073                         tmpreg = apk_rf_init_value[path][index];
2074
2075                         if (!rtlefuse->b_apk_thermalmeterignore) {
2076                                 bb_offset = (tmpreg & 0xF0000) >> 16;
2077
2078                                 if (!(tmpreg & BIT(15)))
2079                                         bb_offset = -bb_offset;
2080
2081                                 delta_v =
2082                                     apk_delta_mapping[index][delta_offset];
2083
2084                                 bb_offset += delta_v;
2085
2086                                 if (bb_offset < 0) {
2087                                         tmpreg = tmpreg & (~BIT(15));
2088                                         bb_offset = -bb_offset;
2089                                 } else {
2090                                         tmpreg = tmpreg | BIT(15);
2091                                 }
2092
2093                                 tmpreg =
2094                                     (tmpreg & 0xFFF0FFFF) | (bb_offset << 16);
2095                         }
2096
2097                         rtl_set_rfreg(hw, (enum radio_path)path, 0xc,
2098                                       MASKDWORD, 0x8992e);
2099                         rtl_set_rfreg(hw, (enum radio_path)path, 0x0,
2100                                       MASKDWORD, apk_rf_value_0[path][index]);
2101                         rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
2102                                       MASKDWORD, tmpreg);
2103
2104                         i = 0;
2105                         do {
2106                                 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000);
2107                                 rtl_set_bbreg(hw, apk_offset[path],
2108                                               MASKDWORD, apk_value[0]);
2109                                 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2110                                         ("PHY_APCalibrate() offset 0x%x "
2111                                          "value 0x%x\n",
2112                                          apk_offset[path],
2113                                          rtl_get_bbreg(hw, apk_offset[path],
2114                                                        MASKDWORD)));
2115
2116                                 mdelay(3);
2117
2118                                 rtl_set_bbreg(hw, apk_offset[path],
2119                                               MASKDWORD, apk_value[1]);
2120                                 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2121                                         ("PHY_APCalibrate() offset 0x%x "
2122                                          "value 0x%x\n",
2123                                          apk_offset[path],
2124                                          rtl_get_bbreg(hw, apk_offset[path],
2125                                                        MASKDWORD)));
2126
2127                                 mdelay(20);
2128
2129                                 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2130
2131                                 if (path == RF90_PATH_A)
2132                                         tmpreg = rtl_get_bbreg(hw, 0xbd8,
2133                                                                0x03E00000);
2134                                 else
2135                                         tmpreg = rtl_get_bbreg(hw, 0xbd8,
2136                                                                0xF8000000);
2137
2138                                 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2139                                         ("PHY_APCalibrate() offset "
2140                                          "0xbd8[25:21] %x\n", tmpreg));
2141
2142                                 i++;
2143
2144                         } while (tmpreg > apkbound && i < 4);
2145
2146                         apk_result[path][index] = tmpreg;
2147                 }
2148         }
2149
2150         _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup);
2151
2152         for (index = 0; index < APK_BB_REG_NUM; index++) {
2153                 if (index == 0)
2154                         continue;
2155                 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]);
2156         }
2157
2158         _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16);
2159
2160         for (path = 0; path < pathbound; path++) {
2161                 rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
2162                               MASKDWORD, reg_d[path]);
2163
2164                 if (path == RF90_PATH_B) {
2165                         rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
2166                                       0x1000f);
2167                         rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
2168                                       0x20101);
2169                 }
2170
2171                 if (apk_result[path][1] > 6)
2172                         apk_result[path][1] = 6;
2173         }
2174
2175         for (path = 0; path < pathbound; path++) {
2176                 rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD,
2177                               ((apk_result[path][1] << 15) |
2178                                (apk_result[path][1] << 10) |
2179                                (apk_result[path][1] << 5) |
2180                                apk_result[path][1]));
2181
2182                 if (path == RF90_PATH_A)
2183                         rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
2184                                       ((apk_result[path][1] << 15) |
2185                                        (apk_result[path][1] << 10) |
2186                                        (0x00 << 5) | 0x05));
2187                 else
2188                         rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
2189                                       ((apk_result[path][1] << 15) |
2190                                        (apk_result[path][1] << 10) |
2191                                        (0x02 << 5) | 0x05));
2192
2193                 rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD,
2194                               ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) |
2195                                0x08));
2196
2197         }
2198
2199         rtlphy->b_apk_done = true;
2200 #endif
2201 }
2202
2203 static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2204                                           bool bmain, bool is2t)
2205 {
2206         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2207
2208         if (is_hal_stop(rtlhal)) {
2209                 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
2210                 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
2211         }
2212         if (is2t) {
2213                 if (bmain)
2214                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2215                                       BIT(5) | BIT(6), 0x1);
2216                 else
2217                         rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2218                                       BIT(5) | BIT(6), 0x2);
2219         } else {
2220                 if (bmain)
2221                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
2222                 else
2223                         rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
2224
2225         }
2226 }
2227
2228 #undef IQK_ADDA_REG_NUM
2229 #undef IQK_DELAY_TIME
2230
2231 void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2232 {
2233         struct rtl_priv *rtlpriv = rtl_priv(hw);
2234         struct rtl_phy *rtlphy = &(rtlpriv->phy);
2235         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2236
2237         long result[4][8];
2238         u8 i, final_candidate;
2239         bool b_patha_ok, b_pathb_ok;
2240         long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
2241             reg_ecc, reg_tmp = 0;
2242         bool is12simular, is13simular, is23simular;
2243         bool b_start_conttx = false, b_singletone = false;
2244         u32 iqk_bb_reg[10] = {
2245                 ROFDM0_XARXIQIMBALANCE,
2246                 ROFDM0_XBRXIQIMBALANCE,
2247                 ROFDM0_ECCATHRESHOLD,
2248                 ROFDM0_AGCRSSITABLE,
2249                 ROFDM0_XATXIQIMBALANCE,
2250                 ROFDM0_XBTXIQIMBALANCE,
2251                 ROFDM0_XCTXIQIMBALANCE,
2252                 ROFDM0_XCTXAFE,
2253                 ROFDM0_XDTXAFE,
2254                 ROFDM0_RXIQEXTANTA
2255         };
2256
2257         if (b_recovery) {
2258                 _rtl92c_phy_reload_adda_registers(hw,
2259                                                   iqk_bb_reg,
2260                                                   rtlphy->iqk_bb_backup, 10);
2261                 return;
2262         }
2263         if (b_start_conttx || b_singletone)
2264                 return;
2265         for (i = 0; i < 8; i++) {
2266                 result[0][i] = 0;
2267                 result[1][i] = 0;
2268                 result[2][i] = 0;
2269                 result[3][i] = 0;
2270         }
2271         final_candidate = 0xff;
2272         b_patha_ok = false;
2273         b_pathb_ok = false;
2274         is12simular = false;
2275         is23simular = false;
2276         is13simular = false;
2277         for (i = 0; i < 3; i++) {
2278                 if (IS_92C_SERIAL(rtlhal->version))
2279                         _rtl92c_phy_iq_calibrate(hw, result, i, true);
2280                 else
2281                         _rtl92c_phy_iq_calibrate(hw, result, i, false);
2282                 if (i == 1) {
2283                         is12simular = _rtl92c_phy_simularity_compare(hw,
2284                                                                      result, 0,
2285                                                                      1);
2286                         if (is12simular) {
2287                                 final_candidate = 0;
2288                                 break;
2289                         }
2290                 }
2291                 if (i == 2) {
2292                         is13simular = _rtl92c_phy_simularity_compare(hw,
2293                                                                      result, 0,
2294                                                                      2);
2295                         if (is13simular) {
2296                                 final_candidate = 0;
2297                                 break;
2298                         }
2299                         is23simular = _rtl92c_phy_simularity_compare(hw,
2300                                                                      result, 1,
2301                                                                      2);
2302                         if (is23simular)
2303                                 final_candidate = 1;
2304                         else {
2305                                 for (i = 0; i < 8; i++)
2306                                         reg_tmp += result[3][i];
2307
2308                                 if (reg_tmp != 0)
2309                                         final_candidate = 3;
2310                                 else
2311                                         final_candidate = 0xFF;
2312                         }
2313                 }
2314         }
2315         for (i = 0; i < 4; i++) {
2316                 reg_e94 = result[i][0];
2317                 reg_e9c = result[i][1];
2318                 reg_ea4 = result[i][2];
2319                 reg_eac = result[i][3];
2320                 reg_eb4 = result[i][4];
2321                 reg_ebc = result[i][5];
2322                 reg_ec4 = result[i][6];
2323                 reg_ecc = result[i][7];
2324         }
2325         if (final_candidate != 0xff) {
2326                 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
2327                 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
2328                 reg_ea4 = result[final_candidate][2];
2329                 reg_eac = result[final_candidate][3];
2330                 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
2331                 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
2332                 reg_ec4 = result[final_candidate][6];
2333                 reg_ecc = result[final_candidate][7];
2334                 b_patha_ok = b_pathb_ok = true;
2335         } else {
2336                 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
2337                 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
2338         }
2339         if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
2340                 _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2341                                                    final_candidate,
2342                                                    (reg_ea4 == 0));
2343         if (IS_92C_SERIAL(rtlhal->version)) {
2344                 if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */
2345                         _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok,
2346                                                            result,
2347                                                            final_candidate,
2348                                                            (reg_ec4 == 0));
2349         }
2350         _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg,
2351                                         rtlphy->iqk_bb_backup, 10);
2352 }
2353
2354 void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw)
2355 {
2356         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2357         bool b_start_conttx = false, b_singletone = false;
2358
2359         if (b_start_conttx || b_singletone)
2360                 return;
2361         if (IS_92C_SERIAL(rtlhal->version))
2362                 _rtl92c_phy_lc_calibrate(hw, true);
2363         else
2364                 _rtl92c_phy_lc_calibrate(hw, false);
2365 }
2366
2367 void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
2368 {
2369         struct rtl_priv *rtlpriv = rtl_priv(hw);
2370         struct rtl_phy *rtlphy = &(rtlpriv->phy);
2371         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2372
2373         if (rtlphy->b_apk_done)
2374                 return;
2375         if (IS_92C_SERIAL(rtlhal->version))
2376                 _rtl92c_phy_ap_calibrate(hw, delta, true);
2377         else
2378                 _rtl92c_phy_ap_calibrate(hw, delta, false);
2379 }
2380
2381 void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2382 {
2383         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2384
2385         if (IS_92C_SERIAL(rtlhal->version))
2386                 _rtl92c_phy_set_rfpath_switch(hw, bmain, true);
2387         else
2388                 _rtl92c_phy_set_rfpath_switch(hw, bmain, false);
2389 }
2390
2391 bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2392 {
2393         struct rtl_priv *rtlpriv = rtl_priv(hw);
2394         struct rtl_phy *rtlphy = &(rtlpriv->phy);
2395         bool b_postprocessing = false;
2396
2397         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2398                  ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2399                   iotype, rtlphy->set_io_inprogress));
2400         do {
2401                 switch (iotype) {
2402                 case IO_CMD_RESUME_DM_BY_SCAN:
2403                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2404                                  ("[IO CMD] Resume DM after scan.\n"));
2405                         b_postprocessing = true;
2406                         break;
2407                 case IO_CMD_PAUSE_DM_BY_SCAN:
2408                         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2409                                  ("[IO CMD] Pause DM before scan.\n"));
2410                         b_postprocessing = true;
2411                         break;
2412                 default:
2413                         RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2414                                  ("switch case not process\n"));
2415                         break;
2416                 }
2417         } while (false);
2418         if (b_postprocessing && !rtlphy->set_io_inprogress) {
2419                 rtlphy->set_io_inprogress = true;
2420                 rtlphy->current_io_type = iotype;
2421         } else {
2422                 return false;
2423         }
2424         rtl92c_phy_set_io(hw);
2425         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
2426         return true;
2427 }
2428
2429 void rtl92c_phy_set_io(struct ieee80211_hw *hw)
2430 {
2431         struct rtl_priv *rtlpriv = rtl_priv(hw);
2432         struct rtl_phy *rtlphy = &(rtlpriv->phy);
2433
2434         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2435                  ("--->Cmd(%#x), set_io_inprogress(%d)\n",
2436                   rtlphy->current_io_type, rtlphy->set_io_inprogress));
2437         switch (rtlphy->current_io_type) {
2438         case IO_CMD_RESUME_DM_BY_SCAN:
2439                 dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2440                 rtl92c_dm_write_dig(hw);
2441                 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
2442                 break;
2443         case IO_CMD_PAUSE_DM_BY_SCAN:
2444                 rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue;
2445                 dm_digtable.cur_igvalue = 0x17;
2446                 rtl92c_dm_write_dig(hw);
2447                 break;
2448         default:
2449                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2450                          ("switch case not process\n"));
2451                 break;
2452         }
2453         rtlphy->set_io_inprogress = false;
2454         RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2455                  ("<---(%#x)\n", rtlphy->current_io_type));
2456 }
2457
2458 void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw)
2459 {
2460         struct rtl_priv *rtlpriv = rtl_priv(hw);
2461
2462         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2463         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2464         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2465         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2466         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2467         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2468 }
2469
2470 static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
2471 {
2472         u32 u4b_tmp;
2473         u8 delay = 5;
2474         struct rtl_priv *rtlpriv = rtl_priv(hw);
2475
2476         rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2477         rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2478         rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2479         u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2480         while (u4b_tmp != 0 && delay > 0) {
2481                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
2482                 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2483                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2484                 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2485                 delay--;
2486         }
2487         if (delay == 0) {
2488                 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2489                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2490                 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2491                 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2492                 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
2493                          ("Switch RF timeout !!!.\n"));
2494                 return;
2495         }
2496         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2497         rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2498 }
2499
2500 static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
2501                                             enum rf_pwrstate rfpwr_state)
2502 {
2503         struct rtl_priv *rtlpriv = rtl_priv(hw);
2504         struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2505         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2506         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2507         bool bresult = true;
2508         u8 i, queue_id;
2509         struct rtl8192_tx_ring *ring = NULL;
2510
2511         ppsc->set_rfpowerstate_inprogress = true;
2512         switch (rfpwr_state) {
2513         case ERFON:{
2514                         if ((ppsc->rfpwr_state == ERFOFF) &&
2515                             RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2516                                 bool rtstatus;
2517                                 u32 InitializeCount = 0;
2518                                 do {
2519                                         InitializeCount++;
2520                                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2521                                                  ("IPS Set eRf nic enable\n"));
2522                                         rtstatus = rtl_ps_enable_nic(hw);
2523                                 } while ((rtstatus != true)
2524                                          && (InitializeCount < 10));
2525                                 RT_CLEAR_PS_LEVEL(ppsc,
2526                                                   RT_RF_OFF_LEVL_HALT_NIC);
2527                         } else {
2528                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2529                                          ("Set ERFON sleeped:%d ms\n",
2530                                           jiffies_to_msecs(jiffies -
2531                                                    ppsc->
2532                                                    last_sleep_jiffies)));
2533                                 ppsc->last_awake_jiffies = jiffies;
2534                                 rtl92ce_phy_set_rf_on(hw);
2535                         }
2536                         if (mac->link_state == MAC80211_LINKED) {
2537                                 rtlpriv->cfg->ops->led_control(hw,
2538                                                                LED_CTL_LINK);
2539                         } else {
2540                                 rtlpriv->cfg->ops->led_control(hw,
2541                                                                LED_CTL_NO_LINK);
2542                         }
2543                         break;
2544                 }
2545         case ERFOFF:{
2546                         for (queue_id = 0, i = 0;
2547                              queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2548                                 ring = &pcipriv->dev.tx_ring[queue_id];
2549                                 if (skb_queue_len(&ring->queue) == 0 ||
2550                                     queue_id == BEACON_QUEUE) {
2551                                         queue_id++;
2552                                         continue;
2553                                 } else {
2554                                         RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2555                                                  ("eRf Off/Sleep: %d times "
2556                                                   "TcbBusyQueue[%d] "
2557                                                   "=%d before doze!\n", (i + 1),
2558                                                   queue_id,
2559                                                   skb_queue_len(&ring->queue)));
2560                                         udelay(10);
2561                                         i++;
2562                                 }
2563                                 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2564                                         RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2565                                                  ("\nERFOFF: %d times "
2566                                                   "TcbBusyQueue[%d] = %d !\n",
2567                                                   MAX_DOZE_WAITING_TIMES_9x,
2568                                                   queue_id,
2569                                                   skb_queue_len(&ring->queue)));
2570                                         break;
2571                                 }
2572                         }
2573                         if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2574                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2575                                          ("IPS Set eRf nic disable\n"));
2576                                 rtl_ps_disable_nic(hw);
2577                                 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2578                         } else {
2579                                 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2580                                         rtlpriv->cfg->ops->led_control(hw,
2581                                                                LED_CTL_NO_LINK);
2582                                 } else {
2583                                         rtlpriv->cfg->ops->led_control(hw,
2584                                                              LED_CTL_POWER_OFF);
2585                                 }
2586                         }
2587                         break;
2588                 }
2589         case ERFSLEEP:{
2590                         if (ppsc->rfpwr_state == ERFOFF)
2591                                 break;
2592                         for (queue_id = 0, i = 0;
2593                              queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2594                                 ring = &pcipriv->dev.tx_ring[queue_id];
2595                                 if (skb_queue_len(&ring->queue) == 0) {
2596                                         queue_id++;
2597                                         continue;
2598                                 } else {
2599                                         RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2600                                                  ("eRf Off/Sleep: %d times "
2601                                                   "TcbBusyQueue[%d] =%d before "
2602                                                   "doze!\n", (i + 1), queue_id,
2603                                                   skb_queue_len(&ring->queue)));
2604                                         udelay(10);
2605                                         i++;
2606                                 }
2607                                 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2608                                         RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2609                                                  ("\n ERFSLEEP: %d times "
2610                                                   "TcbBusyQueue[%d] = %d !\n",
2611                                                   MAX_DOZE_WAITING_TIMES_9x,
2612                                                   queue_id,
2613                                                   skb_queue_len(&ring->queue)));
2614                                         break;
2615                                 }
2616                         }
2617                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2618                                  ("Set ERFSLEEP awaked:%d ms\n",
2619                                   jiffies_to_msecs(jiffies -
2620                                                    ppsc->last_awake_jiffies)));
2621                         ppsc->last_sleep_jiffies = jiffies;
2622                         _rtl92ce_phy_set_rf_sleep(hw);
2623                         break;
2624                 }
2625         default:
2626                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2627                          ("switch case not process\n"));
2628                 bresult = false;
2629                 break;
2630         }
2631         if (bresult)
2632                 ppsc->rfpwr_state = rfpwr_state;
2633         ppsc->set_rfpowerstate_inprogress = false;
2634         return bresult;
2635 }
2636
2637 bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
2638                                    enum rf_pwrstate rfpwr_state)
2639 {
2640         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2641         bool bresult = false;
2642
2643         if (rfpwr_state == ppsc->rfpwr_state)
2644                 return bresult;
2645         bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
2646         return bresult;
2647 }