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 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26 #include "mp_precomp.h"
27 #include "phydm_precomp.h"
28
29 #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
30 do {\
31 for (_offset = 0; _offset < _size; _offset++) { \
32 if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
33 if (_offset != 0)\
34 _offset--;\
35 break;\
36 } \
37 } \
38 if (_offset >= _size)\
39 _offset = _size-1;\
40 } while (0)
41
configure_txpower_track(void * dm_void,struct txpwrtrack_cfg * config)42 void configure_txpower_track(
43 void *dm_void,
44 struct txpwrtrack_cfg *config
45 )
46 {
47 struct dm_struct *dm = (struct dm_struct *)dm_void;
48 #if RTL8195B_SUPPORT
49 if (dm->support_ic_type == ODM_RTL8195B)
50 configure_txpower_track_8195b(config);
51 #endif
52 #if RTL8710C_SUPPORT
53 if (dm->support_ic_type == ODM_RTL8710C)
54 configure_txpower_track_8710c(config);
55 #endif
56 #if RTL8721D_SUPPORT
57 if (dm->support_ic_type == ODM_RTL8721D)
58 configure_txpower_track_8721d(config);
59 #endif
60
61 }
62
63 /* **********************************************************************
64 * <20121113, Kordan> This function should be called when tx_agc changed.
65 * Otherwise the previous compensation is gone, because we record the
66 * delta of temperature between two TxPowerTracking watch dogs.
67 *
68 * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
69 * need to call this function.
70 * ********************************************************************** */
71 void
odm_clear_txpowertracking_state(void * dm_void)72 odm_clear_txpowertracking_state(
73 void *dm_void
74 )
75 {
76 struct dm_struct *dm = (struct dm_struct *)dm_void;
77 struct _hal_rf_ *rf = &dm->rf_table;
78 u8 p = 0;
79 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
80
81 cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
82 cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
83 dm->rf_calibrate_info.CCK_index = 0;
84
85 for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
86 cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;
87 cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
88 cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
89
90 cali_info->power_index_offset[p] = 0;
91 cali_info->delta_power_index[p] = 0;
92 cali_info->delta_power_index_last[p] = 0;
93
94 cali_info->absolute_ofdm_swing_idx[p] = 0;
95 cali_info->remnant_ofdm_swing_idx[p] = 0;
96 cali_info->kfree_offset[p] = 0;
97 }
98
99 cali_info->modify_tx_agc_flag_path_a = false;
100 cali_info->modify_tx_agc_flag_path_b = false;
101 cali_info->modify_tx_agc_flag_path_c = false;
102 cali_info->modify_tx_agc_flag_path_d = false;
103 cali_info->remnant_cck_swing_idx = 0;
104 cali_info->thermal_value = rf->eeprom_thermal;
105 cali_info->modify_tx_agc_value_cck = 0;
106 cali_info->modify_tx_agc_value_ofdm = 0;
107 }
108
109 void
odm_txpowertracking_callback_thermal_meter(void * dm_void)110 odm_txpowertracking_callback_thermal_meter(
111 void *dm_void
112 )
113 {
114 struct dm_struct *dm = (struct dm_struct *)dm_void;
115 struct _hal_rf_ *rf = &dm->rf_table;
116 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
117 struct dm_iqk_info *iqk_info = &dm->IQK_info;
118
119 u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
120 u8 thermal_value_avg_count = 0;
121 u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
122
123 u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
124 u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(hal_data->current_channel) */
125 u8 power_tracking_type = rf->pwt_type;
126 u8 xtal_offset_eanble = 0;
127 s8 thermal_value_temp = 0;
128 u8 xtal_track_efuse = 0;
129
130 struct txpwrtrack_cfg c = {0};
131
132 /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
133 u8 *delta_swing_table_idx_tup_a = NULL;
134 u8 *delta_swing_table_idx_tdown_a = NULL;
135 u8 *delta_swing_table_idx_tup_b = NULL;
136 u8 *delta_swing_table_idx_tdown_b = NULL;
137 #if (RTL8721D_SUPPORT == 1)
138 u8 *delta_swing_table_idx_tup_a_cck = NULL;
139 u8 *delta_swing_table_idx_tdown_a_cck = NULL;
140 u8 *delta_swing_table_idx_tup_b_cck = NULL;
141 u8 *delta_swing_table_idx_tdown_b_cck = NULL;
142 #endif
143 /*for Xtal Offset by James.Tung*/
144 s8 *delta_swing_table_xtal_up = NULL;
145 s8 *delta_swing_table_xtal_down = NULL;
146
147 /* 4 2. Initialization ( 7 steps in total ) */
148 indexforchannel = odm_get_right_chnl_place_for_iqk(*dm->channel);
149 configure_txpower_track(dm, &c);
150 #if (RTL8721D_SUPPORT == 1)
151 (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
152 (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b,
153 (u8 **)&delta_swing_table_idx_tup_a_cck, (u8 **)&delta_swing_table_idx_tdown_a_cck,
154 (u8 **)&delta_swing_table_idx_tup_b_cck, (u8 **)&delta_swing_table_idx_tdown_b_cck);
155 #else
156 (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
157 (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
158 #endif
159
160 /*for Xtal Offset*/
161 odm_efuse_one_byte_read(dm, 0xf7, &xtal_track_efuse, false);
162 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Read efuse 0xf7=0x%x\n", xtal_track_efuse);
163 xtal_track_efuse = xtal_track_efuse & 0x3;
164 if (dm->support_ic_type == ODM_RTL8195B ||
165 dm->support_ic_type == ODM_RTL8721D ||
166 (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2))
167 (*c.get_delta_swing_xtal_table)(dm,
168 (s8 **)&delta_swing_table_xtal_up,
169 (s8 **)&delta_swing_table_xtal_down);
170
171 cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
172 cali_info->is_txpowertracking_init = true;
173
174 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
175 "===>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",
176 cali_info->bb_swing_idx_cck_base,
177 cali_info->bb_swing_idx_ofdm_base[RF_PATH_A],
178 cali_info->default_ofdm_index);
179
180 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
181 "cali_info->txpowertrack_control = %d, hal_data->eeprom_thermal_meter %d\n",
182 cali_info->txpowertrack_control, rf->eeprom_thermal);
183
184 if (dm->support_ic_type == ODM_RTL8721D
185 || dm->support_ic_type == ODM_RTL8710C)
186 thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A,
187 c.thermal_reg_addr, 0x7e0);
188 /* 0x42: RF Reg[10:5] 8721D */
189 else
190 thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A,
191 c.thermal_reg_addr, 0xfc00);
192 /* 0x42: RF Reg[15:10] 88E */
193
194 thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);
195
196 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
197 "thermal_value_temp(%d) = thermal_value(%d) + power_trim_thermal(%d)\n", thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));
198
199 if (thermal_value_temp > 63)
200 thermal_value = 63;
201 else if (thermal_value_temp < 0)
202 thermal_value = 0;
203 else
204 thermal_value = thermal_value_temp;
205
206 if (!cali_info->txpowertrack_control)
207 return;
208
209 if (rf->eeprom_thermal == 0xff) {
210 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no pg, hal_data->eeprom_thermal_meter = 0x%x\n", rf->eeprom_thermal);
211 return;
212 }
213 #if 0
214 /*4 3. Initialize ThermalValues of rf_calibrate_info*/
215 //if (cali_info->is_reloadtxpowerindex)
216 // RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "reload ofdm index for band switch\n");
217 #endif
218 /*4 4. Calculate average thermal meter*/
219
220 cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] = thermal_value;
221 cali_info->thermal_value_avg_index++;
222 if (cali_info->thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
223 cali_info->thermal_value_avg_index = 0;
224
225 for (i = 0; i < c.average_thermal_num; i++) {
226 if (cali_info->thermal_value_avg[i]) {
227 thermal_value_avg += cali_info->thermal_value_avg[i];
228 thermal_value_avg_count++;
229 }
230 }
231
232 if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
233 thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
234 cali_info->thermal_value_delta = thermal_value - rf->eeprom_thermal;
235 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
236 "AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, rf->eeprom_thermal);
237 }
238
239 /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
240 /* "delta" here is used to determine whether thermal value changes or not. */
241 delta = (thermal_value > cali_info->thermal_value) ? (thermal_value - cali_info->thermal_value) : (cali_info->thermal_value - thermal_value);
242 delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
243 delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
244
245 /*4 6. If necessary, do LCK.*/
246 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);
247
248 /* Wait sacn to do LCK by RF Jenyu*/
249 if ((!*dm->is_scan_in_process) && !iqk_info->rfk_forbidden &&
250 (!*dm->is_tdma)) {
251 /* Delta temperature is equal to or larger than 20 centigrade.*/
252 if (delta_LCK >= c.threshold_iqk) {
253 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
254 cali_info->thermal_value_lck = thermal_value;
255
256 /*Use RTLCK, so close power tracking driver LCK*/
257 (*c.phy_lc_calibrate)(dm);
258 }
259 }
260
261 /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
262 if (delta > 0 && cali_info->txpowertrack_control) {
263 /* "delta" here is used to record the absolute value of difference. */
264 delta = thermal_value > rf->eeprom_thermal ? (thermal_value - rf->eeprom_thermal) : (rf->eeprom_thermal - thermal_value);
265
266 if (delta >= TXPWR_TRACK_TABLE_SIZE)
267 delta = TXPWR_TRACK_TABLE_SIZE - 1;
268
269 /*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
270 if (thermal_value > rf->eeprom_thermal) {
271 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
272 cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
273 switch (p) {
274 case RF_PATH_B:
275 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
276 "delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]);
277 #if (RTL8721D_SUPPORT == 1)
278 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
279 "delta_swing_table_idx_tup_b_cck[%d] = %d\n", delta, delta_swing_table_idx_tup_b_cck[delta]);
280
281 cali_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_b_cck[delta];
282
283 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
284 "******Temp is higher and cali_info->absolute_cck_swing_idx[RF_PATH_B] = %d\n",
285 cali_info->absolute_cck_swing_idx[p]);
286 #endif
287 cali_info->delta_power_index[p] =
288 delta_swing_table_idx_tup_b
289 [delta];
290 cali_info->absolute_ofdm_swing_idx[p] =
291 delta_swing_table_idx_tup_b
292 [delta];
293 /*Record delta swing for mix mode*/
294 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
295 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
296 break;
297
298 default:
299 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
300 "delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]);
301 #if (RTL8721D_SUPPORT == 1)
302 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
303 "delta_swing_table_idx_tup_a_cck[%d] = %d\n", delta, delta_swing_table_idx_tup_a_cck[delta]);
304
305 cali_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_a_cck[delta];
306
307 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
308 "******Temp is higher and cali_info->absolute_cck_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_cck_swing_idx[p]);
309 #endif
310 cali_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
311 cali_info->absolute_ofdm_swing_idx[p] =
312 delta_swing_table_idx_tup_a[delta];
313 /*Record delta swing*/
314 /*for mix mode power tracking*/
315 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
316 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
317 break;
318 }
319 }
320 /* JJ ADD 20161014 */
321 if (dm->support_ic_type == ODM_RTL8195B ||
322 dm->support_ic_type == ODM_RTL8721D ||
323 (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) {
324 /*Save xtal_offset from Xtal table*/
325 cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
326 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
327 "[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]);
328 cali_info->xtal_offset = delta_swing_table_xtal_up[delta];
329 xtal_offset_eanble = (cali_info->xtal_offset_last != cali_info->xtal_offset);
330 }
331
332 } else {
333 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
334 cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
335
336 switch (p) {
337 case RF_PATH_B:
338 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
339 "delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]);
340 #if (RTL8721D_SUPPORT == 1)
341 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
342 "delta_swing_table_idx_tdown_b_cck[%d] = %d\n", delta, delta_swing_table_idx_tdown_b_cck[delta]);
343
344 cali_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b_cck[delta];
345
346 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
347 "******Temp is lower and cali_info->absolute_cck_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_cck_swing_idx[p]);
348 #endif
349 cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
350 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/
351 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
352 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
353 break;
354
355 default:
356 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
357 "delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]);
358 #if (RTL8721D_SUPPORT == 1)
359 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
360 "delta_swing_table_idx_tdown_a_cck[%d] = %d\n", delta, delta_swing_table_idx_tdown_a_cck[delta]);
361
362 cali_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a_cck[delta];
363
364 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
365 "******Temp is lower and cali_info->absolute_cck_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_cck_swing_idx[p]);
366 #endif
367 cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
368 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/
369 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
370 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
371 break;
372 }
373 }
374 /* JJ ADD 20161014 */
375
376 if (dm->support_ic_type == ODM_RTL8195B ||
377 dm->support_ic_type == ODM_RTL8721D ||
378 (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) {
379 /*Save xtal_offset from Xtal table*/
380 cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
381 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
382 "[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]);
383 cali_info->xtal_offset = delta_swing_table_xtal_down[delta];
384 xtal_offset_eanble = (cali_info->xtal_offset_last != cali_info->xtal_offset);
385 }
386 }
387 #if 0
388 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
389 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
390 "\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p);
391
392 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*/
393 cali_info->power_index_offset[p] = 0;
394 else
395 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*/
396
397 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
398 "[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]);
399
400 cali_info->OFDM_index[p] = cali_info->bb_swing_idx_ofdm_base[p] + cali_info->power_index_offset[p];
401 cali_info->CCK_index = cali_info->bb_swing_idx_cck_base + cali_info->power_index_offset[p];
402
403 cali_info->bb_swing_idx_cck = cali_info->CCK_index;
404 cali_info->bb_swing_idx_ofdm[p] = cali_info->OFDM_index[p];
405
406 /*************Print BB Swing base and index Offset*************/
407
408 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
409 "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]);
410 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
411 "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]);
412
413 /*4 7.1 Handle boundary conditions of index.*/
414
415 if (cali_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
416 cali_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
417 else if (cali_info->OFDM_index[p] <= OFDM_min_index)
418 cali_info->OFDM_index[p] = OFDM_min_index;
419 }
420
421 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
422 "\n\n========================================================================================================\n");
423
424 if (cali_info->CCK_index > c.swing_table_size_cck - 1)
425 cali_info->CCK_index = c.swing_table_size_cck - 1;
426 else if (cali_info->CCK_index <= 0)
427 cali_info->CCK_index = 0;
428 #endif
429 } else {
430 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
431 "The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
432 cali_info->txpowertrack_control, thermal_value, cali_info->thermal_value);
433
434 for (p = RF_PATH_A; p < c.rf_path_count; p++)
435 cali_info->power_index_offset[p] = 0;
436 }
437 #if 0
438 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
439 "TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
440 cali_info->CCK_index, cali_info->bb_swing_idx_cck_base); /*Print Swing base & current*/
441
442 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
443 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
444 "TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
445 cali_info->OFDM_index[p], p, cali_info->bb_swing_idx_ofdm_base[p]);
446 }
447 #endif
448
449 #if (RTL8721D_SUPPORT == 1)
450 if (thermal_value != cali_info->thermal_value) {
451 if (thermal_value > rf->eeprom_thermal)
452 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
453 "Temperature(%d) higher than PG value(%d)\n",
454 thermal_value, rf->eeprom_thermal);
455 else if (thermal_value < rf->eeprom_thermal)
456 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
457 "Temperature(%d) lower than PG value(%d)\n",
458 thermal_value, rf->eeprom_thermal);
459
460 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
461 "**********Enter POWER Tracking MIX_MODE**********\n");
462 for (p = RF_PATH_A; p < c.rf_path_count; p++)
463 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
464
465 /*Record last time Power Tracking result as base.*/
466 cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;
467 for (p = RF_PATH_A; p < c.rf_path_count; p++)
468 cali_info->bb_swing_idx_ofdm_base[p] =
469 cali_info->bb_swing_idx_ofdm[p];
470
471 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
472 "cali_info->thermal_value = %d thermal_value= %d\n",
473 cali_info->thermal_value, thermal_value);
474 /*Record last Power Tracking Thermal value*/
475 cali_info->thermal_value = thermal_value;
476 }
477
478 #else
479 if (thermal_value > rf->eeprom_thermal) {
480 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
481 "Temperature(%d) higher than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
482
483 if (dm->support_ic_type == ODM_RTL8188E ||
484 dm->support_ic_type == ODM_RTL8192E ||
485 dm->support_ic_type == ODM_RTL8821 ||
486 dm->support_ic_type == ODM_RTL8812 ||
487 dm->support_ic_type == ODM_RTL8723B ||
488 dm->support_ic_type == ODM_RTL8814A ||
489 dm->support_ic_type == ODM_RTL8703B ||
490 dm->support_ic_type == ODM_RTL8188F ||
491 dm->support_ic_type == ODM_RTL8822B ||
492 dm->support_ic_type == ODM_RTL8723D ||
493 dm->support_ic_type == ODM_RTL8821C ||
494 dm->support_ic_type == ODM_RTL8710B ||
495 dm->support_ic_type == ODM_RTL8192F ||
496 dm->support_ic_type == ODM_RTL8195B ||
497 dm->support_ic_type == ODM_RTL8710C){
498 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
499 for (p = RF_PATH_A; p < c.rf_path_count; p++)
500 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
501 } else {
502 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
503 for (p = RF_PATH_A; p < c.rf_path_count; p++)
504 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
505 }
506 } else {
507 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
508 "Temperature(%d) lower than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
509
510 if (dm->support_ic_type == ODM_RTL8188E ||
511 dm->support_ic_type == ODM_RTL8192E ||
512 dm->support_ic_type == ODM_RTL8821 ||
513 dm->support_ic_type == ODM_RTL8812 ||
514 dm->support_ic_type == ODM_RTL8723B ||
515 dm->support_ic_type == ODM_RTL8814A ||
516 dm->support_ic_type == ODM_RTL8703B ||
517 dm->support_ic_type == ODM_RTL8188F ||
518 dm->support_ic_type == ODM_RTL8822B ||
519 dm->support_ic_type == ODM_RTL8723D ||
520 dm->support_ic_type == ODM_RTL8821C ||
521 dm->support_ic_type == ODM_RTL8710B ||
522 dm->support_ic_type == ODM_RTL8192F ||
523 dm->support_ic_type == ODM_RTL8195B ||
524 dm->support_ic_type == ODM_RTL8710C) {
525 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
526 for (p = RF_PATH_A; p < c.rf_path_count; p++)
527 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, indexforchannel);
528 } else {
529 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
530 for (p = RF_PATH_A; p < c.rf_path_count; p++)
531 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
532 }
533
534 cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
535 for (p = RF_PATH_A; p < c.rf_path_count; p++)
536 cali_info->bb_swing_idx_ofdm_base[p] = cali_info->bb_swing_idx_ofdm[p];
537
538 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
539 "cali_info->thermal_value = %d thermal_value= %d\n", cali_info->thermal_value, thermal_value);
540
541 cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
542 }
543 #endif
544 /* JJ ADD 20161014 */
545 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
546 "cali_info->xtal_offset_last=%d cali_info->xtal_offset=%d\n",
547 cali_info->xtal_offset_last, cali_info->xtal_offset);
548
549 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
550 "xtal_offset_eanble=%d cali_info->txpowertrack_control=%d rf->eeprom_thermal=%d xtal_track_efuse=%d\n",
551 xtal_offset_eanble, cali_info->txpowertrack_control, rf->eeprom_thermal, xtal_track_efuse);
552
553 if (dm->support_ic_type == ODM_RTL8195B ||
554 dm->support_ic_type == ODM_RTL8721D ||
555 (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) {
556 if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (rf->eeprom_thermal != 0xff)) {
557 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n");
558
559 if (thermal_value > rf->eeprom_thermal) {
560 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
561 "Temperature(%d) higher than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
562 (*c.odm_txxtaltrack_set_xtal)(dm);
563 } else {
564 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
565 "Temperature(%d) lower than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
566 (*c.odm_txxtaltrack_set_xtal)(dm);
567 }
568 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********End Xtal Tracking**********\n");
569 }
570 }
571 #if (!RTL8721D_SUPPORT)
572 /* Wait sacn to do IQK by RF Jenyu*/
573 if ((!*dm->is_scan_in_process) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) {
574 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
575 if (delta_IQK >= c.threshold_iqk) {
576 cali_info->thermal_value_iqk = thermal_value;
577 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
578 if (!cali_info->is_iqk_in_progress)
579 (*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
580 }
581 }
582 #endif
583 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===odm_txpowertracking_callback_thermal_meter\n");
584
585 cali_info->tx_powercount = 0;
586 }
587
588 /* 3============================================================
589 * 3 IQ Calibration
590 * 3============================================================
591 */
592
593 void
odm_reset_iqk_result(void * dm_void)594 odm_reset_iqk_result(
595 void *dm_void
596 )
597 {
598 return;
599 }
600
601 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
odm_get_right_chnl_place_for_iqk(u8 chnl)602 u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
603 {
604 u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
605 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
606 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
607 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
608 124, 126, 128, 130, 132, 134, 136, 138, 140,
609 149, 151, 153, 155, 157, 159, 161, 163, 165};
610 u8 place = chnl;
611
612 if (chnl > 14) {
613 for (place = 14; place < sizeof(channel_all); place++) {
614 if (channel_all[place] == chnl)
615 return place - 13;
616 }
617 }
618 return 0;
619 }
620 #endif
621
622 void
odm_rf_calibrate(struct dm_struct * dm)623 odm_rf_calibrate(struct dm_struct *dm)
624 {
625 #if (RTL8721D_SUPPORT == 1)
626 struct dm_iqk_info *iqk_info = &dm->IQK_info;
627
628 if (dm->is_linked && !iqk_info->rfk_forbidden) {
629 if ((*dm->channel != dm->pre_channel) &&
630 (!*dm->is_scan_in_process)) {
631 dm->pre_channel = *dm->channel;
632 dm->linked_interval = 0;
633 }
634
635 if (dm->linked_interval < 3)
636 dm->linked_interval++;
637
638 if (dm->linked_interval == 2)
639 halrf_rf_k_connect_trigger(dm, 0, SEGMENT_FREE);
640 } else {
641 dm->linked_interval = 0;
642 }
643 #endif
644 }
645
phydm_rf_init(void * dm_void)646 void phydm_rf_init(void *dm_void)
647 {
648 struct dm_struct *dm = (struct dm_struct *)dm_void;
649
650 odm_txpowertracking_init(dm);
651
652 odm_clear_txpowertracking_state(dm);
653 }
654
phydm_rf_watchdog(void * dm_void)655 void phydm_rf_watchdog(void *dm_void)
656 {
657 struct dm_struct *dm = (struct dm_struct *)dm_void;
658
659 odm_txpowertracking_check(dm);
660 #if (RTL8721D_SUPPORT == 1)
661 odm_rf_calibrate(dm);
662 #endif
663 }
664