1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include "mp_precomp.h"
27#include "phydm_precomp.h"
28
29#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, \
30 _delta_thermal) \
31 do { \
32 for (_offset = 0; _offset < _size; _offset++) { \
33 if (_delta_thermal < \
34 thermal_threshold[_direction][_offset]) { \
35 if (_offset != 0) \
36 _offset--; \
37 break; \
38 } \
39 } \
40 if (_offset >= _size) \
41 _offset = _size - 1; \
42 } while (0)
43
44static inline void phydm_set_calibrate_info_up(
45 struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta,
46 struct dm_rf_calibration_struct *cali_info,
47 u8 *delta_swing_table_idx_tup_a, u8 *delta_swing_table_idx_tup_b,
48 u8 *delta_swing_table_idx_tup_c, u8 *delta_swing_table_idx_tup_d)
49{
50 u8 p = 0;
51
52 for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
53 cali_info->delta_power_index_last[p] =
54 cali_info->delta_power_index
55 [p];
56 switch (p) {
57 case ODM_RF_PATH_B:
58 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
59 "delta_swing_table_idx_tup_b[%d] = %d\n",
60 delta, delta_swing_table_idx_tup_b[delta]);
61
62 cali_info->delta_power_index[p] =
63 delta_swing_table_idx_tup_b[delta];
64
65 cali_info->absolute_ofdm_swing_idx[p] =
66 delta_swing_table_idx_tup_b[delta];
67 ODM_RT_TRACE(
68 dm, ODM_COMP_TX_PWR_TRACK,
69 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n",
70 cali_info->absolute_ofdm_swing_idx[p]);
71 break;
72
73 case ODM_RF_PATH_C:
74 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
75 "delta_swing_table_idx_tup_c[%d] = %d\n",
76 delta, delta_swing_table_idx_tup_c[delta]);
77
78 cali_info->delta_power_index[p] =
79 delta_swing_table_idx_tup_c[delta];
80
81 cali_info->absolute_ofdm_swing_idx[p] =
82 delta_swing_table_idx_tup_c[delta];
83 ODM_RT_TRACE(
84 dm, ODM_COMP_TX_PWR_TRACK,
85 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n",
86 cali_info->absolute_ofdm_swing_idx[p]);
87 break;
88
89 case ODM_RF_PATH_D:
90 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
91 "delta_swing_table_idx_tup_d[%d] = %d\n",
92 delta, delta_swing_table_idx_tup_d[delta]);
93
94 cali_info->delta_power_index[p] =
95 delta_swing_table_idx_tup_d[delta];
96
97 cali_info->absolute_ofdm_swing_idx[p] =
98 delta_swing_table_idx_tup_d[delta];
99 ODM_RT_TRACE(
100 dm, ODM_COMP_TX_PWR_TRACK,
101 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n",
102 cali_info->absolute_ofdm_swing_idx[p]);
103 break;
104
105 default:
106 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
107 "delta_swing_table_idx_tup_a[%d] = %d\n",
108 delta, delta_swing_table_idx_tup_a[delta]);
109
110 cali_info->delta_power_index[p] =
111 delta_swing_table_idx_tup_a[delta];
112
113 cali_info->absolute_ofdm_swing_idx[p] =
114 delta_swing_table_idx_tup_a[delta];
115 ODM_RT_TRACE(
116 dm, ODM_COMP_TX_PWR_TRACK,
117 "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n",
118 cali_info->absolute_ofdm_swing_idx[p]);
119 break;
120 }
121 }
122}
123
124static inline void phydm_set_calibrate_info_down(
125 struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta,
126 struct dm_rf_calibration_struct *cali_info,
127 u8 *delta_swing_table_idx_tdown_a, u8 *delta_swing_table_idx_tdown_b,
128 u8 *delta_swing_table_idx_tdown_c, u8 *delta_swing_table_idx_tdown_d)
129{
130 u8 p = 0;
131
132 for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
133 cali_info->delta_power_index_last[p] =
134 cali_info->delta_power_index
135 [p];
136
137 switch (p) {
138 case ODM_RF_PATH_B:
139 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
140 "delta_swing_table_idx_tdown_b[%d] = %d\n",
141 delta,
142 delta_swing_table_idx_tdown_b[delta]);
143 cali_info->delta_power_index[p] =
144 -1 * delta_swing_table_idx_tdown_b[delta];
145
146 cali_info->absolute_ofdm_swing_idx[p] =
147 -1 * delta_swing_table_idx_tdown_b[delta];
148 ODM_RT_TRACE(
149 dm, ODM_COMP_TX_PWR_TRACK,
150 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n",
151 cali_info->absolute_ofdm_swing_idx[p]);
152 break;
153
154 case ODM_RF_PATH_C:
155 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
156 "delta_swing_table_idx_tdown_c[%d] = %d\n",
157 delta,
158 delta_swing_table_idx_tdown_c[delta]);
159 cali_info->delta_power_index[p] =
160 -1 * delta_swing_table_idx_tdown_c[delta];
161
162 cali_info->absolute_ofdm_swing_idx[p] =
163 -1 * delta_swing_table_idx_tdown_c[delta];
164 ODM_RT_TRACE(
165 dm, ODM_COMP_TX_PWR_TRACK,
166 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n",
167 cali_info->absolute_ofdm_swing_idx[p]);
168 break;
169
170 case ODM_RF_PATH_D:
171 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
172 "delta_swing_table_idx_tdown_d[%d] = %d\n",
173 delta,
174 delta_swing_table_idx_tdown_d[delta]);
175 cali_info->delta_power_index[p] =
176 -1 * delta_swing_table_idx_tdown_d[delta];
177
178 cali_info->absolute_ofdm_swing_idx[p] =
179 -1 * delta_swing_table_idx_tdown_d[delta];
180 ODM_RT_TRACE(
181 dm, ODM_COMP_TX_PWR_TRACK,
182 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n",
183 cali_info->absolute_ofdm_swing_idx[p]);
184 break;
185
186 default:
187 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
188 "delta_swing_table_idx_tdown_a[%d] = %d\n",
189 delta,
190 delta_swing_table_idx_tdown_a[delta]);
191 cali_info->delta_power_index[p] =
192 -1 * delta_swing_table_idx_tdown_a[delta];
193
194 cali_info->absolute_ofdm_swing_idx[p] =
195 -1 * delta_swing_table_idx_tdown_a[delta];
196 ODM_RT_TRACE(
197 dm, ODM_COMP_TX_PWR_TRACK,
198 "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n",
199 cali_info->absolute_ofdm_swing_idx[p]);
200 break;
201 }
202 }
203}
204
205static inline void phydm_odm_tx_power_set(struct phy_dm_struct *dm,
206 struct txpwrtrack_cfg *c,
207 u8 indexforchannel, u8 flag)
208{
209 u8 p = 0;
210
211 if (dm->support_ic_type == ODM_RTL8188E ||
212 dm->support_ic_type == ODM_RTL8192E ||
213 dm->support_ic_type == ODM_RTL8821 ||
214 dm->support_ic_type == ODM_RTL8812 ||
215 dm->support_ic_type == ODM_RTL8723B ||
216 dm->support_ic_type == ODM_RTL8814A ||
217 dm->support_ic_type == ODM_RTL8703B ||
218 dm->support_ic_type == ODM_RTL8188F ||
219 dm->support_ic_type == ODM_RTL8822B ||
220 dm->support_ic_type == ODM_RTL8723D ||
221 dm->support_ic_type == ODM_RTL8821C ||
222 dm->support_ic_type == ODM_RTL8710B) {
223
224 ODM_RT_TRACE(
225 dm, ODM_COMP_TX_PWR_TRACK,
226 "**********Enter POWER Tracking MIX_MODE**********\n");
227 for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
228 if (flag == 0)
229 (*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
230 0);
231 else
232 (*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
233 indexforchannel);
234 }
235 } else {
236 ODM_RT_TRACE(
237 dm, ODM_COMP_TX_PWR_TRACK,
238 "**********Enter POWER Tracking BBSWING_MODE**********\n");
239 for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++)
240 (*c->odm_tx_pwr_track_set_pwr)(dm, BBSWING, p,
241 indexforchannel);
242 }
243}
244
245void configure_txpower_track(void *dm_void, struct txpwrtrack_cfg *config)
246{
247 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
248
249
250
251 if (dm->support_ic_type == ODM_RTL8822B)
252 configure_txpower_track_8822b(config);
253}
254
255
256
257
258
259
260
261
262
263void odm_clear_txpowertracking_state(void *dm_void)
264{
265 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
266 struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
267 struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
268 u8 p = 0;
269 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
270
271 cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
272 cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
273 dm->rf_calibrate_info.CCK_index = 0;
274
275 for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
276 cali_info->bb_swing_idx_ofdm_base[p] =
277 cali_info->default_ofdm_index;
278 cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
279 cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
280
281 cali_info->power_index_offset[p] = 0;
282 cali_info->delta_power_index[p] = 0;
283 cali_info->delta_power_index_last[p] = 0;
284
285 cali_info->absolute_ofdm_swing_idx[p] =
286 0;
287 cali_info->remnant_ofdm_swing_idx[p] = 0;
288 cali_info->kfree_offset[p] = 0;
289 }
290
291 cali_info->modify_tx_agc_flag_path_a =
292 false;
293 cali_info->modify_tx_agc_flag_path_b =
294 false;
295 cali_info->modify_tx_agc_flag_path_c =
296 false;
297 cali_info->modify_tx_agc_flag_path_d =
298 false;
299 cali_info->remnant_cck_swing_idx = 0;
300 cali_info->thermal_value = rtlefu->eeprom_thermalmeter;
301
302 cali_info->modify_tx_agc_value_cck = 0;
303 cali_info->modify_tx_agc_value_ofdm = 0;
304}
305
306void odm_txpowertracking_callback_thermal_meter(void *dm_void)
307{
308 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
309 struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
310 struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
311 void *adapter = dm->adapter;
312
313 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
314
315 u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
316 s8 diff_DPK[4];
317 u8 thermal_value_avg_count = 0;
318 u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
319
320
321 u8 OFDM_min_index = 0;
322
323 u8 indexforchannel = 0;
324 u8 power_tracking_type = 0;
325 u8 xtal_offset_eanble = 0;
326
327 struct txpwrtrack_cfg c;
328
329
330
331
332 u8 *delta_swing_table_idx_tup_a = NULL;
333 u8 *delta_swing_table_idx_tdown_a = NULL;
334 u8 *delta_swing_table_idx_tup_b = NULL;
335 u8 *delta_swing_table_idx_tdown_b = NULL;
336
337 u8 *delta_swing_table_idx_tup_c = NULL;
338 u8 *delta_swing_table_idx_tdown_c = NULL;
339 u8 *delta_swing_table_idx_tup_d = NULL;
340 u8 *delta_swing_table_idx_tdown_d = NULL;
341
342 s8 *delta_swing_table_xtal_up = NULL;
343 s8 *delta_swing_table_xtal_down = NULL;
344
345
346
347 configure_txpower_track(dm, &c);
348
349 (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a,
350 (u8 **)&delta_swing_table_idx_tdown_a,
351 (u8 **)&delta_swing_table_idx_tup_b,
352 (u8 **)&delta_swing_table_idx_tdown_b);
353
354 if (dm->support_ic_type & ODM_RTL8814A)
355 (*c.get_delta_swing_table8814only)(
356 dm, (u8 **)&delta_swing_table_idx_tup_c,
357 (u8 **)&delta_swing_table_idx_tdown_c,
358 (u8 **)&delta_swing_table_idx_tup_d,
359 (u8 **)&delta_swing_table_idx_tdown_d);
360
361 if (dm->support_ic_type &
362 (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B))
363 (*c.get_delta_swing_xtal_table)(
364 dm, (s8 **)&delta_swing_table_xtal_up,
365 (s8 **)&delta_swing_table_xtal_down);
366
367 cali_info->txpowertracking_callback_cnt++;
368 cali_info->is_txpowertracking_init = true;
369
370
371
372
373
374
375 if (dm->mp_mode)
376 cali_info->rega24 = 0x090e1317;
377
378 ODM_RT_TRACE(
379 dm, ODM_COMP_TX_PWR_TRACK,
380 "===>%s\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",
381 __func__, cali_info->bb_swing_idx_cck_base,
382 cali_info->bb_swing_idx_ofdm_base[ODM_RF_PATH_A],
383 cali_info->default_ofdm_index);
384
385 ODM_RT_TRACE(
386 dm, ODM_COMP_TX_PWR_TRACK,
387 "cali_info->txpowertrack_control=%d, rtlefu->eeprom_thermalmeter %d\n",
388 cali_info->txpowertrack_control, rtlefu->eeprom_thermalmeter);
389
390 thermal_value =
391 (u8)odm_get_rf_reg(dm, ODM_RF_PATH_A, c.thermal_reg_addr,
392 0xfc00);
393
394
395 if (dm->support_ic_type == ODM_RTL8723D) {
396 regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
397 regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
398 regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
399 regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
400 ODM_RT_TRACE(
401 dm, ODM_COMP_CALIBRATION,
402 "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n",
403 regc80, regcd0, regcd4, regab4);
404 }
405
406 if (dm->support_ic_type == ODM_RTL8710B) {
407 regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
408 regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
409 regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
410 regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
411 ODM_RT_TRACE(
412 dm, ODM_COMP_CALIBRATION,
413 "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n",
414 regc80, regcd0, regcd4, regab4);
415 }
416
417 if (!cali_info->txpowertrack_control)
418 return;
419
420
421
422 if (cali_info->is_reloadtxpowerindex)
423 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
424 "reload ofdm index for band switch\n");
425
426
427
428 cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] =
429 thermal_value;
430 cali_info->thermal_value_avg_index++;
431 if (cali_info->thermal_value_avg_index ==
432 c.average_thermal_num)
433 cali_info->thermal_value_avg_index = 0;
434
435 for (i = 0; i < c.average_thermal_num; i++) {
436 if (cali_info->thermal_value_avg[i]) {
437 thermal_value_avg += cali_info->thermal_value_avg[i];
438 thermal_value_avg_count++;
439 }
440 }
441
442 if (thermal_value_avg_count) {
443
444 thermal_value =
445 (u8)(thermal_value_avg / thermal_value_avg_count);
446 cali_info->thermal_value_delta =
447 thermal_value - rtlefu->eeprom_thermalmeter;
448 ODM_RT_TRACE(
449 dm, ODM_COMP_TX_PWR_TRACK,
450 "AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n",
451 thermal_value, rtlefu->eeprom_thermalmeter);
452 }
453
454
455
456
457 delta = (thermal_value > cali_info->thermal_value) ?
458 (thermal_value - cali_info->thermal_value) :
459 (cali_info->thermal_value - thermal_value);
460 delta_LCK = (thermal_value > cali_info->thermal_value_lck) ?
461 (thermal_value - cali_info->thermal_value_lck) :
462 (cali_info->thermal_value_lck - thermal_value);
463 delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ?
464 (thermal_value - cali_info->thermal_value_iqk) :
465 (cali_info->thermal_value_iqk - thermal_value);
466
467 if (cali_info->thermal_value_iqk ==
468 0xff) {
469 cali_info->thermal_value_iqk = thermal_value;
470 delta_IQK =
471 (thermal_value > cali_info->thermal_value_iqk) ?
472 (thermal_value - cali_info->thermal_value_iqk) :
473 (cali_info->thermal_value_iqk - thermal_value);
474 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
475 "no PG, use thermal_value for IQK\n");
476 }
477
478 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
479 diff_DPK[p] = (s8)thermal_value - (s8)cali_info->dpk_thermal[p];
480
481
482
483 if (!(dm->support_ic_type &
484 ODM_RTL8821)) {
485 if (cali_info->thermal_value_lck == 0xff) {
486 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
487 "no PG, do LCK\n");
488 cali_info->thermal_value_lck = thermal_value;
489
490
491 if (!(dm->support_ic_type & ODM_RTL8814A) &&
492 c.phy_lc_calibrate)
493 (*c.phy_lc_calibrate)(dm);
494
495 delta_LCK =
496 (thermal_value > cali_info->thermal_value_lck) ?
497 (thermal_value -
498 cali_info->thermal_value_lck) :
499 (cali_info->thermal_value_lck -
500 thermal_value);
501 }
502
503 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
504 "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
505 delta, delta_LCK, delta_IQK);
506
507
508 if (delta_LCK >= c.threshold_iqk) {
509 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
510 "delta_LCK(%d) >= threshold_iqk(%d)\n",
511 delta_LCK, c.threshold_iqk);
512 cali_info->thermal_value_lck = thermal_value;
513
514
515 if (!(dm->support_ic_type & ODM_RTL8814A) &&
516 c.phy_lc_calibrate)
517 (*c.phy_lc_calibrate)(dm);
518 }
519 }
520
521
522
523 if (delta > 0 && cali_info->txpowertrack_control) {
524
525 delta = thermal_value > rtlefu->eeprom_thermalmeter ?
526 (thermal_value - rtlefu->eeprom_thermalmeter) :
527 (rtlefu->eeprom_thermalmeter - thermal_value);
528 if (delta >= TXPWR_TRACK_TABLE_SIZE)
529 delta = TXPWR_TRACK_TABLE_SIZE - 1;
530
531
532
533 if (thermal_value > rtlefu->eeprom_thermalmeter) {
534 phydm_set_calibrate_info_up(
535 dm, &c, delta, cali_info,
536 delta_swing_table_idx_tup_a,
537 delta_swing_table_idx_tup_b,
538 delta_swing_table_idx_tup_c,
539 delta_swing_table_idx_tup_d);
540
541 if (dm->support_ic_type &
542 (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
543
544
545
546 cali_info->xtal_offset_last =
547 cali_info->xtal_offset;
548 ODM_RT_TRACE(
549 dm, ODM_COMP_TX_PWR_TRACK,
550 "[Xtal] delta_swing_table_xtal_up[%d] = %d\n",
551 delta,
552 delta_swing_table_xtal_up[delta]);
553 cali_info->xtal_offset =
554 delta_swing_table_xtal_up[delta];
555 xtal_offset_eanble =
556 (cali_info->xtal_offset_last ==
557 cali_info->xtal_offset) ?
558 0 :
559 1;
560 }
561
562 } else {
563 phydm_set_calibrate_info_down(
564 dm, &c, delta, cali_info,
565 delta_swing_table_idx_tdown_a,
566 delta_swing_table_idx_tdown_b,
567 delta_swing_table_idx_tdown_c,
568 delta_swing_table_idx_tdown_d);
569
570 if (dm->support_ic_type &
571 (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
572
573
574
575 cali_info->xtal_offset_last =
576 cali_info->xtal_offset;
577 ODM_RT_TRACE(
578 dm, ODM_COMP_TX_PWR_TRACK,
579 "[Xtal] delta_swing_table_xtal_down[%d] = %d\n",
580 delta,
581 delta_swing_table_xtal_down[delta]);
582 cali_info->xtal_offset =
583 delta_swing_table_xtal_down[delta];
584 xtal_offset_eanble =
585 (cali_info->xtal_offset_last ==
586 cali_info->xtal_offset) ?
587 0 :
588 1;
589 }
590 }
591
592 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
593 ODM_RT_TRACE(
594 dm, ODM_COMP_TX_PWR_TRACK,
595 "\n\n=========================== [path-%d] Calculating power_index_offset===========================\n",
596 p);
597
598 if (cali_info->delta_power_index[p] ==
599 cali_info->delta_power_index_last[p]) {
600
601
602
603 cali_info->power_index_offset[p] = 0;
604 } else {
605
606 cali_info->power_index_offset[p] =
607 cali_info->delta_power_index[p] -
608 cali_info->delta_power_index_last[p];
609 }
610
611 ODM_RT_TRACE(
612 dm, ODM_COMP_TX_PWR_TRACK,
613 "[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n",
614 p, cali_info->power_index_offset[p],
615 cali_info->delta_power_index[p],
616 cali_info->delta_power_index_last[p]);
617
618 cali_info->OFDM_index[p] =
619 cali_info->bb_swing_idx_ofdm_base[p] +
620 cali_info->power_index_offset[p];
621 cali_info->CCK_index =
622 cali_info->bb_swing_idx_cck_base +
623 cali_info->power_index_offset[p];
624
625 cali_info->bb_swing_idx_cck = cali_info->CCK_index;
626 cali_info->bb_swing_idx_ofdm[p] =
627 cali_info->OFDM_index[p];
628
629
630
631 ODM_RT_TRACE(
632 dm, ODM_COMP_TX_PWR_TRACK,
633 "The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n",
634 cali_info->bb_swing_idx_cck,
635 cali_info->bb_swing_idx_cck_base,
636 cali_info->power_index_offset[p]);
637 ODM_RT_TRACE(
638 dm, ODM_COMP_TX_PWR_TRACK,
639 "The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n",
640 cali_info->bb_swing_idx_ofdm[p], p,
641 cali_info->bb_swing_idx_ofdm_base[p],
642 cali_info->power_index_offset[p]);
643
644
645
646 if (cali_info->OFDM_index[p] >
647 c.swing_table_size_ofdm - 1)
648 cali_info->OFDM_index[p] =
649 c.swing_table_size_ofdm - 1;
650 else if (cali_info->OFDM_index[p] <= OFDM_min_index)
651 cali_info->OFDM_index[p] = OFDM_min_index;
652 }
653
654 ODM_RT_TRACE(
655 dm, ODM_COMP_TX_PWR_TRACK,
656 "\n\n========================================================================================================\n");
657
658 if (cali_info->CCK_index > c.swing_table_size_cck - 1)
659 cali_info->CCK_index = c.swing_table_size_cck - 1;
660 else if (cali_info->CCK_index <= 0)
661 cali_info->CCK_index = 0;
662 } else {
663 ODM_RT_TRACE(
664 dm, ODM_COMP_TX_PWR_TRACK,
665 "The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
666 cali_info->txpowertrack_control, thermal_value,
667 cali_info->thermal_value);
668
669 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
670 cali_info->power_index_offset[p] = 0;
671 }
672
673
674 ODM_RT_TRACE(
675 dm, ODM_COMP_TX_PWR_TRACK,
676 "TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
677 cali_info->CCK_index, cali_info->bb_swing_idx_cck_base);
678
679 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
680 ODM_RT_TRACE(
681 dm, ODM_COMP_TX_PWR_TRACK,
682 "TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
683 cali_info->OFDM_index[p], p,
684 cali_info->bb_swing_idx_ofdm_base[p]);
685
686 if ((dm->support_ic_type & ODM_RTL8814A)) {
687 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
688 "power_tracking_type=%d\n", power_tracking_type);
689
690 if (power_tracking_type == 0) {
691 ODM_RT_TRACE(
692 dm, ODM_COMP_TX_PWR_TRACK,
693 "**********Enter POWER Tracking MIX_MODE**********\n");
694 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
695 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
696 0);
697 } else if (power_tracking_type == 1) {
698 ODM_RT_TRACE(
699 dm, ODM_COMP_TX_PWR_TRACK,
700 "**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n");
701 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
702 (*c.odm_tx_pwr_track_set_pwr)(
703 dm, MIX_2G_TSSI_5G_MODE, p, 0);
704 } else if (power_tracking_type == 2) {
705 ODM_RT_TRACE(
706 dm, ODM_COMP_TX_PWR_TRACK,
707 "**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n");
708 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
709 (*c.odm_tx_pwr_track_set_pwr)(
710 dm, MIX_5G_TSSI_2G_MODE, p, 0);
711 } else if (power_tracking_type == 3) {
712 ODM_RT_TRACE(
713 dm, ODM_COMP_TX_PWR_TRACK,
714 "**********Enter POWER Tracking TSSI MODE**********\n");
715 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
716 (*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p,
717 0);
718 }
719
720 cali_info->thermal_value = thermal_value;
721
722 } else if ((cali_info->power_index_offset[ODM_RF_PATH_A] != 0 ||
723 cali_info->power_index_offset[ODM_RF_PATH_B] != 0 ||
724 cali_info->power_index_offset[ODM_RF_PATH_C] != 0 ||
725 cali_info->power_index_offset[ODM_RF_PATH_D] != 0) &&
726 cali_info->txpowertrack_control &&
727 (rtlefu->eeprom_thermalmeter != 0xff)) {
728
729
730
731 cali_info->is_tx_power_changed = true;
732
733
734
735
736
737
738
739 if (thermal_value > cali_info->thermal_value) {
740 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
741
742 ODM_RT_TRACE(
743 dm, ODM_COMP_TX_PWR_TRACK,
744 "Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
745 p, cali_info->power_index_offset[p],
746 delta, thermal_value,
747 rtlefu->eeprom_thermalmeter,
748 cali_info->thermal_value);
749 }
750 } else if (thermal_value <
751 cali_info->thermal_value) {
752 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
753
754 ODM_RT_TRACE(
755 dm, ODM_COMP_TX_PWR_TRACK,
756 "Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
757 p, cali_info->power_index_offset[p],
758 delta, thermal_value,
759 rtlefu->eeprom_thermalmeter,
760 cali_info->thermal_value);
761 }
762 }
763
764 if (thermal_value > rtlefu->eeprom_thermalmeter) {
765 ODM_RT_TRACE(
766 dm, ODM_COMP_TX_PWR_TRACK,
767 "Temperature(%d) higher than PG value(%d)\n",
768 thermal_value, rtlefu->eeprom_thermalmeter);
769
770 phydm_odm_tx_power_set(dm, &c, indexforchannel, 0);
771 } else {
772 ODM_RT_TRACE(
773 dm, ODM_COMP_TX_PWR_TRACK,
774 "Temperature(%d) lower than PG value(%d)\n",
775 thermal_value, rtlefu->eeprom_thermalmeter);
776 phydm_odm_tx_power_set(dm, &c, indexforchannel, 1);
777 }
778
779
780 cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;
781
782 for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
783 cali_info->bb_swing_idx_ofdm_base[p] =
784 cali_info->bb_swing_idx_ofdm[p];
785
786 ODM_RT_TRACE(
787 dm, ODM_COMP_TX_PWR_TRACK,
788 "cali_info->thermal_value = %d thermal_value= %d\n",
789 cali_info->thermal_value, thermal_value);
790
791
792 cali_info->thermal_value = thermal_value;
793 }
794
795 if (dm->support_ic_type == ODM_RTL8703B ||
796 dm->support_ic_type == ODM_RTL8723D ||
797 dm->support_ic_type == ODM_RTL8710B) {
798
799 if (xtal_offset_eanble != 0 &&
800 cali_info->txpowertrack_control &&
801 rtlefu->eeprom_thermalmeter != 0xff) {
802 ODM_RT_TRACE(
803 dm, ODM_COMP_TX_PWR_TRACK,
804 "**********Enter Xtal Tracking**********\n");
805
806 if (thermal_value > rtlefu->eeprom_thermalmeter) {
807 ODM_RT_TRACE(
808 dm, ODM_COMP_TX_PWR_TRACK,
809 "Temperature(%d) higher than PG value(%d)\n",
810 thermal_value,
811 rtlefu->eeprom_thermalmeter);
812 (*c.odm_txxtaltrack_set_xtal)(dm);
813 } else {
814 ODM_RT_TRACE(
815 dm, ODM_COMP_TX_PWR_TRACK,
816 "Temperature(%d) lower than PG value(%d)\n",
817 thermal_value,
818 rtlefu->eeprom_thermalmeter);
819 (*c.odm_txxtaltrack_set_xtal)(dm);
820 }
821 }
822 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
823 "**********End Xtal Tracking**********\n");
824 }
825
826 if (!IS_HARDWARE_TYPE_8723B(adapter)) {
827
828
829
830 if (delta_IQK >= c.threshold_iqk) {
831 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
832 "delta_IQK(%d) >= threshold_iqk(%d)\n",
833 delta_IQK, c.threshold_iqk);
834 if (!cali_info->is_iqk_in_progress)
835 (*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
836 }
837 }
838 if (cali_info->dpk_thermal[ODM_RF_PATH_A] != 0) {
839 if (diff_DPK[ODM_RF_PATH_A] >= c.threshold_dpk) {
840 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
841 odm_set_bb_reg(
842 dm, 0xcc4,
843 BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10),
844 (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk));
845 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
846 } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.threshold_dpk)) {
847 s32 value = 0x20 +
848 (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk);
849
850 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
851 odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) |
852 BIT(11) | BIT(10),
853 value);
854 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
855 } else {
856 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
857 odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) |
858 BIT(11) | BIT(10),
859 0);
860 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
861 }
862 }
863 if (cali_info->dpk_thermal[ODM_RF_PATH_B] != 0) {
864 if (diff_DPK[ODM_RF_PATH_B] >= c.threshold_dpk) {
865 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
866 odm_set_bb_reg(
867 dm, 0xec4,
868 BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10),
869 (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk));
870 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
871 } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.threshold_dpk)) {
872 s32 value = 0x20 +
873 (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk);
874
875 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
876 odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) |
877 BIT(11) | BIT(10),
878 value);
879 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
880 } else {
881 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
882 odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) |
883 BIT(11) | BIT(10),
884 0);
885 odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
886 }
887 }
888
889 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "<===%s\n", __func__);
890
891 cali_info->tx_powercount = 0;
892}
893
894
895
896
897
898
899void odm_reset_iqk_result(void *dm_void) { return; }
900
901u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
902{
903 u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
904 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
905 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
906 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
907 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136,
908 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165};
909 u8 place = chnl;
910
911 if (chnl > 14) {
912 for (place = 14; place < sizeof(channel_all); place++) {
913 if (channel_all[place] == chnl)
914 return place - 13;
915 }
916 }
917 return 0;
918}
919
920static void odm_iq_calibrate(struct phy_dm_struct *dm)
921{
922 void *adapter = dm->adapter;
923
924 if (IS_HARDWARE_TYPE_8812AU(adapter))
925 return;
926
927 if (dm->is_linked) {
928 if ((*dm->channel != dm->pre_channel) &&
929 (!*dm->is_scan_in_process)) {
930 dm->pre_channel = *dm->channel;
931 dm->linked_interval = 0;
932 }
933
934 if (dm->linked_interval < 3)
935 dm->linked_interval++;
936
937 if (dm->linked_interval == 2) {
938 if (IS_HARDWARE_TYPE_8814A(adapter))
939 ;
940
941 else if (IS_HARDWARE_TYPE_8822B(adapter))
942 phy_iq_calibrate_8822b(dm, false);
943 }
944 } else {
945 dm->linked_interval = 0;
946 }
947}
948
949void phydm_rf_init(void *dm_void)
950{
951 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
952
953 odm_txpowertracking_init(dm);
954
955 odm_clear_txpowertracking_state(dm);
956}
957
958void phydm_rf_watchdog(void *dm_void)
959{
960 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
961
962 odm_txpowertracking_check(dm);
963 if (dm->support_ic_type & ODM_IC_11AC_SERIES)
964 odm_iq_calibrate(dm);
965}
966