halphyrf_ce.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  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 "mp_precomp.h"
  21. #include "phydm_precomp.h"
  22. #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
  23. do {\
  24. for (_offset = 0; _offset < _size; _offset++) { \
  25. \
  26. if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
  27. \
  28. if (_offset != 0)\
  29. _offset--;\
  30. break;\
  31. } \
  32. } \
  33. if (_offset >= _size)\
  34. _offset = _size-1;\
  35. } while (0)
  36. void configure_txpower_track(
  37. void *p_dm_void,
  38. struct _TXPWRTRACK_CFG *p_config
  39. )
  40. {
  41. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  42. #if RTL8192E_SUPPORT
  43. if (p_dm_odm->support_ic_type == ODM_RTL8192E)
  44. configure_txpower_track_8192e(p_config);
  45. #endif
  46. #if RTL8821A_SUPPORT
  47. if (p_dm_odm->support_ic_type == ODM_RTL8821)
  48. configure_txpower_track_8821a(p_config);
  49. #endif
  50. #if RTL8812A_SUPPORT
  51. if (p_dm_odm->support_ic_type == ODM_RTL8812)
  52. configure_txpower_track_8812a(p_config);
  53. #endif
  54. #if RTL8188E_SUPPORT
  55. if (p_dm_odm->support_ic_type == ODM_RTL8188E)
  56. configure_txpower_track_8188e(p_config);
  57. #endif
  58. #if RTL8723B_SUPPORT
  59. if (p_dm_odm->support_ic_type == ODM_RTL8723B)
  60. configure_txpower_track_8723b(p_config);
  61. #endif
  62. #if RTL8814A_SUPPORT
  63. if (p_dm_odm->support_ic_type == ODM_RTL8814A)
  64. configure_txpower_track_8814a(p_config);
  65. #endif
  66. #if RTL8703B_SUPPORT
  67. if (p_dm_odm->support_ic_type == ODM_RTL8703B)
  68. configure_txpower_track_8703b(p_config);
  69. #endif
  70. #if RTL8188F_SUPPORT
  71. if (p_dm_odm->support_ic_type == ODM_RTL8188F)
  72. configure_txpower_track_8188f(p_config);
  73. #endif
  74. #if RTL8723D_SUPPORT
  75. if (p_dm_odm->support_ic_type == ODM_RTL8723D)
  76. configure_txpower_track_8723d(p_config);
  77. #endif
  78. /* JJ ADD 20161014 */
  79. #if RTL8710B_SUPPORT
  80. if (p_dm_odm->support_ic_type == ODM_RTL8710B)
  81. configure_txpower_track_8710b(p_config);
  82. #endif
  83. #if RTL8822B_SUPPORT
  84. if (p_dm_odm->support_ic_type == ODM_RTL8822B)
  85. configure_txpower_track_8822b(p_config);
  86. #endif
  87. #if RTL8821C_SUPPORT
  88. if (p_dm_odm->support_ic_type == ODM_RTL8821C)
  89. configure_txpower_track_8821c(p_config);
  90. #endif
  91. }
  92. /* **********************************************************************
  93. * <20121113, Kordan> This function should be called when tx_agc changed.
  94. * Otherwise the previous compensation is gone, because we record the
  95. * delta of temperature between two TxPowerTracking watch dogs.
  96. *
  97. * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
  98. * need to call this function.
  99. * ********************************************************************** */
  100. void
  101. odm_clear_txpowertracking_state(
  102. void *p_dm_void
  103. )
  104. {
  105. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  106. PHAL_DATA_TYPE p_hal_data = GET_HAL_DATA(p_dm_odm->adapter);
  107. u8 p = 0;
  108. struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
  109. p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->default_cck_index;
  110. p_rf_calibrate_info->bb_swing_idx_cck = p_rf_calibrate_info->default_cck_index;
  111. p_dm_odm->rf_calibrate_info.CCK_index = 0;
  112. for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
  113. p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] = p_rf_calibrate_info->default_ofdm_index;
  114. p_rf_calibrate_info->bb_swing_idx_ofdm[p] = p_rf_calibrate_info->default_ofdm_index;
  115. p_rf_calibrate_info->OFDM_index[p] = p_rf_calibrate_info->default_ofdm_index;
  116. p_rf_calibrate_info->power_index_offset[p] = 0;
  117. p_rf_calibrate_info->delta_power_index[p] = 0;
  118. p_rf_calibrate_info->delta_power_index_last[p] = 0;
  119. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = 0; /* Initial Mix mode power tracking*/
  120. p_rf_calibrate_info->remnant_ofdm_swing_idx[p] = 0;
  121. p_rf_calibrate_info->kfree_offset[p] = 0;
  122. }
  123. p_rf_calibrate_info->modify_tx_agc_flag_path_a = false; /*Initial at Modify Tx Scaling mode*/
  124. p_rf_calibrate_info->modify_tx_agc_flag_path_b = false; /*Initial at Modify Tx Scaling mode*/
  125. p_rf_calibrate_info->modify_tx_agc_flag_path_c = false; /*Initial at Modify Tx Scaling mode*/
  126. p_rf_calibrate_info->modify_tx_agc_flag_path_d = false; /*Initial at Modify Tx Scaling mode*/
  127. p_rf_calibrate_info->remnant_cck_swing_idx = 0;
  128. p_rf_calibrate_info->thermal_value = p_hal_data->eeprom_thermal_meter;
  129. p_rf_calibrate_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */
  130. p_rf_calibrate_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */
  131. }
  132. void
  133. odm_txpowertracking_callback_thermal_meter(
  134. #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
  135. struct PHY_DM_STRUCT *p_dm_odm
  136. #else
  137. struct _ADAPTER *adapter
  138. #endif
  139. )
  140. {
  141. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  142. HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
  143. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  144. struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->DM_OutSrc;
  145. #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
  146. struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
  147. #endif
  148. #endif
  149. struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
  150. u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
  151. s8 diff_DPK[4] = {0};
  152. u8 thermal_value_avg_count = 0;
  153. u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
  154. u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
  155. u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(p_hal_data->current_channel) */
  156. u8 power_tracking_type = p_hal_data->rf_power_tracking_type;
  157. u8 xtal_offset_eanble = 0;
  158. s8 thermal_value_temp = 0;
  159. struct _TXPWRTRACK_CFG c;
  160. /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
  161. u8 *delta_swing_table_idx_tup_a = NULL;
  162. u8 *delta_swing_table_idx_tdown_a = NULL;
  163. u8 *delta_swing_table_idx_tup_b = NULL;
  164. u8 *delta_swing_table_idx_tdown_b = NULL;
  165. /*for 8814 add by Yu Chen*/
  166. u8 *delta_swing_table_idx_tup_c = NULL;
  167. u8 *delta_swing_table_idx_tdown_c = NULL;
  168. u8 *delta_swing_table_idx_tup_d = NULL;
  169. u8 *delta_swing_table_idx_tdown_d = NULL;
  170. /*for Xtal Offset by James.Tung*/
  171. s8 *delta_swing_table_xtal_up = NULL;
  172. s8 *delta_swing_table_xtal_down = NULL;
  173. /* 4 2. Initilization ( 7 steps in total ) */
  174. configure_txpower_track(p_dm_odm, &c);
  175. (*c.get_delta_swing_table)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
  176. (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
  177. if (p_dm_odm->support_ic_type & ODM_RTL8814A) /*for 8814 path C & D*/
  178. (*c.get_delta_swing_table8814only)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
  179. (u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
  180. /* JJ ADD 20161014 */
  181. if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) /*for Xtal Offset*/
  182. (*c.get_delta_swing_xtal_table)(p_dm_odm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down);
  183. p_rf_calibrate_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
  184. p_rf_calibrate_info->is_txpowertracking_init = true;
  185. /*p_rf_calibrate_info->txpowertrack_control = p_hal_data->txpowertrack_control;
  186. <Kordan> We should keep updating the control variable according to HalData.
  187. <Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
  188. #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
  189. #if (MP_DRIVER == 1)
  190. p_rf_calibrate_info->rega24 = 0x090e1317;
  191. #endif
  192. #elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
  193. if (p_dm_odm->mp_mode == true)
  194. p_rf_calibrate_info->rega24 = 0x090e1317;
  195. #endif
  196. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  197. ("===>odm_txpowertracking_callback_thermal_meter\n p_rf_calibrate_info->bb_swing_idx_cck_base: %d, p_rf_calibrate_info->bb_swing_idx_ofdm_base[A]: %d, p_rf_calibrate_info->default_ofdm_index: %d\n",
  198. p_rf_calibrate_info->bb_swing_idx_cck_base, p_rf_calibrate_info->bb_swing_idx_ofdm_base[ODM_RF_PATH_A], p_rf_calibrate_info->default_ofdm_index));
  199. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  200. ("p_rf_calibrate_info->txpowertrack_control=%d, p_hal_data->eeprom_thermal_meter %d\n", p_rf_calibrate_info->txpowertrack_control, p_hal_data->eeprom_thermal_meter));
  201. thermal_value = (u8)odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
  202. thermal_value_temp = thermal_value + phydm_get_thermal_offset(p_dm_odm);
  203. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  204. ("thermal_value_temp(%d) thermal_value(%d) power_time_thermal(%d)\n", thermal_value_temp, thermal_value, phydm_get_thermal_offset(p_dm_odm)));
  205. if (thermal_value_temp > 63)
  206. thermal_value = 63;
  207. else if (thermal_value_temp < 0)
  208. thermal_value = 0;
  209. else
  210. thermal_value = thermal_value_temp;
  211. /*add log by zhao he, check c80/c94/c14/ca0 value*/
  212. if (p_dm_odm->support_ic_type == ODM_RTL8723D) {
  213. regc80 = odm_get_bb_reg(p_dm_odm, 0xc80, MASKDWORD);
  214. regcd0 = odm_get_bb_reg(p_dm_odm, 0xcd0, MASKDWORD);
  215. regcd4 = odm_get_bb_reg(p_dm_odm, 0xcd4, MASKDWORD);
  216. regab4 = odm_get_bb_reg(p_dm_odm, 0xab4, 0x000007FF);
  217. ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4));
  218. }
  219. /* JJ ADD 20161014 */
  220. if (p_dm_odm->support_ic_type == ODM_RTL8710B) {
  221. regc80 = odm_get_bb_reg(p_dm_odm, 0xc80, MASKDWORD);
  222. regcd0 = odm_get_bb_reg(p_dm_odm, 0xcd0, MASKDWORD);
  223. regcd4 = odm_get_bb_reg(p_dm_odm, 0xcd4, MASKDWORD);
  224. regab4 = odm_get_bb_reg(p_dm_odm, 0xab4, 0x000007FF);
  225. ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4));
  226. }
  227. if (!p_rf_calibrate_info->txpowertrack_control)
  228. return;
  229. if (p_hal_data->eeprom_thermal_meter == 0xff) {
  230. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no pg, p_hal_data->eeprom_thermal_meter = 0x%x\n", p_hal_data->eeprom_thermal_meter));
  231. return;
  232. }
  233. /*4 3. Initialize ThermalValues of rf_calibrate_info*/
  234. if (p_rf_calibrate_info->is_reloadtxpowerindex)
  235. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("reload ofdm index for band switch\n"));
  236. /*4 4. Calculate average thermal meter*/
  237. p_rf_calibrate_info->thermal_value_avg[p_rf_calibrate_info->thermal_value_avg_index] = thermal_value;
  238. p_rf_calibrate_info->thermal_value_avg_index++;
  239. if (p_rf_calibrate_info->thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
  240. p_rf_calibrate_info->thermal_value_avg_index = 0;
  241. for (i = 0; i < c.average_thermal_num; i++) {
  242. if (p_rf_calibrate_info->thermal_value_avg[i]) {
  243. thermal_value_avg += p_rf_calibrate_info->thermal_value_avg[i];
  244. thermal_value_avg_count++;
  245. }
  246. }
  247. if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
  248. thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
  249. p_rf_calibrate_info->thermal_value_delta = thermal_value - p_hal_data->eeprom_thermal_meter;
  250. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  251. ("AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, p_hal_data->eeprom_thermal_meter));
  252. }
  253. /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
  254. /* "delta" here is used to determine whether thermal value changes or not. */
  255. delta = (thermal_value > p_rf_calibrate_info->thermal_value) ? (thermal_value - p_rf_calibrate_info->thermal_value) : (p_rf_calibrate_info->thermal_value - thermal_value);
  256. delta_LCK = (thermal_value > p_rf_calibrate_info->thermal_value_lck) ? (thermal_value - p_rf_calibrate_info->thermal_value_lck) : (p_rf_calibrate_info->thermal_value_lck - thermal_value);
  257. delta_IQK = (thermal_value > p_rf_calibrate_info->thermal_value_iqk) ? (thermal_value - p_rf_calibrate_info->thermal_value_iqk) : (p_rf_calibrate_info->thermal_value_iqk - thermal_value);
  258. if (p_rf_calibrate_info->thermal_value_iqk == 0xff) { /*no PG, use thermal value for IQK*/
  259. p_rf_calibrate_info->thermal_value_iqk = thermal_value;
  260. delta_IQK = (thermal_value > p_rf_calibrate_info->thermal_value_iqk) ? (thermal_value - p_rf_calibrate_info->thermal_value_iqk) : (p_rf_calibrate_info->thermal_value_iqk - thermal_value);
  261. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, use thermal_value for IQK\n"));
  262. }
  263. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  264. diff_DPK[p] = (s8)thermal_value - (s8)p_rf_calibrate_info->dpk_thermal[p];
  265. /*4 6. If necessary, do LCK.*/
  266. if (!(p_dm_odm->support_ic_type & ODM_RTL8821)) { /*no PG, do LCK at initial status*/
  267. if (p_rf_calibrate_info->thermal_value_lck == 0xff) {
  268. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, do LCK\n"));
  269. p_rf_calibrate_info->thermal_value_lck = thermal_value;
  270. /*Use RTLCK, so close power tracking driver LCK*/
  271. if ((!(p_dm_odm->support_ic_type & ODM_RTL8814A)) && (!(p_dm_odm->support_ic_type & ODM_RTL8822B))) {
  272. if (c.phy_lc_calibrate)
  273. (*c.phy_lc_calibrate)(p_dm_odm);
  274. }
  275. delta_LCK = (thermal_value > p_rf_calibrate_info->thermal_value_lck) ? (thermal_value - p_rf_calibrate_info->thermal_value_lck) : (p_rf_calibrate_info->thermal_value_lck - thermal_value);
  276. }
  277. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK));
  278. /* Wait sacn to do LCK by RF Jenyu*/
  279. if (*p_dm_odm->p_is_scan_in_process == false) {
  280. /* Delta temperature is equal to or larger than 20 centigrade.*/
  281. if (delta_LCK >= c.threshold_iqk) {
  282. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk));
  283. p_rf_calibrate_info->thermal_value_lck = thermal_value;
  284. /*Use RTLCK, so close power tracking driver LCK*/
  285. if ((!(p_dm_odm->support_ic_type & ODM_RTL8814A)) && (!(p_dm_odm->support_ic_type & ODM_RTL8822B))) {
  286. if (c.phy_lc_calibrate)
  287. (*c.phy_lc_calibrate)(p_dm_odm);
  288. }
  289. }
  290. }
  291. }
  292. /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
  293. if (delta > 0 && p_rf_calibrate_info->txpowertrack_control) {
  294. /* "delta" here is used to record the absolute value of differrence. */
  295. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  296. delta = thermal_value > p_hal_data->eeprom_thermal_meter ? (thermal_value - p_hal_data->eeprom_thermal_meter) : (p_hal_data->eeprom_thermal_meter - thermal_value);
  297. #else
  298. delta = (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - p_dm_odm->priv->pmib->dot11RFEntry.ther) : (p_dm_odm->priv->pmib->dot11RFEntry.ther - thermal_value);
  299. #endif
  300. if (delta >= TXPWR_TRACK_TABLE_SIZE)
  301. delta = TXPWR_TRACK_TABLE_SIZE - 1;
  302. /*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
  303. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  304. if (thermal_value > p_hal_data->eeprom_thermal_meter) {
  305. #else
  306. if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther) {
  307. #endif
  308. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
  309. p_rf_calibrate_info->delta_power_index_last[p] = p_rf_calibrate_info->delta_power_index[p]; /*recording poer index offset*/
  310. switch (p) {
  311. case ODM_RF_PATH_B:
  312. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  313. ("delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]));
  314. p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_b[delta];
  315. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /*Record delta swing for mix mode power tracking*/
  316. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  317. ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  318. break;
  319. case ODM_RF_PATH_C:
  320. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  321. ("delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]));
  322. p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_c[delta];
  323. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /*Record delta swing for mix mode power tracking*/
  324. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  325. ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  326. break;
  327. case ODM_RF_PATH_D:
  328. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  329. ("delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]));
  330. p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_d[delta];
  331. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /*Record delta swing for mix mode power tracking*/
  332. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  333. ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  334. break;
  335. default:
  336. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  337. ("delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]));
  338. p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
  339. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /*Record delta swing for mix mode power tracking*/
  340. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  341. ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  342. break;
  343. }
  344. }
  345. /* JJ ADD 20161014 */
  346. if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
  347. /*Save xtal_offset from Xtal table*/
  348. p_rf_calibrate_info->xtal_offset_last = p_rf_calibrate_info->xtal_offset; /*recording last Xtal offset*/
  349. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  350. ("[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]));
  351. p_rf_calibrate_info->xtal_offset = delta_swing_table_xtal_up[delta];
  352. if (p_rf_calibrate_info->xtal_offset_last == p_rf_calibrate_info->xtal_offset)
  353. xtal_offset_eanble = 0;
  354. else
  355. xtal_offset_eanble = 1;
  356. }
  357. } else {
  358. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
  359. p_rf_calibrate_info->delta_power_index_last[p] = p_rf_calibrate_info->delta_power_index[p]; /*recording poer index offset*/
  360. switch (p) {
  361. case ODM_RF_PATH_B:
  362. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  363. ("delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]));
  364. p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
  365. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/
  366. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  367. ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  368. break;
  369. case ODM_RF_PATH_C:
  370. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  371. ("delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]));
  372. p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_c[delta];
  373. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /*Record delta swing for mix mode power tracking*/
  374. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  375. ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  376. break;
  377. case ODM_RF_PATH_D:
  378. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  379. ("delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]));
  380. p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_d[delta];
  381. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /*Record delta swing for mix mode power tracking*/
  382. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  383. ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  384. break;
  385. default:
  386. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  387. ("delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]));
  388. p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
  389. p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/
  390. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  391. ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
  392. break;
  393. }
  394. }
  395. /* JJ ADD 20161014 */
  396. if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
  397. /*Save xtal_offset from Xtal table*/
  398. p_rf_calibrate_info->xtal_offset_last = p_rf_calibrate_info->xtal_offset; /*recording last Xtal offset*/
  399. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  400. ("[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]));
  401. p_rf_calibrate_info->xtal_offset = delta_swing_table_xtal_down[delta];
  402. if (p_rf_calibrate_info->xtal_offset_last == p_rf_calibrate_info->xtal_offset)
  403. xtal_offset_eanble = 0;
  404. else
  405. xtal_offset_eanble = 1;
  406. }
  407. }
  408. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
  409. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  410. ("\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p));
  411. if (p_rf_calibrate_info->delta_power_index[p] == p_rf_calibrate_info->delta_power_index_last[p]) /*If Thermal value changes but lookup table value still the same*/
  412. p_rf_calibrate_info->power_index_offset[p] = 0;
  413. else
  414. p_rf_calibrate_info->power_index_offset[p] = p_rf_calibrate_info->delta_power_index[p] - p_rf_calibrate_info->delta_power_index_last[p]; /*Power index diff between 2 times Power Tracking*/
  415. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  416. ("[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", p, p_rf_calibrate_info->power_index_offset[p], p_rf_calibrate_info->delta_power_index[p], p_rf_calibrate_info->delta_power_index_last[p]));
  417. p_rf_calibrate_info->OFDM_index[p] = p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] + p_rf_calibrate_info->power_index_offset[p];
  418. p_rf_calibrate_info->CCK_index = p_rf_calibrate_info->bb_swing_idx_cck_base + p_rf_calibrate_info->power_index_offset[p];
  419. p_rf_calibrate_info->bb_swing_idx_cck = p_rf_calibrate_info->CCK_index;
  420. p_rf_calibrate_info->bb_swing_idx_ofdm[p] = p_rf_calibrate_info->OFDM_index[p];
  421. /*************Print BB Swing base and index Offset*************/
  422. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  423. ("The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", p_rf_calibrate_info->bb_swing_idx_cck, p_rf_calibrate_info->bb_swing_idx_cck_base, p_rf_calibrate_info->power_index_offset[p]));
  424. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  425. ("The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", p_rf_calibrate_info->bb_swing_idx_ofdm[p], p, p_rf_calibrate_info->bb_swing_idx_ofdm_base[p], p_rf_calibrate_info->power_index_offset[p]));
  426. /*4 7.1 Handle boundary conditions of index.*/
  427. if (p_rf_calibrate_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
  428. p_rf_calibrate_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
  429. else if (p_rf_calibrate_info->OFDM_index[p] <= OFDM_min_index)
  430. p_rf_calibrate_info->OFDM_index[p] = OFDM_min_index;
  431. }
  432. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  433. ("\n\n========================================================================================================\n"));
  434. if (p_rf_calibrate_info->CCK_index > c.swing_table_size_cck - 1)
  435. p_rf_calibrate_info->CCK_index = c.swing_table_size_cck - 1;
  436. else if (p_rf_calibrate_info->CCK_index <= 0)
  437. p_rf_calibrate_info->CCK_index = 0;
  438. } else {
  439. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  440. ("The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, p_rf_calibrate_info->thermal_value: %d\n",
  441. p_rf_calibrate_info->txpowertrack_control, thermal_value, p_rf_calibrate_info->thermal_value));
  442. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  443. p_rf_calibrate_info->power_index_offset[p] = 0;
  444. }
  445. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  446. ("TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
  447. p_rf_calibrate_info->CCK_index, p_rf_calibrate_info->bb_swing_idx_cck_base)); /*Print Swing base & current*/
  448. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
  449. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  450. ("TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
  451. p_rf_calibrate_info->OFDM_index[p], p, p_rf_calibrate_info->bb_swing_idx_ofdm_base[p]));
  452. }
  453. if ((p_dm_odm->support_ic_type & ODM_RTL8814A)) {
  454. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("power_tracking_type=%d\n", power_tracking_type));
  455. if (power_tracking_type == 0) {
  456. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
  457. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  458. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
  459. } else if (power_tracking_type == 1) {
  460. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n"));
  461. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  462. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_2G_TSSI_5G_MODE, p, 0);
  463. } else if (power_tracking_type == 2) {
  464. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n"));
  465. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  466. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_5G_TSSI_2G_MODE, p, 0);
  467. } else if (power_tracking_type == 3) {
  468. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking TSSI MODE**********\n"));
  469. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  470. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, TSSI_MODE, p, 0);
  471. }
  472. p_rf_calibrate_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
  473. } else if ((p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_A] != 0 ||
  474. p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_B] != 0 ||
  475. p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_C] != 0 ||
  476. p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_D] != 0) &&
  477. p_rf_calibrate_info->txpowertrack_control && (p_hal_data->eeprom_thermal_meter != 0xff)) {
  478. /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
  479. p_rf_calibrate_info->is_tx_power_changed = true; /*Always true after Tx Power is adjusted by power tracking.*/
  480. /* */
  481. /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
  482. /* to increase TX power. Otherwise, EVM will be bad. */
  483. /* */
  484. /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
  485. if (thermal_value > p_rf_calibrate_info->thermal_value) {
  486. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
  487. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  488. ("Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
  489. p, p_rf_calibrate_info->power_index_offset[p], delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_rf_calibrate_info->thermal_value));
  490. }
  491. } else if (thermal_value < p_rf_calibrate_info->thermal_value) { /*Low temperature*/
  492. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
  493. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  494. ("Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
  495. p, p_rf_calibrate_info->power_index_offset[p], delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_rf_calibrate_info->thermal_value));
  496. }
  497. }
  498. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  499. if (thermal_value > p_hal_data->eeprom_thermal_meter)
  500. #else
  501. if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther)
  502. #endif
  503. {
  504. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  505. ("Temperature(%d) higher than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
  506. if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8821 ||
  507. p_dm_odm->support_ic_type == ODM_RTL8812 || p_dm_odm->support_ic_type == ODM_RTL8723B || p_dm_odm->support_ic_type == ODM_RTL8814A ||
  508. p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8188F || p_dm_odm->support_ic_type == ODM_RTL8822B ||
  509. p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8821C || p_dm_odm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
  510. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
  511. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  512. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
  513. } else {
  514. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n"));
  515. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  516. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, indexforchannel);
  517. }
  518. } else {
  519. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  520. ("Temperature(%d) lower than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
  521. if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8821 ||
  522. p_dm_odm->support_ic_type == ODM_RTL8812 || p_dm_odm->support_ic_type == ODM_RTL8723B || p_dm_odm->support_ic_type == ODM_RTL8814A ||
  523. p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8188F || p_dm_odm->support_ic_type == ODM_RTL8822B ||
  524. p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8821C || p_dm_odm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
  525. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
  526. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  527. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, indexforchannel);
  528. } else {
  529. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n"));
  530. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  531. (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, indexforchannel);
  532. }
  533. }
  534. p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
  535. for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
  536. p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] = p_rf_calibrate_info->bb_swing_idx_ofdm[p];
  537. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  538. ("p_rf_calibrate_info->thermal_value = %d thermal_value= %d\n", p_rf_calibrate_info->thermal_value, thermal_value));
  539. p_rf_calibrate_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
  540. }
  541. if (p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
  542. if (xtal_offset_eanble != 0 && p_rf_calibrate_info->txpowertrack_control && (p_hal_data->eeprom_thermal_meter != 0xff)) {
  543. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter Xtal Tracking**********\n"));
  544. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  545. if (thermal_value > p_hal_data->eeprom_thermal_meter) {
  546. #else
  547. if (thermal_value > p_dm_odm->priv->pmib->dot11RFEntry.ther) {
  548. #endif
  549. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  550. ("Temperature(%d) higher than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
  551. (*c.odm_txxtaltrack_set_xtal)(p_dm_odm);
  552. } else {
  553. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
  554. ("Temperature(%d) lower than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
  555. (*c.odm_txxtaltrack_set_xtal)(p_dm_odm);
  556. }
  557. }
  558. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********End Xtal Tracking**********\n"));
  559. }
  560. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  561. /* Wait sacn to do IQK by RF Jenyu*/
  562. if (*p_dm_odm->p_is_scan_in_process == false) {
  563. if (!IS_HARDWARE_TYPE_8723B(adapter)) {
  564. /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
  565. if (delta_IQK >= c.threshold_iqk) {
  566. p_rf_calibrate_info->thermal_value_iqk = thermal_value;
  567. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk));
  568. if (!p_rf_calibrate_info->is_iqk_in_progress)
  569. (*c.do_iqk)(p_dm_odm, delta_IQK, thermal_value, 8);
  570. }
  571. }
  572. }
  573. if (p_rf_calibrate_info->dpk_thermal[ODM_RF_PATH_A] != 0) {
  574. if (diff_DPK[ODM_RF_PATH_A] >= c.threshold_dpk) {
  575. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
  576. odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk));
  577. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
  578. } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.threshold_dpk)) {
  579. s32 value = 0x20 + (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk);
  580. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
  581. odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
  582. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
  583. } else {
  584. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
  585. odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
  586. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
  587. }
  588. }
  589. if (p_rf_calibrate_info->dpk_thermal[ODM_RF_PATH_B] != 0) {
  590. if (diff_DPK[ODM_RF_PATH_B] >= c.threshold_dpk) {
  591. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
  592. odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk));
  593. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
  594. } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.threshold_dpk)) {
  595. s32 value = 0x20 + (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk);
  596. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
  597. odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
  598. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
  599. } else {
  600. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
  601. odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
  602. odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
  603. }
  604. }
  605. #endif
  606. ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("<===odm_txpowertracking_callback_thermal_meter\n"));
  607. p_rf_calibrate_info->tx_powercount = 0;
  608. }
  609. /* 3============================================================
  610. * 3 IQ Calibration
  611. * 3============================================================ */
  612. void
  613. odm_reset_iqk_result(
  614. void *p_dm_void
  615. )
  616. {
  617. return;
  618. }
  619. #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
  620. u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
  621. {
  622. u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
  623. 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
  624. };
  625. u8 place = chnl;
  626. if (chnl > 14) {
  627. for (place = 14; place < sizeof(channel_all); place++) {
  628. if (channel_all[place] == chnl)
  629. return place - 13;
  630. }
  631. }
  632. return 0;
  633. }
  634. #endif
  635. void
  636. odm_iq_calibrate(
  637. struct PHY_DM_STRUCT *p_dm_odm
  638. )
  639. {
  640. struct _ADAPTER *adapter = p_dm_odm->adapter;
  641. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  642. if (*p_dm_odm->p_is_fcs_mode_enable)
  643. return;
  644. #endif
  645. #if (DM_ODM_SUPPORT_TYPE & (ODM_CE))
  646. if (IS_HARDWARE_TYPE_8812AU(adapter))
  647. return;
  648. #endif
  649. if (p_dm_odm->is_linked) {
  650. if ((*p_dm_odm->p_channel != p_dm_odm->pre_channel) && (!*p_dm_odm->p_is_scan_in_process)) {
  651. p_dm_odm->pre_channel = *p_dm_odm->p_channel;
  652. p_dm_odm->linked_interval = 0;
  653. }
  654. if (p_dm_odm->linked_interval < 3)
  655. p_dm_odm->linked_interval++;
  656. if (p_dm_odm->linked_interval == 2) {
  657. if (IS_HARDWARE_TYPE_8814A(adapter)) {
  658. #if (RTL8814A_SUPPORT == 1)
  659. phy_iq_calibrate_8814a(p_dm_odm, false);
  660. #endif
  661. }
  662. #if (RTL8822B_SUPPORT == 1)
  663. else if (IS_HARDWARE_TYPE_8822B(adapter))
  664. phy_iq_calibrate_8822b(p_dm_odm, false);
  665. #endif
  666. #if (RTL8821C_SUPPORT == 1)
  667. else if (IS_HARDWARE_TYPE_8821C(adapter))
  668. phy_iq_calibrate_8821c(p_dm_odm, false);
  669. #endif
  670. #if (RTL8821A_SUPPORT == 1)
  671. else if (IS_HARDWARE_TYPE_8821(adapter))
  672. phy_iq_calibrate_8821a(p_dm_odm, false);
  673. #endif
  674. }
  675. } else
  676. p_dm_odm->linked_interval = 0;
  677. }
  678. void phydm_rf_init(void *p_dm_void)
  679. {
  680. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  681. odm_txpowertracking_init(p_dm_odm);
  682. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  683. odm_clear_txpowertracking_state(p_dm_odm);
  684. #endif
  685. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  686. #if (RTL8814A_SUPPORT == 1)
  687. if (p_dm_odm->support_ic_type & ODM_RTL8814A)
  688. phy_iq_calibrate_8814a_init(p_dm_odm);
  689. #endif
  690. #endif
  691. }
  692. void phydm_rf_watchdog(void *p_dm_void)
  693. {
  694. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  695. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  696. odm_txpowertracking_check(p_dm_odm);
  697. /*if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)*/
  698. /*odm_iq_calibrate(p_dm_odm);*/
  699. #endif
  700. }