net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / hal / phydm / halphyrf_win.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
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.
8  *
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
12  * more details.
13  *
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
17  *
18  *
19  ******************************************************************************/
20
21  #include "mp_precomp.h"
22  #include "phydm_precomp.h"
23
24 //#if(DM_ODM_SUPPORT_TYPE & ODM_WIN)
25
26 #define         CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \
27                                         do {\
28                                                 for(_offset = 0; _offset < _size; _offset++)\
29                                                 {\
30                                                         if(_deltaThermal < thermalThreshold[_direction][_offset])\
31                                                         {\
32                                                                 if(_offset != 0)\
33                                                                         _offset--;\
34                                                                 break;\
35                                                         }\
36                                                 }                       \
37                                                 if(_offset >= _size)\
38                                                         _offset = _size-1;\
39                                         } while(0)
40
41
42 void ConfigureTxpowerTrack(
43         IN      PDM_ODM_T               pDM_Odm,
44         OUT     PTXPWRTRACK_CFG pConfig
45         )
46 {
47 #if RTL8192E_SUPPORT
48         if(pDM_Odm->SupportICType==ODM_RTL8192E)
49                 ConfigureTxpowerTrack_8192E(pConfig);
50 #endif  
51 #if RTL8821A_SUPPORT
52         if(pDM_Odm->SupportICType==ODM_RTL8821)
53                 ConfigureTxpowerTrack_8821A(pConfig);
54 #endif
55 #if RTL8812A_SUPPORT
56         if(pDM_Odm->SupportICType==ODM_RTL8812)
57                 ConfigureTxpowerTrack_8812A(pConfig);
58 #endif
59 #if RTL8188E_SUPPORT
60         if(pDM_Odm->SupportICType==ODM_RTL8188E)
61                 ConfigureTxpowerTrack_8188E(pConfig);
62 #endif 
63
64 #if RTL8188F_SUPPORT
65         if(pDM_Odm->SupportICType==ODM_RTL8188F)
66                 ConfigureTxpowerTrack_8188F(pConfig);
67 #endif 
68
69 #if RTL8723B_SUPPORT
70         if(pDM_Odm->SupportICType==ODM_RTL8723B)
71                 ConfigureTxpowerTrack_8723B(pConfig);
72 #endif
73
74 #if RTL8814A_SUPPORT
75         if(pDM_Odm->SupportICType==ODM_RTL8814A)
76                 ConfigureTxpowerTrack_8814A(pConfig);
77 #endif
78
79 #if RTL8821B_SUPPORT
80         if(pDM_Odm->SupportICType==ODM_RTL8821B)
81                 ConfigureTxpowerTrack_8821B(pConfig);
82 #endif
83
84 #if RTL8703B_SUPPORT
85         if(pDM_Odm->SupportICType==ODM_RTL8703B)
86                 ConfigureTxpowerTrack_8703B(pConfig);
87 #endif
88
89 }
90
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.
95 //
96 // NOTE: If Tx BB swing or Tx scaling is varified during run-time, still 
97 //       need to call this function.
98 //======================================================================
99 VOID
100 ODM_ClearTxPowerTrackingState(
101         IN PDM_ODM_T            pDM_Odm
102         )
103 {
104         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(pDM_Odm->Adapter);
105         u1Byte                  p = 0;
106         PODM_RF_CAL_T   pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
107         
108         pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->DefaultCckIndex;
109         pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->DefaultCckIndex;
110         pRFCalibrateInfo->CCK_index = 0;
111         
112         for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p)
113         {
114                 pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->DefaultOfdmIndex;
115                 pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->DefaultOfdmIndex;
116                 pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->DefaultOfdmIndex;
117
118                 pRFCalibrateInfo->PowerIndexOffset[p] = 0;
119                 pRFCalibrateInfo->DeltaPowerIndex[p] = 0;
120                 pRFCalibrateInfo->DeltaPowerIndexLast[p] = 0;
121
122                 pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = 0;    // Initial Mix mode power tracking
123                 pRFCalibrateInfo->Remnant_OFDMSwingIdx[p] = 0;                    
124                 pRFCalibrateInfo->KfreeOffset[p] = 0;                     
125         }
126         
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;
133
134         pRFCalibrateInfo->Modify_TxAGC_Value_CCK=0;                     //modify by Mingzhi.Guo
135         pRFCalibrateInfo->Modify_TxAGC_Value_OFDM=0;            //modify by Mingzhi.Guo
136
137 }
138
139 VOID
140 ODM_TXPowerTrackingCallback_ThermalMeter(
141 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
142         IN PDM_ODM_T            pDM_Odm
143 #else
144         IN PADAPTER     Adapter
145 #endif
146         )
147 {
148
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;
154 #else
155         PDM_ODM_T               pDM_Odm = &pHalData->odmpriv;
156 #endif
157         PODM_RF_CAL_T   pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
158         
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;   
163
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;
167
168         TXPWRTRACK_CFG  c;
169         
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;
176                 
177         //4 2. Initilization ( 7 steps in total )
178
179         ConfigureTxpowerTrack(pDM_Odm, &c);
180         
181         (*c.GetDeltaSwingTable)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_A, (pu1Byte*)&deltaSwingTableIdx_TDOWN_A,
182                                                                           (pu1Byte*)&deltaSwingTableIdx_TUP_B, (pu1Byte*)&deltaSwingTableIdx_TDOWN_B);
183
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);
187         
188         
189         pRFCalibrateInfo->TXPowerTrackingCallbackCnt++; //cosa add for debug
190         pRFCalibrateInfo->bTXPowerTrackingInit = TRUE;
191    
192 #if (MP_DRIVER == 1)      
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; 
197 #endif
198
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));
203
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
207
208
209         if( ! pRFCalibrateInfo->TxPowerTrackControl )
210                 return;
211
212
213         //4 3. Initialize ThermalValues of RFCalibrateInfo
214
215         if(pRFCalibrateInfo->bReloadtxpowerindex)
216         {
217                 ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("reload ofdm index for band switch\n"));                              
218         }
219
220         //4 4. Calculate average thermal meter
221         
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;
226
227         for(i = 0; i < c.AverageThermalNum; i++)
228         {
229                 if(pRFCalibrateInfo->ThermalValue_AVG[i])
230                 {
231                         ThermalValue_AVG += pRFCalibrateInfo->ThermalValue_AVG[i];
232                         ThermalValue_AVG_count++;
233                 }
234         }
235
236         if(ThermalValue_AVG_count)               //Calculate Average ThermalValue after average enough times
237         {
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));                                 
241         }
242                         
243         //4 5. Calculate delta, delta_LCK, delta_IQK.
244
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);
249
250         if(pRFCalibrateInfo->ThermalValue_IQK == 0xff)  //no PG, use thermal value for IQK
251         {
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"));
255         }
256         
257         for(p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
258                 {
259                 diff_DPK[p] = (s1Byte)ThermalValue - (s1Byte)pRFCalibrateInfo->DpkThermal[p];
260                 }
261
262         //4 6. If necessary, do LCK.    
263
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);
272         }
273
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));
275         
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);
282         }
283         }
284
285         //3 7. If necessary, move the index of swing table to adjust Tx power.  
286         
287         if (delta > 0 && pRFCalibrateInfo->TxPowerTrackControl)
288         {
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);            
292 #else
293             delta = (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)?(ThermalValue - pDM_Odm->priv->pmib->dot11RFEntry.ther):(pDM_Odm->priv->pmib->dot11RFEntry.ther - ThermalValue);            
294 #endif
295                 if (delta >= TXPWR_TRACK_TABLE_SIZE)
296                         delta = TXPWR_TRACK_TABLE_SIZE - 1;
297
298                 //4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset
299                 
300 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))                            
301                 if(ThermalValue > pHalData->EEPROMThermalMeter) {
302 #else
303                 if(ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) {
304 #endif
305
306                 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) 
307                         {
308                         pRFCalibrateInfo->DeltaPowerIndexLast[p] = pRFCalibrateInfo->DeltaPowerIndex[p];        //recording poer index offset
309                         switch(p)
310                                 {
311                                         case ODM_RF_PATH_B:
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])); 
314                                                 
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]));  
319                                         break;
320
321                                         case ODM_RF_PATH_C:
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]));
324                                                 
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]));  
329                                         break;
330
331                                         case ODM_RF_PATH_D:
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]));
334                                                 
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]));  
339                                         break;
340
341                                         default:
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]));
344                                                 
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]));  
349                                         break;
350                                 }       
351                                 
352                         }
353                         
354         } 
355                 else {
356
357                         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) 
358                         {
359                         pRFCalibrateInfo->DeltaPowerIndexLast[p] = pRFCalibrateInfo->DeltaPowerIndex[p];        //recording poer index offset
360                         switch(p)
361                                 {
362                                         case ODM_RF_PATH_B:
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])); 
369                                         break;
370
371                                         case ODM_RF_PATH_C:
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]));   
378                                         break;
379
380                                         case ODM_RF_PATH_D:
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]));  
387                                         break;
388
389                                         default:
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]));  
396                                         break;
397                                 }       
398                                 
399                         }
400                         
401         }
402                 
403            for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)              
404                 {
405                         ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
406                                 ("\n\n=========================== [Path-%d] Calculating PowerIndexOffset===========================\n", p));  
407                         
408                     if(pRFCalibrateInfo->DeltaPowerIndex[p] == pRFCalibrateInfo->DeltaPowerIndexLast[p])         // If Thermal value changes but lookup table value still the same
409                         pRFCalibrateInfo->PowerIndexOffset[p] = 0;
410                     else
411                         pRFCalibrateInfo->PowerIndexOffset[p] = pRFCalibrateInfo->DeltaPowerIndex[p] - pRFCalibrateInfo->DeltaPowerIndexLast[p];      // Power Index Diff between 2 times Power Tracking
412
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]));                
415                 
416                         pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->BbSwingIdxOfdmBase[p] + pRFCalibrateInfo->PowerIndexOffset[p];
417                         pRFCalibrateInfo->CCK_index = pRFCalibrateInfo->BbSwingIdxCckBase + pRFCalibrateInfo->PowerIndexOffset[p];
418
419                         pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->CCK_index;  
420                         pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->OFDM_index[p];  
421
422                    // *************Print BB Swing Base and Index Offset*************
423
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]));
428
429                     //4 7.1 Handle boundary conditions of index.
430                 
431                         if(pRFCalibrateInfo->OFDM_index[p] > c.SwingTableSize_OFDM-1)
432                         {
433                                 pRFCalibrateInfo->OFDM_index[p] = c.SwingTableSize_OFDM-1;
434                         }
435                         else if (pRFCalibrateInfo->OFDM_index[p] <= OFDM_min_index)
436                         {
437                                 pRFCalibrateInfo->OFDM_index[p] = OFDM_min_index;
438                         }
439                 }
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;
446         }
447         else
448         {
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));
452
453                 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)                 
454                     pRFCalibrateInfo->PowerIndexOffset[p] = 0;
455         }
456
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
460                 
461         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
462         {
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]));
466         }
467         
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))
473         {
474                 //4 7.2 Configure the Swing Table to adjust Tx Power.
475                 
476                 pRFCalibrateInfo->bTxPowerChanged = TRUE; // Always TRUE after Tx Power is adjusted by power tracking.                  
477                 //
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.
480                 //
481                 // 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
482                 if (ThermalValue > pRFCalibrateInfo->ThermalValue)
483                 {
484                         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
485                         {
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));  
489                         }
490                 }
491                 
492                 else if (ThermalValue < pRFCalibrateInfo->ThermalValue)// Low temperature
493                 {
494                         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
495                         {
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));                          
499                         }
500                 }                               
501                 
502 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
503                 if (ThermalValue > pHalData->EEPROMThermalMeter)
504 #else
505                 if (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)
506 #endif
507                 {
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));                    
510
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)
513                         {
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);
517                         }
518                         else 
519                         {
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);
523                         }
524                 }
525                 else
526                 {
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));
529
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)
532                         {
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);
536                         }
537                         else
538                         {
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);
542                         }
543                         
544                 }
545
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];
549
550                         ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
551                                 ("pRFCalibrateInfo->ThermalValue = %d ThermalValue= %d\n", pRFCalibrateInfo->ThermalValue, ThermalValue));
552                 
553                         pRFCalibrateInfo->ThermalValue = ThermalValue;         //Record last Power Tracking Thermal Value
554                         
555         }
556         
557 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
558         
559         if(!IS_HARDWARE_TYPE_8723B(Adapter))
560         {
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);
565                 }
566         }
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);
577                 } else {
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);     
581                 }
582         }
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);
593                 } else {
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);     
597                 }
598         }
599
600 #endif          
601                         
602         ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("<===ODM_TXPowerTrackingCallback_ThermalMeter\n"));
603         
604         pRFCalibrateInfo->TXPowercount = 0;
605 }
606
607
608
609 //3============================================================
610 //3 IQ Calibration
611 //3============================================================
612
613 VOID
614 ODM_ResetIQKResult(
615         IN PDM_ODM_T    pDM_Odm 
616 )
617 {
618         return;
619 }
620 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
621 u1Byte ODM_GetRightChnlPlaceforIQK(u1Byte chnl)
622 {
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};
625         u1Byte  place = chnl;
626
627         
628         if(chnl > 14)
629         {
630                 for(place = 14; place<sizeof(channel_all); place++)
631                 {
632                         if(channel_all[place] == chnl)
633                         {
634                                 return place-13;
635                         }
636                 }
637         }       
638         return 0;
639
640 }
641 #endif
642
643 VOID
644 odm_IQCalibrate(
645                 IN      PDM_ODM_T       pDM_Odm 
646                 )
647 {
648         PADAPTER        Adapter = pDM_Odm->Adapter;
649
650 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)    
651         if (*pDM_Odm->pIsFcsModeEnable)
652                 return;
653 #endif
654         
655 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))            
656         if (!IS_HARDWARE_TYPE_JAGUAR(Adapter))
657                 return;
658 #if (DM_ODM_SUPPORT_TYPE & (ODM_CE))
659         else if (IS_HARDWARE_TYPE_8812AU(Adapter))
660                 return;
661 #endif
662 #endif
663         
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;
669                 }
670
671                 if (pDM_Odm->LinkedInterval < 3)
672                         pDM_Odm->LinkedInterval++;
673                 
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);
681 #else
682                         PHY_IQCalibrate_8821A(Adapter, FALSE);
683 #endif
684                 }
685         } else
686                 pDM_Odm->LinkedInterval = 0;
687 #endif
688 }
689
690 void phydm_rf_init(IN           PDM_ODM_T               pDM_Odm)
691 {
692
693         odm_TXPowerTrackingInit(pDM_Odm);
694
695 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
696         ODM_ClearTxPowerTrackingState(pDM_Odm); 
697 #endif
698
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);
703 #endif  
704 #endif
705
706 }
707
708 void phydm_rf_watchdog(IN               PDM_ODM_T               pDM_Odm)
709 {
710
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);
715 #endif
716 }