HalPhyRf.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  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. #include "odm_precomp.h"
  21. #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \
  22. do {\
  23. for(_offset = 0; _offset < _size; _offset++)\
  24. {\
  25. if(_deltaThermal < thermalThreshold[_direction][_offset])\
  26. {\
  27. if(_offset != 0)\
  28. _offset--;\
  29. break;\
  30. }\
  31. } \
  32. if(_offset >= _size)\
  33. _offset = _size-1;\
  34. } while(0)
  35. void ConfigureTxpowerTrack(
  36. IN PDM_ODM_T pDM_Odm,
  37. OUT PTXPWRTRACK_CFG pConfig
  38. )
  39. {
  40. #if RTL8192E_SUPPORT
  41. if(pDM_Odm->SupportICType==ODM_RTL8192E)
  42. ConfigureTxpowerTrack_8192E(pConfig);
  43. #endif
  44. #if RTL8821A_SUPPORT
  45. if(pDM_Odm->SupportICType==ODM_RTL8821)
  46. ConfigureTxpowerTrack_8821A(pConfig);
  47. #endif
  48. #if RTL8812A_SUPPORT
  49. if(pDM_Odm->SupportICType==ODM_RTL8812)
  50. ConfigureTxpowerTrack_8812A(pConfig);
  51. #endif
  52. #if RTL8188E_SUPPORT
  53. if(pDM_Odm->SupportICType==ODM_RTL8188E)
  54. ConfigureTxpowerTrack_8188E(pConfig);
  55. #endif
  56. #if RTL8723B_SUPPORT
  57. if(pDM_Odm->SupportICType==ODM_RTL8723B)
  58. ConfigureTxpowerTrack_8723B(pConfig);
  59. #endif
  60. }
  61. //======================================================================
  62. // <20121113, Kordan> This function should be called when TxAGC changed.
  63. // Otherwise the previous compensation is gone, because we record the
  64. // delta of temperature between two TxPowerTracking watch dogs.
  65. //
  66. // NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
  67. // need to call this function.
  68. //======================================================================
  69. VOID
  70. ODM_ClearTxPowerTrackingState(
  71. IN PDM_ODM_T pDM_Odm
  72. )
  73. {
  74. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pDM_Odm->Adapter);
  75. u1Byte p = 0;
  76. pDM_Odm->BbSwingIdxCckBase = pDM_Odm->DefaultCckIndex;
  77. pDM_Odm->BbSwingIdxCck = pDM_Odm->DefaultCckIndex;
  78. pDM_Odm->RFCalibrateInfo.CCK_index = 0;
  79. for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p)
  80. {
  81. pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->DefaultOfdmIndex;
  82. pDM_Odm->BbSwingIdxOfdm[p] = pDM_Odm->DefaultOfdmIndex;
  83. pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pDM_Odm->DefaultOfdmIndex;
  84. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
  85. pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = 0;
  86. pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = 0;
  87. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
  88. pDM_Odm->Aboslute_OFDMSwingIdx[p] = 0; // Initial Mix mode power tracking
  89. pDM_Odm->Remnant_OFDMSwingIdx[p] = 0;
  90. }
  91. pDM_Odm->Modify_TxAGC_Flag_PathA= FALSE; //Initial at Modify Tx Scaling Mode
  92. pDM_Odm->Modify_TxAGC_Flag_PathB= FALSE; //Initial at Modify Tx Scaling Mode
  93. pDM_Odm->Remnant_CCKSwingIdx= 0;
  94. pDM_Odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter;
  95. pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = pHalData->EEPROMThermalMeter;
  96. pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = pHalData->EEPROMThermalMeter;
  97. }
  98. VOID
  99. ODM_TXPowerTrackingCallback_ThermalMeter(
  100. #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
  101. IN PDM_ODM_T pDM_Odm
  102. #else
  103. IN PADAPTER Adapter
  104. #endif
  105. )
  106. {
  107. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  108. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
  109. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  110. PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc;
  111. #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
  112. PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
  113. #endif
  114. #endif
  115. u1Byte ThermalValue = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
  116. u1Byte ThermalValue_AVG_count = 0;
  117. u4Byte ThermalValue_AVG = 0;
  118. u1Byte OFDM_min_index = 0; // OFDM BB Swing should be less than +3.0dB, which is required by Arthur
  119. u1Byte Indexforchannel = 0; // GetRightChnlPlaceforIQK(pHalData->CurrentChannel)
  120. TXPWRTRACK_CFG c;
  121. //4 1. The following TWO tables decide the final index of OFDM/CCK swing table.
  122. pu1Byte deltaSwingTableIdx_TUP_A;
  123. pu1Byte deltaSwingTableIdx_TDOWN_A;
  124. pu1Byte deltaSwingTableIdx_TUP_B;
  125. pu1Byte deltaSwingTableIdx_TDOWN_B;
  126. //4 2. Initilization ( 7 steps in total )
  127. ConfigureTxpowerTrack(pDM_Odm, &c);
  128. (*c.GetDeltaSwingTable)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_A, (pu1Byte*)&deltaSwingTableIdx_TDOWN_A,
  129. (pu1Byte*)&deltaSwingTableIdx_TUP_B, (pu1Byte*)&deltaSwingTableIdx_TDOWN_B);
  130. pDM_Odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; //cosa add for debug
  131. pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = TRUE;
  132. #if (MP_DRIVER == 1)
  133. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  134. pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = pHalData->TxPowerTrackControl; // <Kordan> We should keep updating the control variable according to HalData.
  135. #endif
  136. #if (DM_ODM_SUPPORT_TYPE == ODM_CE)
  137. if ( *(pDM_Odm->mp_mode) == 1)
  138. #endif
  139. // <Kordan> RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files.
  140. pDM_Odm->RFCalibrateInfo.RegA24 = 0x090e1317;
  141. #endif
  142. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  143. ("===>ODM_TXPowerTrackingCallback_ThermalMeter, \
  144. \n pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]: %d, pDM_Odm->DefaultOfdmIndex: %d\n",
  145. pDM_Odm->BbSwingIdxCckBase, pDM_Odm->BbSwingIdxOfdmBase[ODM_RF_PATH_A], pDM_Odm->DefaultOfdmIndex));
  146. ThermalValue = (u1Byte)ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, c.ThermalRegAddr, 0xfc00); //0x42: RF Reg[15:10] 88E
  147. if( ! pDM_Odm->RFCalibrateInfo.TxPowerTrackControl || pHalData->EEPROMThermalMeter == 0 ||
  148. pHalData->EEPROMThermalMeter == 0xFF)
  149. return;
  150. //4 3. Initialize ThermalValues of RFCalibrateInfo
  151. if(pDM_Odm->RFCalibrateInfo.bReloadtxpowerindex)
  152. {
  153. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("reload ofdm index for band switch\n"));
  154. }
  155. //4 4. Calculate average thermal meter
  156. pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue;
  157. pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index++;
  158. if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index == c.AverageThermalNum) //Average times = c.AverageThermalNum
  159. pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
  160. for(i = 0; i < c.AverageThermalNum; i++)
  161. {
  162. if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i])
  163. {
  164. ThermalValue_AVG += pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i];
  165. ThermalValue_AVG_count++;
  166. }
  167. }
  168. if(ThermalValue_AVG_count) //Calculate Average ThermalValue after average enough times
  169. {
  170. ThermalValue = (u1Byte)(ThermalValue_AVG / ThermalValue_AVG_count);
  171. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  172. ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", ThermalValue, pHalData->EEPROMThermalMeter));
  173. }
  174. //4 5. Calculate delta, delta_LCK, delta_IQK.
  175. //"delta" here is used to determine whether thermal value changes or not.
  176. delta = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue):(pDM_Odm->RFCalibrateInfo.ThermalValue - ThermalValue);
  177. delta_LCK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_LCK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_LCK):(pDM_Odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue);
  178. delta_IQK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_IQK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_IQK):(pDM_Odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue);
  179. 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));
  180. //4 6. If necessary, do LCK.
  181. if ((delta_LCK >= c.Threshold_IQK)) // Delta temperature is equal to or larger than 20 centigrade.
  182. {
  183. 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));
  184. pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue;
  185. if(c.PHY_LCCalibrate)
  186. (*c.PHY_LCCalibrate)(pDM_Odm);
  187. }
  188. //3 7. If necessary, move the index of swing table to adjust Tx power.
  189. if (delta > 0 && pDM_Odm->RFCalibrateInfo.TxPowerTrackControl)
  190. {
  191. //"delta" here is used to record the absolute value of differrence.
  192. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
  193. delta = ThermalValue > pHalData->EEPROMThermalMeter?(ThermalValue - pHalData->EEPROMThermalMeter):(pHalData->EEPROMThermalMeter - ThermalValue);
  194. #else
  195. delta = (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)?(ThermalValue - pDM_Odm->priv->pmib->dot11RFEntry.ther):(pDM_Odm->priv->pmib->dot11RFEntry.ther - ThermalValue);
  196. #endif
  197. if (delta >= TXSCALE_TABLE_SIZE)
  198. delta = TXSCALE_TABLE_SIZE - 1;
  199. //4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset
  200. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))
  201. if(ThermalValue > pHalData->EEPROMThermalMeter) {
  202. #else
  203. if(ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) {
  204. #endif
  205. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  206. ("deltaSwingTableIdx_TUP_A[%d] = %d\n", delta, deltaSwingTableIdx_TUP_A[delta]));
  207. pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_A] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A];
  208. pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A] = deltaSwingTableIdx_TUP_A[delta];
  209. pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = deltaSwingTableIdx_TUP_A[delta]; // Record delta swing for mix mode power tracking
  210. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A]));
  211. if(c.RfPathCount > 1)
  212. {
  213. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  214. ("deltaSwingTableIdx_TUP_B[%d] = %d\n", delta, deltaSwingTableIdx_TUP_B[delta]));
  215. pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_B] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B];
  216. pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B] = deltaSwingTableIdx_TUP_B[delta];
  217. pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = deltaSwingTableIdx_TUP_B[delta]; // Record delta swing for mix mode power tracking
  218. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B]));
  219. }
  220. }
  221. else {
  222. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  223. ("deltaSwingTableIdx_TDOWN_A[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_A[delta]));
  224. pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_A] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A];
  225. pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_A] = -1 * deltaSwingTableIdx_TDOWN_A[delta];
  226. pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = -1 * deltaSwingTableIdx_TDOWN_A[delta]; // Record delta swing for mix mode power tracking
  227. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A]));
  228. if(c.RfPathCount > 1)
  229. {
  230. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  231. ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_B[delta]));
  232. pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[ODM_RF_PATH_B] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B];
  233. pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[ODM_RF_PATH_B] = -1 * deltaSwingTableIdx_TDOWN_B[delta];
  234. pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = -1 * deltaSwingTableIdx_TDOWN_B[delta]; // Record delta swing for mix mode power tracking
  235. ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B]));
  236. }
  237. }
  238. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  239. {
  240. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  241. ("\n\n================================ [Path-%c] Calculating PowerIndexOffset ================================\n", (p == ODM_RF_PATH_A ? 'A' : 'B')));
  242. if (pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] == pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]) // If Thermal value changes but lookup table value still the same
  243. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
  244. else
  245. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] - pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]; // Power Index Diff between 2 times Power Tracking
  246. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
  247. (p == ODM_RF_PATH_A ? 'A' : 'B'), pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p], pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p],
  248. pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]));
  249. pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pDM_Odm->BbSwingIdxOfdmBase[p] + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p];
  250. pDM_Odm->RFCalibrateInfo.CCK_index = pDM_Odm->BbSwingIdxCckBase + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p];
  251. pDM_Odm->BbSwingIdxCck = pDM_Odm->RFCalibrateInfo.CCK_index;
  252. pDM_Odm->BbSwingIdxOfdm[p] = pDM_Odm->RFCalibrateInfo.OFDM_index[p];
  253. // *************Print BB Swing Base and Index Offset*************
  254. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
  255. pDM_Odm->BbSwingIdxCck, pDM_Odm->BbSwingIdxCckBase, pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]));
  256. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
  257. pDM_Odm->BbSwingIdxOfdm[p], (p == ODM_RF_PATH_A ? 'A' : 'B'), pDM_Odm->BbSwingIdxOfdmBase[p], pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]));
  258. //4 7.1 Handle boundary conditions of index.
  259. if(pDM_Odm->RFCalibrateInfo.OFDM_index[p] > c.SwingTableSize_OFDM-1)
  260. {
  261. pDM_Odm->RFCalibrateInfo.OFDM_index[p] = c.SwingTableSize_OFDM-1;
  262. }
  263. else if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] < OFDM_min_index)
  264. {
  265. pDM_Odm->RFCalibrateInfo.OFDM_index[p] = OFDM_min_index;
  266. }
  267. }
  268. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  269. ("\n\n========================================================================================================\n"));
  270. if(pDM_Odm->RFCalibrateInfo.CCK_index > c.SwingTableSize_CCK-1)
  271. pDM_Odm->RFCalibrateInfo.CCK_index = c.SwingTableSize_CCK-1;
  272. //else if (pDM_Odm->RFCalibrateInfo.CCK_index < 0)
  273. //pDM_Odm->RFCalibrateInfo.CCK_index = 0;
  274. }
  275. else
  276. {
  277. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  278. ("The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
  279. pDM_Odm->RFCalibrateInfo.TxPowerTrackControl, ThermalValue, pDM_Odm->RFCalibrateInfo.ThermalValue));
  280. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  281. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0;
  282. }
  283. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  284. ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
  285. pDM_Odm->RFCalibrateInfo.CCK_index, pDM_Odm->BbSwingIdxCckBase)); //Print Swing base & current
  286. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  287. {
  288. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  289. ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
  290. pDM_Odm->RFCalibrateInfo.OFDM_index[p], (p == ODM_RF_PATH_A ? 'A' : 'B'), pDM_Odm->BbSwingIdxOfdmBase[p]));
  291. }
  292. if ((pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A] != 0 ||
  293. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_B] != 0 ) &&
  294. pDM_Odm->RFCalibrateInfo.TxPowerTrackControl)
  295. {
  296. //4 7.2 Configure the Swing Table to adjust Tx Power.
  297. pDM_Odm->RFCalibrateInfo.bTxPowerChanged = TRUE; // Always TRUE after Tx Power is adjusted by power tracking.
  298. //
  299. // 2012/04/23 MH According to Luke's suggestion, we can not write BB digital
  300. // to increase TX power. Otherwise, EVM will be bad.
  301. //
  302. // 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
  303. if (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue)
  304. {
  305. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  306. ("Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
  307. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A], delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue));
  308. if(c.RfPathCount > 1)
  309. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  310. ("Temperature Increasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
  311. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_B], delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue));
  312. }
  313. else if (ThermalValue < pDM_Odm->RFCalibrateInfo.ThermalValue)// Low temperature
  314. {
  315. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  316. ("Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
  317. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A], delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue));
  318. if(c.RfPathCount > 1)
  319. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  320. ("Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
  321. pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_B], delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue));
  322. }
  323. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  324. if (ThermalValue > pHalData->EEPROMThermalMeter)
  325. #else
  326. if (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)
  327. #endif
  328. {
  329. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  330. ("Temperature(%d) higher than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter));
  331. if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E)
  332. {
  333. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  334. (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, TXAGC, p, 0);
  335. }
  336. else if(pDM_Odm->SupportICType == ODM_RTL8821)
  337. {
  338. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking MIX_MODE**********\n"));
  339. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  340. (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel);
  341. }
  342. else
  343. {
  344. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  345. (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel);
  346. }
  347. }
  348. else
  349. {
  350. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  351. ("Temperature(%d) lower than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter));
  352. if(pDM_Odm->SupportICType == ODM_RTL8821)
  353. {
  354. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking MIX_MODE**********\n"));
  355. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  356. (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel);
  357. }
  358. else
  359. {
  360. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  361. (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel);
  362. }
  363. }
  364. pDM_Odm->BbSwingIdxCckBase = pDM_Odm->BbSwingIdxCck; // Record last time Power Tracking result as base.
  365. for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++)
  366. pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->BbSwingIdxOfdm[p];
  367. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  368. ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", pDM_Odm->RFCalibrateInfo.ThermalValue, ThermalValue));
  369. pDM_Odm->RFCalibrateInfo.ThermalValue = ThermalValue; //Record last Power Tracking Thermal Value
  370. }
  371. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  372. if ((delta_IQK >= c.Threshold_IQK)) // Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).
  373. (*c.DoIQK)(pDM_Odm, delta_IQK, ThermalValue, 8);
  374. #endif
  375. ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("<===ODM_TXPowerTrackingCallback_ThermalMeter\n"));
  376. pDM_Odm->RFCalibrateInfo.TXPowercount = 0;
  377. }
  378. //3============================================================
  379. //3 IQ Calibration
  380. //3============================================================
  381. VOID
  382. ODM_ResetIQKResult(
  383. IN PDM_ODM_T pDM_Odm
  384. )
  385. {
  386. u1Byte i;
  387. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN || DM_ODM_SUPPORT_TYPE == ODM_CE)
  388. PADAPTER Adapter = pDM_Odm->Adapter;
  389. if (!IS_HARDWARE_TYPE_8192D(Adapter))
  390. return;
  391. #endif
  392. ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD,("PHY_ResetIQKResult:: settings regs %d default regs %d\n", (u32)(sizeof(pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting)/sizeof(IQK_MATRIX_REGS_SETTING)), IQK_Matrix_Settings_NUM));
  393. //0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc
  394. for(i = 0; i < IQK_Matrix_Settings_NUM; i++)
  395. {
  396. {
  397. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][0] =
  398. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][2] =
  399. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][4] =
  400. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][6] = 0x100;
  401. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][1] =
  402. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][3] =
  403. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][5] =
  404. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].Value[0][7] = 0x0;
  405. pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[i].bIQKDone = FALSE;
  406. }
  407. }
  408. }
  409. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  410. u1Byte ODM_GetRightChnlPlaceforIQK(u1Byte chnl)
  411. {
  412. u1Byte channel_all[ODM_TARGET_CHNL_NUM_2G_5G] =
  413. {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};
  414. u1Byte place = chnl;
  415. if(chnl > 14)
  416. {
  417. for(place = 14; place<sizeof(channel_all); place++)
  418. {
  419. if(channel_all[place] == chnl)
  420. {
  421. return place-13;
  422. }
  423. }
  424. }
  425. return 0;
  426. }
  427. #endif