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