Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[cascardo/linux.git] / drivers / staging / rtl8188eu / hal / HalPhyRf_8188e.c
1
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18  *
19  *
20  ******************************************************************************/
21
22 #include "odm_precomp.h"
23
24 /*---------------------------Define Local Constant---------------------------*/
25 /*  2010/04/25 MH Define the max tx power tracking tx agc power. */
26 #define         ODM_TXPWRTRACK_MAX_IDX_88E              6
27
28 /*---------------------------Define Local Constant---------------------------*/
29
30 /* 3============================================================ */
31 /* 3 Tx Power Tracking */
32 /* 3============================================================ */
33 /*-----------------------------------------------------------------------------
34  * Function:    ODM_TxPwrTrackAdjust88E()
35  *
36  * Overview:    88E we can not write 0xc80/c94/c4c/ 0xa2x. Instead of write TX agc.
37  *                              No matter OFDM & CCK use the same method.
38  *
39  * Input:               NONE
40  *
41  * Output:              NONE
42  *
43  * Return:              NONE
44  *
45  * Revised History:
46  *      When            Who             Remark
47  *      04/23/2012      MHC             Create Version 0.
48  *      04/23/2012      MHC             Adjust TX agc directly not throughput BB digital.
49  *
50  *---------------------------------------------------------------------------*/
51 void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/*  0 = OFDM, 1 = CCK */
52         u8 *pDirection,                 /*  1 = +(increase) 2 = -(decrease) */
53         u32 *pOutWriteVal               /*  Tx tracking CCK/OFDM BB swing index adjust */
54         )
55 {
56         u8 pwr_value = 0;
57         /*  Tx power tracking BB swing table. */
58         /*  The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
59         if (Type == 0) {                /*  For OFDM afjust */
60                 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
61                              ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
62                              dm_odm->BbSwingIdxOfdm, dm_odm->BbSwingFlagOfdm));
63
64                 if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
65                         *pDirection     = 1;
66                         pwr_value               = (dm_odm->BbSwingIdxOfdmBase - dm_odm->BbSwingIdxOfdm);
67                 } else {
68                         *pDirection     = 2;
69                         pwr_value               = (dm_odm->BbSwingIdxOfdm - dm_odm->BbSwingIdxOfdmBase);
70                 }
71
72                 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
73                              ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
74                              dm_odm->BbSwingIdxOfdm, dm_odm->BbSwingFlagOfdm));
75         } else if (Type == 1) { /*  For CCK adjust. */
76                 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
77                              ("dm_odm->BbSwingIdxCck = %d dm_odm->BbSwingIdxCckBase = %d\n",
78                              dm_odm->BbSwingIdxCck, dm_odm->BbSwingIdxCckBase));
79
80                 if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
81                         *pDirection     = 1;
82                         pwr_value               = (dm_odm->BbSwingIdxCckBase - dm_odm->BbSwingIdxCck);
83                 } else {
84                         *pDirection     = 2;
85                         pwr_value               = (dm_odm->BbSwingIdxCck - dm_odm->BbSwingIdxCckBase);
86                 }
87         }
88
89         /*  */
90         /*  2012/04/25 MH According to Ed/Luke.Lees estimate for EVM the max tx power tracking */
91         /*  need to be less than 6 power index for 88E. */
92         /*  */
93         if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *pDirection == 1)
94                 pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
95
96         *pOutWriteVal = pwr_value | (pwr_value<<8) | (pwr_value<<16) | (pwr_value<<24);
97 }       /*  ODM_TxPwrTrackAdjust88E */
98
99 /*-----------------------------------------------------------------------------
100  * Function:    odm_TxPwrTrackSetPwr88E()
101  *
102  * Overview:    88E change all channel tx power accordign to flag.
103  *                              OFDM & CCK are all different.
104  *
105  * Input:               NONE
106  *
107  * Output:              NONE
108  *
109  * Return:              NONE
110  *
111  * Revised History:
112  *      When            Who             Remark
113  *      04/23/2012      MHC             Create Version 0.
114  *
115  *---------------------------------------------------------------------------*/
116 static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm)
117 {
118         if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
119                 ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("odm_TxPwrTrackSetPwr88E CH=%d\n", *(dm_odm->pChannel)));
120                 PHY_SetTxPowerLevel8188E(dm_odm->Adapter, *(dm_odm->pChannel));
121                 dm_odm->BbSwingFlagOfdm = false;
122                 dm_odm->BbSwingFlagCck  = false;
123         }
124 }       /*  odm_TxPwrTrackSetPwr88E */
125
126 /* 091212 chiyokolin */
127 void
128 odm_TXPowerTrackingCallback_ThermalMeter_8188E(
129         struct adapter *Adapter
130         )
131 {
132         struct hal_data_8188e   *pHalData = GET_HAL_DATA(Adapter);
133         u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, offset;
134         u8 ThermalValue_AVG_count = 0;
135         u32 ThermalValue_AVG = 0;
136         s32 ele_A = 0, ele_D, TempCCk, X, value32;
137         s32 Y, ele_C = 0;
138         s8 OFDM_index[2], CCK_index = 0;
139         s8 OFDM_index_old[2] = {0, 0}, CCK_index_old = 0;
140         u32 i = 0, j = 0;
141         bool is2t = false;
142
143         u8 OFDM_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
144         u8 Indexforchannel = 0/*GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/;
145         s8 OFDM_index_mapping[2][index_mapping_NUM_88E] = {
146                 {0, 0, 2, 3, 4, 4,              /* 2.4G, decrease power */
147                 5, 6, 7, 7, 8, 9,
148                 10, 10, 11}, /*  For lower temperature, 20120220 updated on 20120220. */
149                 {0, 0, -1, -2, -3, -4,          /* 2.4G, increase power */
150                 -4, -4, -4, -5, -7, -8,
151                 -9, -9, -10},
152         };
153         u8 Thermal_mapping[2][index_mapping_NUM_88E] = {
154                 {0, 2, 4, 6, 8, 10,             /* 2.4G, decrease power */
155                 12, 14, 16, 18, 20, 22,
156                 24, 26, 27},
157                 {0, 2, 4, 6, 8, 10,             /* 2.4G,, increase power */
158                 12, 14, 16, 18, 20, 22,
159                 25, 25, 25},
160         };
161         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
162
163         /*  2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
164         odm_TxPwrTrackSetPwr88E(dm_odm);
165
166         dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; /* cosa add for debug */
167         dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
168
169         /*  <Kordan> RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */
170         dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
171
172         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
173                      ("===>dm_TXPowerTrackingCallback_ThermalMeter_8188E txpowercontrol %d\n",
174                      dm_odm->RFCalibrateInfo.TxPowerTrackControl));
175
176         ThermalValue = (u8)ODM_GetRFReg(dm_odm, RF_PATH_A, RF_T_METER_88E, 0xfc00);     /* 0x42: RF Reg[15:10] 88E */
177
178         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
179                      ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n",
180                      ThermalValue, dm_odm->RFCalibrateInfo.ThermalValue, pHalData->EEPROMThermalMeter));
181
182         if (is2t)
183                 rf = 2;
184         else
185                 rf = 1;
186
187         if (ThermalValue) {
188                 /* Query OFDM path A default setting */
189                 ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D;
190                 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {     /* find the index */
191                         if (ele_D == (OFDMSwingTable[i]&bMaskOFDM_D)) {
192                                 OFDM_index_old[0] = (u8)i;
193                                 dm_odm->BbSwingIdxOfdmBase = (u8)i;
194                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
195                                              ("Initial pathA ele_D reg0x%x = 0x%x, OFDM_index=0x%x\n",
196                                              rOFDM0_XATxIQImbalance, ele_D, OFDM_index_old[0]));
197                                 break;
198                         }
199                 }
200
201                 /* Query OFDM path B default setting */
202                 if (is2t) {
203                         ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord)&bMaskOFDM_D;
204                         for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {     /* find the index */
205                                 if (ele_D == (OFDMSwingTable[i]&bMaskOFDM_D)) {
206                                         OFDM_index_old[1] = (u8)i;
207                                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
208                                                      ("Initial pathB ele_D reg0x%x = 0x%x, OFDM_index=0x%x\n",
209                                                 rOFDM0_XBTxIQImbalance, ele_D, OFDM_index_old[1]));
210                                         break;
211                                 }
212                         }
213                 }
214
215                 /* Query CCK default setting From 0xa24 */
216                 TempCCk = dm_odm->RFCalibrateInfo.RegA24;
217
218                 for (i = 0; i < CCK_TABLE_SIZE; i++) {
219                         if (dm_odm->RFCalibrateInfo.bCCKinCH14) {
220                                 if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4) == 0) {
221                                         CCK_index_old = (u8)i;
222                                         dm_odm->BbSwingIdxCckBase = (u8)i;
223                                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
224                                                      ("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch 14 %d\n",
225                                                      rCCK0_TxFilter2, TempCCk, CCK_index_old, dm_odm->RFCalibrateInfo.bCCKinCH14));
226                                         break;
227                                 }
228                         } else {
229                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
230                                              ("RegA24: 0x%X, CCKSwingTable_Ch1_Ch13[%d][2]: CCKSwingTable_Ch1_Ch13[i][2]: 0x%X\n",
231                                              TempCCk, i, CCKSwingTable_Ch1_Ch13[i][2]));
232                                 if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4) == 0) {
233                                         CCK_index_old = (u8)i;
234                                         dm_odm->BbSwingIdxCckBase = (u8)i;
235                                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
236                                                      ("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch14 %d\n",
237                                                      rCCK0_TxFilter2, TempCCk, CCK_index_old, dm_odm->RFCalibrateInfo.bCCKinCH14));
238                                         break;
239                                 }
240                         }
241                 }
242
243                 if (!dm_odm->RFCalibrateInfo.ThermalValue) {
244                         dm_odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
245                         dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
246                         dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
247
248                         for (i = 0; i < rf; i++)
249                                 dm_odm->RFCalibrateInfo.OFDM_index[i] = OFDM_index_old[i];
250                         dm_odm->RFCalibrateInfo.CCK_index = CCK_index_old;
251                 }
252
253                 if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex)
254                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
255                                      ("reload ofdm index for band switch\n"));
256
257                 /* calculate average thermal meter */
258                 dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue;
259                 dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
260                 if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
261                         dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
262
263                 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
264                         if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
265                                 ThermalValue_AVG += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
266                                 ThermalValue_AVG_count++;
267                         }
268                 }
269
270                 if (ThermalValue_AVG_count) {
271                         ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count);
272                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
273                                      ("AVG Thermal Meter = 0x%x\n", ThermalValue));
274                 }
275
276                 if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
277                         delta = ThermalValue > pHalData->EEPROMThermalMeter ?
278                                 (ThermalValue - pHalData->EEPROMThermalMeter) :
279                                 (pHalData->EEPROMThermalMeter - ThermalValue);
280                         dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
281                         dm_odm->RFCalibrateInfo.bDoneTxpower = false;
282                 } else if (dm_odm->RFCalibrateInfo.bDoneTxpower) {
283                         delta = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue) ?
284                                 (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue) :
285                                 (dm_odm->RFCalibrateInfo.ThermalValue - ThermalValue);
286                 } else {
287                         delta = ThermalValue > pHalData->EEPROMThermalMeter ?
288                                 (ThermalValue - pHalData->EEPROMThermalMeter) :
289                                 (pHalData->EEPROMThermalMeter - ThermalValue);
290                 }
291                 delta_LCK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_LCK) ?
292                             (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_LCK) :
293                             (dm_odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue);
294                 delta_IQK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_IQK) ?
295                             (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_IQK) :
296                             (dm_odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue);
297                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
298                              ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x delta 0x%x delta_LCK 0x%x delta_IQK 0x%x\n",
299                              ThermalValue, dm_odm->RFCalibrateInfo.ThermalValue,
300                              pHalData->EEPROMThermalMeter, delta, delta_LCK, delta_IQK));
301                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
302                              ("pre thermal meter LCK 0x%x pre thermal meter IQK 0x%x delta_LCK_bound 0x%x delta_IQK_bound 0x%x\n",
303                              dm_odm->RFCalibrateInfo.ThermalValue_LCK,
304                              dm_odm->RFCalibrateInfo.ThermalValue_IQK,
305                              dm_odm->RFCalibrateInfo.Delta_LCK,
306                              dm_odm->RFCalibrateInfo.Delta_IQK));
307
308                 if ((delta_LCK >= 8)) { /*  Delta temperature is equal to or larger than 20 centigrade. */
309                         dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
310                         PHY_LCCalibrate_8188E(Adapter);
311                 }
312
313                 if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
314                         delta = ThermalValue > pHalData->EEPROMThermalMeter ?
315                                 (ThermalValue - pHalData->EEPROMThermalMeter) :
316                                 (pHalData->EEPROMThermalMeter - ThermalValue);
317                         /* calculate new OFDM / CCK offset */
318                         if (ThermalValue > pHalData->EEPROMThermalMeter)
319                                 j = 1;
320                         else
321                                 j = 0;
322                         for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
323                                 if (delta < Thermal_mapping[j][offset]) {
324                                         if (offset != 0)
325                                                 offset--;
326                                         break;
327                                 }
328                         }
329                         if (offset >= index_mapping_NUM_88E)
330                                 offset = index_mapping_NUM_88E-1;
331                         for (i = 0; i < rf; i++)
332                                 OFDM_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + OFDM_index_mapping[j][offset];
333                         CCK_index = dm_odm->RFCalibrateInfo.CCK_index + OFDM_index_mapping[j][offset];
334
335                         if (is2t) {
336                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
337                                              ("temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n",
338                                              dm_odm->RFCalibrateInfo.OFDM_index[0],
339                                              dm_odm->RFCalibrateInfo.OFDM_index[1],
340                                              dm_odm->RFCalibrateInfo.CCK_index));
341                         } else {
342                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
343                                              ("temp OFDM_A_index=0x%x, CCK_index=0x%x\n",
344                                              dm_odm->RFCalibrateInfo.OFDM_index[0],
345                                              dm_odm->RFCalibrateInfo.CCK_index));
346                         }
347
348                         for (i = 0; i < rf; i++) {
349                                 if (OFDM_index[i] > OFDM_TABLE_SIZE_92D-1)
350                                         OFDM_index[i] = OFDM_TABLE_SIZE_92D-1;
351                                 else if (OFDM_index[i] < OFDM_min_index)
352                                         OFDM_index[i] = OFDM_min_index;
353                         }
354
355                         if (CCK_index > CCK_TABLE_SIZE-1)
356                                 CCK_index = CCK_TABLE_SIZE-1;
357                         else if (CCK_index < 0)
358                                 CCK_index = 0;
359
360                         if (is2t) {
361                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
362                                              ("new OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n",
363                                              OFDM_index[0], OFDM_index[1], CCK_index));
364                         } else {
365                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
366                                              ("new OFDM_A_index=0x%x, CCK_index=0x%x\n",
367                                              OFDM_index[0], CCK_index));
368                         }
369
370                         /* 2 temporarily remove bNOPG */
371                         /* Config by SwingTable */
372                         if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
373                                 dm_odm->RFCalibrateInfo.bDoneTxpower = true;
374
375                                 /* Adujst OFDM Ant_A according to IQK result */
376                                 ele_D = (OFDMSwingTable[(u8)OFDM_index[0]] & 0xFFC00000)>>22;
377                                 X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][0];
378                                 Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][1];
379
380                                 /*  Revse TX power table. */
381                                 dm_odm->BbSwingIdxOfdm          = (u8)OFDM_index[0];
382                                 dm_odm->BbSwingIdxCck           = (u8)CCK_index;
383
384                                 if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
385                                         dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
386                                         dm_odm->BbSwingFlagOfdm = true;
387                                 }
388
389                                 if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
390                                         dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
391                                         dm_odm->BbSwingFlagCck = true;
392                                 }
393
394                                 if (X != 0) {
395                                         if ((X & 0x00000200) != 0)
396                                                 X = X | 0xFFFFFC00;
397                                         ele_A = ((X * ele_D)>>8)&0x000003FF;
398
399                                         /* new element C = element D x Y */
400                                         if ((Y & 0x00000200) != 0)
401                                                 Y = Y | 0xFFFFFC00;
402                                         ele_C = ((Y * ele_D)>>8)&0x000003FF;
403
404                                         /*  2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
405                                         /*  to increase TX power. Otherwise, EVM will be bad. */
406                                 }
407
408                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
409                                              ("TxPwrTracking for path A: X=0x%x, Y=0x%x ele_A=0x%x ele_C=0x%x ele_D=0x%x 0xe94=0x%x 0xe9c=0x%x\n",
410                                              (u32)X, (u32)Y, (u32)ele_A, (u32)ele_C, (u32)ele_D, (u32)X, (u32)Y));
411
412                                 if (is2t) {
413                                         ele_D = (OFDMSwingTable[(u8)OFDM_index[1]] & 0xFFC00000)>>22;
414
415                                         /* new element A = element D x X */
416                                         X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][4];
417                                         Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][5];
418
419                                         if ((X != 0) && (*(dm_odm->pBandType) == ODM_BAND_2_4G)) {
420                                                 if ((X & 0x00000200) != 0)      /* consider minus */
421                                                         X = X | 0xFFFFFC00;
422                                                 ele_A = ((X * ele_D)>>8)&0x000003FF;
423
424                                                 /* new element C = element D x Y */
425                                                 if ((Y & 0x00000200) != 0)
426                                                         Y = Y | 0xFFFFFC00;
427                                                 ele_C = ((Y * ele_D)>>8)&0x00003FF;
428
429                                                 /* wtite new elements A, C, D to regC88 and regC9C, element B is always 0 */
430                                                 value32 = (ele_D<<22) | ((ele_C&0x3F)<<16) | ele_A;
431                                                 ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
432
433                                                 value32 = (ele_C&0x000003C0)>>6;
434                                                 ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
435
436                                                 value32 = ((X * ele_D)>>7)&0x01;
437                                                 ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT28, value32);
438                                         } else {
439                                                 ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[(u8)OFDM_index[1]]);
440                                                 ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
441                                                 ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT28, 0x00);
442                                         }
443
444                                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
445                                                      ("TxPwrTracking path B: X=0x%x, Y=0x%x ele_A=0x%x ele_C=0x%x ele_D=0x%x 0xeb4=0x%x 0xebc=0x%x\n",
446                                                      (u32)X, (u32)Y, (u32)ele_A,
447                                                      (u32)ele_C, (u32)ele_D, (u32)X, (u32)Y));
448                                 }
449
450                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
451                                              ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n",
452                                              ODM_GetBBReg(dm_odm, 0xc80, bMaskDWord), ODM_GetBBReg(dm_odm,
453                                              0xc94, bMaskDWord), ODM_GetRFReg(dm_odm, RF_PATH_A, 0x24, bRFRegOffsetMask)));
454                         }
455                 }
456
457                 if (delta_IQK >= 8) { /*  Delta temperature is equal to or larger than 20 centigrade. */
458                         ODM_ResetIQKResult(dm_odm);
459
460                         dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
461                         PHY_IQCalibrate_8188E(Adapter, false);
462                 }
463                 /* update thermal meter value */
464                 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
465                         dm_odm->RFCalibrateInfo.ThermalValue = ThermalValue;
466         }
467         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
468                      ("<===dm_TXPowerTrackingCallback_ThermalMeter_8188E\n"));
469         dm_odm->RFCalibrateInfo.TXPowercount = 0;
470 }
471
472 /* 1 7. IQK */
473 #define MAX_TOLERANCE           5
474 #define IQK_DELAY_TIME          1               /* ms */
475
476 static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
477 phy_PathA_IQK_8188E(struct adapter *adapt, bool configPathB)
478 {
479         u32 regeac, regE94, regE9C, regEA4;
480         u8 result = 0x00;
481         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
482         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
483         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A IQK!\n"));
484
485         /* 1 Tx IQK */
486         /* path-A IQK setting */
487         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A IQK setting!\n"));
488         ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
489         ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
490         ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
491         ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
492
493         /* LO calibration setting */
494         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n"));
495         ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
496
497         /* One shot, path A LOK & IQK */
498         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
499         ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
500         ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
501
502         /*  delay x ms */
503         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_88E));
504         /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
505         ODM_delay_ms(IQK_DELAY_TIME_88E);
506
507         /*  Check failed */
508         regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
509         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regeac));
510         regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord);
511         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe94 = 0x%x\n", regE94));
512         regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord);
513         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("0xe9c = 0x%x\n", regE9C));
514         regEA4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord);
515         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xea4 = 0x%x\n", regEA4));
516
517         if (!(regeac & BIT28) &&
518             (((regE94 & 0x03FF0000)>>16) != 0x142) &&
519             (((regE9C & 0x03FF0000)>>16) != 0x42))
520                 result |= 0x01;
521         return result;
522 }
523
524 static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
525 phy_PathA_RxIQK(struct adapter *adapt, bool configPathB)
526 {
527         u32 regeac, regE94, regE9C, regEA4, u4tmp;
528         u8 result = 0x00;
529         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
530         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
531         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK!\n"));
532
533         /* 1 Get TXIMR setting */
534         /* modify RXIQK mode table */
535         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A Rx IQK modify RXIQK mode table!\n"));
536         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
537         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
538         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
539         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
540         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
541
542         /* PA,PAD off */
543         ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
544         ODM_SetRFReg(dm_odm, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
545
546         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
547
548         /* IQK setting */
549         ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00);
550         ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800);
551
552         /* path-A IQK setting */
553         ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
554         ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
555         ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
556         ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
557
558         /* LO calibration setting */
559         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n"));
560         ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
561
562         /* One shot, path A LOK & IQK */
563         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
564         ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
565         ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
566
567         /*  delay x ms */
568         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
569                      ("Delay %d ms for One shot, path A LOK & IQK.\n",
570                      IQK_DELAY_TIME_88E));
571         ODM_delay_ms(IQK_DELAY_TIME_88E);
572
573         /*  Check failed */
574         regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
575         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
576                      ("0xeac = 0x%x\n", regeac));
577         regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord);
578         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
579                      ("0xe94 = 0x%x\n", regE94));
580         regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord);
581         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
582                      ("0xe9c = 0x%x\n", regE9C));
583
584         if (!(regeac & BIT28) &&
585             (((regE94 & 0x03FF0000)>>16) != 0x142) &&
586             (((regE9C & 0x03FF0000)>>16) != 0x42))
587                 result |= 0x01;
588         else                                                    /* if Tx not OK, ignore Rx */
589                 return result;
590
591         u4tmp = 0x80007C00 | (regE94&0x3FF0000)  | ((regE9C&0x3FF0000) >> 16);
592         ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, u4tmp);
593         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe40 = 0x%x u4tmp = 0x%x\n", ODM_GetBBReg(dm_odm, rTx_IQK, bMaskDWord), u4tmp));
594
595         /* 1 RX IQK */
596         /* modify RXIQK mode table */
597         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
598         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
599         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
600         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
601         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
602         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
603         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
604
605         /* IQK setting */
606         ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x01004800);
607
608         /* path-A IQK setting */
609         ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
610         ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
611         ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
612         ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
613
614         /* LO calibration setting */
615         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n"));
616         ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
617
618         /* One shot, path A LOK & IQK */
619         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
620         ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
621         ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
622
623         /*  delay x ms */
624         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_88E));
625         /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
626         ODM_delay_ms(IQK_DELAY_TIME_88E);
627
628         /*  Check failed */
629         regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
630         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("0xeac = 0x%x\n", regeac));
631         regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord);
632         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("0xe94 = 0x%x\n", regE94));
633         regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord);
634         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("0xe9c = 0x%x\n", regE9C));
635         regEA4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord);
636         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("0xea4 = 0x%x\n", regEA4));
637
638         /* reload RF 0xdf */
639         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
640         ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
641
642         if (!(regeac & BIT27) &&                /* if Tx is OK, check whether Rx is OK */
643             (((regEA4 & 0x03FF0000)>>16) != 0x132) &&
644             (((regeac & 0x03FF0000)>>16) != 0x36))
645                 result |= 0x02;
646         else
647                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Path A Rx IQK fail!!\n"));
648
649         return result;
650 }
651
652 static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
653 phy_PathB_IQK_8188E(struct adapter *adapt)
654 {
655         u32 regeac, regeb4, regebc, regec4, regecc;
656         u8 result = 0x00;
657         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
658         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
659         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Path B IQK!\n"));
660
661         /* One shot, path B LOK & IQK */
662         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
663         ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
664         ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
665
666         /*  delay x ms */
667         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
668                      ("Delay %d ms for One shot, path B LOK & IQK.\n",
669                      IQK_DELAY_TIME_88E));
670         ODM_delay_ms(IQK_DELAY_TIME_88E);
671
672         /*  Check failed */
673         regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord);
674         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
675                      ("0xeac = 0x%x\n", regeac));
676         regeb4 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord);
677         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
678                      ("0xeb4 = 0x%x\n", regeb4));
679         regebc = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord);
680         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
681                      ("0xebc = 0x%x\n", regebc));
682         regec4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord);
683         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
684                      ("0xec4 = 0x%x\n", regec4));
685         regecc = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord);
686         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
687                      ("0xecc = 0x%x\n", regecc));
688
689         if (!(regeac & BIT31) &&
690             (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
691             (((regebc & 0x03FF0000)>>16) != 0x42))
692                 result |= 0x01;
693         else
694                 return result;
695
696         if (!(regeac & BIT30) &&
697             (((regec4 & 0x03FF0000)>>16) != 0x132) &&
698             (((regecc & 0x03FF0000)>>16) != 0x36))
699                 result |= 0x02;
700         else
701                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Path B Rx IQK fail!!\n"));
702         return result;
703 }
704
705 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly)
706 {
707         u32 Oldval_0, X, TX0_A, reg;
708         s32 Y, TX0_C;
709         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
710         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
711         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
712                      ("Path A IQ Calibration %s !\n",
713                      (iqkok) ? "Success" : "Failed"));
714
715         if (final_candidate == 0xFF) {
716                 return;
717         } else if (iqkok) {
718                 Oldval_0 = (ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
719
720                 X = result[final_candidate][0];
721                 if ((X & 0x00000200) != 0)
722                         X = X | 0xFFFFFC00;
723                 TX0_A = (X * Oldval_0) >> 8;
724                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
725                              ("X = 0x%x, TX0_A = 0x%x, Oldval_0 0x%x\n",
726                              X, TX0_A, Oldval_0));
727                 ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
728
729                 ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0>>7) & 0x1));
730
731                 Y = result[final_candidate][1];
732                 if ((Y & 0x00000200) != 0)
733                         Y = Y | 0xFFFFFC00;
734
735                 TX0_C = (Y * Oldval_0) >> 8;
736                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Y = 0x%x, TX = 0x%x\n", Y, TX0_C));
737                 ODM_SetBBReg(dm_odm, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6));
738                 ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F));
739
740                 ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0>>7) & 0x1));
741
742                 if (txonly) {
743                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("patha_fill_iqk only Tx OK\n"));
744                         return;
745                 }
746
747                 reg = result[final_candidate][2];
748                 ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0x3FF, reg);
749
750                 reg = result[final_candidate][3] & 0x3F;
751                 ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0xFC00, reg);
752
753                 reg = (result[final_candidate][3] >> 6) & 0xF;
754                 ODM_SetBBReg(dm_odm, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
755         }
756 }
757
758 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly)
759 {
760         u32 Oldval_1, X, TX1_A, reg;
761         s32 Y, TX1_C;
762         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
763         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
764         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
765                      ("Path B IQ Calibration %s !\n",
766                      (iqkok) ? "Success" : "Failed"));
767
768         if (final_candidate == 0xFF) {
769                 return;
770         } else if (iqkok) {
771                 Oldval_1 = (ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
772
773                 X = result[final_candidate][4];
774                 if ((X & 0x00000200) != 0)
775                         X = X | 0xFFFFFC00;
776                 TX1_A = (X * Oldval_1) >> 8;
777                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("X = 0x%x, TX1_A = 0x%x\n", X, TX1_A));
778                 ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A);
779
780                 ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1>>7) & 0x1));
781
782                 Y = result[final_candidate][5];
783                 if ((Y & 0x00000200) != 0)
784                         Y = Y | 0xFFFFFC00;
785
786                 TX1_C = (Y * Oldval_1) >> 8;
787                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Y = 0x%x, TX1_C = 0x%x\n", Y, TX1_C));
788                 ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6));
789                 ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F));
790
791                 ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1>>7) & 0x1));
792
793                 if (txonly)
794                         return;
795
796                 reg = result[final_candidate][6];
797                 ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
798
799                 reg = result[final_candidate][7] & 0x3F;
800                 ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
801
802                 reg = (result[final_candidate][7] >> 6) & 0xF;
803                 ODM_SetBBReg(dm_odm, rOFDM0_AGCRSSITable, 0x0000F000, reg);
804         }
805 }
806
807 /*  */
808 /*  2011/07/26 MH Add an API for testing IQK fail case. */
809 /*  */
810 /*  MP Already declare in odm.c */
811 static bool ODM_CheckPowerStatus(struct adapter *Adapter)
812 {
813         return  true;
814 }
815
816 void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum)
817 {
818         u32 i;
819         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
820         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
821
822         if (!ODM_CheckPowerStatus(adapt))
823                 return;
824
825         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save ADDA parameters.\n"));
826         for (i = 0; i < RegisterNum; i++) {
827                 ADDABackup[i] = ODM_GetBBReg(dm_odm, ADDAReg[i], bMaskDWord);
828         }
829 }
830
831 static void _PHY_SaveMACRegisters(
832                 struct adapter *adapt,
833                 u32 *MACReg,
834                 u32 *MACBackup
835         )
836 {
837         u32 i;
838         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
839         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
840         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save MAC parameters.\n"));
841         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
842                 MACBackup[i] = ODM_Read1Byte(dm_odm, MACReg[i]);
843         }
844         MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
845 }
846
847 static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
848 {
849         u32 i;
850         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
851         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
852
853         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload ADDA power saving parameters !\n"));
854         for (i = 0; i < RegiesterNum; i++)
855                 ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, ADDABackup[i]);
856 }
857
858 static void
859 _PHY_ReloadMACRegisters(
860                 struct adapter *adapt,
861                 u32 *MACReg,
862                 u32 *MACBackup
863         )
864 {
865         u32 i;
866         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
867         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
868
869         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Reload MAC parameters !\n"));
870         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
871                 ODM_Write1Byte(dm_odm, MACReg[i], (u8)MACBackup[i]);
872         }
873         ODM_Write4Byte(dm_odm, MACReg[i], MACBackup[i]);
874 }
875
876 void
877 _PHY_PathADDAOn(
878                 struct adapter *adapt,
879                 u32 *ADDAReg,
880                 bool isPathAOn,
881                 bool is2t
882         )
883 {
884         u32 pathOn;
885         u32 i;
886         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
887         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
888         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("ADDA ON.\n"));
889
890         pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4;
891         if (!is2t) {
892                 pathOn = 0x0bdb25a0;
893                 ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, 0x0b1b25a0);
894         } else {
895                 ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, pathOn);
896         }
897
898         for (i = 1; i < IQK_ADDA_REG_NUM; i++)
899                 ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, pathOn);
900 }
901
902 void
903 _PHY_MACSettingCalibration(
904                 struct adapter *adapt,
905                 u32 *MACReg,
906                 u32 *MACBackup
907         )
908 {
909         u32 i = 0;
910         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
911         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
912
913         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("MAC settings for Calibration.\n"));
914
915         ODM_Write1Byte(dm_odm, MACReg[i], 0x3F);
916
917         for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
918                 ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i]&(~BIT3)));
919         }
920         ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i]&(~BIT5)));
921 }
922
923 void
924 _PHY_PathAStandBy(
925         struct adapter *adapt
926         )
927 {
928         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
929         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
930
931         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Path-A standby mode!\n"));
932
933         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x0);
934         ODM_SetBBReg(dm_odm, 0x840, bMaskDWord, 0x00010000);
935         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
936 }
937
938 static void _PHY_PIModeSwitch(
939                 struct adapter *adapt,
940                 bool PIMode
941         )
942 {
943         u32 mode;
944         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
945         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
946
947         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("BB Switch to %s mode!\n", (PIMode ? "PI" : "SI")));
948
949         mode = PIMode ? 0x01000100 : 0x01000000;
950         ODM_SetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
951         ODM_SetBBReg(dm_odm, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
952 }
953
954 static bool phy_SimularityCompare_8188E(
955                 struct adapter *adapt,
956                 s32 resulta[][8],
957                 u8  c1,
958                 u8  c2
959         )
960 {
961         u32 i, j, diff, sim_bitmap, bound = 0;
962         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
963         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
964         u8 final_candidate[2] = {0xFF, 0xFF};   /* for path A and path B */
965         bool result = true;
966         bool is2t;
967         s32 tmp1 = 0, tmp2 = 0;
968
969         if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) || (dm_odm->RFType == ODM_2T4R))
970                 is2t = true;
971         else
972                 is2t = false;
973
974         if (is2t)
975                 bound = 8;
976         else
977                 bound = 4;
978
979         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("===> IQK:phy_SimularityCompare_8188E c1 %d c2 %d!!!\n", c1, c2));
980
981         sim_bitmap = 0;
982
983         for (i = 0; i < bound; i++) {
984                 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
985                         if ((resulta[c1][i] & 0x00000200) != 0)
986                                 tmp1 = resulta[c1][i] | 0xFFFFFC00;
987                         else
988                                 tmp1 = resulta[c1][i];
989
990                         if ((resulta[c2][i] & 0x00000200) != 0)
991                                 tmp2 = resulta[c2][i] | 0xFFFFFC00;
992                         else
993                                 tmp2 = resulta[c2][i];
994                 } else {
995                         tmp1 = resulta[c1][i];
996                         tmp2 = resulta[c2][i];
997                 }
998
999                 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1000
1001                 if (diff > MAX_TOLERANCE) {
1002                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1003                                      ("IQK:phy_SimularityCompare_8188E differnece overflow index %d compare1 0x%x compare2 0x%x!!!\n",
1004                                      i, resulta[c1][i], resulta[c2][i]));
1005
1006                         if ((i == 2 || i == 6) && !sim_bitmap) {
1007                                 if (resulta[c1][i] + resulta[c1][i+1] == 0)
1008                                         final_candidate[(i/4)] = c2;
1009                                 else if (resulta[c2][i] + resulta[c2][i+1] == 0)
1010                                         final_candidate[(i/4)] = c1;
1011                                 else
1012                                         sim_bitmap = sim_bitmap | (1<<i);
1013                         } else {
1014                                 sim_bitmap = sim_bitmap | (1<<i);
1015                         }
1016                 }
1017         }
1018
1019         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:phy_SimularityCompare_8188E sim_bitmap   %d !!!\n", sim_bitmap));
1020
1021         if (sim_bitmap == 0) {
1022                 for (i = 0; i < (bound/4); i++) {
1023                         if (final_candidate[i] != 0xFF) {
1024                                 for (j = i*4; j < (i+1)*4-2; j++)
1025                                         resulta[3][j] = resulta[final_candidate[i]][j];
1026                                 result = false;
1027                         }
1028                 }
1029                 return result;
1030         } else {
1031                 if (!(sim_bitmap & 0x03)) {                /* path A TX OK */
1032                         for (i = 0; i < 2; i++)
1033                                 resulta[3][i] = resulta[c1][i];
1034                 }
1035                 if (!(sim_bitmap & 0x0c)) {                /* path A RX OK */
1036                         for (i = 2; i < 4; i++)
1037                                 resulta[3][i] = resulta[c1][i];
1038                 }
1039
1040                 if (!(sim_bitmap & 0x30)) { /* path B TX OK */
1041                         for (i = 4; i < 6; i++)
1042                                 resulta[3][i] = resulta[c1][i];
1043                 }
1044
1045                 if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
1046                         for (i = 6; i < 8; i++)
1047                                 resulta[3][i] = resulta[c1][i];
1048                 }
1049                 return false;
1050         }
1051 }
1052
1053 static void phy_IQCalibrate_8188E(struct adapter *adapt, s32 result[][8], u8 t, bool is2t)
1054 {
1055         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1056         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1057         u32 i;
1058         u8 PathAOK, PathBOK;
1059         u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
1060                                                 rFPGA0_XCD_SwitchControl, rBlue_Tooth,
1061                                                 rRx_Wait_CCA,   rTx_CCK_RFON,
1062                                                 rTx_CCK_BBON, rTx_OFDM_RFON,
1063                                                 rTx_OFDM_BBON, rTx_To_Rx,
1064                                                 rTx_To_Tx,      rRx_CCK,
1065                                                 rRx_OFDM,       rRx_Wait_RIFS,
1066                                                 rRx_TO_Rx,      rStandby,
1067                                                 rSleep,                         rPMPD_ANAEN };
1068         u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
1069                                                 REG_TXPAUSE,    REG_BCN_CTRL,
1070                                                 REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1071
1072         /* since 92C & 92D have the different define in IQK_BB_REG */
1073         u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1074                                                         rOFDM0_TRxPathEnable,   rOFDM0_TRMuxPar,
1075                                                         rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
1076                                                         rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
1077                                                         rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD
1078                                                         };
1079
1080         u32 retryCount = 9;
1081         if (*(dm_odm->mp_mode) == 1)
1082                 retryCount = 9;
1083         else
1084                 retryCount = 2;
1085         /*  Note: IQ calibration must be performed after loading */
1086         /*              PHY_REG.txt , and radio_a, radio_b.txt */
1087
1088         if (t == 0) {
1089                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQ Calibration for %s for %d times\n", (is2t ? "2T2R" : "1T1R"), t));
1090
1091                 /*  Save ADDA parameters, turn Path A ADDA on */
1092                 _PHY_SaveADDARegisters(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
1093                 _PHY_SaveMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1094                 _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1095         }
1096         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQ Calibration for %s for %d times\n", (is2t ? "2T2R" : "1T1R"), t));
1097
1098         _PHY_PathADDAOn(adapt, ADDA_REG, true, is2t);
1099         if (t == 0)
1100                 dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)ODM_GetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, BIT(8));
1101
1102         if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1103                 /*  Switch BB to PI mode to do IQ Calibration. */
1104                 _PHY_PIModeSwitch(adapt, true);
1105         }
1106
1107         /* BB setting */
1108         ODM_SetBBReg(dm_odm, rFPGA0_RFMOD, BIT24, 0x00);
1109         ODM_SetBBReg(dm_odm, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1110         ODM_SetBBReg(dm_odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1111         ODM_SetBBReg(dm_odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1112
1113         ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01);
1114         ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01);
1115         ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00);
1116         ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00);
1117
1118         if (is2t) {
1119                 ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000);
1120                 ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000);
1121         }
1122
1123         /* MAC settings */
1124         _PHY_MACSettingCalibration(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1125
1126         /* Page B init */
1127         /* AP or IQK */
1128         ODM_SetBBReg(dm_odm, rConfig_AntA, bMaskDWord, 0x0f600000);
1129
1130         if (is2t)
1131                 ODM_SetBBReg(dm_odm, rConfig_AntB, bMaskDWord, 0x0f600000);
1132
1133         /*  IQ calibration setting */
1134         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK setting!\n"));
1135         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000);
1136         ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00);
1137         ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800);
1138
1139         for (i = 0; i < retryCount; i++) {
1140                 PathAOK = phy_PathA_IQK_8188E(adapt, is2t);
1141                 if (PathAOK == 0x01) {
1142                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Tx IQK Success!!\n"));
1143                                 result[t][0] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1144                                 result[t][1] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1145                         break;
1146                 }
1147         }
1148
1149         for (i = 0; i < retryCount; i++) {
1150                 PathAOK = phy_PathA_RxIQK(adapt, is2t);
1151                 if (PathAOK == 0x03) {
1152                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("Path A Rx IQK Success!!\n"));
1153                                 result[t][2] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1154                                 result[t][3] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1155                         break;
1156                 } else {
1157                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK Fail!!\n"));
1158                 }
1159         }
1160
1161         if (0x00 == PathAOK) {
1162                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A IQK failed!!\n"));
1163         }
1164
1165         if (is2t) {
1166                 _PHY_PathAStandBy(adapt);
1167
1168                 /*  Turn Path B ADDA on */
1169                 _PHY_PathADDAOn(adapt, ADDA_REG, false, is2t);
1170
1171                 for (i = 0; i < retryCount; i++) {
1172                         PathBOK = phy_PathB_IQK_8188E(adapt);
1173                         if (PathBOK == 0x03) {
1174                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B IQK Success!!\n"));
1175                                 result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16;
1176                                 result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16;
1177                                 result[t][6] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord)&0x3FF0000)>>16;
1178                                 result[t][7] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord)&0x3FF0000)>>16;
1179                                 break;
1180                         } else if (i == (retryCount - 1) && PathBOK == 0x01) {  /* Tx IQK OK */
1181                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Only Tx IQK Success!!\n"));
1182                                 result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16;
1183                                 result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16;
1184                         }
1185                 }
1186
1187                 if (0x00 == PathBOK) {
1188                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B IQK failed!!\n"));
1189                 }
1190         }
1191
1192         /* Back to BB mode, load original value */
1193         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:Back to BB mode, load original value!\n"));
1194         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0);
1195
1196         if (t != 0) {
1197                 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1198                         /*  Switch back BB to SI mode after finish IQ Calibration. */
1199                         _PHY_PIModeSwitch(adapt, false);
1200                 }
1201
1202                 /*  Reload ADDA power saving parameters */
1203                 reload_adda_reg(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
1204
1205                 /*  Reload MAC parameters */
1206                 _PHY_ReloadMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1207
1208                 reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1209
1210                 /*  Restore RX initial gain */
1211                 ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3);
1212                 if (is2t)
1213                         ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3);
1214
1215                 /* load 0xe30 IQC default value */
1216                 ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1217                 ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1218         }
1219         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_IQCalibrate_8188E() <==\n"));
1220 }
1221
1222 static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
1223 {
1224         u8 tmpreg;
1225         u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
1226         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1227         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1228
1229         /* Check continuous TX and Packet TX */
1230         tmpreg = ODM_Read1Byte(dm_odm, 0xd03);
1231
1232         if ((tmpreg&0x70) != 0)                 /* Deal with contisuous TX case */
1233                 ODM_Write1Byte(dm_odm, 0xd03, tmpreg&0x8F);     /* disable all continuous TX */
1234         else                                                    /*  Deal with Packet TX case */
1235                 ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0xFF);                      /*  block all queues */
1236
1237         if ((tmpreg&0x70) != 0) {
1238                 /* 1. Read original RF mode */
1239                 /* Path-A */
1240                 RF_Amode = PHY_QueryRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits);
1241
1242                 /* Path-B */
1243                 if (is2t)
1244                         RF_Bmode = PHY_QueryRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits);
1245
1246                 /* 2. Set RF mode = standby mode */
1247                 /* Path-A */
1248                 ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000);
1249
1250                 /* Path-B */
1251                 if (is2t)
1252                         ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000);
1253         }
1254
1255         /* 3. Read RF reg18 */
1256         LC_Cal = PHY_QueryRFReg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1257
1258         /* 4. Set LC calibration begin  bit15 */
1259         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000);
1260
1261         ODM_sleep_ms(100);
1262
1263         /* Restore original situation */
1264         if ((tmpreg&0x70) != 0) {
1265                 /* Deal with continuous TX case */
1266                 /* Path-A */
1267                 ODM_Write1Byte(dm_odm, 0xd03, tmpreg);
1268                 ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
1269
1270                 /* Path-B */
1271                 if (is2t)
1272                         ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
1273         } else {
1274                 /*  Deal with Packet TX case */
1275                 ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0x00);
1276         }
1277 }
1278
1279 void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
1280 {
1281         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1282         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1283         struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
1284         s32 result[4][8];       /* last is final result */
1285         u8 i, final_candidate, Indexforchannel;
1286         bool pathaok, pathbok;
1287         s32 RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC;
1288         bool is12simular, is13simular, is23simular;
1289         bool singletone = false, carrier_sup = false;
1290         u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1291                 rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1292                 rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1293                 rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1294                 rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1295                 rOFDM0_RxIQExtAnta};
1296         bool is2t;
1297
1298         is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1299         if (!ODM_CheckPowerStatus(adapt))
1300                 return;
1301
1302         if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1303                 return;
1304
1305         if (*(dm_odm->mp_mode) == 1) {
1306                 singletone = pMptCtx->bSingleTone;
1307                 carrier_sup = pMptCtx->bCarrierSuppression;
1308         }
1309
1310         /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1311         if (singletone || carrier_sup)
1312                 return;
1313
1314         if (recovery) {
1315                 ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("PHY_IQCalibrate_8188E: Return due to recovery!\n"));
1316                 reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1317                 return;
1318         }
1319         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("IQK:Start!!!\n"));
1320
1321         for (i = 0; i < 8; i++) {
1322                 result[0][i] = 0;
1323                 result[1][i] = 0;
1324                 result[2][i] = 0;
1325                 if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
1326                         result[3][i] = 0x100;
1327                 else
1328                         result[3][i] = 0;
1329         }
1330         final_candidate = 0xff;
1331         pathaok = false;
1332         pathbok = false;
1333         is12simular = false;
1334         is23simular = false;
1335         is13simular = false;
1336
1337         for (i = 0; i < 3; i++) {
1338                 phy_IQCalibrate_8188E(adapt, result, i, is2t);
1339
1340                 if (i == 1) {
1341                         is12simular = phy_SimularityCompare_8188E(adapt, result, 0, 1);
1342                         if (is12simular) {
1343                                 final_candidate = 0;
1344                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is12simular final_candidate is %x\n", final_candidate));
1345                                 break;
1346                         }
1347                 }
1348
1349                 if (i == 2) {
1350                         is13simular = phy_SimularityCompare_8188E(adapt, result, 0, 2);
1351                         if (is13simular) {
1352                                 final_candidate = 0;
1353                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is13simular final_candidate is %x\n", final_candidate));
1354
1355                                 break;
1356                         }
1357                         is23simular = phy_SimularityCompare_8188E(adapt, result, 1, 2);
1358                         if (is23simular) {
1359                                 final_candidate = 1;
1360                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is23simular final_candidate is %x\n", final_candidate));
1361                         } else {
1362                                 final_candidate = 3;
1363                         }
1364                 }
1365         }
1366
1367         for (i = 0; i < 4; i++) {
1368                 RegE94 = result[i][0];
1369                 RegE9C = result[i][1];
1370                 RegEA4 = result[i][2];
1371                 RegEAC = result[i][3];
1372                 RegEB4 = result[i][4];
1373                 RegEBC = result[i][5];
1374                 RegEC4 = result[i][6];
1375                 RegECC = result[i][7];
1376                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1377                              ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n",
1378                              RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC));
1379         }
1380
1381         if (final_candidate != 0xff) {
1382                 RegE94 = result[final_candidate][0];
1383                 RegE9C = result[final_candidate][1];
1384                 RegEA4 = result[final_candidate][2];
1385                 RegEAC = result[final_candidate][3];
1386                 RegEB4 = result[final_candidate][4];
1387                 RegEBC = result[final_candidate][5];
1388                 dm_odm->RFCalibrateInfo.RegE94 = RegE94;
1389                 dm_odm->RFCalibrateInfo.RegE9C = RegE9C;
1390                 dm_odm->RFCalibrateInfo.RegEB4 = RegEB4;
1391                 dm_odm->RFCalibrateInfo.RegEBC = RegEBC;
1392                 RegEC4 = result[final_candidate][6];
1393                 RegECC = result[final_candidate][7];
1394                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1395                              ("IQK: final_candidate is %x\n", final_candidate));
1396                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1397                              ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n",
1398                              RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC));
1399                 pathaok = true;
1400                 pathbok = true;
1401         } else {
1402                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("IQK: FAIL use default value\n"));
1403                 dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1404                 dm_odm->RFCalibrateInfo.RegEB4 = 0x100; /* X default value */
1405                 dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1406                 dm_odm->RFCalibrateInfo.RegEBC = 0x0;   /* Y default value */
1407         }
1408         if (RegE94 != 0)
1409                 patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0));
1410         if (is2t) {
1411                 if (RegEB4 != 0)
1412                         pathb_fill_iqk(adapt, pathbok, result, final_candidate, (RegEC4 == 0));
1413         }
1414
1415         Indexforchannel = ODM_GetRightChnlPlaceforIQK(pHalData->CurrentChannel);
1416
1417 /* To Fix BSOD when final_candidate is 0xff */
1418 /* by sherry 20120321 */
1419         if (final_candidate < 4) {
1420                 for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1421                         dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][i] = result[final_candidate][i];
1422                 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].bIQKDone = true;
1423         }
1424         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("\nIQK OK Indexforchannel %d.\n", Indexforchannel));
1425
1426         _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1427
1428         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("IQK finished\n"));
1429 }
1430
1431 void PHY_LCCalibrate_8188E(struct adapter *adapt)
1432 {
1433         bool singletone = false, carrier_sup = false;
1434         u32 timeout = 2000, timecount = 0;
1435         struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt);
1436         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1437         struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
1438
1439         if (*(dm_odm->mp_mode) == 1) {
1440                 singletone = pMptCtx->bSingleTone;
1441                 carrier_sup = pMptCtx->bCarrierSuppression;
1442         }
1443         if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1444                 return;
1445         /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1446         if (singletone || carrier_sup)
1447                 return;
1448
1449         while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1450                 ODM_delay_ms(50);
1451                 timecount += 50;
1452         }
1453
1454         dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1455
1456         if (dm_odm->RFType == ODM_2T2R) {
1457                 phy_LCCalibrate_8188E(adapt, true);
1458         } else {
1459                 /*  For 88C 1T1R */
1460                 phy_LCCalibrate_8188E(adapt, false);
1461         }
1462
1463         dm_odm->RFCalibrateInfo.bLCKInProgress = false;
1464
1465         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1466                      ("LCK:Finish!!!interface %d\n", dm_odm->InterfaceIndex));
1467 }
1468
1469 static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2t)
1470 {
1471         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1472         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1473
1474         if (!adapt->hw_init_completed) {
1475                 u8 u1btmp;
1476                 u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT7;
1477                 ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp);
1478                 ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT13, 0x01);
1479         }
1480
1481         if (is2t) {     /* 92C */
1482                 if (main)
1483                         ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT5|BIT6, 0x1);  /* 92C_Path_A */
1484                 else
1485                         ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT5|BIT6, 0x2);  /* BT */
1486         } else {                        /* 88C */
1487                 if (main)
1488                         ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT8|BIT9, 0x2);  /* Main */
1489                 else
1490                         ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT8|BIT9, 0x1);  /* Aux */
1491         }
1492 }
1493
1494 void PHY_SetRFPathSwitch_8188E(struct adapter *adapt, bool main)
1495 {
1496         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1497         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1498
1499         if (dm_odm->RFType == ODM_2T2R) {
1500                 phy_setrfpathswitch_8188e(adapt, main, true);
1501         } else {
1502                 /*  For 88C 1T1R */
1503                 phy_setrfpathswitch_8188e(adapt, main, false);
1504         }
1505 }