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