• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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