1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
21 #include "mp_precomp.h"
22 #include "phydm_precomp.h"
24 //#if(DM_ODM_SUPPORT_TYPE & ODM_WIN)
26 #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \
28 for(_offset = 0; _offset < _size; _offset++)\
30 if(_deltaThermal < thermalThreshold[_direction][_offset])\
42 void ConfigureTxpowerTrack(
44 OUT PTXPWRTRACK_CFG pConfig
48 if(pDM_Odm->SupportICType==ODM_RTL8192E)
49 ConfigureTxpowerTrack_8192E(pConfig);
52 if(pDM_Odm->SupportICType==ODM_RTL8821)
53 ConfigureTxpowerTrack_8821A(pConfig);
56 if(pDM_Odm->SupportICType==ODM_RTL8812)
57 ConfigureTxpowerTrack_8812A(pConfig);
60 if(pDM_Odm->SupportICType==ODM_RTL8188E)
61 ConfigureTxpowerTrack_8188E(pConfig);
65 if(pDM_Odm->SupportICType==ODM_RTL8188F)
66 ConfigureTxpowerTrack_8188F(pConfig);
70 if(pDM_Odm->SupportICType==ODM_RTL8723B)
71 ConfigureTxpowerTrack_8723B(pConfig);
75 if(pDM_Odm->SupportICType==ODM_RTL8814A)
76 ConfigureTxpowerTrack_8814A(pConfig);
80 if(pDM_Odm->SupportICType==ODM_RTL8821B)
81 ConfigureTxpowerTrack_8821B(pConfig);
85 if(pDM_Odm->SupportICType==ODM_RTL8703B)
86 ConfigureTxpowerTrack_8703B(pConfig);
91 //======================================================================
92 // <20121113, Kordan> This function should be called when TxAGC changed.
93 // Otherwise the previous compensation is gone, because we record the
94 // delta of temperature between two TxPowerTracking watch dogs.
96 // NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
97 // need to call this function.
98 //======================================================================
100 ODM_ClearTxPowerTrackingState(
104 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pDM_Odm->Adapter);
106 PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
108 pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->DefaultCckIndex;
109 pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->DefaultCckIndex;
110 pRFCalibrateInfo->CCK_index = 0;
112 for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p)
114 pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->DefaultOfdmIndex;
115 pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->DefaultOfdmIndex;
116 pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->DefaultOfdmIndex;
118 pRFCalibrateInfo->PowerIndexOffset[p] = 0;
119 pRFCalibrateInfo->DeltaPowerIndex[p] = 0;
120 pRFCalibrateInfo->DeltaPowerIndexLast[p] = 0;
122 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = 0; // Initial Mix mode power tracking
123 pRFCalibrateInfo->Remnant_OFDMSwingIdx[p] = 0;
124 pRFCalibrateInfo->KfreeOffset[p] = 0;
127 pRFCalibrateInfo->Modify_TxAGC_Flag_PathA= FALSE; //Initial at Modify Tx Scaling Mode
128 pRFCalibrateInfo->Modify_TxAGC_Flag_PathB= FALSE; //Initial at Modify Tx Scaling Mode
129 pRFCalibrateInfo->Modify_TxAGC_Flag_PathC= FALSE; //Initial at Modify Tx Scaling Mode
130 pRFCalibrateInfo->Modify_TxAGC_Flag_PathD= FALSE; //Initial at Modify Tx Scaling Mode
131 pRFCalibrateInfo->Remnant_CCKSwingIdx= 0;
132 pRFCalibrateInfo->ThermalValue = pHalData->EEPROMThermalMeter;
134 pRFCalibrateInfo->Modify_TxAGC_Value_CCK=0; //modify by Mingzhi.Guo
135 pRFCalibrateInfo->Modify_TxAGC_Value_OFDM=0; //modify by Mingzhi.Guo
140 ODM_TXPowerTrackingCallback_ThermalMeter(
141 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
149 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
150 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
151 PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
152 #elif (DM_ODM_SUPPORT_TYPE == ODM_WIN)
153 PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
155 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
157 PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
159 u1Byte ThermalValue = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0, pathName = 0;
160 s1Byte diff_DPK[4] = {0};
161 u1Byte ThermalValue_AVG_count = 0;
162 u4Byte ThermalValue_AVG = 0;
164 u1Byte OFDM_min_index = 0; // OFDM BB Swing should be less than +3.0dB, which is required by Arthur
165 u1Byte Indexforchannel = 0; // GetRightChnlPlaceforIQK(pHalData->CurrentChannel)
166 BOOLEAN bTSSIenable = FALSE;
170 //4 1. The following TWO tables decide the final index of OFDM/CCK swing table.
171 pu1Byte deltaSwingTableIdx_TUP_A, deltaSwingTableIdx_TDOWN_A;
172 pu1Byte deltaSwingTableIdx_TUP_B, deltaSwingTableIdx_TDOWN_B;
173 //for 8814 add by Yu Chen
174 pu1Byte deltaSwingTableIdx_TUP_C = NULL, deltaSwingTableIdx_TDOWN_C = NULL;
175 pu1Byte deltaSwingTableIdx_TUP_D= NULL, deltaSwingTableIdx_TDOWN_D = NULL;
177 //4 2. Initilization ( 7 steps in total )
179 ConfigureTxpowerTrack(pDM_Odm, &c);
181 (*c.GetDeltaSwingTable)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_A, (pu1Byte*)&deltaSwingTableIdx_TDOWN_A,
182 (pu1Byte*)&deltaSwingTableIdx_TUP_B, (pu1Byte*)&deltaSwingTableIdx_TDOWN_B);
184 if(pDM_Odm->SupportICType & ODM_RTL8814A) // for 8814 path C & D
185 (*c.GetDeltaSwingTable8814only)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_C, (pu1Byte*)&deltaSwingTableIdx_TDOWN_C,
186 (pu1Byte*)&deltaSwingTableIdx_TUP_D, (pu1Byte*)&deltaSwingTableIdx_TDOWN_D);
189 pRFCalibrateInfo->TXPowerTrackingCallbackCnt++; //cosa add for debug
190 pRFCalibrateInfo->bTXPowerTrackingInit = TRUE;
193 /*pRFCalibrateInfo->TxPowerTrackControl = pHalData->TxPowerTrackControl;
194 <Kordan> We should keep updating the control variable according to HalData.
195 <Kordan> RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */
196 pRFCalibrateInfo->RegA24 = 0x090e1317;
199 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
200 ("===>ODM_TXPowerTrackingCallback_ThermalMeter, \
201 \n pRFCalibrateInfo->BbSwingIdxCckBase: %d, pRFCalibrateInfo->BbSwingIdxOfdmBase[A]: %d, pRFCalibrateInfo->DefaultOfdmIndex: %d\n",
202 pRFCalibrateInfo->BbSwingIdxCckBase, pRFCalibrateInfo->BbSwingIdxOfdmBase[ODM_RF_PATH_A], pRFCalibrateInfo->DefaultOfdmIndex));
204 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
205 ("pRFCalibrateInfo->TxPowerTrackControl %d, pHalData->EEPROMThermalMeter %d\n", pRFCalibrateInfo->TxPowerTrackControl, pHalData->EEPROMThermalMeter));
206 ThermalValue = (u1Byte)ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, c.ThermalRegAddr, 0xfc00); //0x42: RF Reg[15:10] 88E
209 if( ! pRFCalibrateInfo->TxPowerTrackControl )
213 //4 3. Initialize ThermalValues of RFCalibrateInfo
215 if(pRFCalibrateInfo->bReloadtxpowerindex)
217 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("reload ofdm index for band switch\n"));
220 //4 4. Calculate average thermal meter
222 pRFCalibrateInfo->ThermalValue_AVG[pRFCalibrateInfo->ThermalValue_AVG_index] = ThermalValue;
223 pRFCalibrateInfo->ThermalValue_AVG_index++;
224 if(pRFCalibrateInfo->ThermalValue_AVG_index == c.AverageThermalNum) //Average times = c.AverageThermalNum
225 pRFCalibrateInfo->ThermalValue_AVG_index = 0;
227 for(i = 0; i < c.AverageThermalNum; i++)
229 if(pRFCalibrateInfo->ThermalValue_AVG[i])
231 ThermalValue_AVG += pRFCalibrateInfo->ThermalValue_AVG[i];
232 ThermalValue_AVG_count++;
236 if(ThermalValue_AVG_count) //Calculate Average ThermalValue after average enough times
238 ThermalValue = (u1Byte)(ThermalValue_AVG / ThermalValue_AVG_count);
239 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
240 ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", ThermalValue, pHalData->EEPROMThermalMeter));
243 //4 5. Calculate delta, delta_LCK, delta_IQK.
245 //"delta" here is used to determine whether thermal value changes or not.
246 delta = (ThermalValue > pRFCalibrateInfo->ThermalValue)?(ThermalValue - pRFCalibrateInfo->ThermalValue):(pRFCalibrateInfo->ThermalValue - ThermalValue);
247 delta_LCK = (ThermalValue > pRFCalibrateInfo->ThermalValue_LCK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_LCK):(pRFCalibrateInfo->ThermalValue_LCK - ThermalValue);
248 delta_IQK = (ThermalValue > pRFCalibrateInfo->ThermalValue_IQK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_IQK):(pRFCalibrateInfo->ThermalValue_IQK - ThermalValue);
250 if(pRFCalibrateInfo->ThermalValue_IQK == 0xff) //no PG, use thermal value for IQK
252 pRFCalibrateInfo->ThermalValue_IQK = ThermalValue;
253 delta_IQK = (ThermalValue > pRFCalibrateInfo->ThermalValue_IQK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_IQK):(pRFCalibrateInfo->ThermalValue_IQK - ThermalValue);
254 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, use ThermalValue for IQK\n"));
257 for(p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
259 diff_DPK[p] = (s1Byte)ThermalValue - (s1Byte)pRFCalibrateInfo->DpkThermal[p];
262 //4 6. If necessary, do LCK.
264 if (!(pDM_Odm->SupportICType & ODM_RTL8821)) {
265 /*no PG , do LCK at initial status*/
266 if (pRFCalibrateInfo->ThermalValue_LCK == 0xff) {
267 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, do LCK\n"));
268 pRFCalibrateInfo->ThermalValue_LCK = ThermalValue;
269 if(c.PHY_LCCalibrate)
270 (*c.PHY_LCCalibrate)(pDM_Odm);
271 delta_LCK = (ThermalValue > pRFCalibrateInfo->ThermalValue_LCK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_LCK):(pRFCalibrateInfo->ThermalValue_LCK - ThermalValue);
274 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK));
276 /* Delta temperature is equal to or larger than 20 centigrade.*/
277 if (delta_LCK >= c.Threshold_IQK) {
278 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_LCK(%d) >= Threshold_IQK(%d)\n", delta_LCK, c.Threshold_IQK));
279 pRFCalibrateInfo->ThermalValue_LCK = ThermalValue;
280 if(c.PHY_LCCalibrate)
281 (*c.PHY_LCCalibrate)(pDM_Odm);
285 //3 7. If necessary, move the index of swing table to adjust Tx power.
287 if (delta > 0 && pRFCalibrateInfo->TxPowerTrackControl)
289 //"delta" here is used to record the absolute value of differrence.
290 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
291 delta = ThermalValue > pHalData->EEPROMThermalMeter?(ThermalValue - pHalData->EEPROMThermalMeter):(pHalData->EEPROMThermalMeter - ThermalValue);
293 delta = (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)?(ThermalValue - pDM_Odm->priv->pmib->dot11RFEntry.ther):(pDM_Odm->priv->pmib->dot11RFEntry.ther - ThermalValue);
295 if (delta >= TXPWR_TRACK_TABLE_SIZE)
296 delta = TXPWR_TRACK_TABLE_SIZE - 1;
298 //4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset
300 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
301 if(ThermalValue > pHalData->EEPROMThermalMeter) {
303 if(ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) {
306 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
308 pRFCalibrateInfo->DeltaPowerIndexLast[p] = pRFCalibrateInfo->DeltaPowerIndex[p]; //recording poer index offset
312 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
313 ("deltaSwingTableIdx_TUP_B[%d] = %d\n", delta, deltaSwingTableIdx_TUP_B[delta]));
315 pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_B[delta];
316 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_B[delta]; // Record delta swing for mix mode power tracking
317 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
318 ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
322 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
323 ("deltaSwingTableIdx_TUP_C[%d] = %d\n", delta, deltaSwingTableIdx_TUP_C[delta]));
325 pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_C[delta];
326 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_C[delta]; // Record delta swing for mix mode power tracking
327 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
328 ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
332 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
333 ("deltaSwingTableIdx_TUP_D[%d] = %d\n", delta, deltaSwingTableIdx_TUP_D[delta]));
335 pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_D[delta];
336 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_D[delta]; // Record delta swing for mix mode power tracking
337 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
338 ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
342 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
343 ("deltaSwingTableIdx_TUP_A[%d] = %d\n", delta, deltaSwingTableIdx_TUP_A[delta]));
345 pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_A[delta];
346 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_A[delta]; // Record delta swing for mix mode power tracking
347 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
348 ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
357 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
359 pRFCalibrateInfo->DeltaPowerIndexLast[p] = pRFCalibrateInfo->DeltaPowerIndex[p]; //recording poer index offset
363 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
364 ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_B[delta]));
365 pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_B[delta];
366 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_B[delta]; // Record delta swing for mix mode power tracking
367 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
368 ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
372 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
373 ("deltaSwingTableIdx_TDOWN_C[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_C[delta]));
374 pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_C[delta];
375 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_C[delta]; // Record delta swing for mix mode power tracking
376 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
377 ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
381 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
382 ("deltaSwingTableIdx_TDOWN_D[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_D[delta]));
383 pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_D[delta];
384 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_D[delta]; // Record delta swing for mix mode power tracking
385 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
386 ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
390 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
391 ("deltaSwingTableIdx_TDOWN_A[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_A[delta]));
392 pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_A[delta];
393 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_A[delta]; // Record delta swing for mix mode power tracking
394 ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
395 ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p]));
403 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
405 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
406 ("\n\n=========================== [Path-%d] Calculating PowerIndexOffset===========================\n", p));
408 if(pRFCalibrateInfo->DeltaPowerIndex[p] == pRFCalibrateInfo->DeltaPowerIndexLast[p]) // If Thermal value changes but lookup table value still the same
409 pRFCalibrateInfo->PowerIndexOffset[p] = 0;
411 pRFCalibrateInfo->PowerIndexOffset[p] = pRFCalibrateInfo->DeltaPowerIndex[p] - pRFCalibrateInfo->DeltaPowerIndexLast[p]; // Power Index Diff between 2 times Power Tracking
413 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
414 ("[Path-%d] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n", p, pRFCalibrateInfo->PowerIndexOffset[p], pRFCalibrateInfo->DeltaPowerIndex[p], pRFCalibrateInfo->DeltaPowerIndexLast[p]));
416 pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->BbSwingIdxOfdmBase[p] + pRFCalibrateInfo->PowerIndexOffset[p];
417 pRFCalibrateInfo->CCK_index = pRFCalibrateInfo->BbSwingIdxCckBase + pRFCalibrateInfo->PowerIndexOffset[p];
419 pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->CCK_index;
420 pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->OFDM_index[p];
422 // *************Print BB Swing Base and Index Offset*************
424 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
425 ("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxCck, pRFCalibrateInfo->BbSwingIdxCckBase, pRFCalibrateInfo->PowerIndexOffset[p]));
426 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
427 ("The 'OFDM' final index(%d) = BaseIndex[%d](%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxOfdm[p], p, pRFCalibrateInfo->BbSwingIdxOfdmBase[p], pRFCalibrateInfo->PowerIndexOffset[p]));
429 //4 7.1 Handle boundary conditions of index.
431 if(pRFCalibrateInfo->OFDM_index[p] > c.SwingTableSize_OFDM-1)
433 pRFCalibrateInfo->OFDM_index[p] = c.SwingTableSize_OFDM-1;
435 else if (pRFCalibrateInfo->OFDM_index[p] <= OFDM_min_index)
437 pRFCalibrateInfo->OFDM_index[p] = OFDM_min_index;
440 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
441 ("\n\n========================================================================================================\n"));
442 if(pRFCalibrateInfo->CCK_index > c.SwingTableSize_CCK-1)
443 pRFCalibrateInfo->CCK_index = c.SwingTableSize_CCK-1;
444 else if (pRFCalibrateInfo->CCK_index <= 0)
445 pRFCalibrateInfo->CCK_index = 0;
449 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
450 ("The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pRFCalibrateInfo->ThermalValue: %d\n",
451 pRFCalibrateInfo->TxPowerTrackControl, ThermalValue, pRFCalibrateInfo->ThermalValue));
453 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
454 pRFCalibrateInfo->PowerIndexOffset[p] = 0;
457 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
458 ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
459 pRFCalibrateInfo->CCK_index, pRFCalibrateInfo->BbSwingIdxCckBase)); //Print Swing base & current
461 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
463 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
464 ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%d]: %d\n",
465 pRFCalibrateInfo->OFDM_index[p], p, pRFCalibrateInfo->BbSwingIdxOfdmBase[p]));
468 if ((pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_A] != 0 ||
469 pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_B] != 0 ||
470 pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_C] != 0 ||
471 pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_D] != 0) &&
472 pRFCalibrateInfo->TxPowerTrackControl && (pHalData->EEPROMThermalMeter != 0xff))
474 //4 7.2 Configure the Swing Table to adjust Tx Power.
476 pRFCalibrateInfo->bTxPowerChanged = TRUE; // Always TRUE after Tx Power is adjusted by power tracking.
478 // 2012/04/23 MH According to Luke's suggestion, we can not write BB digital
479 // to increase TX power. Otherwise, EVM will be bad.
481 // 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
482 if (ThermalValue > pRFCalibrateInfo->ThermalValue)
484 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
486 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
487 ("Temperature Increasing(%d): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
488 p, pRFCalibrateInfo->PowerIndexOffset[p], delta, ThermalValue, pHalData->EEPROMThermalMeter, pRFCalibrateInfo->ThermalValue));
492 else if (ThermalValue < pRFCalibrateInfo->ThermalValue)// Low temperature
494 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
496 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
497 ("Temperature Decreasing(%d): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
498 p, pRFCalibrateInfo->PowerIndexOffset[p], delta, ThermalValue, pHalData->EEPROMThermalMeter, pRFCalibrateInfo->ThermalValue));
502 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
503 if (ThermalValue > pHalData->EEPROMThermalMeter)
505 if (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)
508 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
509 ("Temperature(%d) higher than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter));
511 if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E ||pDM_Odm->SupportICType == ODM_RTL8821 ||
512 pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8814A || pDM_Odm->SupportICType == ODM_RTL8703B || pDM_Odm->SupportICType == ODM_RTL8188F)
514 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking MIX_MODE**********\n"));
515 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
516 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0);
520 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking BBSWING_MODE**********\n"));
521 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
522 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel);
527 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
528 ("Temperature(%d) lower than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter));
530 if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8821 ||
531 pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8814A || pDM_Odm->SupportICType == ODM_RTL8703B || pDM_Odm->SupportICType == ODM_RTL8188F)
533 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking MIX_MODE**********\n"));
534 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
535 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel);
539 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking BBSWING_MODE**********\n"));
540 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
541 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel);
546 pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->BbSwingIdxCck; // Record last time Power Tracking result as base.
547 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
548 pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->BbSwingIdxOfdm[p];
550 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
551 ("pRFCalibrateInfo->ThermalValue = %d ThermalValue= %d\n", pRFCalibrateInfo->ThermalValue, ThermalValue));
553 pRFCalibrateInfo->ThermalValue = ThermalValue; //Record last Power Tracking Thermal Value
557 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
559 if(!IS_HARDWARE_TYPE_8723B(Adapter))
561 // Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).
562 if ((delta_IQK >= c.Threshold_IQK)) {
563 if ( ! pRFCalibrateInfo->bIQKInProgress)
564 (*c.DoIQK)(pDM_Odm, delta_IQK, ThermalValue, 8);
567 if (pRFCalibrateInfo->DpkThermal[ODM_RF_PATH_A] != 0) {
568 if ((diff_DPK[ODM_RF_PATH_A] >= c.Threshold_DPK)) {
569 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1);
570 ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, (diff_DPK[ODM_RF_PATH_A] / c.Threshold_DPK));
571 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0);
572 } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.Threshold_DPK)) {
573 s4Byte value = 0x20 + (diff_DPK[ODM_RF_PATH_A] / c.Threshold_DPK);
574 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1);
575 ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, value);
576 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0);
578 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1);
579 ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, 0);
580 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0);
583 if (pRFCalibrateInfo->DpkThermal[ODM_RF_PATH_B] != 0) {
584 if ((diff_DPK[ODM_RF_PATH_B] >= c.Threshold_DPK)) {
585 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1);
586 ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, (diff_DPK[ODM_RF_PATH_B] / c.Threshold_DPK));
587 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0);
588 } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.Threshold_DPK)) {
589 s4Byte value = 0x20 + (diff_DPK[ODM_RF_PATH_B] / c.Threshold_DPK);
590 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1);
591 ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, value);
592 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0);
594 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1);
595 ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, 0);
596 ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0);
602 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("<===ODM_TXPowerTrackingCallback_ThermalMeter\n"));
604 pRFCalibrateInfo->TXPowercount = 0;
609 //3============================================================
611 //3============================================================
620 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
621 u1Byte ODM_GetRightChnlPlaceforIQK(u1Byte chnl)
623 u1Byte channel_all[ODM_TARGET_CHNL_NUM_2G_5G] =
624 {1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,161,163,165};
630 for(place = 14; place<sizeof(channel_all); place++)
632 if(channel_all[place] == chnl)
648 PADAPTER Adapter = pDM_Odm->Adapter;
650 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
651 if (*pDM_Odm->pIsFcsModeEnable)
655 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
656 if (!IS_HARDWARE_TYPE_JAGUAR(Adapter))
658 #if (DM_ODM_SUPPORT_TYPE & (ODM_CE))
659 else if (IS_HARDWARE_TYPE_8812AU(Adapter))
664 #if (RTL8821A_SUPPORT == 1)
665 if (pDM_Odm->bLinked) {
666 if ((*pDM_Odm->pChannel != pDM_Odm->preChannel) && (!*pDM_Odm->pbScanInProcess)) {
667 pDM_Odm->preChannel = *pDM_Odm->pChannel;
668 pDM_Odm->LinkedInterval = 0;
671 if (pDM_Odm->LinkedInterval < 3)
672 pDM_Odm->LinkedInterval++;
674 if (pDM_Odm->LinkedInterval == 2) {
675 /*Mark out IQK flow to prevent tx stuck. by Maddest 20130306*/
676 /*Open it verified by James 20130715*/
677 #if (DM_ODM_SUPPORT_TYPE == ODM_CE)
678 PHY_IQCalibrate_8821A(pDM_Odm, FALSE);
679 #elif (DM_ODM_SUPPORT_TYPE == ODM_WIN)
680 PHY_IQCalibrate(Adapter, FALSE);
682 PHY_IQCalibrate_8821A(Adapter, FALSE);
686 pDM_Odm->LinkedInterval = 0;
690 void phydm_rf_init(IN PDM_ODM_T pDM_Odm)
693 odm_TXPowerTrackingInit(pDM_Odm);
695 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
696 ODM_ClearTxPowerTrackingState(pDM_Odm);
699 #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
700 #if (RTL8814A_SUPPORT == 1)
701 if (pDM_Odm->SupportICType & ODM_RTL8814A)
702 PHY_IQCalibrate_8814A_Init(pDM_Odm);
708 void phydm_rf_watchdog(IN PDM_ODM_T pDM_Odm)
711 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
712 ODM_TXPowerTrackingCheck(pDM_Odm);
713 if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES)
714 odm_IQCalibrate(pDM_Odm);