GNU Linux-libre 4.14.295-gnu1
[releases.git] / drivers / staging / rtl8723bs / hal / HalPhyRf.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  ******************************************************************************/
15
16 /* include "Mp_Precomp.h" */
17 #include "odm_precomp.h"
18
19
20 #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \
21         do {\
22                 for (_offset = 0; _offset < _size; _offset++) {\
23                         if (_deltaThermal < thermalThreshold[_direction][_offset]) {\
24                                 if (_offset != 0)\
25                                         _offset--;\
26                                 break;\
27                         } \
28                 } \
29                 if (_offset >= _size)\
30                         _offset = _size-1;\
31         } while (0)
32
33
34 void ConfigureTxpowerTrack(PDM_ODM_T pDM_Odm, PTXPWRTRACK_CFG pConfig)
35 {
36         ConfigureTxpowerTrack_8723B(pConfig);
37 }
38
39 /*  */
40 /*  <20121113, Kordan> This function should be called when TxAGC changed. */
41 /*  Otherwise the previous compensation is gone, because we record the */
42 /*  delta of temperature between two TxPowerTracking watch dogs. */
43 /*  */
44 /*  NOTE: If Tx BB swing or Tx scaling is varified during run-time, still */
45 /*        need to call this function. */
46 /*  */
47 void ODM_ClearTxPowerTrackingState(PDM_ODM_T pDM_Odm)
48 {
49         struct hal_com_data *pHalData = GET_HAL_DATA(pDM_Odm->Adapter);
50         u8 p = 0;
51
52         pDM_Odm->BbSwingIdxCckBase = pDM_Odm->DefaultCckIndex;
53         pDM_Odm->BbSwingIdxCck = pDM_Odm->DefaultCckIndex;
54         pDM_Odm->RFCalibrateInfo.CCK_index = 0;
55
56         for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
57                 pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->DefaultOfdmIndex;
58                 pDM_Odm->BbSwingIdxOfdm[p] = pDM_Odm->DefaultOfdmIndex;
59                 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pDM_Odm->DefaultOfdmIndex;
60
61                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
62                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = 0;
63                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = 0;
64                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
65
66                 /*  Initial Mix mode power tracking */
67                 pDM_Odm->Absolute_OFDMSwingIdx[p] = 0;
68                 pDM_Odm->Remnant_OFDMSwingIdx[p] = 0;
69         }
70
71         /* Initial at Modify Tx Scaling Mode */
72         pDM_Odm->Modify_TxAGC_Flag_PathA = false;
73         /* Initial at Modify Tx Scaling Mode */
74         pDM_Odm->Modify_TxAGC_Flag_PathB = false;
75         pDM_Odm->Remnant_CCKSwingIdx = 0;
76         pDM_Odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
77         pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = pHalData->EEPROMThermalMeter;
78         pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = pHalData->EEPROMThermalMeter;
79 }
80
81 void ODM_TXPowerTrackingCallback_ThermalMeter(struct adapter *Adapter)
82 {
83
84         struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
85         PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
86
87         u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
88         u8 ThermalValue_AVG_count = 0;
89         u32 ThermalValue_AVG = 0;
90
91         u8 OFDM_min_index = 0;  /*  OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
92         u8 Indexforchannel = 0; /*  GetRightChnlPlaceforIQK(pHalData->CurrentChannel) */
93
94         TXPWRTRACK_CFG c;
95
96
97         /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
98         u8 *deltaSwingTableIdx_TUP_A;
99         u8 *deltaSwingTableIdx_TDOWN_A;
100         u8 *deltaSwingTableIdx_TUP_B;
101         u8 *deltaSwingTableIdx_TDOWN_B;
102
103         /* 4 2. Initilization (7 steps in total) */
104
105         ConfigureTxpowerTrack(pDM_Odm, &c);
106
107         (*c.GetDeltaSwingTable)(
108                 pDM_Odm,
109                 (u8 **)&deltaSwingTableIdx_TUP_A,
110                 (u8 **)&deltaSwingTableIdx_TDOWN_A,
111                 (u8 **)&deltaSwingTableIdx_TUP_B,
112                 (u8 **)&deltaSwingTableIdx_TDOWN_B
113         );
114
115         /* cosa add for debug */
116         pDM_Odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
117         pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
118
119         ODM_RT_TRACE(
120                 pDM_Odm,
121                 ODM_COMP_TX_PWR_TRACK,
122                 ODM_DBG_LOUD,
123                 (
124                         "===>ODM_TXPowerTrackingCallback_ThermalMeter,\npDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]: %d, pDM_Odm->DefaultOfdmIndex: %d\n",
125                         pDM_Odm->BbSwingIdxCckBase,
126                         pDM_Odm->BbSwingIdxOfdmBase[ODM_RF_PATH_A],
127                         pDM_Odm->DefaultOfdmIndex
128                 )
129         );
130
131         ThermalValue = (u8)PHY_QueryRFReg(pDM_Odm->Adapter, ODM_RF_PATH_A, c.ThermalRegAddr, 0xfc00);   /* 0x42: RF Reg[15:10] 88E */
132         if (
133                 !pDM_Odm->RFCalibrateInfo.TxPowerTrackControl ||
134                 pHalData->EEPROMThermalMeter == 0 ||
135                 pHalData->EEPROMThermalMeter == 0xFF
136         )
137                 return;
138
139         /* 4 3. Initialize ThermalValues of RFCalibrateInfo */
140
141         if (pDM_Odm->RFCalibrateInfo.bReloadtxpowerindex)
142                 ODM_RT_TRACE(
143                         pDM_Odm,
144                         ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
145                         ("reload ofdm index for band switch\n")
146                 );
147
148         /* 4 4. Calculate average thermal meter */
149
150         pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue;
151         pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index++;
152         if (pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index == c.AverageThermalNum)   /* Average times =  c.AverageThermalNum */
153                 pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
154
155         for (i = 0; i < c.AverageThermalNum; i++) {
156                 if (pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
157                         ThermalValue_AVG += pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i];
158                         ThermalValue_AVG_count++;
159                 }
160         }
161
162         /* Calculate Average ThermalValue after average enough times */
163         if (ThermalValue_AVG_count) {
164                 ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count);
165                 ODM_RT_TRACE(
166                         pDM_Odm,
167                         ODM_COMP_TX_PWR_TRACK,
168                         ODM_DBG_LOUD,
169                         (
170                                 "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
171                                 ThermalValue,
172                                 pHalData->EEPROMThermalMeter
173                         )
174                 );
175         }
176
177         /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
178         /* delta" here is used to determine whether thermal value changes or not. */
179         delta =
180                 (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue) ?
181                 (ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue) :
182                 (pDM_Odm->RFCalibrateInfo.ThermalValue - ThermalValue);
183         delta_LCK =
184                 (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_LCK) ?
185                 (ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_LCK) :
186                 (pDM_Odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue);
187         delta_IQK =
188                 (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_IQK) ?
189                 (ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_IQK) :
190                 (pDM_Odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue);
191
192         ODM_RT_TRACE(
193                 pDM_Odm,
194                 ODM_COMP_TX_PWR_TRACK,
195                 ODM_DBG_LOUD,
196                 (
197                         "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
198                         delta,
199                         delta_LCK,
200                         delta_IQK
201                 )
202         );
203
204         /* 4 6. If necessary, do LCK. */
205         /*  Delta temperature is equal to or larger than 20 centigrade. */
206         if (delta_LCK >= c.Threshold_IQK) {
207                 ODM_RT_TRACE(
208                         pDM_Odm,
209                         ODM_COMP_TX_PWR_TRACK,
210                         ODM_DBG_LOUD,
211                         (
212                                 "delta_LCK(%d) >= Threshold_IQK(%d)\n",
213                                 delta_LCK,
214                                 c.Threshold_IQK
215                         )
216                 );
217                 pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
218                 if (c.PHY_LCCalibrate)
219                         (*c.PHY_LCCalibrate)(pDM_Odm);
220         }
221
222         /* 3 7. If necessary, move the index of swing table to adjust Tx power. */
223         if (delta > 0 && pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) {
224                 /* delta" here is used to record the absolute value of differrence. */
225                 delta =
226                         ThermalValue > pHalData->EEPROMThermalMeter ?
227                         (ThermalValue - pHalData->EEPROMThermalMeter) :
228                         (pHalData->EEPROMThermalMeter - ThermalValue);
229
230                 if (delta >= TXPWR_TRACK_TABLE_SIZE)
231                         delta = TXPWR_TRACK_TABLE_SIZE - 1;
232
233                 /* 4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset */
234                 if (ThermalValue > pHalData->EEPROMThermalMeter) {
235                         ODM_RT_TRACE(
236                                 pDM_Odm,
237                                 ODM_COMP_TX_PWR_TRACK,
238                                 ODM_DBG_LOUD,
239                                 (
240                                         "deltaSwingTableIdx_TUP_A[%d] = %d\n",
241                                         delta,
242                                         deltaSwingTableIdx_TUP_A[delta]
243                                 )
244                         );
245                         pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_A] =
246                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A];
247                         pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A] =
248                                 deltaSwingTableIdx_TUP_A[delta];
249
250                         /*  Record delta swing for mix mode power tracking */
251                         pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] =
252                                 deltaSwingTableIdx_TUP_A[delta];
253
254                         ODM_RT_TRACE(
255                                 pDM_Odm,
256                                 ODM_COMP_TX_PWR_TRACK,
257                                 ODM_DBG_LOUD,
258                                 (
259                                         "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
260                                         pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A]
261                                 )
262                         );
263
264                         if (c.RfPathCount > 1) {
265                                 ODM_RT_TRACE(
266                                         pDM_Odm,
267                                         ODM_COMP_TX_PWR_TRACK,
268                                         ODM_DBG_LOUD,
269                                         (
270                                                 "deltaSwingTableIdx_TUP_B[%d] = %d\n",
271                                                 delta,
272                                                 deltaSwingTableIdx_TUP_B[delta]
273                                         )
274                                 );
275                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_B] =
276                                         pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B];
277                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B] =
278                                         deltaSwingTableIdx_TUP_B[delta];
279
280                                 /*  Record delta swing for mix mode power tracking */
281                                 pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] =
282                                         deltaSwingTableIdx_TUP_B[delta];
283                                 ODM_RT_TRACE(
284                                         pDM_Odm,
285                                         ODM_COMP_TX_PWR_TRACK,
286                                         ODM_DBG_LOUD,
287                                         (
288                                                 "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
289                                                 pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B]
290                                         )
291                                 );
292                         }
293
294                 } else {
295                         ODM_RT_TRACE(
296                                 pDM_Odm,
297                                 ODM_COMP_TX_PWR_TRACK,
298                                 ODM_DBG_LOUD,
299                                 (
300                                         "deltaSwingTableIdx_TDOWN_A[%d] = %d\n",
301                                         delta,
302                                         deltaSwingTableIdx_TDOWN_A[delta]
303                                 )
304                         );
305
306                         pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_A] =
307                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A];
308                         pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A] =
309                                 -1 * deltaSwingTableIdx_TDOWN_A[delta];
310
311                         /*  Record delta swing for mix mode power tracking */
312                         pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] =
313                                 -1 * deltaSwingTableIdx_TDOWN_A[delta];
314
315                         ODM_RT_TRACE(
316                                 pDM_Odm,
317                                 ODM_COMP_TX_PWR_TRACK,
318                                 ODM_DBG_LOUD,
319                                 (
320                                         "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
321                                         pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A]
322                                 )
323                         );
324
325                         if (c.RfPathCount > 1) {
326                                 ODM_RT_TRACE(
327                                         pDM_Odm,
328                                         ODM_COMP_TX_PWR_TRACK,
329                                         ODM_DBG_LOUD,
330                                         (
331                                                 "deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
332                                                 delta,
333                                                 deltaSwingTableIdx_TDOWN_B[delta]
334                                         )
335                                 );
336
337                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_B] =
338                                         pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B];
339                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B] =
340                                         -1 * deltaSwingTableIdx_TDOWN_B[delta];
341
342                                  /*  Record delta swing for mix mode power tracking */
343                                 pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] =
344                                         -1 * deltaSwingTableIdx_TDOWN_B[delta];
345
346                                 ODM_RT_TRACE(
347                                         pDM_Odm,
348                                         ODM_COMP_TX_PWR_TRACK,
349                                         ODM_DBG_LOUD,
350                                         (
351                                                 "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
352                                                 pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B]
353                                         )
354                                 );
355                         }
356                 }
357
358                 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) {
359                         ODM_RT_TRACE(
360                                 pDM_Odm,
361                                 ODM_COMP_TX_PWR_TRACK,
362                                 ODM_DBG_LOUD,
363                                 (
364                                         "\n\n ================================ [Path-%c] Calculating PowerIndexOffset ================================\n",
365                                         (p == ODM_RF_PATH_A ? 'A' : 'B')
366                                 )
367                         );
368
369                         if (
370                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] ==
371                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]
372                         ) /*  If Thermal value changes but lookup table value still the same */
373                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
374                         else
375                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] - pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p];      /*  Power Index Diff between 2 times Power Tracking */
376
377                         ODM_RT_TRACE(
378                                 pDM_Odm,
379                                 ODM_COMP_TX_PWR_TRACK,
380                                 ODM_DBG_LOUD,
381                                 (
382                                         "[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
383                                         (
384                                                 p == ODM_RF_PATH_A ? 'A' : 'B'),
385                                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p],
386                                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p],
387                                                 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]
388                                         )
389                                 );
390
391                         pDM_Odm->RFCalibrateInfo.OFDM_index[p] =
392                                 pDM_Odm->BbSwingIdxOfdmBase[p] +
393                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p];
394
395                         pDM_Odm->RFCalibrateInfo.CCK_index =
396                                 pDM_Odm->BbSwingIdxCckBase +
397                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p];
398
399                         pDM_Odm->BbSwingIdxCck =
400                                 pDM_Odm->RFCalibrateInfo.CCK_index;
401
402                         pDM_Odm->BbSwingIdxOfdm[p] =
403                                 pDM_Odm->RFCalibrateInfo.OFDM_index[p];
404
405                         /*  *************Print BB Swing Base and Index Offset************* */
406                         ODM_RT_TRACE(
407                                 pDM_Odm,
408                                 ODM_COMP_TX_PWR_TRACK,
409                                 ODM_DBG_LOUD,
410                                 (
411                                         "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
412                                         pDM_Odm->BbSwingIdxCck,
413                                         pDM_Odm->BbSwingIdxCckBase,
414                                         pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]
415                                 )
416                         );
417                         ODM_RT_TRACE(
418                                 pDM_Odm,
419                                 ODM_COMP_TX_PWR_TRACK,
420                                 ODM_DBG_LOUD,
421                                 (
422                                         "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
423                                         pDM_Odm->BbSwingIdxOfdm[p],
424                                         (p == ODM_RF_PATH_A ? 'A' : 'B'),
425                                         pDM_Odm->BbSwingIdxOfdmBase[p],
426                                         pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]
427                                 )
428                         );
429
430                         /* 4 7.1 Handle boundary conditions of index. */
431                         if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] > c.SwingTableSize_OFDM-1)
432                                 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = c.SwingTableSize_OFDM-1;
433                         else if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] < OFDM_min_index)
434                                 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = OFDM_min_index;
435                 }
436                 ODM_RT_TRACE(
437                         pDM_Odm,
438                         ODM_COMP_TX_PWR_TRACK,
439                         ODM_DBG_LOUD,
440                         ("\n\n ========================================================================================================\n")
441                 );
442                 if (pDM_Odm->RFCalibrateInfo.CCK_index > c.SwingTableSize_CCK-1)
443                         pDM_Odm->RFCalibrateInfo.CCK_index = c.SwingTableSize_CCK-1;
444                 /* else if (pDM_Odm->RFCalibrateInfo.CCK_index < 0) */
445                         /* pDM_Odm->RFCalibrateInfo.CCK_index = 0; */
446         } else {
447                 ODM_RT_TRACE(
448                         pDM_Odm,
449                         ODM_COMP_TX_PWR_TRACK,
450                         ODM_DBG_LOUD,
451                         (
452                                 "The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
453                                 pDM_Odm->RFCalibrateInfo.TxPowerTrackControl,
454                                 ThermalValue,
455                                 pDM_Odm->RFCalibrateInfo.ThermalValue
456                         )
457                 );
458
459                         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
460                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
461         }
462         ODM_RT_TRACE(
463                 pDM_Odm,
464                 ODM_COMP_TX_PWR_TRACK,
465                 ODM_DBG_LOUD,
466                 (
467                         "TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
468                         pDM_Odm->RFCalibrateInfo.CCK_index,
469                         pDM_Odm->BbSwingIdxCckBase
470                 )
471         );
472
473         /* Print Swing base & current */
474         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) {
475                 ODM_RT_TRACE(
476                         pDM_Odm,
477                         ODM_COMP_TX_PWR_TRACK,
478                         ODM_DBG_LOUD,
479                         (
480                                 "TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
481                                 pDM_Odm->RFCalibrateInfo.OFDM_index[p],
482                                 (p == ODM_RF_PATH_A ? 'A' : 'B'),
483                                 pDM_Odm->BbSwingIdxOfdmBase[p]
484                         )
485                 );
486         }
487
488         if (
489                 (pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A] != 0 ||
490                  pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_B] != 0) &&
491                  pDM_Odm->RFCalibrateInfo.TxPowerTrackControl
492          ) {
493                 /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
494
495                 pDM_Odm->RFCalibrateInfo.bTxPowerChanged = true; /*  Always true after Tx Power is adjusted by power tracking. */
496                 /*  */
497                 /*  2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
498                 /*  to increase TX power. Otherwise, EVM will be bad. */
499                 /*  */
500                 /*  2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
501                 if (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue) {
502                         ODM_RT_TRACE(
503                                 pDM_Odm,
504                                 ODM_COMP_TX_PWR_TRACK,
505                                 ODM_DBG_LOUD,
506                                 (
507                                         "Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
508                                         pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A],
509                                         delta,
510                                         ThermalValue,
511                                         pHalData->EEPROMThermalMeter,
512                                         pDM_Odm->RFCalibrateInfo.ThermalValue
513                                 )
514                         );
515
516                         if (c.RfPathCount > 1)
517                                 ODM_RT_TRACE(
518                                         pDM_Odm,
519                                         ODM_COMP_TX_PWR_TRACK,
520                                         ODM_DBG_LOUD,
521                                         (
522                                                 "Temperature Increasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
523                                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_B],
524                                                 delta,
525                                                 ThermalValue,
526                                                 pHalData->EEPROMThermalMeter,
527                                                 pDM_Odm->RFCalibrateInfo.ThermalValue
528                                         )
529                                 );
530
531                 } else if (ThermalValue < pDM_Odm->RFCalibrateInfo.ThermalValue) { /*  Low temperature */
532                         ODM_RT_TRACE(
533                                 pDM_Odm,
534                                 ODM_COMP_TX_PWR_TRACK,
535                                 ODM_DBG_LOUD,
536                                 (
537                                         "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
538                                         pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A],
539                                         delta,
540                                         ThermalValue,
541                                         pHalData->EEPROMThermalMeter,
542                                         pDM_Odm->RFCalibrateInfo.ThermalValue
543                                 )
544                         );
545
546                         if (c.RfPathCount > 1)
547                                 ODM_RT_TRACE(
548                                         pDM_Odm,
549                                         ODM_COMP_TX_PWR_TRACK,
550                                         ODM_DBG_LOUD,
551                                         (
552                                                 "Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
553                                                 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_B],
554                                                 delta,
555                                                 ThermalValue,
556                                                 pHalData->EEPROMThermalMeter,
557                                                 pDM_Odm->RFCalibrateInfo.ThermalValue
558                                         )
559                                 );
560
561                 }
562
563                 if (ThermalValue > pHalData->EEPROMThermalMeter) {
564                         ODM_RT_TRACE(
565                                 pDM_Odm,
566                                 ODM_COMP_TX_PWR_TRACK,
567                                 ODM_DBG_LOUD,
568                                 (
569                                         "Temperature(%d) higher than PG value(%d)\n",
570                                         ThermalValue,
571                                         pHalData->EEPROMThermalMeter
572                                 )
573                         );
574
575                         ODM_RT_TRACE(
576                                 pDM_Odm,
577                                 ODM_COMP_TX_PWR_TRACK,
578                                 ODM_DBG_LOUD,
579                                 ("**********Enter POWER Tracking MIX_MODE**********\n")
580                         );
581                         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
582                                         (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0);
583                 } else {
584                         ODM_RT_TRACE(
585                                 pDM_Odm,
586                                 ODM_COMP_TX_PWR_TRACK,
587                                 ODM_DBG_LOUD,
588                                 (
589                                         "Temperature(%d) lower than PG value(%d)\n",
590                                         ThermalValue,
591                                         pHalData->EEPROMThermalMeter
592                                 )
593                         );
594
595                         ODM_RT_TRACE(
596                                 pDM_Odm,
597                                 ODM_COMP_TX_PWR_TRACK,
598                                 ODM_DBG_LOUD,
599                                 ("**********Enter POWER Tracking MIX_MODE**********\n")
600                         );
601                         for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
602                                 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel);
603                 }
604
605                 /*  Record last time Power Tracking result as base. */
606                 pDM_Odm->BbSwingIdxCckBase = pDM_Odm->BbSwingIdxCck;
607                 for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
608                         pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->BbSwingIdxOfdm[p];
609
610                 ODM_RT_TRACE(
611                         pDM_Odm,
612                         ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
613                         (
614                                 "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue = %d\n",
615                                 pDM_Odm->RFCalibrateInfo.ThermalValue,
616                                 ThermalValue
617                         )
618                 );
619
620                 /* Record last Power Tracking Thermal Value */
621                 pDM_Odm->RFCalibrateInfo.ThermalValue = ThermalValue;
622         }
623
624         ODM_RT_TRACE(
625                 pDM_Odm,
626                 ODM_COMP_TX_PWR_TRACK,
627                 ODM_DBG_LOUD,
628                 ("<===ODM_TXPowerTrackingCallback_ThermalMeter\n")
629         );
630
631         pDM_Odm->RFCalibrateInfo.TXPowercount = 0;
632 }
633
634
635
636
637 /* 3 ============================================================ */
638 /* 3 IQ Calibration */
639 /* 3 ============================================================ */
640
641 u8 ODM_GetRightChnlPlaceforIQK(u8 chnl)
642 {
643         u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
644                 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
645                 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
646                 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
647                 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
648                 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
649                 161, 163, 165
650         };
651         u8 place = chnl;
652
653
654         if (chnl > 14) {
655                 for (place = 14; place < sizeof(channel_all); place++) {
656                         if (channel_all[place] == chnl)
657                                 return place-13;
658                 }
659         }
660         return 0;
661
662 }