halphyrf_win.c 34 KB

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