1// SPDX-License-Identifier: GPL-2.0
2/*****************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7
8#include <drv_types.h>
9#include <rtw_debug.h>
10#include "odm_precomp.h"
11
12/* MACRO definition for pRFCalibrateInfo->TxIQC_8723B[0] */
13#define PATH_S0 1 /* RF_PATH_B */
14#define IDX_0xC94 0
15#define IDX_0xC80 1
16#define IDX_0xC14 0
17#define IDX_0xCA0 1
18#define KEY 0
19#define VAL 1
20
21/* MACRO definition for pRFCalibrateInfo->TxIQC_8723B[1] */
22#define PATH_S1 0 /* RF_PATH_A */
23#define IDX_0xC4C 2
24
25/*---------------------------Define Local Constant---------------------------*/
26
27/* In the case that we fail to read TxPowerTrack.txt, we use the table for
28 * 88E as the default table.
29 */
30static u8 DeltaSwingTableIdx_2GA_N_8188E[] = {
31 0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
32 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11
33};
34static u8 DeltaSwingTableIdx_2GA_P_8188E[] = {
35 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4,
36 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9
37};
38
39/* 3 ============================================================ */
40/* 3 Tx Power Tracking */
41/* 3 ============================================================ */
42
43
44static void setIqkMatrix_8723B(
45 struct dm_odm_t *pDM_Odm,
46 u8 OFDM_index,
47 u8 RFPath,
48 s32 IqkResult_X,
49 s32 IqkResult_Y
50)
51{
52 s32 ele_A = 0, ele_D, ele_C = 0, value32;
53
54 if (OFDM_index >= OFDM_TABLE_SIZE)
55 OFDM_index = OFDM_TABLE_SIZE-1;
56
57 ele_D = (OFDMSwingTable_New[OFDM_index] & 0xFFC00000)>>22;
58
59 /* new element A = element D x X */
60 if (IqkResult_X != 0) {
61 if ((IqkResult_X & 0x00000200) != 0) /* consider minus */
62 IqkResult_X = IqkResult_X | 0xFFFFFC00;
63 ele_A = ((IqkResult_X * ele_D)>>8)&0x000003FF;
64
65 /* new element C = element D x Y */
66 if ((IqkResult_Y & 0x00000200) != 0)
67 IqkResult_Y = IqkResult_Y | 0xFFFFFC00;
68 ele_C = ((IqkResult_Y * ele_D)>>8)&0x000003FF;
69
70 /* if (RFPath == RF_PATH_A) */
71 switch (RFPath) {
72 case RF_PATH_A:
73 /* write new elements A, C, D to regC80 and regC94,
74 * element B is always 0
75 */
76 value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
77 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, value32);
78
79 value32 = (ele_C&0x000003C0)>>6;
80 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, value32);
81
82 value32 = ((IqkResult_X * ele_D)>>7)&0x01;
83 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT24, value32);
84 break;
85 case RF_PATH_B:
86 /* write new elements A, C, D to regC88 and regC9C,
87 * element B is always 0
88 */
89 value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
90 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, value32);
91
92 value32 = (ele_C&0x000003C0)>>6;
93 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
94
95 value32 = ((IqkResult_X * ele_D)>>7)&0x01;
96 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT28, value32);
97
98 break;
99 default:
100 break;
101 }
102 } else {
103 switch (RFPath) {
104 case RF_PATH_A:
105 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]);
106 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00);
107 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT24, 0x00);
108 break;
109
110 case RF_PATH_B:
111 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]);
112 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00);
113 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT28, 0x00);
114 break;
115
116 default:
117 break;
118 }
119 }
120}
121
122
123static void setCCKFilterCoefficient(struct dm_odm_t *pDM_Odm, u8 CCKSwingIndex)
124{
125 if (!pDM_Odm->RFCalibrateInfo.bCCKinCH14) {
126 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa22, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][0]);
127 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa23, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][1]);
128 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa24, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][2]);
129 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa25, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][3]);
130 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa26, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][4]);
131 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa27, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][5]);
132 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa28, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][6]);
133 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa29, val: CCKSwingTable_Ch1_Ch13_New[CCKSwingIndex][7]);
134 } else {
135 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa22, val: CCKSwingTable_Ch14_New[CCKSwingIndex][0]);
136 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa23, val: CCKSwingTable_Ch14_New[CCKSwingIndex][1]);
137 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa24, val: CCKSwingTable_Ch14_New[CCKSwingIndex][2]);
138 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa25, val: CCKSwingTable_Ch14_New[CCKSwingIndex][3]);
139 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa26, val: CCKSwingTable_Ch14_New[CCKSwingIndex][4]);
140 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa27, val: CCKSwingTable_Ch14_New[CCKSwingIndex][5]);
141 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa28, val: CCKSwingTable_Ch14_New[CCKSwingIndex][6]);
142 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xa29, val: CCKSwingTable_Ch14_New[CCKSwingIndex][7]);
143 }
144}
145
146void DoIQK_8723B(
147 struct dm_odm_t *pDM_Odm,
148 u8 DeltaThermalIndex,
149 u8 ThermalValue,
150 u8 Threshold
151)
152{
153}
154
155/*-----------------------------------------------------------------------------
156 * Function: odm_TxPwrTrackSetPwr88E()
157 *
158 * Overview: 88E change all channel tx power according to flag.
159 * OFDM & CCK are all different.
160 *
161 * Input: NONE
162 *
163 * Output: NONE
164 *
165 * Return: NONE
166 *
167 * Revised History:
168 *When Who Remark
169 *04/23/2012 MHC Create Version 0.
170 *
171 *---------------------------------------------------------------------------*/
172void ODM_TxPwrTrackSetPwr_8723B(
173 struct dm_odm_t *pDM_Odm,
174 enum pwrtrack_method Method,
175 u8 RFPath,
176 u8 ChannelMappedIndex
177)
178{
179 struct adapter *Adapter = pDM_Odm->Adapter;
180 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
181 u8 PwrTrackingLimit_OFDM = 34; /* 0dB */
182 u8 PwrTrackingLimit_CCK = 28; /* 2dB */
183 u8 TxRate = 0xFF;
184 u8 Final_OFDM_Swing_Index = 0;
185 u8 Final_CCK_Swing_Index = 0;
186
187 {
188 u16 rate = *(pDM_Odm->pForcedDataRate);
189
190 if (!rate) { /* auto rate */
191 if (pDM_Odm->TxRate != 0xFF)
192 TxRate = HwRateToMRate(rate: pDM_Odm->TxRate);
193 } else /* force rate */
194 TxRate = (u8)rate;
195
196 }
197
198 if (TxRate != 0xFF) {
199 /* 2 CCK */
200 if ((TxRate >= MGN_1M) && (TxRate <= MGN_11M))
201 PwrTrackingLimit_CCK = 28; /* 2dB */
202 /* 2 OFDM */
203 else if ((TxRate >= MGN_6M) && (TxRate <= MGN_48M))
204 PwrTrackingLimit_OFDM = 36; /* 3dB */
205 else if (TxRate == MGN_54M)
206 PwrTrackingLimit_OFDM = 34; /* 2dB */
207
208 /* 2 HT */
209 else if ((TxRate >= MGN_MCS0) && (TxRate <= MGN_MCS2)) /* QPSK/BPSK */
210 PwrTrackingLimit_OFDM = 38; /* 4dB */
211 else if ((TxRate >= MGN_MCS3) && (TxRate <= MGN_MCS4)) /* 16QAM */
212 PwrTrackingLimit_OFDM = 36; /* 3dB */
213 else if ((TxRate >= MGN_MCS5) && (TxRate <= MGN_MCS7)) /* 64QAM */
214 PwrTrackingLimit_OFDM = 34; /* 2dB */
215
216 else
217 PwrTrackingLimit_OFDM = pDM_Odm->DefaultOfdmIndex; /* Default OFDM index = 30 */
218 }
219
220 if (Method == TXAGC) {
221 struct adapter *Adapter = pDM_Odm->Adapter;
222
223 pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
224
225 pDM_Odm->Modify_TxAGC_Flag_PathA = true;
226 pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = true;
227
228 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: CCK);
229 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: OFDM);
230 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: HT_MCS0_MCS7);
231 } else if (Method == BBSWING) {
232 Final_OFDM_Swing_Index = pDM_Odm->DefaultOfdmIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
233 Final_CCK_Swing_Index = pDM_Odm->DefaultCckIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
234
235 /* Adjust BB swing by OFDM IQ matrix */
236 if (Final_OFDM_Swing_Index >= PwrTrackingLimit_OFDM)
237 Final_OFDM_Swing_Index = PwrTrackingLimit_OFDM;
238 else if (Final_OFDM_Swing_Index <= 0)
239 Final_OFDM_Swing_Index = 0;
240
241 if (Final_CCK_Swing_Index >= CCK_TABLE_SIZE)
242 Final_CCK_Swing_Index = CCK_TABLE_SIZE-1;
243 else if (pDM_Odm->BbSwingIdxCck <= 0)
244 Final_CCK_Swing_Index = 0;
245
246 setIqkMatrix_8723B(pDM_Odm, OFDM_index: Final_OFDM_Swing_Index, RFPath,
247 IqkResult_X: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0],
248 IqkResult_Y: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]);
249
250 setCCKFilterCoefficient(pDM_Odm, CCKSwingIndex: Final_CCK_Swing_Index);
251
252 } else if (Method == MIX_MODE) {
253 Final_OFDM_Swing_Index = pDM_Odm->DefaultOfdmIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
254 Final_CCK_Swing_Index = pDM_Odm->DefaultCckIndex + pDM_Odm->Absolute_OFDMSwingIdx[RFPath];
255
256 if (Final_OFDM_Swing_Index > PwrTrackingLimit_OFDM) { /* BBSwing higher then Limit */
257 pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index - PwrTrackingLimit_OFDM;
258
259 setIqkMatrix_8723B(pDM_Odm, OFDM_index: PwrTrackingLimit_OFDM, RFPath,
260 IqkResult_X: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0],
261 IqkResult_Y: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]);
262
263 pDM_Odm->Modify_TxAGC_Flag_PathA = true;
264 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: OFDM);
265 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: HT_MCS0_MCS7);
266 } else if (Final_OFDM_Swing_Index <= 0) {
267 pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index;
268
269 setIqkMatrix_8723B(pDM_Odm, OFDM_index: 0, RFPath,
270 IqkResult_X: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0],
271 IqkResult_Y: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]);
272
273 pDM_Odm->Modify_TxAGC_Flag_PathA = true;
274 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: OFDM);
275 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: HT_MCS0_MCS7);
276 } else {
277 setIqkMatrix_8723B(pDM_Odm, OFDM_index: Final_OFDM_Swing_Index, RFPath,
278 IqkResult_X: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][0],
279 IqkResult_Y: pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[ChannelMappedIndex][1]);
280
281 if (pDM_Odm->Modify_TxAGC_Flag_PathA) { /* If TxAGC has changed, reset TxAGC again */
282 pDM_Odm->Remnant_OFDMSwingIdx[RFPath] = 0;
283 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: OFDM);
284 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: HT_MCS0_MCS7);
285 pDM_Odm->Modify_TxAGC_Flag_PathA = false;
286 }
287 }
288
289 if (Final_CCK_Swing_Index > PwrTrackingLimit_CCK) {
290 pDM_Odm->Remnant_CCKSwingIdx = Final_CCK_Swing_Index - PwrTrackingLimit_CCK;
291 setCCKFilterCoefficient(pDM_Odm, CCKSwingIndex: PwrTrackingLimit_CCK);
292 pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = true;
293 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: CCK);
294 } else if (Final_CCK_Swing_Index <= 0) { /* Lowest CCK Index = 0 */
295 pDM_Odm->Remnant_CCKSwingIdx = Final_CCK_Swing_Index;
296 setCCKFilterCoefficient(pDM_Odm, CCKSwingIndex: 0);
297 pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = true;
298 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: CCK);
299 } else {
300 setCCKFilterCoefficient(pDM_Odm, CCKSwingIndex: Final_CCK_Swing_Index);
301
302 if (pDM_Odm->Modify_TxAGC_Flag_PathA_CCK) { /* If TxAGC has changed, reset TxAGC again */
303 pDM_Odm->Remnant_CCKSwingIdx = 0;
304 PHY_SetTxPowerIndexByRateSection(padapter: Adapter, RFPath, Channel: pHalData->CurrentChannel, RateSection: CCK);
305 pDM_Odm->Modify_TxAGC_Flag_PathA_CCK = false;
306 }
307 }
308 } else
309 return; /* This method is not supported. */
310}
311
312static void GetDeltaSwingTable_8723B(
313 struct dm_odm_t *pDM_Odm,
314 u8 **TemperatureUP_A,
315 u8 **TemperatureDOWN_A,
316 u8 **TemperatureUP_B,
317 u8 **TemperatureDOWN_B
318)
319{
320 struct adapter *Adapter = pDM_Odm->Adapter;
321 struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
322 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
323 u16 rate = *(pDM_Odm->pForcedDataRate);
324 u8 channel = pHalData->CurrentChannel;
325
326 if (1 <= channel && channel <= 14) {
327 if (IS_CCK_RATE(rate)) {
328 *TemperatureUP_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P;
329 *TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N;
330 *TemperatureUP_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P;
331 *TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N;
332 } else {
333 *TemperatureUP_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P;
334 *TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N;
335 *TemperatureUP_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P;
336 *TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N;
337 }
338 } else {
339 *TemperatureUP_A = (u8 *)DeltaSwingTableIdx_2GA_P_8188E;
340 *TemperatureDOWN_A = (u8 *)DeltaSwingTableIdx_2GA_N_8188E;
341 *TemperatureUP_B = (u8 *)DeltaSwingTableIdx_2GA_P_8188E;
342 *TemperatureDOWN_B = (u8 *)DeltaSwingTableIdx_2GA_N_8188E;
343 }
344}
345
346
347void ConfigureTxpowerTrack_8723B(struct txpwrtrack_cfg *pConfig)
348{
349 pConfig->SwingTableSize_CCK = CCK_TABLE_SIZE;
350 pConfig->SwingTableSize_OFDM = OFDM_TABLE_SIZE;
351 pConfig->Threshold_IQK = IQK_THRESHOLD;
352 pConfig->AverageThermalNum = AVG_THERMAL_NUM_8723B;
353 pConfig->RfPathCount = MAX_PATH_NUM_8723B;
354 pConfig->ThermalRegAddr = RF_T_METER_8723B;
355
356 pConfig->ODM_TxPwrTrackSetPwr = ODM_TxPwrTrackSetPwr_8723B;
357 pConfig->DoIQK = DoIQK_8723B;
358 pConfig->PHY_LCCalibrate = PHY_LCCalibrate_8723B;
359 pConfig->GetDeltaSwingTable = GetDeltaSwingTable_8723B;
360}
361
362/* 1 7. IQK */
363#define MAX_TOLERANCE 5
364
365/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
366static u8 phy_PathA_IQK_8723B(
367 struct adapter *padapter, bool configPathB, u8 RF_Path
368)
369{
370 u32 regEAC, regE94, regE9C, tmp, Path_SEL_BB /*, regEA4*/;
371 u8 result = 0x00;
372
373 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
374 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
375
376 /* Save RF Path */
377 Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
378
379 /* leave IQK mode */
380 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
381
382 /* enable path A PA in TXIQK mode */
383 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
384 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
385 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0003f);
386 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xc7f87);
387 /* disable path B PA in TXIQK mode */
388/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xed, bRFRegOffsetMask, 0x00020); */
389/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x43, bRFRegOffsetMask, 0x40ec1); */
390
391 /* 1 Tx IQK */
392 /* IQK setting */
393 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
394 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
395 /* path-A IQK setting */
396 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
397 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
398 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
399 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
400/* PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x8214010a); */
401 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x821303ea);
402 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
403 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
404 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
405
406 /* LO calibration setting */
407 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
408
409 /* enter IQK mode */
410 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
411
412 /* Ant switch */
413 if (configPathB || (RF_Path == 0))
414 /* wifi switch to S1 */
415 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000000);
416 else
417 /* wifi switch to S0 */
418 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
419
420 /* GNT_BT = 0 */
421 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
422
423 /* One shot, path A LOK & IQK */
424 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
425 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
426
427 /* delay x ms */
428 /* PlatformStallExecution(IQK_DELAY_TIME_8723B*1000); */
429 mdelay(IQK_DELAY_TIME_8723B);
430
431 /* restore Ant Path */
432 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
433 /* GNT_BT = 1 */
434 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
435
436 /* leave IQK mode */
437 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
438
439
440 /* Check failed */
441 regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
442 regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
443 regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
444
445
446 /* Allen 20131125 */
447 tmp = (regE9C & 0x03FF0000)>>16;
448 if ((tmp & 0x200) > 0)
449 tmp = 0x400 - tmp;
450
451 if (
452 !(regEAC & BIT28) &&
453 (((regE94 & 0x03FF0000)>>16) != 0x142) &&
454 (((regE9C & 0x03FF0000)>>16) != 0x42) &&
455 (((regE94 & 0x03FF0000)>>16) < 0x110) &&
456 (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
457 (tmp < 0xf)
458 )
459 result |= 0x01;
460 else /* if Tx not OK, ignore Rx */
461 return result;
462
463 return result;
464}
465
466/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
467static u8 phy_PathA_RxIQK8723B(
468 struct adapter *padapter, bool configPathB, u8 RF_Path
469)
470{
471 u32 regEAC, regE94, regE9C, regEA4, u4tmp, tmp, Path_SEL_BB;
472 u8 result = 0x00;
473 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
474 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
475
476 /* Save RF Path */
477 Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
478
479 /* leave IQK mode */
480 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
481 /* 1 Get TXIMR setting */
482 /* modify RXIQK mode table */
483 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
484 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
485 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
486 /* LNA2 off, PA on for Dcut */
487 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7fb7);
488/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); */
489 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
490
491 /* IQK setting */
492 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
493 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
494
495 /* path-A IQK setting */
496 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
497 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
498 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
499 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
500
501/* PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); */
502 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82130ff0);
503 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
504 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
505 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
506
507 /* LO calibration setting */
508 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
509
510 /* enter IQK mode */
511 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
512
513 /* Ant switch */
514 if (configPathB || (RF_Path == 0))
515 /* wifi switch to S1 */
516 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000000);
517 else
518 /* wifi switch to S0 */
519 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
520
521 /* GNT_BT = 0 */
522 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
523
524 /* One shot, path A LOK & IQK */
525 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
526 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
527
528 /* delay x ms */
529 /* PlatformStallExecution(IQK_DELAY_TIME_8723B*1000); */
530 mdelay(IQK_DELAY_TIME_8723B);
531
532 /* restore Ant Path */
533 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
534 /* GNT_BT = 1 */
535 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
536
537 /* leave IQK mode */
538 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
539
540 /* Check failed */
541 regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
542 regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
543 regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
544
545 /* Allen 20131125 */
546 tmp = (regE9C & 0x03FF0000)>>16;
547 if ((tmp & 0x200) > 0)
548 tmp = 0x400 - tmp;
549
550 if (
551 !(regEAC & BIT28) &&
552 (((regE94 & 0x03FF0000)>>16) != 0x142) &&
553 (((regE9C & 0x03FF0000)>>16) != 0x42) &&
554 (((regE94 & 0x03FF0000)>>16) < 0x110) &&
555 (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
556 (tmp < 0xf)
557 )
558 result |= 0x01;
559 else /* if Tx not OK, ignore Rx */
560 return result;
561
562 u4tmp = 0x80007C00 | (regE94&0x3FF0000) | ((regE9C&0x3FF0000) >> 16);
563 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, u4tmp);
564
565 /* modify RXIQK mode table */
566 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
567 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
568 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
569 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
570 /* LAN2 on, PA off for Dcut */
571 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7d77);
572/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); */
573
574 /* PA, PAD setting */
575 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0xf80);
576 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x55, bRFRegOffsetMask, 0x4021f);
577
578
579 /* IQK setting */
580 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
581
582 /* path-A IQK setting */
583 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
584 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
585 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
586 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
587
588 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82110000);
589/* PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x281604c2); */
590 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x2813001f);
591 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
592 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
593
594 /* LO calibration setting */
595 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a8d1);
596
597 /* enter IQK mode */
598 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
599
600 /* Ant switch */
601 if (configPathB || (RF_Path == 0))
602 /* wifi switch to S1 */
603 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000000);
604 else
605 /* wifi switch to S0 */
606 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
607
608 /* GNT_BT = 0 */
609 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
610
611 /* One shot, path A LOK & IQK */
612 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
613 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
614
615 /* delay x ms */
616 /* PlatformStallExecution(IQK_DELAY_TIME_8723B*1000); */
617 mdelay(IQK_DELAY_TIME_8723B);
618
619 /* restore Ant Path */
620 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
621 /* GNT_BT = 1 */
622 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
623
624 /* leave IQK mode */
625 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
626
627 /* Check failed */
628 regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
629 regEA4 = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord);
630
631 /* PA/PAD controlled by 0x0 */
632 /* leave IQK mode */
633 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
634 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x780);
635
636 /* Allen 20131125 */
637 tmp = (regEAC & 0x03FF0000)>>16;
638 if ((tmp & 0x200) > 0)
639 tmp = 0x400 - tmp;
640
641 if (
642 !(regEAC & BIT27) && /* if Tx is OK, check whether Rx is OK */
643 (((regEA4 & 0x03FF0000)>>16) != 0x132) &&
644 (((regEAC & 0x03FF0000)>>16) != 0x36) &&
645 (((regEA4 & 0x03FF0000)>>16) < 0x110) &&
646 (((regEA4 & 0x03FF0000)>>16) > 0xf0) &&
647 (tmp < 0xf)
648 )
649 result |= 0x02;
650
651 return result;
652}
653
654/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
655static u8 phy_PathB_IQK_8723B(struct adapter *padapter)
656{
657 u32 regEAC, regE94, regE9C, tmp, Path_SEL_BB/*, regEC4, regECC, Path_SEL_BB*/;
658 u8 result = 0x00;
659 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
660 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
661
662 /* Save RF Path */
663 Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
664
665 /* leave IQK mode */
666 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
667
668 /* in TXIQK mode */
669/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1); */
670/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x20000); */
671/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0003f); */
672/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xc7f87); */
673 /* enable path B PA in TXIQK mode */
674 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xed, 0x20, 0x1);
675 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x43, bRFRegOffsetMask, 0x30fc1);
676
677
678
679 /* 1 Tx IQK */
680 /* IQK setting */
681 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
682 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
683 /* path-A IQK setting */
684 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
685 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
686 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
687 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
688
689/* PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82140114); */
690 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x821303ea);
691 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
692 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
693 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
694
695 /* LO calibration setting */
696 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
697
698 /* enter IQK mode */
699 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
700
701 /* switch to path B */
702 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
703/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xb0, bRFRegOffsetMask, 0xeffe0); */
704
705 /* GNT_BT = 0 */
706 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
707
708 /* One shot, path B LOK & IQK */
709 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
710 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
711
712 /* delay x ms */
713 /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
714 mdelay(IQK_DELAY_TIME_8723B);
715
716 /* restore Ant Path */
717 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
718 /* GNT_BT = 1 */
719 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
720
721 /* leave IQK mode */
722 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
723
724 /* Check failed */
725 regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
726 regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
727 regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
728
729 /* Allen 20131125 */
730 tmp = (regE9C & 0x03FF0000)>>16;
731 if ((tmp & 0x200) > 0)
732 tmp = 0x400 - tmp;
733
734 if (
735 !(regEAC & BIT28) &&
736 (((regE94 & 0x03FF0000)>>16) != 0x142) &&
737 (((regE9C & 0x03FF0000)>>16) != 0x42) &&
738 (((regE94 & 0x03FF0000)>>16) < 0x110) &&
739 (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
740 (tmp < 0xf)
741 )
742 result |= 0x01;
743
744 return result;
745}
746
747/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
748static u8 phy_PathB_RxIQK8723B(struct adapter *padapter, bool configPathB)
749{
750 u32 regE94, regE9C, regEA4, regEAC, u4tmp, tmp, Path_SEL_BB;
751 u8 result = 0x00;
752 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
753 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
754
755 /* Save RF Path */
756 Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord);
757 /* leave IQK mode */
758 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
759
760 /* switch to path B */
761 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
762 /* modify RXIQK mode table */
763 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
764 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
765 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
766 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7fb7);
767 /* open PA S1 & SMIXER */
768 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xed, 0x20, 0x1);
769 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x43, bRFRegOffsetMask, 0x30fcd);
770
771
772 /* IQK setting */
773 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, 0x01007c00);
774 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
775
776
777 /* path-B IQK setting */
778 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
779 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
780 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
781 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
782
783/* PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); */
784 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82130ff0);
785 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x28110000);
786 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
787 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
788
789 /* LO calibration setting */
790 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
791
792 /* enter IQK mode */
793 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
794
795 /* switch to path B */
796 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
797/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xb0, bRFRegOffsetMask, 0xeffe0); */
798
799 /* GNT_BT = 0 */
800 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
801
802 /* One shot, path B TXIQK @ RXIQK */
803 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
804 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
805
806
807 /* delay x ms */
808 /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
809 mdelay(IQK_DELAY_TIME_8723B);
810
811 /* restore Ant Path */
812 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
813 /* GNT_BT = 1 */
814 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
815
816 /* leave IQK mode */
817 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
818
819 /* Check failed */
820 regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
821 regE94 = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord);
822 regE9C = PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord);
823
824 /* Allen 20131125 */
825 tmp = (regE9C & 0x03FF0000)>>16;
826 if ((tmp & 0x200) > 0)
827 tmp = 0x400 - tmp;
828
829 if (
830 !(regEAC & BIT28) &&
831 (((regE94 & 0x03FF0000)>>16) != 0x142) &&
832 (((regE9C & 0x03FF0000)>>16) != 0x42) &&
833 (((regE94 & 0x03FF0000)>>16) < 0x110) &&
834 (((regE94 & 0x03FF0000)>>16) > 0xf0) &&
835 (tmp < 0xf)
836 )
837 result |= 0x01;
838 else /* if Tx not OK, ignore Rx */
839 return result;
840
841 u4tmp = 0x80007C00 | (regE94&0x3FF0000) | ((regE9C&0x3FF0000) >> 16);
842 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK, bMaskDWord, u4tmp);
843
844 /* modify RXIQK mode table */
845 /* 20121009, Kordan> RF Mode = 3 */
846 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
847 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
848 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
849 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
850 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7d77);
851/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); */
852
853 /* open PA S1 & close SMIXER */
854 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xed, 0x20, 0x1);
855 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x43, bRFRegOffsetMask, 0x30ebd);
856
857 /* PA, PAD setting */
858/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0xf80); */
859/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000); */
860
861 /* IQK setting */
862 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK, bMaskDWord, 0x01004800);
863
864 /* path-B IQK setting */
865 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
866 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
867 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
868 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_B, bMaskDWord, 0x38008c1c);
869
870 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_A, bMaskDWord, 0x82110000);
871/* PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x281604c2); */
872 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_A, bMaskDWord, 0x2813001f);
873 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_PI_B, bMaskDWord, 0x82110000);
874 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_PI_B, bMaskDWord, 0x28110000);
875
876 /* LO calibration setting */
877 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Rsp, bMaskDWord, 0x0046a8d1);
878
879 /* enter IQK mode */
880 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x808000);
881
882 /* switch to path B */
883 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, 0x00000280);
884/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xb0, bRFRegOffsetMask, 0xeffe0); */
885
886 /* GNT_BT = 0 */
887 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00000800);
888
889 /* One shot, path B LOK & IQK */
890 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
891 PHY_SetBBReg(pDM_Odm->Adapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
892
893 /* delay x ms */
894 /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */
895 mdelay(IQK_DELAY_TIME_8723B);
896
897 /* restore Ant Path */
898 PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB);
899 /* GNT_BT = 1 */
900 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, 0x00001800);
901
902 /* leave IQK mode */
903 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
904
905 /* Check failed */
906 regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord);
907 regEA4 = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord);
908
909 /* PA/PAD controlled by 0x0 */
910 /* leave IQK mode */
911/* PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, 0xffffff00, 0x00000000); */
912/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_B, 0xdf, bRFRegOffsetMask, 0x180); */
913
914
915
916 /* Allen 20131125 */
917 tmp = (regEAC & 0x03FF0000)>>16;
918 if ((tmp & 0x200) > 0)
919 tmp = 0x400 - tmp;
920
921 if (
922 !(regEAC & BIT27) && /* if Tx is OK, check whether Rx is OK */
923 (((regEA4 & 0x03FF0000)>>16) != 0x132) &&
924 (((regEAC & 0x03FF0000)>>16) != 0x36) &&
925 (((regEA4 & 0x03FF0000)>>16) < 0x110) &&
926 (((regEA4 & 0x03FF0000)>>16) > 0xf0) &&
927 (tmp < 0xf)
928 )
929 result |= 0x02;
930
931 return result;
932}
933
934static void _PHY_PathAFillIQKMatrix8723B(
935 struct adapter *padapter,
936 bool bIQKOK,
937 s32 result[][8],
938 u8 final_candidate,
939 bool bTxOnly
940)
941{
942 u32 Oldval_0, X, TX0_A, reg;
943 s32 Y, TX0_C;
944 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
945 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
946
947 struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
948
949 if (final_candidate == 0xFF)
950 return;
951
952 else if (bIQKOK) {
953 Oldval_0 = (PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
954
955 X = result[final_candidate][0];
956 if ((X & 0x00000200) != 0)
957 X = X | 0xFFFFFC00;
958 TX0_A = (X * Oldval_0) >> 8;
959 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
960
961 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(31), ((X*Oldval_0>>7) & 0x1));
962
963 Y = result[final_candidate][1];
964 if ((Y & 0x00000200) != 0)
965 Y = Y | 0xFFFFFC00;
966
967 /* 2 Tx IQC */
968 TX0_C = (Y * Oldval_0) >> 8;
969 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6));
970 pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][KEY] = rOFDM0_XCTxAFE;
971 pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XCTxAFE, bMaskDWord);
972
973 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F));
974 pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][KEY] = rOFDM0_XATxIQImbalance;
975 pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XATxIQImbalance, bMaskDWord);
976
977 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(29), ((Y*Oldval_0>>7) & 0x1));
978 pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold;
979 pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskDWord);
980
981 if (bTxOnly) {
982 /* <20130226, Kordan> Saving RxIQC, otherwise not initialized. */
983 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
984 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL] = 0xfffffff & PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord);
985 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
986/* pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, bMaskDWord); */
987 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = 0x40000100;
988 return;
989 }
990
991 reg = result[final_candidate][2];
992
993 /* 2 Rx IQC */
994 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, 0x3FF, reg);
995 reg = result[final_candidate][3] & 0x3F;
996 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, 0xFC00, reg);
997 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
998 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, bMaskDWord);
999
1000 reg = (result[final_candidate][3] >> 6) & 0xF;
1001 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
1002 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
1003 pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord);
1004
1005 }
1006}
1007
1008static void _PHY_PathBFillIQKMatrix8723B(
1009 struct adapter *padapter,
1010 bool bIQKOK,
1011 s32 result[][8],
1012 u8 final_candidate,
1013 bool bTxOnly /* do Tx only */
1014)
1015{
1016 u32 Oldval_1, X, TX1_A, reg;
1017 s32 Y, TX1_C;
1018 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1019 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1020
1021 struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
1022
1023 if (final_candidate == 0xFF)
1024 return;
1025
1026 else if (bIQKOK) {
1027 Oldval_1 = (PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
1028
1029 X = result[final_candidate][4];
1030 if ((X & 0x00000200) != 0)
1031 X = X | 0xFFFFFC00;
1032 TX1_A = (X * Oldval_1) >> 8;
1033
1034 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A);
1035
1036 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(27), ((X*Oldval_1>>7) & 0x1));
1037
1038 Y = result[final_candidate][5];
1039 if ((Y & 0x00000200) != 0)
1040 Y = Y | 0xFFFFFC00;
1041
1042 TX1_C = (Y * Oldval_1) >> 8;
1043
1044 /* 2 Tx IQC */
1045 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6));
1046/* pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC9C][KEY] = rOFDM0_XDTxAFE; */
1047/* pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC9C][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskDWord); */
1048 pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][KEY] = rOFDM0_XCTxAFE;
1049 pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XDTxAFE, bMaskDWord);
1050
1051 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F));
1052 pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][KEY] = rOFDM0_XATxIQImbalance;
1053 pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord);
1054
1055 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, BIT(25), ((Y*Oldval_1>>7) & 0x1));
1056 pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold;
1057 pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskDWord);
1058
1059 if (bTxOnly) {
1060 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
1061/* pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XARxIQImbalance, bMaskDWord); */
1062 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] = 0x40000100;
1063 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
1064 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][VAL] = 0x0fffffff & PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord);
1065 return;
1066 }
1067
1068 /* 2 Rx IQC */
1069 reg = result[final_candidate][6];
1070 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
1071 reg = result[final_candidate][7] & 0x3F;
1072 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
1073 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance;
1074 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] = PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_XBRxIQImbalance, bMaskDWord);
1075
1076 reg = (result[final_candidate][7] >> 6) & 0xF;
1077/* PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_AGCRSSITable, 0x0000F000, reg); */
1078 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta;
1079 pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][VAL] = (reg << 28)|(PHY_QueryBBReg(pDM_Odm->Adapter, rOFDM0_RxIQExtAnta, bMaskDWord)&0x0fffffff);
1080 }
1081}
1082
1083/* */
1084/* 2011/07/26 MH Add an API for testing IQK fail case. */
1085/* */
1086/* MP Already declare in odm.c */
1087
1088void ODM_SetIQCbyRFpath(struct dm_odm_t *pDM_Odm, u32 RFpath)
1089{
1090
1091 struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
1092
1093 if (
1094 (pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL] != 0x0) &&
1095 (pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL] != 0x0) &&
1096 (pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL] != 0x0) &&
1097 (pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] != 0x0)
1098 ) {
1099 if (RFpath) { /* S1: RFpath = 0, S0:RFpath = 1 */
1100 /* S0 TX IQC */
1101 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][VAL]);
1102 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL]);
1103 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][VAL]);
1104 /* S0 RX IQC */
1105 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL]);
1106 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][VAL]);
1107 } else {
1108 /* S1 TX IQC */
1109 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][VAL]);
1110 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL]);
1111 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][VAL]);
1112 /* S1 RX IQC */
1113 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL]);
1114 PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL]);
1115 }
1116 }
1117}
1118
1119static bool ODM_CheckPowerStatus(struct adapter *Adapter)
1120{
1121 return true;
1122}
1123
1124static void _PHY_SaveADDARegisters8723B(
1125 struct adapter *padapter,
1126 u32 *ADDAReg,
1127 u32 *ADDABackup,
1128 u32 RegisterNum
1129)
1130{
1131 u32 i;
1132 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1133 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1134
1135 if (!ODM_CheckPowerStatus(Adapter: padapter))
1136 return;
1137
1138 for (i = 0 ; i < RegisterNum ; i++) {
1139 ADDABackup[i] = PHY_QueryBBReg(pDM_Odm->Adapter, ADDAReg[i], bMaskDWord);
1140 }
1141}
1142
1143
1144static void _PHY_SaveMACRegisters8723B(
1145 struct adapter *padapter, u32 *MACReg, u32 *MACBackup
1146)
1147{
1148 u32 i;
1149 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1150 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1151
1152 for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++) {
1153 MACBackup[i] = rtw_read8(adapter: pDM_Odm->Adapter, addr: MACReg[i]);
1154 }
1155 MACBackup[i] = rtw_read32(adapter: pDM_Odm->Adapter, addr: MACReg[i]);
1156
1157}
1158
1159
1160static void _PHY_ReloadADDARegisters8723B(
1161 struct adapter *padapter,
1162 u32 *ADDAReg,
1163 u32 *ADDABackup,
1164 u32 RegiesterNum
1165)
1166{
1167 u32 i;
1168 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1169 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1170
1171 for (i = 0 ; i < RegiesterNum; i++) {
1172 PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[i], bMaskDWord, ADDABackup[i]);
1173 }
1174}
1175
1176static void _PHY_ReloadMACRegisters8723B(
1177 struct adapter *padapter, u32 *MACReg, u32 *MACBackup
1178)
1179{
1180 u32 i;
1181
1182 for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++) {
1183 rtw_write8(adapter: padapter, addr: MACReg[i], val: (u8)MACBackup[i]);
1184 }
1185 rtw_write32(adapter: padapter, addr: MACReg[i], val: MACBackup[i]);
1186}
1187
1188
1189static void _PHY_PathADDAOn8723B(
1190 struct adapter *padapter,
1191 u32 *ADDAReg,
1192 bool is2T
1193)
1194{
1195 u32 pathOn;
1196 u32 i;
1197 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1198 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1199
1200 pathOn = 0x01c00014;
1201 if (!is2T) {
1202 pathOn = 0x01c00014;
1203 PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[0], bMaskDWord, 0x01c00014);
1204 } else {
1205 PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[0], bMaskDWord, pathOn);
1206 }
1207
1208 for (i = 1 ; i < IQK_ADDA_REG_NUM ; i++) {
1209 PHY_SetBBReg(pDM_Odm->Adapter, ADDAReg[i], bMaskDWord, pathOn);
1210 }
1211
1212}
1213
1214static void _PHY_MACSettingCalibration8723B(
1215 struct adapter *padapter, u32 *MACReg, u32 *MACBackup
1216)
1217{
1218 u32 i = 0;
1219 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1220 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1221
1222 rtw_write8(adapter: pDM_Odm->Adapter, addr: MACReg[i], val: 0x3F);
1223
1224 for (i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++) {
1225 rtw_write8(adapter: pDM_Odm->Adapter, addr: MACReg[i], val: (u8)(MACBackup[i]&(~BIT3)));
1226 }
1227 rtw_write8(adapter: pDM_Odm->Adapter, addr: MACReg[i], val: (u8)(MACBackup[i]&(~BIT5)));
1228
1229}
1230
1231static bool phy_SimularityCompare_8723B(
1232 struct adapter *padapter,
1233 s32 result[][8],
1234 u8 c1,
1235 u8 c2
1236)
1237{
1238 u32 i, j, diff, SimularityBitMap, bound = 0;
1239 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
1240 bool bResult = true;
1241 s32 tmp1 = 0, tmp2 = 0;
1242
1243 bound = 8;
1244 SimularityBitMap = 0;
1245
1246 for (i = 0; i < bound; i++) {
1247
1248 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1249 if ((result[c1][i] & 0x00000200) != 0)
1250 tmp1 = result[c1][i] | 0xFFFFFC00;
1251 else
1252 tmp1 = result[c1][i];
1253
1254 if ((result[c2][i] & 0x00000200) != 0)
1255 tmp2 = result[c2][i] | 0xFFFFFC00;
1256 else
1257 tmp2 = result[c2][i];
1258 } else {
1259 tmp1 = result[c1][i];
1260 tmp2 = result[c2][i];
1261 }
1262
1263 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1264
1265 if (diff > MAX_TOLERANCE) {
1266 if ((i == 2 || i == 6) && !SimularityBitMap) {
1267 if (result[c1][i]+result[c1][i+1] == 0)
1268 final_candidate[(i/4)] = c2;
1269 else if (result[c2][i]+result[c2][i+1] == 0)
1270 final_candidate[(i/4)] = c1;
1271 else
1272 SimularityBitMap = SimularityBitMap|(1<<i);
1273 } else
1274 SimularityBitMap = SimularityBitMap|(1<<i);
1275 }
1276 }
1277
1278 if (SimularityBitMap == 0) {
1279 for (i = 0; i < (bound/4); i++) {
1280 if (final_candidate[i] != 0xFF) {
1281 for (j = i*4; j < (i+1)*4-2; j++)
1282 result[3][j] = result[final_candidate[i]][j];
1283 bResult = false;
1284 }
1285 }
1286 return bResult;
1287 } else {
1288
1289 if (!(SimularityBitMap & 0x03)) { /* path A TX OK */
1290 for (i = 0; i < 2; i++)
1291 result[3][i] = result[c1][i];
1292 }
1293
1294 if (!(SimularityBitMap & 0x0c)) { /* path A RX OK */
1295 for (i = 2; i < 4; i++)
1296 result[3][i] = result[c1][i];
1297 }
1298
1299 if (!(SimularityBitMap & 0x30)) { /* path B TX OK */
1300 for (i = 4; i < 6; i++)
1301 result[3][i] = result[c1][i];
1302 }
1303
1304 if (!(SimularityBitMap & 0xc0)) { /* path B RX OK */
1305 for (i = 6; i < 8; i++)
1306 result[3][i] = result[c1][i];
1307 }
1308 return false;
1309 }
1310}
1311
1312
1313
1314static void phy_IQCalibrate_8723B(
1315 struct adapter *padapter,
1316 s32 result[][8],
1317 u8 t,
1318 bool is2T,
1319 u8 RF_Path
1320)
1321{
1322 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1323 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1324
1325 u32 i;
1326 u8 PathAOK, PathBOK;
1327 u8 tmp0xc50 = (u8)PHY_QueryBBReg(pDM_Odm->Adapter, 0xC50, bMaskByte0);
1328 u8 tmp0xc58 = (u8)PHY_QueryBBReg(pDM_Odm->Adapter, 0xC58, bMaskByte0);
1329 u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
1330 rFPGA0_XCD_SwitchControl,
1331 rBlue_Tooth,
1332 rRx_Wait_CCA,
1333 rTx_CCK_RFON,
1334 rTx_CCK_BBON,
1335 rTx_OFDM_RFON,
1336 rTx_OFDM_BBON,
1337 rTx_To_Rx,
1338 rTx_To_Tx,
1339 rRx_CCK,
1340 rRx_OFDM,
1341 rRx_Wait_RIFS,
1342 rRx_TO_Rx,
1343 rStandby,
1344 rSleep,
1345 rPMPD_ANAEN
1346 };
1347 u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
1348 REG_TXPAUSE,
1349 REG_BCN_CTRL,
1350 REG_BCN_CTRL_1,
1351 REG_GPIO_MUXCFG
1352 };
1353
1354 /* since 92C & 92D have the different define in IQK_BB_REG */
1355 u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1356 rOFDM0_TRxPathEnable,
1357 rOFDM0_TRMuxPar,
1358 rFPGA0_XCD_RFInterfaceSW,
1359 rConfig_AntA,
1360 rConfig_AntB,
1361 rFPGA0_XAB_RFInterfaceSW,
1362 rFPGA0_XA_RFInterfaceOE,
1363 rFPGA0_XB_RFInterfaceOE,
1364 rCCK0_AFESetting
1365 };
1366 const u32 retryCount = 2;
1367
1368 /* Note: IQ calibration must be performed after loading */
1369 /* PHY_REG.txt , and radio_a, radio_b.txt */
1370
1371 /* u32 bbvalue; */
1372
1373 if (t == 0) {
1374
1375 /* Save ADDA parameters, turn Path A ADDA on */
1376 _PHY_SaveADDARegisters8723B(padapter, ADDAReg: ADDA_REG, ADDABackup: pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
1377 _PHY_SaveMACRegisters8723B(padapter, MACReg: IQK_MAC_REG, MACBackup: pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
1378 _PHY_SaveADDARegisters8723B(padapter, ADDAReg: IQK_BB_REG_92C, ADDABackup: pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1379 }
1380
1381 _PHY_PathADDAOn8723B(padapter, ADDAReg: ADDA_REG, is2T);
1382
1383/* no serial mode */
1384
1385 /* save RF path for 8723B */
1386/* Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord); */
1387/* Path_SEL_RF = PHY_QueryRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xb0, 0xfffff); */
1388
1389 /* MAC settings */
1390 _PHY_MACSettingCalibration8723B(padapter, MACReg: IQK_MAC_REG, MACBackup: pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
1391
1392 /* BB setting */
1393 /* PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_RFMOD, BIT24, 0x00); */
1394 PHY_SetBBReg(pDM_Odm->Adapter, rCCK0_AFESetting, 0x0f000000, 0xf);
1395 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1396 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1397 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1398
1399
1400/* PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01); */
1401/* PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01); */
1402/* PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00); */
1403/* PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00); */
1404
1405
1406/* RX IQ calibration setting for 8723B D cut large current issue when leaving IPS */
1407
1408 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
1409 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1410 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
1411 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
1412 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7fb7);
1413 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xed, 0x20, 0x1);
1414 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x43, bRFRegOffsetMask, 0x60fbd);
1415
1416/* path A TX IQK */
1417 for (i = 0 ; i < retryCount ; i++) {
1418 PathAOK = phy_PathA_IQK_8723B(padapter, configPathB: is2T, RF_Path);
1419/* if (PathAOK == 0x03) { */
1420 if (PathAOK == 0x01) {
1421 /* Path A Tx IQK Success */
1422 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
1423 pDM_Odm->RFCalibrateInfo.TxLOK[RF_PATH_A] = PHY_QueryRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x8, bRFRegOffsetMask);
1424
1425 result[t][0] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1426 result[t][1] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1427 break;
1428 }
1429 }
1430
1431/* path A RXIQK */
1432 for (i = 0 ; i < retryCount ; i++) {
1433 PathAOK = phy_PathA_RxIQK8723B(padapter, configPathB: is2T, RF_Path);
1434 if (PathAOK == 0x03) {
1435/* result[t][0] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1436/* result[t][1] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1437 result[t][2] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1438 result[t][3] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1439 break;
1440 }
1441 }
1442
1443 if (0x00 == PathAOK) {
1444 }
1445
1446/* path B IQK */
1447 if (is2T) {
1448
1449 /* path B TX IQK */
1450 for (i = 0 ; i < retryCount ; i++) {
1451 PathBOK = phy_PathB_IQK_8723B(padapter);
1452 if (PathBOK == 0x01) {
1453 /* Path B Tx IQK Success */
1454 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0x000000);
1455 pDM_Odm->RFCalibrateInfo.TxLOK[RF_PATH_B] = PHY_QueryRFReg(pDM_Odm->Adapter, RF_PATH_B, 0x8, bRFRegOffsetMask);
1456
1457 result[t][4] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1458 result[t][5] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16;
1459 break;
1460 }
1461 }
1462
1463/* path B RX IQK */
1464 for (i = 0 ; i < retryCount ; i++) {
1465 PathBOK = phy_PathB_RxIQK8723B(padapter, configPathB: is2T);
1466 if (PathBOK == 0x03) {
1467/* result[t][0] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1468/* result[t][1] = (PHY_QueryBBReg(pDM_Odm->Adapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; */
1469 result[t][6] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1470 result[t][7] = (PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16;
1471 break;
1472 }
1473 }
1474
1475/* Allen end */
1476 }
1477
1478 /* Back to BB mode, load original value */
1479 PHY_SetBBReg(pDM_Odm->Adapter, rFPGA0_IQK, bMaskH3Bytes, 0);
1480
1481 if (t != 0) {
1482 /* Reload ADDA power saving parameters */
1483 _PHY_ReloadADDARegisters8723B(padapter, ADDAReg: ADDA_REG, ADDABackup: pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM);
1484
1485 /* Reload MAC parameters */
1486 _PHY_ReloadMACRegisters8723B(padapter, MACReg: IQK_MAC_REG, MACBackup: pDM_Odm->RFCalibrateInfo.IQK_MAC_backup);
1487
1488 _PHY_ReloadADDARegisters8723B(padapter, ADDAReg: IQK_BB_REG_92C, ADDABackup: pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1489
1490 /* Reload RF path */
1491/* PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB); */
1492/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xb0, 0xfffff, Path_SEL_RF); */
1493
1494 /* Allen initial gain 0xc50 */
1495 /* Restore RX initial gain */
1496 PHY_SetBBReg(pDM_Odm->Adapter, 0xc50, bMaskByte0, 0x50);
1497 PHY_SetBBReg(pDM_Odm->Adapter, 0xc50, bMaskByte0, tmp0xc50);
1498 if (is2T) {
1499 PHY_SetBBReg(pDM_Odm->Adapter, 0xc58, bMaskByte0, 0x50);
1500 PHY_SetBBReg(pDM_Odm->Adapter, 0xc58, bMaskByte0, tmp0xc58);
1501 }
1502
1503 /* load 0xe30 IQC default value */
1504 PHY_SetBBReg(pDM_Odm->Adapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1505 PHY_SetBBReg(pDM_Odm->Adapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1506
1507 }
1508
1509}
1510
1511
1512static void phy_LCCalibrate_8723B(struct dm_odm_t *pDM_Odm, bool is2T)
1513{
1514 u8 tmpReg;
1515 u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
1516 struct adapter *padapter = pDM_Odm->Adapter;
1517
1518 /* Check continuous TX and Packet TX */
1519 tmpReg = rtw_read8(adapter: pDM_Odm->Adapter, addr: 0xd03);
1520
1521 if ((tmpReg&0x70) != 0) /* Deal with contisuous TX case */
1522 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xd03, val: tmpReg&0x8F); /* disable all continuous TX */
1523 else /* Deal with Packet TX case */
1524 rtw_write8(adapter: pDM_Odm->Adapter, REG_TXPAUSE, val: 0xFF); /* block all queues */
1525
1526 if ((tmpReg&0x70) != 0) {
1527 /* 1. Read original RF mode */
1528 /* Path-A */
1529 RF_Amode = PHY_QueryRFReg(padapter, RF_PATH_A, RF_AC, bMask12Bits);
1530
1531 /* Path-B */
1532 if (is2T)
1533 RF_Bmode = PHY_QueryRFReg(padapter, RF_PATH_B, RF_AC, bMask12Bits);
1534
1535 /* 2. Set RF mode = standby mode */
1536 /* Path-A */
1537 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000);
1538
1539 /* Path-B */
1540 if (is2T)
1541 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000);
1542 }
1543
1544 /* 3. Read RF reg18 */
1545 LC_Cal = PHY_QueryRFReg(padapter, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1546
1547 /* 4. Set LC calibration begin bit15 */
1548 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0); /* LDO ON */
1549 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000);
1550
1551 mdelay(100);
1552
1553 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0); /* LDO OFF */
1554
1555 /* Channel 10 LC calibration issue for 8723bs with 26M xtal */
1556 if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO && pDM_Odm->PackageType >= 0x2) {
1557 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal);
1558 }
1559
1560 /* Restore original situation */
1561 if ((tmpReg&0x70) != 0) { /* Deal with contisuous TX case */
1562 /* Path-A */
1563 rtw_write8(adapter: pDM_Odm->Adapter, addr: 0xd03, val: tmpReg);
1564 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
1565
1566 /* Path-B */
1567 if (is2T)
1568 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
1569 } else /* Deal with Packet TX case */
1570 rtw_write8(adapter: pDM_Odm->Adapter, REG_TXPAUSE, val: 0x00);
1571}
1572
1573/* IQK version:V2.5 20140123 */
1574/* IQK is controlled by Is2ant, RF path */
1575void PHY_IQCalibrate_8723B(
1576 struct adapter *padapter,
1577 bool bReCovery,
1578 bool bRestore,
1579 bool Is2ant, /* false:1ant, true:2-ant */
1580 u8 RF_Path /* 0:S1, 1:S0 */
1581)
1582{
1583 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1584
1585 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1586
1587 s32 result[4][8]; /* last is final result */
1588 u8 i, final_candidate;
1589 bool bPathAOK, bPathBOK;
1590 s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC, RegEC4, RegTmp = 0;
1591 bool is12simular, is13simular, is23simular;
1592 bool bSingleTone = false, bCarrierSuppression = false;
1593 u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
1594 rOFDM0_XARxIQImbalance,
1595 rOFDM0_XBRxIQImbalance,
1596 rOFDM0_ECCAThreshold,
1597 rOFDM0_AGCRSSITable,
1598 rOFDM0_XATxIQImbalance,
1599 rOFDM0_XBTxIQImbalance,
1600 rOFDM0_XCTxAFE,
1601 rOFDM0_XDTxAFE,
1602 rOFDM0_RxIQExtAnta
1603 };
1604/* u32 Path_SEL_BB = 0; */
1605 u32 GNT_BT_default;
1606
1607 if (!ODM_CheckPowerStatus(Adapter: padapter))
1608 return;
1609
1610 if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION))
1611 return;
1612
1613 /* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1614 if (bSingleTone || bCarrierSuppression)
1615 return;
1616
1617 if (pDM_Odm->RFCalibrateInfo.bIQKInProgress)
1618 return;
1619
1620
1621 pDM_Odm->RFCalibrateInfo.bIQKInProgress = true;
1622
1623 if (bRestore) {
1624 u32 offset, data;
1625 u8 path, bResult = SUCCESS;
1626 struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo;
1627
1628 path = (PHY_QueryBBReg(pDM_Odm->Adapter, rS0S1_PathSwitch, bMaskByte0) == 0x00) ? RF_PATH_A : RF_PATH_B;
1629
1630 /* Restore TX IQK */
1631 for (i = 0; i < 3; ++i) {
1632 offset = pRFCalibrateInfo->TxIQC_8723B[path][i][0];
1633 data = pRFCalibrateInfo->TxIQC_8723B[path][i][1];
1634 if ((offset == 0) || (data == 0)) {
1635 bResult = FAIL;
1636 break;
1637 }
1638 PHY_SetBBReg(pDM_Odm->Adapter, offset, bMaskDWord, data);
1639 }
1640
1641 /* Restore RX IQK */
1642 for (i = 0; i < 2; ++i) {
1643 offset = pRFCalibrateInfo->RxIQC_8723B[path][i][0];
1644 data = pRFCalibrateInfo->RxIQC_8723B[path][i][1];
1645 if ((offset == 0) || (data == 0)) {
1646 bResult = FAIL;
1647 break;
1648 }
1649 PHY_SetBBReg(pDM_Odm->Adapter, offset, bMaskDWord, data);
1650 }
1651
1652 if (pDM_Odm->RFCalibrateInfo.TxLOK[RF_PATH_A] == 0) {
1653 bResult = FAIL;
1654 } else {
1655 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXM_IDAC, bRFRegOffsetMask, pDM_Odm->RFCalibrateInfo.TxLOK[RF_PATH_A]);
1656 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_B, RF_TXM_IDAC, bRFRegOffsetMask, pDM_Odm->RFCalibrateInfo.TxLOK[RF_PATH_B]);
1657 }
1658
1659 if (bResult == SUCCESS)
1660 return;
1661 }
1662
1663 if (bReCovery) {
1664 _PHY_ReloadADDARegisters8723B(padapter, ADDAReg: IQK_BB_REG_92C, ADDABackup: pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, RegiesterNum: 9);
1665 return;
1666 }
1667
1668 /* save default GNT_BT */
1669 GNT_BT_default = PHY_QueryBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord);
1670 /* Save RF Path */
1671/* Path_SEL_BB = PHY_QueryBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord); */
1672/* Path_SEL_RF = PHY_QueryRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xb0, 0xfffff); */
1673
1674 /* set GNT_BT = 0, pause BT traffic */
1675/* PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT12, 0x0); */
1676/* PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT11, 0x1); */
1677
1678
1679 for (i = 0; i < 8; i++) {
1680 result[0][i] = 0;
1681 result[1][i] = 0;
1682 result[2][i] = 0;
1683 result[3][i] = 0;
1684 }
1685
1686 final_candidate = 0xff;
1687 bPathAOK = false;
1688 bPathBOK = false;
1689 is12simular = false;
1690 is23simular = false;
1691 is13simular = false;
1692
1693
1694 for (i = 0; i < 3; i++) {
1695 phy_IQCalibrate_8723B(padapter, result, t: i, is2T: Is2ant, RF_Path);
1696
1697 if (i == 1) {
1698 is12simular = phy_SimularityCompare_8723B(padapter, result, c1: 0, c2: 1);
1699 if (is12simular) {
1700 final_candidate = 0;
1701 break;
1702 }
1703 }
1704
1705 if (i == 2) {
1706 is13simular = phy_SimularityCompare_8723B(padapter, result, c1: 0, c2: 2);
1707 if (is13simular) {
1708 final_candidate = 0;
1709
1710 break;
1711 }
1712
1713 is23simular = phy_SimularityCompare_8723B(padapter, result, c1: 1, c2: 2);
1714 if (is23simular) {
1715 final_candidate = 1;
1716 } else {
1717 for (i = 0; i < 8; i++)
1718 RegTmp += result[3][i];
1719
1720 if (RegTmp != 0)
1721 final_candidate = 3;
1722 else
1723 final_candidate = 0xFF;
1724 }
1725 }
1726 }
1727
1728 for (i = 0; i < 4; i++) {
1729 RegE94 = result[i][0];
1730 RegE9C = result[i][1];
1731 RegEA4 = result[i][2];
1732 RegEB4 = result[i][4];
1733 RegEBC = result[i][5];
1734 RegEC4 = result[i][6];
1735 }
1736
1737 if (final_candidate != 0xff) {
1738 pDM_Odm->RFCalibrateInfo.RegE94 = RegE94 = result[final_candidate][0];
1739 pDM_Odm->RFCalibrateInfo.RegE9C = RegE9C = result[final_candidate][1];
1740 RegEA4 = result[final_candidate][2];
1741 pDM_Odm->RFCalibrateInfo.RegEB4 = RegEB4 = result[final_candidate][4];
1742 pDM_Odm->RFCalibrateInfo.RegEBC = RegEBC = result[final_candidate][5];
1743 RegEC4 = result[final_candidate][6];
1744 bPathAOK = bPathBOK = true;
1745 } else {
1746 pDM_Odm->RFCalibrateInfo.RegE94 = pDM_Odm->RFCalibrateInfo.RegEB4 = 0x100; /* X default value */
1747 pDM_Odm->RFCalibrateInfo.RegE9C = pDM_Odm->RFCalibrateInfo.RegEBC = 0x0; /* Y default value */
1748 }
1749
1750 {
1751 if (RegE94 != 0)
1752 _PHY_PathAFillIQKMatrix8723B(padapter, bIQKOK: bPathAOK, result, final_candidate, bTxOnly: (RegEA4 == 0));
1753 }
1754 {
1755 if (RegEB4 != 0)
1756 _PHY_PathBFillIQKMatrix8723B(padapter, bIQKOK: bPathBOK, result, final_candidate, bTxOnly: (RegEC4 == 0));
1757 }
1758
1759/* To Fix BSOD when final_candidate is 0xff */
1760/* by sherry 20120321 */
1761 if (final_candidate < 4) {
1762 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1763 pDM_Odm->RFCalibrateInfo.iqk_matrix_regs_setting_value[0][i] = result[final_candidate][i];
1764 }
1765
1766 _PHY_SaveADDARegisters8723B(padapter, ADDAReg: IQK_BB_REG_92C, ADDABackup: pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, RegisterNum: 9);
1767
1768 /* restore GNT_BT */
1769 PHY_SetBBReg(pDM_Odm->Adapter, 0x764, bMaskDWord, GNT_BT_default);
1770 /* Restore RF Path */
1771/* PHY_SetBBReg(pDM_Odm->Adapter, 0x948, bMaskDWord, Path_SEL_BB); */
1772/* PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xb0, 0xfffff, Path_SEL_RF); */
1773
1774 /* Resotr RX mode table parameter */
1775 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1776 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000);
1777 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0001f);
1778 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xe6177);
1779 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0xed, 0x20, 0x1);
1780 PHY_SetRFReg(pDM_Odm->Adapter, RF_PATH_A, 0x43, bRFRegOffsetMask, 0x300bd);
1781
1782 /* set GNT_BT = HW control */
1783/* PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT12, 0x0); */
1784/* PHY_SetBBReg(pDM_Odm->Adapter, 0x764, BIT11, 0x0); */
1785
1786 if (Is2ant) {
1787 if (RF_Path == 0x0) /* S1 */
1788 ODM_SetIQCbyRFpath(pDM_Odm, RFpath: 0);
1789 else /* S0 */
1790 ODM_SetIQCbyRFpath(pDM_Odm, RFpath: 1);
1791 }
1792
1793 pDM_Odm->RFCalibrateInfo.bIQKInProgress = false;
1794}
1795
1796
1797void PHY_LCCalibrate_8723B(struct dm_odm_t *pDM_Odm)
1798{
1799 bool bSingleTone = false, bCarrierSuppression = false;
1800 u32 timeout = 2000, timecount = 0;
1801
1802 if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION))
1803 return;
1804
1805 /* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
1806 if (bSingleTone || bCarrierSuppression)
1807 return;
1808
1809 while (*(pDM_Odm->pbScanInProcess) && timecount < timeout) {
1810 mdelay(50);
1811 timecount += 50;
1812 }
1813
1814 pDM_Odm->RFCalibrateInfo.bLCKInProgress = true;
1815
1816
1817 phy_LCCalibrate_8723B(pDM_Odm, is2T: false);
1818
1819
1820 pDM_Odm->RFCalibrateInfo.bLCKInProgress = false;
1821}
1822

source code of linux/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c