]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c
staging: r8188eu: Add files for new driver - part 10
[karo-tx-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) == false)
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 (false == 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 /* Analog Pre-distortion calibration */
1280 #define         APK_BB_REG_NUM  8
1281 #define         APK_CURVE_REG_NUM 4
1282 #define         PATH_NUM                2
1283
1284 static void phy_APCalibrate_8188E(struct adapter *adapt, s8 delta, bool is2t)
1285 {
1286         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1287         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1288         u32 regD[PATH_NUM];
1289         u32 tmpreg, index, offset,  apkbound;
1290         u8 path, i, pathbound = PATH_NUM;
1291         u32 BB_backup[APK_BB_REG_NUM];
1292         u32 BB_REG[APK_BB_REG_NUM] = {
1293                 rFPGA1_TxBlock,         rOFDM0_TRxPathEnable,
1294                 rFPGA0_RFMOD, rOFDM0_TRMuxPar,
1295                 rFPGA0_XCD_RFInterfaceSW, rFPGA0_XAB_RFInterfaceSW,
1296                 rFPGA0_XA_RFInterfaceOE, rFPGA0_XB_RFInterfaceOE        };
1297         u32 BB_AP_MODE[APK_BB_REG_NUM] = {
1298                 0x00000020, 0x00a05430, 0x02040000,
1299                 0x000800e4, 0x00204000 };
1300         u32 BB_normal_AP_MODE[APK_BB_REG_NUM] = {
1301                 0x00000020, 0x00a05430, 0x02040000,
1302                 0x000800e4, 0x22204000 };
1303
1304         u32 AFE_backup[IQK_ADDA_REG_NUM];
1305         u32 AFE_REG[IQK_ADDA_REG_NUM] = {
1306                 rFPGA0_XCD_SwitchControl, rBlue_Tooth,
1307                 rRx_Wait_CCA,   rTx_CCK_RFON,
1308                 rTx_CCK_BBON, rTx_OFDM_RFON,
1309                 rTx_OFDM_BBON, rTx_To_Rx,
1310                 rTx_To_Tx,      rRx_CCK,
1311                 rRx_OFDM,       rRx_Wait_RIFS,
1312                 rRx_TO_Rx,      rStandby,
1313                 rSleep,                         rPMPD_ANAEN };
1314
1315         u32 MAC_backup[IQK_MAC_REG_NUM];
1316         u32 MAC_REG[IQK_MAC_REG_NUM] = {
1317                 REG_TXPAUSE,    REG_BCN_CTRL,
1318                 REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1319
1320         u32 APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1321                 {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
1322                 {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
1323         };
1324
1325         u32 APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1326                 {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, /* path settings equal to path b settings */
1327                 {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
1328         };
1329
1330         u32 APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1331                 {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
1332                 {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
1333         };
1334
1335         u32 APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1336                 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, /* path settings equal to path b settings */
1337                 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
1338         };
1339
1340         u32 AFE_on_off[PATH_NUM] = {
1341                 0x04db25a4, 0x0b1b25a4};        /* path A on path B off / path A off path B on */
1342
1343         u32 APK_offset[PATH_NUM] = {
1344                 rConfig_AntA, rConfig_AntB};
1345
1346         u32 APK_normal_offset[PATH_NUM] = {
1347                 rConfig_Pmpd_AntA, rConfig_Pmpd_AntB};
1348
1349         u32 APK_value[PATH_NUM] = {
1350                 0x92fc0000, 0x12fc0000};
1351
1352         u32 APK_normal_value[PATH_NUM] = {
1353                 0x92680000, 0x12680000};
1354
1355         s8 APK_delta_mapping[APK_BB_REG_NUM][13] = {
1356                 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1357                 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1358                 {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1359                 {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1360                 {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
1361         };
1362
1363         u32 APK_normal_setting_value_1[13] = {
1364                 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
1365                 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
1366                 0x12680000, 0x00880000, 0x00880000
1367         };
1368
1369         u32 APK_normal_setting_value_2[16] = {
1370                 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
1371                 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
1372                 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
1373                 0x00050006
1374         };
1375
1376         u32 APK_result[PATH_NUM][APK_BB_REG_NUM];       /* val_1_1a, val_1_2a, val_2a, val_3a, val_4a */
1377         s32 BB_offset, delta_V, delta_offset;
1378
1379         if (*(dm_odm->mp_mode) == 1) {
1380                 struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
1381                 pMptCtx->APK_bound[0] = 45;
1382                 pMptCtx->APK_bound[1] = 52;
1383         }
1384
1385         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("==>phy_APCalibrate_8188E() delta %d\n", delta));
1386         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("AP Calibration for %s\n", (is2t ? "2T2R" : "1T1R")));
1387         if (!is2t)
1388                 pathbound = 1;
1389
1390         /* 2 FOR NORMAL CHIP SETTINGS */
1391
1392 /*  Temporarily do not allow normal driver to do the following settings
1393  *  because these offset and value will cause RF internal PA to be
1394  *  unpredictably disabled by HW, such that RF Tx signal  will disappear
1395  *  after disable/enable card many times on 88CU. RF SD and DD have not
1396  *  find the root cause, so we remove these actions temporarily.
1397  */
1398         if (*(dm_odm->mp_mode) != 1)
1399                 return;
1400         /* settings adjust for normal chip */
1401         for (index = 0; index < PATH_NUM; index++) {
1402                 APK_offset[index] = APK_normal_offset[index];
1403                 APK_value[index] = APK_normal_value[index];
1404                 AFE_on_off[index] = 0x6fdb25a4;
1405         }
1406
1407         for (index = 0; index < APK_BB_REG_NUM; index++) {
1408                 for (path = 0; path < pathbound; path++) {
1409                         APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index];
1410                         APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index];
1411                 }
1412                 BB_AP_MODE[index] = BB_normal_AP_MODE[index];
1413         }
1414
1415         apkbound = 6;
1416
1417         /* save BB default value */
1418         for (index = 0; index < APK_BB_REG_NUM; index++) {
1419                 if (index == 0)         /* skip */
1420                         continue;
1421                 BB_backup[index] = ODM_GetBBReg(dm_odm, BB_REG[index], bMaskDWord);
1422         }
1423
1424         /* save MAC default value */
1425         _PHY_SaveMACRegisters(adapt, MAC_REG, MAC_backup);
1426
1427         /* save AFE default value */
1428         _PHY_SaveADDARegisters(adapt, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
1429
1430         for (path = 0; path < pathbound; path++) {
1431                 if (path == RF_PATH_A) {
1432                         /* path A APK */
1433                         /* load APK setting */
1434                         /* path-A */
1435                         offset = rPdp_AntA;
1436                         for (index = 0; index < 11; index++) {
1437                                 ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
1438                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1439                                              ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
1440                                              offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
1441                                 offset += 0x04;
1442                         }
1443
1444                         ODM_SetBBReg(dm_odm, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000);
1445
1446                         offset = rConfig_AntA;
1447                         for (; index < 13; index++) {
1448                                 ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
1449                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1450                                              ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
1451                                              offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
1452                                 offset += 0x04;
1453                         }
1454
1455                         /* page-B1 */
1456                         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x40000000);
1457
1458                         /* path A */
1459                         offset = rPdp_AntA;
1460                         for (index = 0; index < 16; index++) {
1461                                 ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_2[index]);
1462                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1463                                              ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
1464                                              offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
1465
1466                                 offset += 0x04;
1467                         }
1468                         ODM_SetBBReg(dm_odm,  rFPGA0_IQK, bMaskDWord, 0x00000000);
1469                 } else if (path == RF_PATH_B) {
1470                         /* path B APK */
1471                         /* load APK setting */
1472                         /* path-B */
1473                         offset = rPdp_AntB;
1474                         for (index = 0; index < 10; index++) {
1475                                 ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
1476                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1477                                              ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
1478                                              offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
1479
1480                                 offset += 0x04;
1481                         }
1482                         ODM_SetBBReg(dm_odm, rConfig_Pmpd_AntA, bMaskDWord, 0x12680000);
1483                         PHY_SetBBReg(adapt, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000);
1484
1485                         offset = rConfig_AntA;
1486                         index = 11;
1487                         for (; index < 13; index++) { /* offset 0xb68, 0xb6c */
1488                                 ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
1489                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1490                                              ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
1491                                              offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
1492                                 offset += 0x04;
1493                         }
1494
1495                         /* page-B1 */
1496                         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x40000000);
1497
1498                         /* path B */
1499                         offset = 0xb60;
1500                         for (index = 0; index < 16; index++) {
1501                                 ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_2[index]);
1502                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1503                                              ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
1504                                              offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
1505
1506                                 offset += 0x04;
1507                         }
1508                         ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0);
1509                 }
1510
1511                 /* save RF default value */
1512                 regD[path] = PHY_QueryRFReg(adapt, path, RF_TXBIAS_A, bMaskDWord);
1513
1514                 /* Path A AFE all on, path B AFE All off or vise versa */
1515                 for (index = 0; index < IQK_ADDA_REG_NUM; index++)
1516                         ODM_SetBBReg(dm_odm, AFE_REG[index], bMaskDWord, AFE_on_off[path]);
1517                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1518                              ("phy_APCalibrate_8188E() offset 0xe70 %x\n",
1519                              ODM_GetBBReg(dm_odm, rRx_Wait_CCA, bMaskDWord)));
1520
1521                 /* BB to AP mode */
1522                 if (path == 0) {
1523                         for (index = 0; index < APK_BB_REG_NUM; index++) {
1524                                 if (index == 0)         /* skip */
1525                                         continue;
1526                                 else if (index < 5)
1527                                 ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_AP_MODE[index]);
1528                                 else if (BB_REG[index] == 0x870)
1529                                         ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_backup[index]|BIT10|BIT26);
1530                                 else
1531                                         ODM_SetBBReg(dm_odm, BB_REG[index], BIT10, 0x0);
1532                         }
1533
1534                         ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1535                         ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1536                 } else {
1537                         /* path B */
1538                         ODM_SetBBReg(dm_odm, rTx_IQK_Tone_B, bMaskDWord, 0x01008c00);
1539                         ODM_SetBBReg(dm_odm, rRx_IQK_Tone_B, bMaskDWord, 0x01008c00);
1540                 }
1541
1542                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1543                              ("phy_APCalibrate_8188E() offset 0x800 %x\n",
1544                              ODM_GetBBReg(dm_odm, 0x800, bMaskDWord)));
1545
1546                 /* MAC settings */
1547                 _PHY_MACSettingCalibration(adapt, MAC_REG, MAC_backup);
1548
1549                 if (path == RF_PATH_A) {
1550                         /* Path B to standby mode */
1551                         ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMaskDWord, 0x10000);
1552                 } else {
1553                         /* Path A to standby mode */
1554                         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMaskDWord, 0x10000);
1555                         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f);
1556                         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE2, bMaskDWord, 0x20103);
1557                 }
1558
1559                 delta_offset = ((delta+14)/2);
1560                 if (delta_offset < 0)
1561                         delta_offset = 0;
1562                 else if (delta_offset > 12)
1563                         delta_offset = 12;
1564
1565                 /* AP calibration */
1566                 for (index = 0; index < APK_BB_REG_NUM; index++) {
1567                         if (index != 1) /* only DO PA11+PAD01001, AP RF setting */
1568                                 continue;
1569
1570                         tmpreg = APK_RF_init_value[path][index];
1571                         if (!dm_odm->RFCalibrateInfo.bAPKThermalMeterIgnore) {
1572                                 BB_offset = (tmpreg & 0xF0000) >> 16;
1573
1574                                 if (!(tmpreg & BIT15)) /* sign bit 0 */
1575                                         BB_offset = -BB_offset;
1576
1577                                 delta_V = APK_delta_mapping[index][delta_offset];
1578
1579                                 BB_offset += delta_V;
1580
1581                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1582                                              ("phy_APCalibrate_8188E() APK index %d tmpreg 0x%x delta_V %d delta_offset %d\n",
1583                                              index, tmpreg, delta_V, delta_offset));
1584
1585                                 if (BB_offset < 0) {
1586                                         tmpreg = tmpreg & (~BIT15);
1587                                         BB_offset = -BB_offset;
1588                                 } else {
1589                                         tmpreg = tmpreg | BIT15;
1590                                 }
1591                                 tmpreg = (tmpreg & 0xFFF0FFFF) | (BB_offset << 16);
1592                         }
1593
1594                         ODM_SetRFReg(dm_odm, path, RF_IPA_A, bMaskDWord, 0x8992e);
1595                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xc %x\n", PHY_QueryRFReg(adapt, path, RF_IPA_A, bMaskDWord)));
1596                         ODM_SetRFReg(dm_odm, path, RF_AC, bMaskDWord, APK_RF_value_0[path][index]);
1597                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("phy_APCalibrate_8188E() offset 0x0 %x\n", PHY_QueryRFReg(adapt, path, RF_AC, bMaskDWord)));
1598                         ODM_SetRFReg(dm_odm, path, RF_TXBIAS_A, bMaskDWord, tmpreg);
1599                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xd %x\n", PHY_QueryRFReg(adapt, path, RF_TXBIAS_A, bMaskDWord)));
1600                         /*  PA11+PAD01111, one shot */
1601                         i = 0;
1602                         do {
1603                                 ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80000000);
1604                                 ODM_SetBBReg(dm_odm, APK_offset[path], bMaskDWord, APK_value[0]);
1605                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(dm_odm, APK_offset[path], bMaskDWord)));
1606                                 ODM_delay_ms(3);
1607                                 ODM_SetBBReg(dm_odm, APK_offset[path], bMaskDWord, APK_value[1]);
1608                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(dm_odm, APK_offset[path], bMaskDWord)));
1609
1610                                 ODM_delay_ms(20);
1611                                 ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
1612
1613                                 if (path == RF_PATH_A)
1614                                         tmpreg = ODM_GetBBReg(dm_odm, rAPK, 0x03E00000);
1615                                 else
1616                                         tmpreg = ODM_GetBBReg(dm_odm, rAPK, 0xF8000000);
1617                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xbd8[25:21] %x\n", tmpreg));
1618
1619                                 i++;
1620                         } while (tmpreg > apkbound && i < 4);
1621
1622                         APK_result[path][index] = tmpreg;
1623                 }
1624         }
1625
1626         /* reload MAC default value */
1627         _PHY_ReloadMACRegisters(adapt, MAC_REG, MAC_backup);
1628
1629         /* reload BB default value */
1630         for (index = 0; index < APK_BB_REG_NUM; index++) {
1631                 if (index == 0)         /* skip */
1632                         continue;
1633                 ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_backup[index]);
1634         }
1635
1636         /* reload AFE default value */
1637         reload_adda_reg(adapt, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
1638
1639         /* reload RF path default value */
1640         for (path = 0; path < pathbound; path++) {
1641                 ODM_SetRFReg(dm_odm, path, 0xd, bMaskDWord, regD[path]);
1642                 if (path == RF_PATH_B) {
1643                         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f);
1644                         ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE2, bMaskDWord, 0x20101);
1645                 }
1646
1647                 /* note no index == 0 */
1648                 if (APK_result[path][1] > 6)
1649                         APK_result[path][1] = 6;
1650                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1]));
1651         }
1652
1653         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("\n"));
1654
1655         for (path = 0; path < pathbound; path++) {
1656                 ODM_SetRFReg(dm_odm, path, 0x3, bMaskDWord,
1657                              ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1]));
1658                 if (path == RF_PATH_A)
1659                         ODM_SetRFReg(dm_odm, path, 0x4, bMaskDWord,
1660                                      ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05));
1661                 else
1662                         ODM_SetRFReg(dm_odm, path, 0x4, bMaskDWord,
1663                                      ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05));
1664                 ODM_SetRFReg(dm_odm, path, RF_BS_PA_APSET_G9_G11, bMaskDWord,
1665                              ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08));
1666         }
1667
1668         dm_odm->RFCalibrateInfo.bAPKdone = true;
1669
1670         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("<==phy_APCalibrate_8188E()\n"));
1671 }
1672
1673 #define         DP_BB_REG_NUM           7
1674 #define         DP_RF_REG_NUM           1
1675 #define         DP_RETRY_LIMIT          10
1676 #define         DP_PATH_NUM             2
1677 #define         DP_DPK_NUM                      3
1678 #define         DP_DPK_VALUE_NUM        2
1679
1680 void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
1681 {
1682         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1683         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1684         struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
1685         s32 result[4][8];       /* last is final result */
1686         u8 i, final_candidate, Indexforchannel;
1687         bool pathaok, pathbok;
1688         s32 RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC;
1689         bool is12simular, is13simular, is23simular;
1690         bool singletone = false, carrier_sup = false;
1691         u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1692                 rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1693                 rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1694                 rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1695                 rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1696                 rOFDM0_RxIQExtAnta};
1697         bool is2t;
1698
1699         is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1700         if (ODM_CheckPowerStatus(adapt) == false)
1701                 return;
1702
1703         if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1704                 return;
1705
1706         if (*(dm_odm->mp_mode) == 1) {
1707                 singletone = pMptCtx->bSingleTone;
1708                 carrier_sup = pMptCtx->bCarrierSuppression;
1709         }
1710
1711         /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1712         if (singletone || carrier_sup)
1713                 return;
1714
1715         if (recovery) {
1716                 ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("PHY_IQCalibrate_8188E: Return due to recovery!\n"));
1717                 reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1718                 return;
1719         }
1720         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("IQK:Start!!!\n"));
1721
1722         for (i = 0; i < 8; i++) {
1723                 result[0][i] = 0;
1724                 result[1][i] = 0;
1725                 result[2][i] = 0;
1726                 if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
1727                         result[3][i] = 0x100;
1728                 else
1729                         result[3][i] = 0;
1730         }
1731         final_candidate = 0xff;
1732         pathaok = false;
1733         pathbok = false;
1734         is12simular = false;
1735         is23simular = false;
1736         is13simular = false;
1737
1738         for (i = 0; i < 3; i++) {
1739                 phy_IQCalibrate_8188E(adapt, result, i, is2t);
1740
1741                 if (i == 1) {
1742                         is12simular = phy_SimularityCompare_8188E(adapt, result, 0, 1);
1743                         if (is12simular) {
1744                                 final_candidate = 0;
1745                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is12simular final_candidate is %x\n", final_candidate));
1746                                 break;
1747                         }
1748                 }
1749
1750                 if (i == 2) {
1751                         is13simular = phy_SimularityCompare_8188E(adapt, result, 0, 2);
1752                         if (is13simular) {
1753                                 final_candidate = 0;
1754                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is13simular final_candidate is %x\n", final_candidate));
1755
1756                                 break;
1757                         }
1758                         is23simular = phy_SimularityCompare_8188E(adapt, result, 1, 2);
1759                         if (is23simular) {
1760                                 final_candidate = 1;
1761                                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is23simular final_candidate is %x\n", final_candidate));
1762                         } else {
1763                                 final_candidate = 3;
1764                         }
1765                 }
1766         }
1767
1768         for (i = 0; i < 4; i++) {
1769                 RegE94 = result[i][0];
1770                 RegE9C = result[i][1];
1771                 RegEA4 = result[i][2];
1772                 RegEAC = result[i][3];
1773                 RegEB4 = result[i][4];
1774                 RegEBC = result[i][5];
1775                 RegEC4 = result[i][6];
1776                 RegECC = result[i][7];
1777                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1778                              ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n",
1779                              RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC));
1780         }
1781
1782         if (final_candidate != 0xff) {
1783                 RegE94 = result[final_candidate][0];
1784                 RegE9C = result[final_candidate][1];
1785                 RegEA4 = result[final_candidate][2];
1786                 RegEAC = result[final_candidate][3];
1787                 RegEB4 = result[final_candidate][4];
1788                 RegEBC = result[final_candidate][5];
1789                 dm_odm->RFCalibrateInfo.RegE94 = RegE94;
1790                 dm_odm->RFCalibrateInfo.RegE9C = RegE9C;
1791                 dm_odm->RFCalibrateInfo.RegEB4 = RegEB4;
1792                 dm_odm->RFCalibrateInfo.RegEBC = RegEBC;
1793                 RegEC4 = result[final_candidate][6];
1794                 RegECC = result[final_candidate][7];
1795                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1796                              ("IQK: final_candidate is %x\n", final_candidate));
1797                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1798                              ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n",
1799                              RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC));
1800                 pathaok = true;
1801                 pathbok = true;
1802         } else {
1803                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("IQK: FAIL use default value\n"));
1804                 dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1805                 dm_odm->RFCalibrateInfo.RegEB4 = 0x100; /* X default value */
1806                 dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1807                 dm_odm->RFCalibrateInfo.RegEBC = 0x0;   /* Y default value */
1808         }
1809         if (RegE94 != 0)
1810                 patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0));
1811         if (is2t) {
1812                 if (RegEB4 != 0)
1813                         pathb_fill_iqk(adapt, pathbok, result, final_candidate, (RegEC4 == 0));
1814         }
1815
1816         Indexforchannel = ODM_GetRightChnlPlaceforIQK(pHalData->CurrentChannel);
1817
1818 /* To Fix BSOD when final_candidate is 0xff */
1819 /* by sherry 20120321 */
1820         if (final_candidate < 4) {
1821                 for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1822                         dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][i] = result[final_candidate][i];
1823                 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].bIQKDone = true;
1824         }
1825         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("\nIQK OK Indexforchannel %d.\n", Indexforchannel));
1826
1827         _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1828
1829         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("IQK finished\n"));
1830 }
1831
1832 void PHY_LCCalibrate_8188E(struct adapter *adapt)
1833 {
1834         bool singletone = false, carrier_sup = false;
1835         u32 timeout = 2000, timecount = 0;
1836         struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt);
1837         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1838         struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
1839
1840         if (*(dm_odm->mp_mode) == 1) {
1841                 singletone = pMptCtx->bSingleTone;
1842                 carrier_sup = pMptCtx->bCarrierSuppression;
1843         }
1844         if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1845                 return;
1846         /*  20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1847         if (singletone || carrier_sup)
1848                 return;
1849
1850         while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1851                 ODM_delay_ms(50);
1852                 timecount += 50;
1853         }
1854
1855         dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1856
1857         if (dm_odm->RFType == ODM_2T2R) {
1858                 phy_LCCalibrate_8188E(adapt, true);
1859         } else {
1860                 /*  For 88C 1T1R */
1861                 phy_LCCalibrate_8188E(adapt, false);
1862         }
1863
1864         dm_odm->RFCalibrateInfo.bLCKInProgress = false;
1865
1866         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1867                      ("LCK:Finish!!!interface %d\n", dm_odm->InterfaceIndex));
1868 }
1869
1870 void PHY_APCalibrate_8188E(struct adapter *adapt, s8 delta)
1871 {
1872         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1873         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1874
1875         return;
1876         if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1877                 return;
1878
1879 #if FOR_BRAZIL_PRETEST != 1
1880         if (dm_odm->RFCalibrateInfo.bAPKdone)
1881 #endif
1882                 return;
1883
1884         if (dm_odm->RFType == ODM_2T2R) {
1885                 phy_APCalibrate_8188E(adapt, delta, true);
1886         } else {
1887                 /*  For 88C 1T1R */
1888                 phy_APCalibrate_8188E(adapt, delta, false);
1889         }
1890 }
1891
1892 static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2t)
1893 {
1894         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1895         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1896
1897         if (!adapt->hw_init_completed) {
1898                 u8 u1btmp;
1899                 u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT7;
1900                 ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp);
1901                 ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT13, 0x01);
1902         }
1903
1904         if (is2t) {     /* 92C */
1905                 if (main)
1906                         ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT5|BIT6, 0x1);  /* 92C_Path_A */
1907                 else
1908                         ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT5|BIT6, 0x2);  /* BT */
1909         } else {                        /* 88C */
1910                 if (main)
1911                         ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT8|BIT9, 0x2);  /* Main */
1912                 else
1913                         ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT8|BIT9, 0x1);  /* Aux */
1914         }
1915 }
1916
1917 void PHY_SetRFPathSwitch_8188E(struct adapter *adapt, bool main)
1918 {
1919         struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
1920         struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
1921
1922         if (dm_odm->RFType == ODM_2T2R) {
1923                 phy_setrfpathswitch_8188e(adapt, main, true);
1924         } else {
1925                 /*  For 88C 1T1R */
1926                 phy_setrfpathswitch_8188e(adapt, main, false);
1927         }
1928 }