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
16 #include "mp_precomp.h"
17 #include "phydm_precomp.h"
18
19 #define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
20 do {\
21 for (_offset = 0; _offset < _size; _offset++) { \
22 \
23 if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
24 \
25 if (_offset != 0)\
26 _offset--;\
27 break;\
28 } \
29 } \
30 if (_offset >= _size)\
31 _offset = _size-1;\
32 } while (0)
33
configure_txpower_track(struct dm_struct * dm,struct txpwrtrack_cfg * config)34 void configure_txpower_track(
35 struct dm_struct *dm,
36 struct txpwrtrack_cfg *config
37 )
38 {
39 #if RTL8192E_SUPPORT
40 if (dm->support_ic_type == ODM_RTL8192E)
41 configure_txpower_track_8192e(config);
42 #endif
43 #if RTL8821A_SUPPORT
44 if (dm->support_ic_type == ODM_RTL8821)
45 configure_txpower_track_8821a(config);
46 #endif
47 #if RTL8812A_SUPPORT
48 if (dm->support_ic_type == ODM_RTL8812)
49 configure_txpower_track_8812a(config);
50 #endif
51 #if RTL8188E_SUPPORT
52 if (dm->support_ic_type == ODM_RTL8188E)
53 configure_txpower_track_8188e(config);
54 #endif
55
56 #if RTL8188F_SUPPORT
57 if (dm->support_ic_type == ODM_RTL8188F)
58 configure_txpower_track_8188f(config);
59 #endif
60
61 #if RTL8723B_SUPPORT
62 if (dm->support_ic_type == ODM_RTL8723B)
63 configure_txpower_track_8723b(config);
64 #endif
65
66 #if RTL8814A_SUPPORT
67 if (dm->support_ic_type == ODM_RTL8814A)
68 configure_txpower_track_8814a(config);
69 #endif
70
71 #if RTL8703B_SUPPORT
72 if (dm->support_ic_type == ODM_RTL8703B)
73 configure_txpower_track_8703b(config);
74 #endif
75
76 #if RTL8822B_SUPPORT
77 if (dm->support_ic_type == ODM_RTL8822B)
78 configure_txpower_track_8822b(config);
79 #endif
80
81 #if RTL8723D_SUPPORT
82 if (dm->support_ic_type == ODM_RTL8723D)
83 configure_txpower_track_8723d(config);
84 #endif
85
86 /* JJ ADD 20161014 */
87 #if RTL8710B_SUPPORT
88 if (dm->support_ic_type == ODM_RTL8710B)
89 configure_txpower_track_8710b(config);
90 #endif
91
92 #if RTL8821C_SUPPORT
93 if (dm->support_ic_type == ODM_RTL8821C)
94 configure_txpower_track_8821c(config);
95 #endif
96
97 #if RTL8192F_SUPPORT
98 if (dm->support_ic_type == ODM_RTL8192F)
99 configure_txpower_track_8192f(config);
100 #endif
101
102 #if RTL8822C_SUPPORT
103 if (dm->support_ic_type == ODM_RTL8822C)
104 configure_txpower_track_8822c(config);
105 #endif
106
107 #if RTL8814B_SUPPORT
108 if (dm->support_ic_type == ODM_RTL8814B)
109 configure_txpower_track_8814b(config);
110 #endif
111
112 #if RTL8723F_SUPPORT
113 if (dm->support_ic_type == ODM_RTL8723F)
114 configure_txpower_track_8723f(config);
115 #endif
116
117 }
118
119 /* **********************************************************************
120 * <20121113, Kordan> This function should be called when tx_agc changed.
121 * Otherwise the previous compensation is gone, because we record the
122 * delta of temperature between two TxPowerTracking watch dogs.
123 *
124 * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
125 * need to call this function.
126 * ********************************************************************** */
127 void
odm_clear_txpowertracking_state(struct dm_struct * dm)128 odm_clear_txpowertracking_state(
129 struct dm_struct *dm
130 )
131 {
132 PHAL_DATA_TYPE hal_data = GET_HAL_DATA((PADAPTER)(dm->adapter));
133 u8 p = 0;
134 struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
135
136 cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
137 cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
138 cali_info->CCK_index = 0;
139
140 for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
141 cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;
142 cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
143 cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
144
145 cali_info->power_index_offset[p] = 0;
146 cali_info->delta_power_index[p] = 0;
147 cali_info->delta_power_index_last[p] = 0;
148
149 cali_info->absolute_ofdm_swing_idx[p] = 0; /* Initial Mix mode power tracking*/
150 cali_info->remnant_ofdm_swing_idx[p] = 0;
151 cali_info->kfree_offset[p] = 0;
152 }
153
154 cali_info->modify_tx_agc_flag_path_a = false; /*Initial at Modify Tx Scaling mode*/
155 cali_info->modify_tx_agc_flag_path_b = false; /*Initial at Modify Tx Scaling mode*/
156 cali_info->modify_tx_agc_flag_path_c = false; /*Initial at Modify Tx Scaling mode*/
157 cali_info->modify_tx_agc_flag_path_d = false; /*Initial at Modify Tx Scaling mode*/
158 cali_info->remnant_cck_swing_idx = 0;
159 cali_info->thermal_value = hal_data->eeprom_thermal_meter;
160
161 cali_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */
162 cali_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */
163
164 }
165
166 void
odm_txpowertracking_callback_thermal_meter(struct dm_struct * dm)167 odm_txpowertracking_callback_thermal_meter(
168 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
169 struct dm_struct *dm
170 #else
171 void *adapter
172 #endif
173 )
174 {
175 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
176 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
177 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
178 struct dm_struct *dm = &hal_data->DM_OutSrc;
179 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
180 struct dm_struct *dm = &hal_data->odmpriv;
181 #endif
182 #endif
183
184 struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
185 struct dm_iqk_info *iqk_info = &dm->IQK_info;
186 struct _hal_rf_ *rf = &(dm->rf_table);
187 u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
188 s8 diff_DPK[4] = {0};
189 u8 thermal_value_avg_count = 0;
190 u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4, regc88, rege14, reg848,reg838, reg86c;
191
192 u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
193 u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(hal_data->current_channel) */
194 u8 power_tracking_type = hal_data->RfPowerTrackingType;
195 u8 xtal_offset_eanble = 0;
196 s8 thermal_value_temp = 0;
197
198 struct txpwrtrack_cfg c;
199
200 /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
201 u8 *delta_swing_table_idx_tup_a = NULL;
202 u8 *delta_swing_table_idx_tdown_a = NULL;
203 u8 *delta_swing_table_idx_tup_b = NULL;
204 u8 *delta_swing_table_idx_tdown_b = NULL;
205 /*for 8814 add by Yu Chen*/
206 u8 *delta_swing_table_idx_tup_c = NULL;
207 u8 *delta_swing_table_idx_tdown_c = NULL;
208 u8 *delta_swing_table_idx_tup_d = NULL;
209 u8 *delta_swing_table_idx_tdown_d = NULL;
210 /*for Xtal Offset by James.Tung*/
211 s8 *delta_swing_table_xtal_up = NULL;
212 s8 *delta_swing_table_xtal_down = NULL;
213
214 /* 4 2. Initilization ( 7 steps in total ) */
215
216 configure_txpower_track(dm, &c);
217
218 (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
219 (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
220
221 if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8814B)) /*for 8814 path C & D*/
222 (*c.get_delta_swing_table8814only)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
223 (u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
224 /* JJ ADD 20161014 */
225 if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B | ODM_RTL8192F)) /*for Xtal Offset*/
226 (*c.get_delta_swing_xtal_table)(dm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down);
227
228
229 cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
230 cali_info->is_txpowertracking_init = true;
231
232 /*cali_info->txpowertrack_control = hal_data->txpowertrack_control;
233 <Kordan> We should keep updating the control variable according to HalData.
234 <Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
235 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
236 #if (MP_DRIVER == 1)
237 #ifndef RTL8723F_SUPPORT
238 cali_info->rega24 = 0x090e1317;
239 #endif
240 #endif
241
242 #elif (DM_ODM_SUPPORT_TYPE & ODM_CE)
243 if (*(dm->mp_mode) == true)
244 cali_info->rega24 = 0x090e1317;
245 #endif
246
247 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
248 "===>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",
249 cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base[RF_PATH_A], cali_info->default_ofdm_index);
250
251 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
252 "cali_info->txpowertrack_control=%d, hal_data->eeprom_thermal_meter %d\n", cali_info->txpowertrack_control, hal_data->eeprom_thermal_meter);
253 thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
254
255 thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);
256
257 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
258 "thermal_value_temp(%d) = thermal_value(%d) + power_time_thermal(%d)\n", thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));
259
260 if (thermal_value_temp > 63)
261 thermal_value = 63;
262 else if (thermal_value_temp < 0)
263 thermal_value = 0;
264 else
265 thermal_value = thermal_value_temp;
266
267 /*add log by zhao he, check c80/c94/c14/ca0 value*/
268 if (dm->support_ic_type == ODM_RTL8723D) {
269 regc80 = odm_get_bb_reg(dm, R_0xc80, MASKDWORD);
270 regcd0 = odm_get_bb_reg(dm, R_0xcd0, MASKDWORD);
271 regcd4 = odm_get_bb_reg(dm, R_0xcd4, MASKDWORD);
272 regab4 = odm_get_bb_reg(dm, R_0xab4, 0x000007FF);
273 RF_DBG(dm, DBG_RF_IQK, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);
274 }
275
276 /* JJ ADD 20161014 */
277 if (dm->support_ic_type == ODM_RTL8710B) {
278 regc80 = odm_get_bb_reg(dm, R_0xc80, MASKDWORD);
279 regcd0 = odm_get_bb_reg(dm, R_0xcd0, MASKDWORD);
280 regcd4 = odm_get_bb_reg(dm, R_0xcd4, MASKDWORD);
281 regab4 = odm_get_bb_reg(dm, R_0xab4, 0x000007FF);
282 RF_DBG(dm, DBG_RF_IQK, "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4);
283 }
284 /* Winnita add 20171205 */
285 if (dm->support_ic_type == ODM_RTL8192F) {
286 regc80 = odm_get_bb_reg(dm, R_0xc80, MASKDWORD);
287 regc88 = odm_get_bb_reg(dm, R_0xc88, MASKDWORD);
288 regab4 = odm_get_bb_reg(dm, R_0xab4, MASKDWORD);
289 rege14 = odm_get_bb_reg(dm, R_0xe14, MASKDWORD);
290 reg848 = odm_get_bb_reg(dm, R_0x848, MASKDWORD);
291 reg838 = odm_get_bb_reg(dm, R_0x838, MASKDWORD);
292 reg86c = odm_get_bb_reg(dm, R_0x86c, MASKDWORD);
293 RF_DBG(dm, DBG_RF_IQK, "0xc80 = 0x%x 0xc88 = 0x%x 0xab4 = 0x%x 0xe14 = 0x%x\n", regc80, regc88, regab4, rege14);
294 RF_DBG(dm, DBG_RF_IQK, "0x848 = 0x%x 0x838 = 0x%x 0x86c = 0x%x\n", reg848, reg838, reg86c);
295 }
296
297 if (!cali_info->txpowertrack_control)
298 return;
299
300 if (hal_data->eeprom_thermal_meter == 0xff) {
301 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no pg, hal_data->eeprom_thermal_meter = 0x%x\n", hal_data->eeprom_thermal_meter);
302 return;
303 }
304
305 /*4 3. Initialize ThermalValues of rf_calibrate_info*/
306
307 if (cali_info->is_reloadtxpowerindex)
308 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "reload ofdm index for band switch\n");
309
310 /*4 4. Calculate average thermal meter*/
311
312 cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] = thermal_value;
313 cali_info->thermal_value_avg_index++;
314 if (cali_info->thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
315 cali_info->thermal_value_avg_index = 0;
316
317 for (i = 0; i < c.average_thermal_num; i++) {
318 if (cali_info->thermal_value_avg[i]) {
319 thermal_value_avg += cali_info->thermal_value_avg[i];
320 thermal_value_avg_count++;
321 }
322 }
323
324 if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
325 thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
326 cali_info->thermal_value_delta = thermal_value - hal_data->eeprom_thermal_meter;
327 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
328 "AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, hal_data->eeprom_thermal_meter);
329 }
330
331 /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
332
333 /* "delta" here is used to determine whether thermal value changes or not. */
334 delta = (thermal_value > cali_info->thermal_value) ? (thermal_value - cali_info->thermal_value) : (cali_info->thermal_value - thermal_value);
335 delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
336 delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
337
338 if (cali_info->thermal_value_iqk == 0xff) { /*no PG, use thermal value for IQK*/
339 cali_info->thermal_value_iqk = thermal_value;
340 delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
341 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no PG, use thermal_value for IQK\n");
342 }
343
344 for (p = RF_PATH_A; p < c.rf_path_count; p++)
345 diff_DPK[p] = (s8)thermal_value - (s8)cali_info->dpk_thermal[p];
346
347 /*4 6. If necessary, do LCK.*/
348
349 if (!(dm->support_ic_type & ODM_RTL8821)) { /*no PG, do LCK at initial status*/
350 if (cali_info->thermal_value_lck == 0xff) {
351 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no PG, do LCK\n");
352 cali_info->thermal_value_lck = thermal_value;
353
354 /*Use RTLCK, so close power tracking driver LCK*/
355 if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {
356 if (c.phy_lc_calibrate)
357 (*c.phy_lc_calibrate)(dm);
358 }
359
360 delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
361 }
362
363 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);
364
365 /* Wait sacn to do LCK by RF Jenyu*/
366 if( (*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
367 /* Delta temperature is equal to or larger than 20 centigrade.*/
368 if (delta_LCK >= c.threshold_iqk) {
369 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
370 cali_info->thermal_value_lck = thermal_value;
371
372 /*Use RTLCK, so close power tracking driver LCK*/
373 if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {
374 if (c.phy_lc_calibrate)
375 (*c.phy_lc_calibrate)(dm);
376 }
377 }
378 }
379 }
380
381 /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
382
383 if (delta > 0 && cali_info->txpowertrack_control) {
384 /* "delta" here is used to record the absolute value of differrence. */
385 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
386 delta = thermal_value > hal_data->eeprom_thermal_meter ? (thermal_value - hal_data->eeprom_thermal_meter) : (hal_data->eeprom_thermal_meter - thermal_value);
387 #else
388 delta = (thermal_value > dm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - dm->priv->pmib->dot11RFEntry.ther) : (dm->priv->pmib->dot11RFEntry.ther - thermal_value);
389 #endif
390 if (delta >= TXPWR_TRACK_TABLE_SIZE)
391 delta = TXPWR_TRACK_TABLE_SIZE - 1;
392
393 /*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
394
395 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
396 if (thermal_value > hal_data->eeprom_thermal_meter) {
397 #else
398 if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
399 #endif
400
401 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
402 cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
403 switch (p) {
404 case RF_PATH_B:
405 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
406 "delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]);
407
408 cali_info->delta_power_index[p] = delta_swing_table_idx_tup_b[delta];
409 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /*Record delta swing for mix mode power tracking*/
410 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
411 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
412 break;
413
414 case RF_PATH_C:
415 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
416 "delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]);
417
418 cali_info->delta_power_index[p] = delta_swing_table_idx_tup_c[delta];
419 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /*Record delta swing for mix mode power tracking*/
420 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
421 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
422 break;
423
424 case RF_PATH_D:
425 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
426 "delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]);
427
428 cali_info->delta_power_index[p] = delta_swing_table_idx_tup_d[delta];
429 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /*Record delta swing for mix mode power tracking*/
430 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
431 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
432 break;
433
434 default:
435 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
436 "delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]);
437
438 cali_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
439 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /*Record delta swing for mix mode power tracking*/
440 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
441 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
442 break;
443 }
444 }
445 /* JJ ADD 20161014 */
446 if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B | ODM_RTL8192F)) {
447 /*Save xtal_offset from Xtal table*/
448 cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
449 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
450 "[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]);
451 cali_info->xtal_offset = delta_swing_table_xtal_up[delta];
452
453 if (cali_info->xtal_offset_last == cali_info->xtal_offset)
454 xtal_offset_eanble = 0;
455 else
456 xtal_offset_eanble = 1;
457 }
458
459 } else {
460 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
461 cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
462
463 switch (p) {
464 case RF_PATH_B:
465 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
466 "delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]);
467 cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
468 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/
469 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
470 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
471 break;
472
473 case RF_PATH_C:
474 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
475 "delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]);
476 cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_c[delta];
477 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /*Record delta swing for mix mode power tracking*/
478 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
479 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
480 break;
481
482 case RF_PATH_D:
483 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
484 "delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]);
485 cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_d[delta];
486 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /*Record delta swing for mix mode power tracking*/
487 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
488 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
489 break;
490
491 default:
492 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
493 "delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]);
494 cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
495 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/
496 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
497 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
498 break;
499 }
500 }
501 /* JJ ADD 20161014 */
502 if (dm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B | ODM_RTL8192F)) {
503 /*Save xtal_offset from Xtal table*/
504 cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/
505 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
506 "[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]);
507 cali_info->xtal_offset = delta_swing_table_xtal_down[delta];
508
509 if (cali_info->xtal_offset_last == cali_info->xtal_offset)
510 xtal_offset_eanble = 0;
511 else
512 xtal_offset_eanble = 1;
513 }
514
515 }
516
517 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
518 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
519 "\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p);
520
521 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*/
522 cali_info->power_index_offset[p] = 0;
523 else
524 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*/
525
526 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
527 "[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]);
528
529 cali_info->OFDM_index[p] = cali_info->bb_swing_idx_ofdm_base[p] + cali_info->power_index_offset[p];
530 cali_info->CCK_index = cali_info->bb_swing_idx_cck_base + cali_info->power_index_offset[p];
531
532 cali_info->bb_swing_idx_cck = cali_info->CCK_index;
533 cali_info->bb_swing_idx_ofdm[p] = cali_info->OFDM_index[p];
534
535 /*************Print BB Swing base and index Offset*************/
536
537 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
538 "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]);
539 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
540 "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]);
541
542 /*4 7.1 Handle boundary conditions of index.*/
543
544 if (cali_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
545 cali_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
546 else if (cali_info->OFDM_index[p] <= OFDM_min_index)
547 cali_info->OFDM_index[p] = OFDM_min_index;
548 }
549
550 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
551 "\n\n========================================================================================================\n");
552
553 if (cali_info->CCK_index > c.swing_table_size_cck - 1)
554 cali_info->CCK_index = c.swing_table_size_cck - 1;
555 else if (cali_info->CCK_index <= 0)
556 cali_info->CCK_index = 0;
557 } else {
558 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
559 "The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
560 cali_info->txpowertrack_control, thermal_value, cali_info->thermal_value);
561
562 for (p = RF_PATH_A; p < c.rf_path_count; p++)
563 cali_info->power_index_offset[p] = 0;
564 }
565
566 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
567 "TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
568 cali_info->CCK_index, cali_info->bb_swing_idx_cck_base); /*Print Swing base & current*/
569
570 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
571 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
572 "TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
573 cali_info->OFDM_index[p], p, cali_info->bb_swing_idx_ofdm_base[p]);
574 }
575
576 if (dm->support_ic_type & ODM_RTL8814B)
577 power_tracking_type = TSSI_MODE;
578
579 if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8814B)) {
580 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "power_tracking_type=%d\n", power_tracking_type);
581
582 if (power_tracking_type == 0) {
583 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
584 for (p = RF_PATH_A; p < c.rf_path_count; p++)
585 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
586 } else if (power_tracking_type == 1) {
587 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n");
588 for (p = RF_PATH_A; p < c.rf_path_count; p++)
589 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_2G_TSSI_5G_MODE, p, 0);
590 } else if (power_tracking_type == 2) {
591 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n");
592 for (p = RF_PATH_A; p < c.rf_path_count; p++)
593 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_5G_TSSI_2G_MODE, p, 0);
594 } else if (power_tracking_type == 3) {
595 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI MODE**********\n");
596 for (p = RF_PATH_A; p < c.rf_path_count; p++)
597 (*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p, 0);
598 }
599 cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
600
601 } else if ((cali_info->power_index_offset[RF_PATH_A] != 0 ||
602 cali_info->power_index_offset[RF_PATH_B] != 0 ||
603 cali_info->power_index_offset[RF_PATH_C] != 0 ||
604 cali_info->power_index_offset[RF_PATH_D] != 0) &&
605 cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {
606 /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
607
608 cali_info->is_tx_power_changed = true; /*Always true after Tx Power is adjusted by power tracking.*/
609 /* */
610 /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
611 /* to increase TX power. Otherwise, EVM will be bad. */
612 /* */
613 /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
614 if (thermal_value > cali_info->thermal_value) {
615 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
616 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
617 "Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
618 p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);
619 }
620 } else if (thermal_value < cali_info->thermal_value) { /*Low temperature*/
621 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
622 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
623 "Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
624 p, cali_info->power_index_offset[p], delta, thermal_value, hal_data->eeprom_thermal_meter, cali_info->thermal_value);
625 }
626 }
627
628 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
629 if (thermal_value > hal_data->eeprom_thermal_meter)
630 #else
631 if (thermal_value > dm->priv->pmib->dot11RFEntry.ther)
632 #endif
633 {
634 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
635 "Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
636
637 if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||
638 dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||
639 dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||
640 dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B ||
641 dm->support_ic_type == ODM_RTL8192F) {
642
643 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
644 for (p = RF_PATH_A; p < c.rf_path_count; p++)
645 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
646 } else {
647 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
648 for (p = RF_PATH_A; p < c.rf_path_count; p++)
649 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
650 }
651 } else {
652 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
653 "Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
654
655 if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type == ODM_RTL8821 ||
656 dm->support_ic_type == ODM_RTL8812 || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8814A ||
657 dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8822B ||
658 dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8710B ||
659 dm->support_ic_type == ODM_RTL8192F) {
660 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
661 for (p = RF_PATH_A; p < c.rf_path_count; p++)
662 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, indexforchannel);
663 } else {
664 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
665 for (p = RF_PATH_A; p < c.rf_path_count; p++)
666 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
667 }
668
669 }
670
671 cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
672 for (p = RF_PATH_A; p < c.rf_path_count; p++)
673 cali_info->bb_swing_idx_ofdm_base[p] = cali_info->bb_swing_idx_ofdm[p];
674
675 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
676 "cali_info->thermal_value = %d thermal_value= %d\n", cali_info->thermal_value, thermal_value);
677
678 cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
679
680 }
681
682
683 if (dm->support_ic_type == ODM_RTL8703B || dm->support_ic_type == ODM_RTL8723D ||
684 dm->support_ic_type == ODM_RTL8192F || dm->support_ic_type == ODM_RTL8710B) {/* JJ ADD 20161014 */
685
686 if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (hal_data->eeprom_thermal_meter != 0xff)) {
687
688 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n");
689
690 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
691 if (thermal_value > hal_data->eeprom_thermal_meter) {
692 #else
693 if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
694 #endif
695 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
696 "Temperature(%d) higher than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
697 (*c.odm_txxtaltrack_set_xtal)(dm);
698 } else {
699 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
700 "Temperature(%d) lower than PG value(%d)\n", thermal_value, hal_data->eeprom_thermal_meter);
701 (*c.odm_txxtaltrack_set_xtal)(dm);
702 }
703 }
704 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********End Xtal Tracking**********\n");
705 }
706
707 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
708
709 /* Wait sacn to do IQK by RF Jenyu*/
710 if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && dm->is_linked) {
711 if (!IS_HARDWARE_TYPE_8723B(adapter)) {
712 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
713 if (delta_IQK >= c.threshold_iqk) {
714 cali_info->thermal_value_iqk = thermal_value;
715 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
716 if (!cali_info->is_iqk_in_progress)
717 (*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
718 }
719 }
720 }
721 if (cali_info->dpk_thermal[RF_PATH_A] != 0) {
722 if (diff_DPK[RF_PATH_A] >= c.threshold_dpk) {
723 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);
724 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));
725 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);
726 } else if ((diff_DPK[RF_PATH_A] <= -1 * c.threshold_dpk)) {
727 s32 value = 0x20 + (diff_DPK[RF_PATH_A] / c.threshold_dpk);
728
729 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);
730 odm_set_bb_reg(dm, R_0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
731 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);
732 } else {
733 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);
734 odm_set_bb_reg(dm, R_0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
735 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);
736 }
737 }
738 if (cali_info->dpk_thermal[RF_PATH_B] != 0) {
739 if (diff_DPK[RF_PATH_B] >= c.threshold_dpk) {
740 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);
741 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));
742 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);
743 } else if ((diff_DPK[RF_PATH_B] <= -1 * c.threshold_dpk)) {
744 s32 value = 0x20 + (diff_DPK[RF_PATH_B] / c.threshold_dpk);
745
746 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);
747 odm_set_bb_reg(dm, R_0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
748 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);
749 } else {
750 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x1);
751 odm_set_bb_reg(dm, R_0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
752 odm_set_bb_reg(dm, R_0x82c, BIT(31), 0x0);
753 }
754 }
755
756 #endif
757
758 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===odm_txpowertracking_callback_thermal_meter\n");
759
760 cali_info->tx_powercount = 0;
761 }
762
763 #if (RTL8822C_SUPPORT == 1 || RTL8814B_SUPPORT == 1 || RTL8723F_SUPPORT == 1)
764 void
765 odm_txpowertracking_new_callback_thermal_meter(void *dm_void)
766 {
767 struct dm_struct *dm = (struct dm_struct *)dm_void;
768 struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
769 struct dm_iqk_info *iqk_info = &dm->IQK_info;
770 struct _hal_rf_ *rf = &dm->rf_table;
771 struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data;
772 u8 thermal_value[MAX_RF_PATH] = {0}, delta[MAX_RF_PATH] = {0};
773 u8 delta_swing_table_idx_tup[DELTA_SWINGIDX_SIZE] = {0};
774 u8 delta_swing_table_idx_tdown[DELTA_SWINGIDX_SIZE] = {0};
775 u8 delta_LCK = 0, delta_IQK = 0, i = 0, j = 0, p;
776 u8 thermal_value_avg_count[MAX_RF_PATH] = {0};
777 u32 thermal_value_avg[MAX_RF_PATH] = {0};
778 s8 thermal_value_temp[MAX_RF_PATH] = {0};
779 u8 tracking_method = MIX_MODE;
780
781 struct txpwrtrack_cfg c;
782
783 u8 *delta_swing_table_idx_tup_a = NULL;
784 u8 *delta_swing_table_idx_tdown_a = NULL;
785 u8 *delta_swing_table_idx_tup_b = NULL;
786 u8 *delta_swing_table_idx_tdown_b = NULL;
787 u8 *delta_swing_table_idx_tup_c = NULL;
788 u8 *delta_swing_table_idx_tdown_c = NULL;
789 u8 *delta_swing_table_idx_tup_d = NULL;
790 u8 *delta_swing_table_idx_tdown_d = NULL;
791
792 configure_txpower_track(dm, &c);
793
794 (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
795 (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
796
797 if (dm->support_ic_type == ODM_RTL8814B) {
798 (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
799 (u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
800 }
801
802 cali_info->txpowertracking_callback_cnt++;
803 cali_info->is_txpowertracking_init = true;
804
805 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
806 "===>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",
807 cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base[RF_PATH_A], cali_info->default_ofdm_index);
808
809 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
810 "cali_info->txpowertrack_control=%d, tssi->thermal[RF_PATH_A]=%d tssi->thermal[RF_PATH_B]=%d\n",
811 cali_info->txpowertrack_control, tssi->thermal[RF_PATH_A], tssi->thermal[RF_PATH_B]);
812
813 if (dm->support_ic_type == ODM_RTL8822C) {
814 for (i = 0; i < c.rf_path_count; i++)
815 thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0x7e); /* 0x42: RF Reg[6:1] Thermal Trim*/
816 } else {
817 for (i = 0; i < c.rf_path_count; i++) {
818 thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
819
820 if (dm->support_ic_type == ODM_RTL8814B) {
821 thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_multi_thermal_offset(dm, i);
822 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
823 "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + multi_thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_multi_thermal_offset(dm, i));
824 } else {
825 thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm);
826 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
827 "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm));
828 }
829
830 if (thermal_value_temp[i] > 63)
831 thermal_value[i] = 63;
832 else if (thermal_value_temp[i] < 0)
833 thermal_value[i] = 0;
834 else
835 thermal_value[i] = thermal_value_temp[i];
836 }
837 }
838
839 if ((tssi->thermal[RF_PATH_A] == 0xff || tssi->thermal[RF_PATH_B] == 0xff)) {
840 for (i = 0; i < c.rf_path_count; i++)
841 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no pg, tssi->thermal[%d] = 0x%x\n",
842 i, tssi->thermal[i]);
843 return;
844 }
845
846 for (j = 0; j < c.rf_path_count; j++) {
847 cali_info->thermal_value_avg_path[j][cali_info->thermal_value_avg_index_path[j]] = thermal_value[j];
848 cali_info->thermal_value_avg_index_path[j]++;
849 if (cali_info->thermal_value_avg_index_path[j] == c.average_thermal_num) /*Average times = c.average_thermal_num*/
850 cali_info->thermal_value_avg_index_path[j] = 0;
851
852
853 for (i = 0; i < c.average_thermal_num; i++) {
854 if (cali_info->thermal_value_avg_path[j][i]) {
855 thermal_value_avg[j] += cali_info->thermal_value_avg_path[j][i];
856 thermal_value_avg_count[j]++;
857 }
858 }
859
860 if (thermal_value_avg_count[j]) { /* Calculate Average thermal_value after average enough times */
861 thermal_value[j] = (u8)(thermal_value_avg[j] / thermal_value_avg_count[j]);
862 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
863 "AVG Thermal Meter = 0x%X, tssi->thermal[%d] = 0x%x\n",
864 thermal_value[j], j, tssi->thermal[j]);
865 }
866 /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
867
868 /* "delta" here is used to determine whether thermal value changes or not. */
869 delta[j] = (thermal_value[j] > cali_info->thermal_value_path[j]) ? (thermal_value[j] - cali_info->thermal_value_path[j]) : (cali_info->thermal_value_path[j] - thermal_value[j]);
870 delta_LCK = (thermal_value[0] > cali_info->thermal_value_lck) ? (thermal_value[0] - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value[0]);
871 delta_IQK = (thermal_value[0] > cali_info->thermal_value_iqk) ? (thermal_value[0] - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value[0]);
872 }
873
874 /*4 6. If necessary, do LCK.*/
875
876 for (i = 0; i < c.rf_path_count; i++)
877 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta[%d], delta_LCK, delta_IQK) = (%d, %d, %d)\n", i, delta[i], delta_LCK, delta_IQK);
878
879 /* Wait sacn to do LCK by RF Jenyu*/
880 if( (*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
881 /* Delta temperature is equal to or larger than 20 centigrade.*/
882 if (delta_LCK >= c.threshold_iqk) {
883 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
884 cali_info->thermal_value_lck = thermal_value[RF_PATH_A];
885
886 /*Use RTLCK, so close power tracking driver LCK*/
887 if ((!(dm->support_ic_type & ODM_RTL8814A)) &&
888 (!(dm->support_ic_type & ODM_RTL8822B)) &&
889 (!(dm->support_ic_type & ODM_RTL8723F))) {
890 if (c.phy_lc_calibrate)
891 (*c.phy_lc_calibrate)(dm);
892 } else
893 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do not do LCK\n");
894 }
895 }
896
897 /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
898 for (i = 0; i < c.rf_path_count; i++) {
899 if (i == RF_PATH_B) {
900 odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_b, DELTA_SWINGIDX_SIZE);
901 odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_b, DELTA_SWINGIDX_SIZE);
902 } else if (i == RF_PATH_C) {
903 odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_c, DELTA_SWINGIDX_SIZE);
904 odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_c, DELTA_SWINGIDX_SIZE);
905 } else if (i == RF_PATH_D) {
906 odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_d, DELTA_SWINGIDX_SIZE);
907 odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_d, DELTA_SWINGIDX_SIZE);
908 } else {
909 odm_move_memory(dm, delta_swing_table_idx_tup, delta_swing_table_idx_tup_a, DELTA_SWINGIDX_SIZE);
910 odm_move_memory(dm, delta_swing_table_idx_tdown, delta_swing_table_idx_tdown_a, DELTA_SWINGIDX_SIZE);
911 }
912
913 cali_info->delta_power_index_last[i] = cali_info->delta_power_index[i]; /*recording poer index offset*/
914 delta[i] = thermal_value[i] > tssi->thermal[i] ? (thermal_value[i] - tssi->thermal[i]) : (tssi->thermal[i] - thermal_value[i]);
915
916 if (delta[i] >= TXPWR_TRACK_TABLE_SIZE)
917 delta[i] = TXPWR_TRACK_TABLE_SIZE - 1;
918
919 if (thermal_value[i] > tssi->thermal[i]) {
920 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
921 "delta_swing_table_idx_tup[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tup[delta[i]], i);
922
923 cali_info->delta_power_index[i] = delta_swing_table_idx_tup[delta[i]];
924 cali_info->absolute_ofdm_swing_idx[i] = delta_swing_table_idx_tup[delta[i]]; /*Record delta swing for mix mode power tracking*/
925 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
926 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[%d]=%d Path=%d\n", delta[i], cali_info->absolute_ofdm_swing_idx[i], i);
927 } else {
928 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
929 "delta_swing_table_idx_tdown[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tdown[delta[i]], i);
930 cali_info->delta_power_index[i] = -1 * delta_swing_table_idx_tdown[delta[i]];
931 cali_info->absolute_ofdm_swing_idx[i] = -1 * delta_swing_table_idx_tdown[delta[i]]; /*Record delta swing for mix mode power tracking*/
932 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
933 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[%d]=%d Path=%d\n", delta[i], cali_info->absolute_ofdm_swing_idx[i], i);
934 }
935 }
936
937 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
938 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*/
939 cali_info->power_index_offset[p] = 0;
940 else
941 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*/
942 }
943
944 #if 0
945 if (dm->support_ic_type == ODM_RTL8822C) {
946 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
947 for (p = RF_PATH_A; p < c.rf_path_count; p++)
948 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
949 } else {
950 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
951 for (p = RF_PATH_A; p < c.rf_path_count; p++)
952 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);
953 }
954 #endif
955 if (*dm->mp_mode == 1) {
956 if (cali_info->txpowertrack_control == 1) {
957 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
958 tracking_method = MIX_MODE;
959 } else if (cali_info->txpowertrack_control == 3) {
960 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");
961 tracking_method = TSSI_MODE;
962 }
963 } else {
964 if (rf->power_track_type >= 0 && rf->power_track_type <= 3) {
965 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
966 tracking_method = MIX_MODE;
967 } else if (rf->power_track_type >= 4 && rf->power_track_type <= 7) {
968 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");
969 tracking_method = TSSI_MODE;
970 }
971 }
972
973 if (dm->support_ic_type == ODM_RTL8822C || dm->support_ic_type == ODM_RTL8814B)
974 for (p = RF_PATH_A; p < c.rf_path_count; p++)
975 (*c.odm_tx_pwr_track_set_pwr)(dm, tracking_method, p, 0);
976
977 /* Wait sacn to do IQK by RF Jenyu*/
978 if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) {
979 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
980 if (delta_IQK >= c.threshold_iqk) {
981 cali_info->thermal_value_iqk = thermal_value[RF_PATH_A];
982 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
983 /*if (!cali_info->is_iqk_in_progress)*/
984 /* (*c.do_iqk)(dm, delta_IQK, thermal_value[RF_PATH_A], 8);*/
985 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do IQK\n");
986
987 /*if (!cali_info->is_iqk_in_progress)*/
988 /* (*c.do_tssi_dck)(dm, true);*/
989 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do TSSI DCK\n");
990 }
991 }
992
993 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===%s\n", __func__);
994
995 cali_info->tx_powercount = 0;
996 }
997 #endif
998
999 /* 3============================================================
1000 * 3 IQ Calibration
1001 * 3============================================================ */
1002
1003 void
1004 odm_reset_iqk_result(
1005 struct dm_struct *dm
1006 )
1007 {
1008 return;
1009 }
1010 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
1011 u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
1012 {
1013 u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
1014 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
1015 };
1016 u8 place = chnl;
1017
1018
1019 if (chnl > 14) {
1020 for (place = 14; place < sizeof(channel_all); place++) {
1021 if (channel_all[place] == chnl)
1022 return place - 13;
1023 }
1024 }
1025 return 0;
1026
1027 }
1028 #endif
1029
1030 void
1031 odm_iq_calibrate(
1032 struct dm_struct *dm
1033 )
1034 {
1035 void *adapter = dm->adapter;
1036 struct dm_iqk_info *iqk_info = &dm->IQK_info;
1037
1038 RF_DBG(dm, DBG_RF_IQK, "=>%s\n",__FUNCTION__);
1039
1040 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1041 if (*dm->is_fcs_mode_enable)
1042 return;
1043 #endif
1044 if (dm->is_linked) {
1045 RF_DBG(dm, DBG_RF_IQK,
1046 "interval=%d ch=%d prech=%d scan=%s rfk_f =%s\n",
1047 dm->linked_interval, *dm->channel, dm->pre_channel,
1048 *dm->is_scan_in_process == TRUE ? "TRUE":"FALSE",
1049 iqk_info->rfk_forbidden == TRUE ? "TRUE":"FALSE");
1050
1051 if (iqk_info->rfk_forbidden) {
1052 RF_DBG(dm, DBG_RF_IQK, "return by rfk_forbidden\n");
1053 return;
1054 }
1055
1056 if (*dm->is_scan_in_process) {
1057 RF_DBG(dm, DBG_RF_IQK, "return by is_scan_in_process\n");
1058 return;
1059 }
1060
1061 if (*dm->channel != dm->pre_channel) {
1062 dm->pre_channel = *dm->channel;
1063 dm->linked_interval = 0;
1064 }
1065
1066 if (dm->linked_interval < 3)
1067 dm->linked_interval++;
1068
1069 if (dm->linked_interval == 2)
1070 PHY_IQCalibrate(adapter, false);
1071 } else {
1072 dm->linked_interval = 0;
1073 RF_DBG(dm, DBG_RF_IQK, "is_linked =%s, interval =%d\n",
1074 dm->is_linked == TRUE ? "TRUE":"FALSE",
1075 dm->linked_interval);
1076 }
1077 }
1078
1079 void phydm_rf_init(struct dm_struct *dm)
1080 {
1081
1082 odm_txpowertracking_init(dm);
1083
1084 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
1085 odm_clear_txpowertracking_state(dm);
1086 #endif
1087
1088 #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
1089 #if (RTL8814A_SUPPORT == 1)
1090 if (dm->support_ic_type & ODM_RTL8814A)
1091 phy_iq_calibrate_8814a_init(dm);
1092 #endif
1093 #endif
1094
1095 }
1096
1097 void phydm_rf_watchdog(struct dm_struct *dm)
1098 {
1099 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
1100 FunctionIn(COMP_MLME);
1101
1102 if (*dm->mp_mode == 1) {
1103 #if (MP_DRIVER == 1)
1104 odm_txpowertracking_check(dm);
1105 #endif
1106 } else {
1107 odm_txpowertracking_check(dm);
1108
1109 if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES))
1110 odm_iq_calibrate(dm);
1111 }
1112 #endif
1113 }
1114