Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/halrf/halphyrf_ap.c
1308 views
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
#ifndef index_mapping_NUM_88E
20
#define index_mapping_NUM_88E 15
21
#endif
22
23
/* #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) */
24
25
#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
26
do {\
27
for (_offset = 0; _offset < _size; _offset++) { \
28
\
29
if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
30
\
31
if (_offset != 0)\
32
_offset--;\
33
break;\
34
} \
35
} \
36
if (_offset >= _size)\
37
_offset = _size-1;\
38
} while (0)
39
40
void odm_clear_txpowertracking_state(
41
void *dm_void
42
)
43
{
44
struct dm_struct *dm = (struct dm_struct *)dm_void;
45
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
46
struct rtl8192cd_priv *priv = dm->priv;
47
48
u8 i;
49
50
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "===>%s\n", __func__);
51
52
for (i = 0; i < MAX_RF_PATH; i++) {
53
cali_info->absolute_ofdm_swing_idx[i] = 0;
54
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "cali_info->absolute_ofdm_swing_idx[%d]=%d\n",
55
i, cali_info->absolute_ofdm_swing_idx[i]);
56
}
57
58
dm->rf_calibrate_info.thermal_value = 0;
59
dm->rf_calibrate_info.thermal_value_lck = 0;
60
dm->rf_calibrate_info.thermal_value_iqk = 0;
61
}
62
63
void configure_txpower_track(
64
void *dm_void,
65
struct txpwrtrack_cfg *config
66
)
67
{
68
struct dm_struct *dm = (struct dm_struct *)dm_void;
69
#if RTL8812A_SUPPORT
70
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
71
/* if (IS_HARDWARE_TYPE_8812(dm->adapter)) */
72
if (dm->support_ic_type == ODM_RTL8812)
73
configure_txpower_track_8812a(config);
74
/* else */
75
#endif
76
#endif
77
78
#if RTL8814A_SUPPORT
79
if (dm->support_ic_type == ODM_RTL8814A)
80
configure_txpower_track_8814a(config);
81
#endif
82
83
84
#if RTL8188E_SUPPORT
85
if (dm->support_ic_type == ODM_RTL8188E)
86
configure_txpower_track_8188e(config);
87
#endif
88
89
#if RTL8197F_SUPPORT
90
if (dm->support_ic_type == ODM_RTL8197F)
91
configure_txpower_track_8197f(config);
92
#endif
93
94
#if RTL8822B_SUPPORT
95
if (dm->support_ic_type == ODM_RTL8822B)
96
configure_txpower_track_8822b(config);
97
#endif
98
99
#if RTL8192F_SUPPORT
100
if (dm->support_ic_type == ODM_RTL8192F)
101
configure_txpower_track_8192f(config);
102
#endif
103
104
#if RTL8198F_SUPPORT
105
if (dm->support_ic_type == ODM_RTL8198F)
106
configure_txpower_track_8198f(config);
107
#endif
108
109
#if RTL8814B_SUPPORT
110
if (dm->support_ic_type == ODM_RTL8814B)
111
configure_txpower_track_8814b(config);
112
#endif
113
114
#if RTL8812F_SUPPORT
115
if (dm->support_ic_type == ODM_RTL8812F)
116
configure_txpower_track_8812f(config);
117
#endif
118
119
#if RTL8197G_SUPPORT
120
if (dm->support_ic_type == ODM_RTL8197G)
121
configure_txpower_track_8197g(config);
122
#endif
123
124
}
125
126
#if (RTL8192E_SUPPORT == 1)
127
void
128
odm_txpowertracking_callback_thermal_meter_92e(
129
void *dm_void
130
)
131
{
132
struct dm_struct *dm = (struct dm_struct *)dm_void;
133
struct dm_iqk_info *iqk_info = &dm->IQK_info;
134
u8 thermal_value = 0, delta, delta_IQK, delta_LCK, channel, is_decrease, rf_mimo_mode;
135
u8 thermal_value_avg_count = 0;
136
u8 OFDM_min_index = 10; /* OFDM BB Swing should be less than +2.5dB, which is required by Arthur */
137
s8 OFDM_index[2], index ;
138
u32 thermal_value_avg = 0, reg0x18;
139
u32 i = 0, j = 0, rf;
140
s32 value32, CCK_index = 0, ele_A, ele_D, ele_C, X, Y;
141
struct rtl8192cd_priv *priv = dm->priv;
142
143
rf_mimo_mode = dm->rf_type;
144
/* RF_DBG(dm,DBG_RF_TX_PWR_TRACK,"%s:%d rf_mimo_mode:%d\n", __FUNCTION__, __LINE__, rf_mimo_mode); */
145
146
#ifdef MP_TEST
147
if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
148
channel = priv->pshare->working_channel;
149
if (priv->pshare->mp_txpwr_tracking == false)
150
return;
151
} else
152
#endif
153
{
154
channel = (priv->pmib->dot11RFEntry.dot11channel);
155
}
156
157
thermal_value = (unsigned char)odm_get_rf_reg(dm, RF_PATH_A, ODM_RF_T_METER_92E, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
158
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther);
159
160
161
switch (rf_mimo_mode) {
162
case RF_1T1R:
163
rf = 1;
164
break;
165
case RF_2T2R:
166
rf = 2;
167
break;
168
default:
169
rf = 2;
170
break;
171
}
172
173
/* Query OFDM path A default setting Bit[31:21] */
174
ele_D = phy_query_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKOFDM_D);
175
for (i = 0; i < OFDM_TABLE_SIZE_92E; i++) {
176
if (ele_D == (ofdm_swing_table_92e[i] >> 22)) {
177
OFDM_index[0] = (unsigned char)i;
178
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "PathA 0xC80[31:22] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[0]);
179
break;
180
}
181
}
182
183
/* Query OFDM path B default setting */
184
if (rf_mimo_mode == RF_2T2R) {
185
ele_D = phy_query_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKOFDM_D);
186
for (i = 0; i < OFDM_TABLE_SIZE_92E; i++) {
187
if (ele_D == (ofdm_swing_table_92e[i] >> 22)) {
188
OFDM_index[1] = (unsigned char)i;
189
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "PathB 0xC88[31:22] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[1]);
190
break;
191
}
192
}
193
}
194
195
/* calculate average thermal meter */
196
{
197
priv->pshare->thermal_value_avg_88xx[priv->pshare->thermal_value_avg_index_88xx] = thermal_value;
198
priv->pshare->thermal_value_avg_index_88xx++;
199
if (priv->pshare->thermal_value_avg_index_88xx == AVG_THERMAL_NUM_88XX)
200
priv->pshare->thermal_value_avg_index_88xx = 0;
201
202
for (i = 0; i < AVG_THERMAL_NUM_88XX; i++) {
203
if (priv->pshare->thermal_value_avg_88xx[i]) {
204
thermal_value_avg += priv->pshare->thermal_value_avg_88xx[i];
205
thermal_value_avg_count++;
206
}
207
}
208
209
if (thermal_value_avg_count) {
210
thermal_value = (unsigned char)(thermal_value_avg / thermal_value_avg_count);
211
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "AVG Thermal Meter = 0x%x\n", thermal_value);
212
}
213
}
214
215
/* Initialize */
216
if (!priv->pshare->thermal_value) {
217
priv->pshare->thermal_value = priv->pmib->dot11RFEntry.ther;
218
priv->pshare->thermal_value_iqk = thermal_value;
219
priv->pshare->thermal_value_lck = thermal_value;
220
}
221
222
if (thermal_value != priv->pshare->thermal_value) {
223
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** START POWER TRACKING ********\n");
224
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther);
225
226
delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
227
delta_IQK = RTL_ABS(thermal_value, priv->pshare->thermal_value_iqk);
228
delta_LCK = RTL_ABS(thermal_value, priv->pshare->thermal_value_lck);
229
is_decrease = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 1 : 0);
230
231
#ifdef _TRACKING_TABLE_FILE
232
if (priv->pshare->rf_ft_var.pwr_track_file) {
233
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "diff: (%s)%d ==> get index from table : %d)\n", (is_decrease ? "-" : "+"), delta, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0));
234
235
if (is_decrease) {
236
for (i = 0; i < rf; i++) {
237
OFDM_index[i] = priv->pshare->OFDM_index0[i] + get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0);
238
OFDM_index[i] = ((OFDM_index[i] > (OFDM_TABLE_SIZE_92E- 1)) ? (OFDM_TABLE_SIZE_92E - 1) : OFDM_index[i]);
239
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> decrese power ---> new OFDM_INDEX:%d (%d + %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0));
240
CCK_index = priv->pshare->CCK_index0 + get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1);
241
CCK_index = ((CCK_index > (CCK_TABLE_SIZE_92E - 1)) ? (CCK_TABLE_SIZE_92E - 1) : CCK_index);
242
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> Decrese power ---> new CCK_INDEX:%d (%d + %d)\n", CCK_index, priv->pshare->CCK_index0, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1));
243
}
244
} else {
245
for (i = 0; i < rf; i++) {
246
OFDM_index[i] = priv->pshare->OFDM_index0[i] - get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0);
247
OFDM_index[i] = ((OFDM_index[i] < OFDM_min_index) ? OFDM_min_index : OFDM_index[i]);
248
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> Increse power ---> new OFDM_INDEX:%d (%d - %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0));
249
CCK_index = priv->pshare->CCK_index0 - get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1);
250
CCK_index = ((CCK_index < 0) ? 0 : CCK_index);
251
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> Increse power ---> new CCK_INDEX:%d (%d - %d)\n", CCK_index, priv->pshare->CCK_index0, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1));
252
}
253
}
254
}
255
#endif /* CFG_TRACKING_TABLE_FILE */
256
257
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "ofdm_swing_table_92e[(unsigned int)OFDM_index[0]] = %x\n", ofdm_swing_table_92e[(unsigned int)OFDM_index[0]]);
258
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "ofdm_swing_table_92e[(unsigned int)OFDM_index[1]] = %x\n", ofdm_swing_table_92e[(unsigned int)OFDM_index[1]]);
259
260
/* Adujst OFDM Ant_A according to IQK result */
261
ele_D = (ofdm_swing_table_92e[(unsigned int)OFDM_index[0]] & 0xFFC00000) >> 22;
262
X = priv->pshare->rege94;
263
Y = priv->pshare->rege9c;
264
265
if (X != 0) {
266
if ((X & 0x00000200) != 0)
267
X = X | 0xFFFFFC00;
268
ele_A = ((X * ele_D) >> 8) & 0x000003FF;
269
270
/* new element C = element D x Y */
271
if ((Y & 0x00000200) != 0)
272
Y = Y | 0xFFFFFC00;
273
ele_C = ((Y * ele_D) >> 8) & 0x000003FF;
274
275
/* wirte new elements A, C, D to regC80 and regC94, element B is always 0 */
276
value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
277
phy_set_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD, value32);
278
279
value32 = (ele_C & 0x000003C0) >> 6;
280
phy_set_bb_reg(priv, REG_OFDM_0_XC_TX_AFE, MASKH4BITS, value32);
281
282
value32 = ((X * ele_D) >> 7) & 0x01;
283
phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(24), value32);
284
} else {
285
phy_set_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD, ofdm_swing_table_92e[(unsigned int)OFDM_index[0]]);
286
phy_set_bb_reg(priv, REG_OFDM_0_XC_TX_AFE, MASKH4BITS, 0x00);
287
phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(24), 0x00);
288
}
289
290
set_CCK_swing_index(priv, CCK_index);
291
292
if (rf == 2) {
293
ele_D = (ofdm_swing_table_92e[(unsigned int)OFDM_index[1]] & 0xFFC00000) >> 22;
294
X = priv->pshare->regeb4;
295
Y = priv->pshare->regebc;
296
297
if (X != 0) {
298
if ((X & 0x00000200) != 0) /* consider minus */
299
X = X | 0xFFFFFC00;
300
ele_A = ((X * ele_D) >> 8) & 0x000003FF;
301
302
/* new element C = element D x Y */
303
if ((Y & 0x00000200) != 0)
304
Y = Y | 0xFFFFFC00;
305
ele_C = ((Y * ele_D) >> 8) & 0x00003FF;
306
307
/* wirte new elements A, C, D to regC88 and regC9C, element B is always 0 */
308
value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
309
phy_set_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD, value32);
310
311
value32 = (ele_C & 0x000003C0) >> 6;
312
phy_set_bb_reg(priv, REG_OFDM_0_XD_TX_AFE, MASKH4BITS, value32);
313
314
value32 = ((X * ele_D) >> 7) & 0x01;
315
phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(28), value32);
316
} else {
317
phy_set_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD, ofdm_swing_table_92e[(unsigned int)OFDM_index[1]]);
318
phy_set_bb_reg(priv, REG_OFDM_0_XD_TX_AFE, MASKH4BITS, 0x00);
319
phy_set_bb_reg(priv, REG_OFDM_0_ECCA_THRESHOLD, BIT(28), 0x00);
320
}
321
322
}
323
324
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "0xc80 = 0x%x\n", phy_query_bb_reg(priv, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD));
325
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "0xc88 = 0x%x\n", phy_query_bb_reg(priv, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD));
326
327
if ((delta_IQK > 3) && (!iqk_info->rfk_forbidden)) {
328
priv->pshare->thermal_value_iqk = thermal_value;
329
#ifdef MP_TEST
330
#endif if (!(*(dm->mp_mode) && (OPMODE & (WIFI_MP_CTX_BACKGROUND | WIFI_MP_CTX_PACKET))))
331
332
halrf_iqk_trigger(dm, false);
333
}
334
335
if ((delta_LCK > 8) && (!iqk_info->rfk_forbidden)) {
336
RTL_W8(0x522, 0xff);
337
reg0x18 = phy_query_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, 1);
338
phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 1);
339
phy_set_rf_reg(priv, RF_PATH_A, 0x18, BIT(15), 1);
340
delay_ms(1);
341
phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 0);
342
phy_set_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, reg0x18);
343
RTL_W8(0x522, 0x0);
344
priv->pshare->thermal_value_lck = thermal_value;
345
}
346
}
347
348
/* update thermal meter value */
349
priv->pshare->thermal_value = thermal_value;
350
for (i = 0 ; i < rf ; i++)
351
priv->pshare->OFDM_index[i] = OFDM_index[i];
352
priv->pshare->CCK_index = CCK_index;
353
354
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** END:%s() ********\n", __FUNCTION__);
355
}
356
#endif
357
358
#if (RTL8814B_SUPPORT == 1 || RTL8812F_SUPPORT == 1 || RTL8822C_SUPPORT == 1 || RTL8197G_SUPPORT == 1)
359
void
360
odm_txpowertracking_callback_thermal_meter_jaguar_series4(void *dm_void)
361
{
362
struct dm_struct *dm = (struct dm_struct *)dm_void;
363
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
364
struct dm_iqk_info *iqk_info = &dm->IQK_info;
365
struct _hal_rf_ *rf = &dm->rf_table;
366
struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data;
367
struct rtl8192cd_priv *priv = dm->priv;
368
struct txpwrtrack_cfg c;
369
370
if (!(rf->rf_supportability & HAL_RF_TX_PWR_TRACK))
371
return;
372
373
u8 thermal_value[MAX_RF_PATH] = {0}, delta[MAX_RF_PATH] = {0};
374
u8 delta_swing_table_idx_tup[DELTA_SWINGIDX_SIZE] = {0};
375
u8 delta_swing_table_idx_tdown[DELTA_SWINGIDX_SIZE] = {0};
376
u8 delta_LCK = 0, delta_IQK = 0, i = 0, j = 0, p;
377
u8 thermal_value_avg_count[MAX_RF_PATH] = {0};
378
u32 thermal_value_avg[MAX_RF_PATH] = {0};
379
s8 thermal_value_temp[MAX_RF_PATH] = {0};
380
381
u8 *pwrtrk_tab_up_a = NULL;
382
u8 *pwrtrk_tab_down_a = NULL;
383
u8 *pwrtrk_tab_up_b = NULL;
384
u8 *pwrtrk_tab_down_b = NULL;
385
u8 *pwrtrk_tab_up_c = NULL;
386
u8 *pwrtrk_tab_down_c = NULL;
387
u8 *pwrtrk_tab_up_d = NULL;
388
u8 *pwrtrk_tab_down_d = NULL;
389
u8 tracking_method = MIX_MODE;
390
391
configure_txpower_track(dm, &c);
392
393
(*c.get_delta_swing_table)(dm,
394
(u8 **)&pwrtrk_tab_up_a, (u8 **)&pwrtrk_tab_down_a,
395
(u8 **)&pwrtrk_tab_up_b, (u8 **)&pwrtrk_tab_down_b);
396
397
if (GET_CHIP_VER(priv) == VERSION_8814B) {
398
(*c.get_delta_swing_table8814only)(dm,
399
(u8 **)&pwrtrk_tab_up_c, (u8 **)&pwrtrk_tab_down_c,
400
(u8 **)&pwrtrk_tab_up_d, (u8 **)&pwrtrk_tab_down_d);
401
}
402
403
cali_info->txpowertracking_callback_cnt++;
404
cali_info->is_txpowertracking_init = true;
405
406
/* Initialize */
407
if (!dm->rf_calibrate_info.thermal_value)
408
dm->rf_calibrate_info.thermal_value =
409
priv->pmib->dot11RFEntry.thermal[RF_PATH_A];
410
411
if (!dm->rf_calibrate_info.thermal_value_lck)
412
dm->rf_calibrate_info.thermal_value_lck =
413
priv->pmib->dot11RFEntry.thermal[RF_PATH_A];
414
415
if (!dm->rf_calibrate_info.thermal_value_iqk)
416
dm->rf_calibrate_info.thermal_value_iqk =
417
priv->pmib->dot11RFEntry.thermal[RF_PATH_A];
418
419
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
420
"===>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",
421
cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base_path[RF_PATH_A], cali_info->default_ofdm_index);
422
423
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
424
"cali_info->txpowertrack_control=%d\n", cali_info->txpowertrack_control);
425
426
for (i = 0; i < c.rf_path_count; i++) {
427
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
428
"PGthermal[%d]=0x%x(%d)\n", i,
429
priv->pmib->dot11RFEntry.thermal[i],
430
priv->pmib->dot11RFEntry.thermal[i]);
431
432
if (priv->pmib->dot11RFEntry.thermal[i] == 0xff ||
433
priv->pmib->dot11RFEntry.thermal[i] == 0x0)
434
return;
435
}
436
if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G)) {
437
for (i = 0; i < c.rf_path_count; i++)
438
thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0x7e); /* 0x42: RF Reg[6:1] Thermal Trim*/
439
} else {
440
for (i = 0; i < c.rf_path_count; i++) {
441
thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
442
443
thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm);
444
445
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
446
"thermal_value_temp[%d](%d) = thermal_value[%d](%d) + power_time_thermal(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm));
447
448
if (thermal_value_temp[i] > 63)
449
thermal_value[i] = 63;
450
else if (thermal_value_temp[i] < 0)
451
thermal_value[i] = 0;
452
else
453
thermal_value[i] = thermal_value_temp[i];
454
}
455
}
456
457
for (j = 0; j < c.rf_path_count; j++) {
458
cali_info->thermal_value_avg_path[j][cali_info->thermal_value_avg_index_path[j]] = thermal_value[j];
459
cali_info->thermal_value_avg_index_path[j]++;
460
if (cali_info->thermal_value_avg_index_path[j] == c.average_thermal_num) /*Average times = c.average_thermal_num*/
461
cali_info->thermal_value_avg_index_path[j] = 0;
462
463
464
for (i = 0; i < c.average_thermal_num; i++) {
465
if (cali_info->thermal_value_avg_path[j][i]) {
466
thermal_value_avg[j] += cali_info->thermal_value_avg_path[j][i];
467
thermal_value_avg_count[j]++;
468
}
469
}
470
471
if (thermal_value_avg_count[j]) { /* Calculate Average thermal_value after average enough times */
472
thermal_value[j] = (u8)(thermal_value_avg[j] / thermal_value_avg_count[j]);
473
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
474
"PGthermal[%d] = 0x%x(%d), AVG Thermal Meter = 0x%x(%d)\n", j,
475
priv->pmib->dot11RFEntry.thermal[j],
476
priv->pmib->dot11RFEntry.thermal[j],
477
thermal_value[j],
478
thermal_value[j]);
479
}
480
/* 4 5. Calculate delta, delta_LCK, delta_IQK. */
481
482
/* "delta" here is used to determine whether thermal value changes or not. */
483
delta[j] = RTL_ABS(thermal_value[j], priv->pmib->dot11RFEntry.thermal[j]);
484
delta_LCK = RTL_ABS(thermal_value[RF_PATH_A], dm->rf_calibrate_info.thermal_value_lck);
485
delta_IQK = RTL_ABS(thermal_value[RF_PATH_A], dm->rf_calibrate_info.thermal_value_iqk);
486
}
487
488
/*4 6. If necessary, do LCK.*/
489
for (i = 0; i < c.rf_path_count; i++)
490
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);
491
492
/* Wait sacn to do LCK by RF Jenyu*/
493
if( (*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
494
/* Delta temperature is equal to or larger than 20 centigrade.*/
495
if (delta_LCK >= c.threshold_iqk) {
496
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
497
cali_info->thermal_value_lck = thermal_value[RF_PATH_A];
498
499
/*Use RTLCK, so close power tracking driver LCK*/
500
if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {
501
if (c.phy_lc_calibrate)
502
(*c.phy_lc_calibrate)(dm);
503
} else
504
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do not do LCK\n");
505
}
506
}
507
508
/*3 7. If necessary, move the index of swing table to adjust Tx power.*/
509
#ifdef _TRACKING_TABLE_FILE
510
for (i = 0; i < c.rf_path_count; i++) {
511
if (i == RF_PATH_B) {
512
odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_b, DELTA_SWINGIDX_SIZE);
513
odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_b, DELTA_SWINGIDX_SIZE);
514
} else if (i == RF_PATH_C) {
515
odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_c, DELTA_SWINGIDX_SIZE);
516
odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_c, DELTA_SWINGIDX_SIZE);
517
} else if (i == RF_PATH_D) {
518
odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_d, DELTA_SWINGIDX_SIZE);
519
odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_d, DELTA_SWINGIDX_SIZE);
520
} else {
521
odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_a, DELTA_SWINGIDX_SIZE);
522
odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_a, DELTA_SWINGIDX_SIZE);
523
}
524
525
cali_info->delta_power_index_last_path[i] = cali_info->delta_power_index_path[i]; /*recording poer index offset*/
526
delta[i] = thermal_value[i] > priv->pmib->dot11RFEntry.thermal[i] ? (thermal_value[i] - priv->pmib->dot11RFEntry.thermal[i]) : (priv->pmib->dot11RFEntry.thermal[i] - thermal_value[i]);
527
528
if (delta[i] >= TXPWR_TRACK_TABLE_SIZE)
529
delta[i] = TXPWR_TRACK_TABLE_SIZE - 1;
530
531
if (thermal_value[i] > priv->pmib->dot11RFEntry.thermal[i]) {
532
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
533
"delta_swing_table_idx_tup[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tup[delta[i]], i);
534
535
cali_info->delta_power_index_path[i] = delta_swing_table_idx_tup[delta[i]];
536
cali_info->absolute_ofdm_swing_idx[i] = delta_swing_table_idx_tup[delta[i]]; /*Record delta swing for mix mode power tracking*/
537
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
538
"******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);
539
} else {
540
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
541
"delta_swing_table_idx_tdown[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tdown[delta[i]], i);
542
cali_info->delta_power_index_path[i] = -1 * delta_swing_table_idx_tdown[delta[i]];
543
cali_info->absolute_ofdm_swing_idx[i] = -1 * delta_swing_table_idx_tdown[delta[i]]; /*Record delta swing for mix mode power tracking*/
544
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
545
"******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);
546
}
547
}
548
549
#endif
550
551
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
552
if (cali_info->delta_power_index_path[p] == cali_info->delta_power_index_last_path[p]) /*If Thermal value changes but lookup table value still the same*/
553
cali_info->power_index_offset_path[p] = 0;
554
else
555
cali_info->power_index_offset_path[p] = cali_info->delta_power_index_path[p] - cali_info->delta_power_index_last_path[p]; /*Power index diff between 2 times Power Tracking*/
556
}
557
558
#if 0
559
if (dm->support_ic_type == ODM_RTL8814B) {
560
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
561
for (p = RF_PATH_A; p < c.rf_path_count; p++)
562
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
563
} else {
564
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
565
for (p = RF_PATH_A; p < c.rf_path_count; p++)
566
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);
567
}
568
#else
569
if (*dm->mp_mode == 1) {
570
if (cali_info->txpowertrack_control == 1) {
571
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
572
tracking_method = MIX_MODE;
573
} else if (cali_info->txpowertrack_control == 3) {
574
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");
575
tracking_method = TSSI_MODE;
576
}
577
} else {
578
if (dm->priv->pmib->dot11RFEntry.tssi_enable == 0) {
579
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
580
tracking_method = MIX_MODE;
581
} else if (dm->priv->pmib->dot11RFEntry.tssi_enable == 1) {
582
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");
583
tracking_method = TSSI_MODE;
584
}
585
}
586
587
if (dm->support_ic_type == ODM_RTL8822C || dm->support_ic_type == ODM_RTL8812F ||
588
dm->support_ic_type == ODM_RTL8814B || dm->support_ic_type == ODM_RTL8197G)
589
for (p = RF_PATH_A; p < c.rf_path_count; p++)
590
(*c.odm_tx_pwr_track_set_pwr)(dm, tracking_method, p, 0);
591
592
#endif
593
/* Wait sacn to do IQK by RF Jenyu*/
594
if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
595
/*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
596
if (delta_IQK >= c.threshold_iqk) {
597
cali_info->thermal_value_iqk = thermal_value[RF_PATH_A];
598
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
599
600
/*if (!cali_info->is_iqk_in_progress)*/
601
/* (*c.do_iqk)(dm, delta_IQK, thermal_value[RF_PATH_A], 8);*/
602
/*RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do IQK\n");*/
603
604
/*if (!cali_info->is_iqk_in_progress)*/
605
/* (*c.do_tssi_dck)(dm, true);*/
606
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do TSSI DCK\n");
607
}
608
}
609
610
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===%s\n", __func__);
611
612
cali_info->tx_powercount = 0;
613
}
614
#endif
615
616
#if (RTL8197F_SUPPORT == 1 || RTL8192F_SUPPORT == 1 || RTL8822B_SUPPORT == 1 ||\
617
RTL8821C_SUPPORT == 1 || RTL8198F_SUPPORT == 1)
618
void
619
odm_txpowertracking_callback_thermal_meter_jaguar_series3(
620
void *dm_void
621
)
622
{
623
#if 1
624
struct dm_struct *dm = (struct dm_struct *)dm_void;
625
u8 thermal_value = 0, delta, delta_LCK, delta_IQK, channel, is_increase;
626
u8 thermal_value_avg_count = 0, p = 0, i = 0;
627
u32 thermal_value_avg = 0;
628
struct rtl8192cd_priv *priv = dm->priv;
629
struct txpwrtrack_cfg c;
630
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
631
struct dm_iqk_info *iqk_info = &dm->IQK_info;
632
struct _hal_rf_ *rf = &dm->rf_table;
633
/*The following tables decide the final index of OFDM/CCK swing table.*/
634
u8 *pwrtrk_tab_up_a = NULL, *pwrtrk_tab_down_a = NULL;
635
u8 *pwrtrk_tab_up_b = NULL, *pwrtrk_tab_down_b = NULL;
636
u8 *pwrtrk_tab_up_cck_a = NULL, *pwrtrk_tab_down_cck_a = NULL;
637
u8 *pwrtrk_tab_up_cck_b = NULL, *pwrtrk_tab_down_cck_b = NULL;
638
/*for 8814 add by Yu Chen*/
639
u8 *pwrtrk_tab_up_c = NULL, *pwrtrk_tab_down_c = NULL;
640
u8 *pwrtrk_tab_up_d = NULL, *pwrtrk_tab_down_d = NULL;
641
u8 *pwrtrk_tab_up_cck_c = NULL, *pwrtrk_tab_down_cck_c = NULL;
642
u8 *pwrtrk_tab_up_cck_d = NULL, *pwrtrk_tab_down_cck_d = NULL;
643
s8 thermal_value_temp = 0;
644
645
#ifdef MP_TEST
646
if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
647
channel = priv->pshare->working_channel;
648
if (priv->pshare->mp_txpwr_tracking == false)
649
return;
650
} else
651
#endif
652
{
653
channel = (priv->pmib->dot11RFEntry.dot11channel);
654
}
655
656
configure_txpower_track(dm, &c);
657
658
(*c.get_delta_all_swing_table)(dm,
659
(u8 **)&pwrtrk_tab_up_a, (u8 **)&pwrtrk_tab_down_a,
660
(u8 **)&pwrtrk_tab_up_b, (u8 **)&pwrtrk_tab_down_b,
661
(u8 **)&pwrtrk_tab_up_cck_a, (u8 **)&pwrtrk_tab_down_cck_a,
662
(u8 **)&pwrtrk_tab_up_cck_b, (u8 **)&pwrtrk_tab_down_cck_b);
663
664
if (GET_CHIP_VER(priv) == VERSION_8198F) {
665
(*c.get_delta_all_swing_table_ex)(dm,
666
(u8 **)&pwrtrk_tab_up_c, (u8 **)&pwrtrk_tab_down_c,
667
(u8 **)&pwrtrk_tab_up_d, (u8 **)&pwrtrk_tab_down_d,
668
(u8 **)&pwrtrk_tab_up_cck_c, (u8 **)&pwrtrk_tab_down_cck_c,
669
(u8 **)&pwrtrk_tab_up_cck_d, (u8 **)&pwrtrk_tab_down_cck_d);
670
}
671
/*0x42: RF Reg[15:10] 88E*/
672
thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00);
673
#ifdef THER_TRIM
674
if (GET_CHIP_VER(priv) == VERSION_8197F) {
675
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"orig thermal_value=%d, ther_trim_val=%d\n", thermal_value, priv->pshare->rf_ft_var.ther_trim_val);
676
677
thermal_value += priv->pshare->rf_ft_var.ther_trim_val;
678
679
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"after thermal trim, thermal_value=%d\n", thermal_value);
680
}
681
682
if (GET_CHIP_VER(priv) == VERSION_8198F) {
683
thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);
684
685
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
686
"thermal_value_temp(%d) = ther_value(%d) + ther_trim_ther(%d)\n",
687
thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));
688
689
if (thermal_value_temp > 63)
690
thermal_value = 63;
691
else if (thermal_value_temp < 0)
692
thermal_value = 0;
693
else
694
thermal_value = thermal_value_temp;
695
}
696
#endif
697
698
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"\n\n\nCurrent Thermal = 0x%x(%d) EEPROMthermalmeter 0x%x(%d)\n"
699
, thermal_value, thermal_value, priv->pmib->dot11RFEntry.ther, priv->pmib->dot11RFEntry.ther);
700
701
/* Initialize */
702
if (!dm->rf_calibrate_info.thermal_value)
703
dm->rf_calibrate_info.thermal_value = priv->pmib->dot11RFEntry.ther;
704
705
if (!dm->rf_calibrate_info.thermal_value_lck)
706
dm->rf_calibrate_info.thermal_value_lck = priv->pmib->dot11RFEntry.ther;
707
708
if (!dm->rf_calibrate_info.thermal_value_iqk)
709
dm->rf_calibrate_info.thermal_value_iqk = priv->pmib->dot11RFEntry.ther;
710
711
/* calculate average thermal meter */
712
dm->rf_calibrate_info.thermal_value_avg[dm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
713
dm->rf_calibrate_info.thermal_value_avg_index++;
714
715
if (dm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
716
dm->rf_calibrate_info.thermal_value_avg_index = 0;
717
718
for (i = 0; i < c.average_thermal_num; i++) {
719
if (dm->rf_calibrate_info.thermal_value_avg[i]) {
720
thermal_value_avg += dm->rf_calibrate_info.thermal_value_avg[i];
721
thermal_value_avg_count++;
722
}
723
}
724
725
if (thermal_value_avg_count) {/*Calculate Average thermal_value after average enough times*/
726
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"thermal_value_avg=0x%x(%d) thermal_value_avg_count = %d\n"
727
, thermal_value_avg, thermal_value_avg, thermal_value_avg_count);
728
729
thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
730
731
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"AVG Thermal Meter = 0x%X(%d), EEPROMthermalmeter = 0x%X(%d)\n", thermal_value, thermal_value, priv->pmib->dot11RFEntry.ther, priv->pmib->dot11RFEntry.ther);
732
}
733
734
/*4 Calculate delta, delta_LCK, delta_IQK.*/
735
delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
736
delta_LCK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_lck);
737
delta_IQK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_iqk);
738
is_increase = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 0 : 1);
739
740
if (delta > 29) { /* power track table index(thermal diff.) upper bound*/
741
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta(%d) > 29, set delta to 29\n", delta);
742
delta = 29;
743
}
744
745
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);
746
747
/*4 if necessary, do LCK.*/
748
if ((delta_LCK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
749
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
750
dm->rf_calibrate_info.thermal_value_lck = thermal_value;
751
#if (RTL8822B_SUPPORT != 1)
752
if (!(dm->support_ic_type & ODM_RTL8822B)) {
753
if (c.phy_lc_calibrate)
754
(*c.phy_lc_calibrate)(dm);
755
}
756
#endif
757
}
758
759
if (!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/
760
return;
761
762
/*4 Do Power Tracking*/
763
764
if (thermal_value != dm->rf_calibrate_info.thermal_value) {
765
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******** START POWER TRACKING ********\n");
766
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"Readback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n",
767
thermal_value, dm->rf_calibrate_info.thermal_value, priv->pmib->dot11RFEntry.ther);
768
769
#ifdef _TRACKING_TABLE_FILE
770
if (priv->pshare->rf_ft_var.pwr_track_file) {
771
if (is_increase) { /*thermal is higher than base*/
772
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
773
switch (p) {
774
case RF_PATH_B:
775
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_up_b[%d] = %d pwrtrk_tab_up_cck_b[%d] = %d\n", delta, pwrtrk_tab_up_b[delta], delta, pwrtrk_tab_up_cck_b[delta]);
776
cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_b[delta];
777
cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_b[delta];
778
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and pRF->absolute_ofdm_swing_idx[RF_PATH_B] = %d pRF->absolute_cck_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
779
break;
780
781
case RF_PATH_C:
782
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_up_c[%d] = %d pwrtrk_tab_up_cck_c[%d] = %d\n", delta, pwrtrk_tab_up_c[delta], delta, pwrtrk_tab_up_cck_c[delta]);
783
cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_c[delta];
784
cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_c[delta];
785
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and pRF->absolute_ofdm_swing_idx[RF_PATH_C] = %d pRF->absolute_cck_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
786
break;
787
788
case RF_PATH_D:
789
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_up_d[%d] = %d pwrtrk_tab_up_cck_d[%d] = %d\n", delta, pwrtrk_tab_up_d[delta], delta, pwrtrk_tab_up_cck_d[delta]);
790
cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_d[delta];
791
cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_d[delta];
792
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and pRF->absolute_ofdm_swing_idx[RF_PATH_D] = %d pRF->absolute_cck_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
793
break;
794
default:
795
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_up_a[%d] = %d pwrtrk_tab_up_cck_a[%d] = %d\n", delta, pwrtrk_tab_up_a[delta], delta, pwrtrk_tab_up_cck_a[delta]);
796
cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_a[delta];
797
cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_a[delta];
798
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and pRF->absolute_ofdm_swing_idx[RF_PATH_A] = %d pRF->absolute_cck_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
799
break;
800
}
801
}
802
} else { /* thermal is lower than base*/
803
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
804
switch (p) {
805
case RF_PATH_B:
806
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_down_b[%d] = %d pwrtrk_tab_down_cck_b[%d] = %d\n", delta, pwrtrk_tab_down_b[delta], delta, pwrtrk_tab_down_cck_b[delta]);
807
cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_b[delta];
808
cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_b[delta];
809
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and pRF->absolute_ofdm_swing_idx[RF_PATH_B] = %d pRF->absolute_cck_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
810
break;
811
812
case RF_PATH_C:
813
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_down_c[%d] = %d pwrtrk_tab_down_cck_c[%d] = %d\n", delta, pwrtrk_tab_down_c[delta], delta, pwrtrk_tab_down_cck_c[delta]);
814
cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_c[delta];
815
cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_c[delta];
816
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and pRF->absolute_ofdm_swing_idx[RF_PATH_C] = %d pRF->absolute_cck_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
817
break;
818
819
case RF_PATH_D:
820
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_down_d[%d] = %d pwrtrk_tab_down_cck_d[%d] = %d\n", delta, pwrtrk_tab_down_d[delta], delta, pwrtrk_tab_down_cck_d[delta]);
821
cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_d[delta];
822
cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_d[delta];
823
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and pRF->absolute_ofdm_swing_idx[RF_PATH_D] = %d pRF->absolute_cck_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
824
break;
825
826
default:
827
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"pwrtrk_tab_down_a[%d] = %d pwrtrk_tab_down_cck_a[%d] = %d\n", delta, pwrtrk_tab_down_a[delta], delta, pwrtrk_tab_down_cck_a[delta]);
828
cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_a[delta];
829
cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_a[delta];
830
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and pRF->absolute_ofdm_swing_idx[RF_PATH_A] = %d pRF->absolute_cck_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p], cali_info->absolute_cck_swing_idx[p]);
831
break;
832
}
833
}
834
}
835
836
if (is_increase) {
837
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> increse power --->\n");
838
if (GET_CHIP_VER(priv) == VERSION_8197F) {
839
for (p = RF_PATH_A; p < c.rf_path_count; p++)
840
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);
841
//} else if (GET_CHIP_VER(priv) == VERSION_8192F) {
842
// for (p = RF_PATH_A; p < c.rf_path_count; p++)
843
// (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
844
} else if (GET_CHIP_VER(priv) == VERSION_8822B) {
845
for (p = RF_PATH_A; p < c.rf_path_count; p++)
846
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
847
} else if (GET_CHIP_VER(priv) == VERSION_8821C) {
848
for (p = RF_PATH_A; p < c.rf_path_count; p++)
849
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
850
} else if (GET_CHIP_VER(priv) == VERSION_8198F) {
851
for (p = RF_PATH_A; p < c.rf_path_count; p++)
852
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
853
}
854
} else {
855
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> decrese power --->\n");
856
if (GET_CHIP_VER(priv) == VERSION_8197F) {
857
for (p = RF_PATH_A; p < c.rf_path_count; p++)
858
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);
859
//} else if (GET_CHIP_VER(priv) == VERSION_8192F) {
860
// for (p = RF_PATH_A; p < c.rf_path_count; p++)
861
// (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
862
} else if (GET_CHIP_VER(priv) == VERSION_8822B) {
863
for (p = RF_PATH_A; p < c.rf_path_count; p++)
864
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
865
} else if (GET_CHIP_VER(priv) == VERSION_8821C) {
866
for (p = RF_PATH_A; p < c.rf_path_count; p++)
867
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
868
} else if (GET_CHIP_VER(priv) == VERSION_8198F) {
869
for (p = RF_PATH_A; p < c.rf_path_count; p++)
870
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
871
}
872
}
873
}
874
#endif
875
876
if (GET_CHIP_VER(priv) != VERSION_8198F) {
877
if ((delta_IQK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
878
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
879
dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
880
if (!(dm->support_ic_type & ODM_RTL8197F)) {
881
if (c.do_iqk)
882
(*c.do_iqk)(dm, false, thermal_value, 0);
883
}
884
}
885
}
886
887
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** END:%s() ********\n\n", __func__);
888
/*update thermal meter value*/
889
dm->rf_calibrate_info.thermal_value = thermal_value;
890
891
}
892
893
#endif
894
}
895
#endif
896
897
/*#if (RTL8814A_SUPPORT == 1)*/
898
#if (RTL8814A_SUPPORT == 1)
899
900
void
901
odm_txpowertracking_callback_thermal_meter_jaguar_series2(
902
void *dm_void
903
)
904
{
905
struct dm_struct *dm = (struct dm_struct *)dm_void;
906
u8 thermal_value = 0, delta, delta_LCK, delta_IQK, channel, is_increase;
907
u8 thermal_value_avg_count = 0, p = 0, i = 0;
908
u32 thermal_value_avg = 0, reg0x18;
909
u32 bb_swing_reg[4] = {REG_A_TX_SCALE_JAGUAR, REG_B_TX_SCALE_JAGUAR, REG_C_TX_SCALE_JAGUAR2, REG_D_TX_SCALE_JAGUAR2};
910
s32 ele_D;
911
u32 bb_swing_idx;
912
struct rtl8192cd_priv *priv = dm->priv;
913
struct txpwrtrack_cfg c;
914
boolean is_tssi_enable = false;
915
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
916
struct dm_iqk_info *iqk_info = &dm->IQK_info;
917
918
/* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
919
u8 *delta_swing_table_idx_tup_a = NULL, *delta_swing_table_idx_tdown_a = NULL;
920
u8 *delta_swing_table_idx_tup_b = NULL, *delta_swing_table_idx_tdown_b = NULL;
921
/* for 8814 add by Yu Chen */
922
u8 *delta_swing_table_idx_tup_c = NULL, *delta_swing_table_idx_tdown_c = NULL;
923
u8 *delta_swing_table_idx_tup_d = NULL, *delta_swing_table_idx_tdown_d = NULL;
924
925
#ifdef MP_TEST
926
if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
927
channel = priv->pshare->working_channel;
928
if (priv->pshare->mp_txpwr_tracking == false)
929
return;
930
} else
931
#endif
932
{
933
channel = (priv->pmib->dot11RFEntry.dot11channel);
934
}
935
936
configure_txpower_track(dm, &c);
937
cali_info->default_ofdm_index = priv->pshare->OFDM_index0[RF_PATH_A];
938
939
(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
940
(u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
941
942
if (dm->support_ic_type & ODM_RTL8814A) /* for 8814 path C & D */
943
(*c.get_delta_swing_table8814only)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
944
(u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
945
946
thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
947
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"\nReadback Thermal Meter = 0x%x, pre thermal meter 0x%x, EEPROMthermalmeter 0x%x\n", thermal_value, dm->rf_calibrate_info.thermal_value, priv->pmib->dot11RFEntry.ther);
948
949
/* Initialize */
950
if (!dm->rf_calibrate_info.thermal_value)
951
dm->rf_calibrate_info.thermal_value = priv->pmib->dot11RFEntry.ther;
952
953
if (!dm->rf_calibrate_info.thermal_value_lck)
954
dm->rf_calibrate_info.thermal_value_lck = priv->pmib->dot11RFEntry.ther;
955
956
if (!dm->rf_calibrate_info.thermal_value_iqk)
957
dm->rf_calibrate_info.thermal_value_iqk = priv->pmib->dot11RFEntry.ther;
958
959
is_tssi_enable = (boolean)odm_get_rf_reg(dm, RF_PATH_A, REG_RF_TX_GAIN_OFFSET, BIT(7)); /* check TSSI enable */
960
961
/* 4 Query OFDM BB swing default setting Bit[31:21] */
962
for (p = RF_PATH_A ; p < c.rf_path_count ; p++) {
963
ele_D = odm_get_bb_reg(dm, bb_swing_reg[p], 0xffe00000);
964
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"0x%x:0x%x ([31:21] = 0x%x)\n", bb_swing_reg[p], odm_get_bb_reg(dm, bb_swing_reg[p], MASKDWORD), ele_D);
965
966
for (bb_swing_idx = 0; bb_swing_idx < TXSCALE_TABLE_SIZE; bb_swing_idx++) {/* 4 */
967
if (ele_D == tx_scaling_table_jaguar[bb_swing_idx]) {
968
dm->rf_calibrate_info.OFDM_index[p] = (u8)bb_swing_idx;
969
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"OFDM_index[%d]=%d\n", p, dm->rf_calibrate_info.OFDM_index[p]);
970
break;
971
}
972
}
973
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "kfree_offset[%d]=%d\n", p, cali_info->kfree_offset[p]);
974
975
}
976
977
/* calculate average thermal meter */
978
dm->rf_calibrate_info.thermal_value_avg[dm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
979
dm->rf_calibrate_info.thermal_value_avg_index++;
980
if (dm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num) /* Average times = c.average_thermal_num */
981
dm->rf_calibrate_info.thermal_value_avg_index = 0;
982
983
for (i = 0; i < c.average_thermal_num; i++) {
984
if (dm->rf_calibrate_info.thermal_value_avg[i]) {
985
thermal_value_avg += dm->rf_calibrate_info.thermal_value_avg[i];
986
thermal_value_avg_count++;
987
}
988
}
989
990
if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
991
thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
992
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"AVG Thermal Meter = 0x%X, EEPROMthermalmeter = 0x%X\n", thermal_value, priv->pmib->dot11RFEntry.ther);
993
}
994
995
/* 4 Calculate delta, delta_LCK, delta_IQK. */
996
delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
997
delta_LCK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_lck);
998
delta_IQK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_iqk);
999
is_increase = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 0 : 1);
1000
1001
/* 4 if necessary, do LCK. */
1002
if (!(dm->support_ic_type & ODM_RTL8821)) {
1003
if ((delta_LCK > c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
1004
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
1005
dm->rf_calibrate_info.thermal_value_lck = thermal_value;
1006
1007
/*Use RTLCK, so close power tracking driver LCK*/
1008
#if (RTL8814A_SUPPORT != 1)
1009
if (!(dm->support_ic_type & ODM_RTL8814A)) {
1010
if (c.phy_lc_calibrate)
1011
(*c.phy_lc_calibrate)(dm);
1012
}
1013
#endif
1014
}
1015
}
1016
1017
if ((delta_IQK > c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
1018
panic_printk("%s(%d)\n", __FUNCTION__, __LINE__);
1019
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
1020
dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
1021
if (c.do_iqk)
1022
(*c.do_iqk)(dm, true, 0, 0);
1023
}
1024
1025
if (!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/
1026
return;
1027
1028
/* 4 Do Power Tracking */
1029
1030
if (is_tssi_enable == true) {
1031
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter PURE TSSI MODE**********\n");
1032
for (p = RF_PATH_A; p < c.rf_path_count; p++)
1033
(*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p, 0);
1034
} else if (thermal_value != dm->rf_calibrate_info.thermal_value) {
1035
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"\n******** START POWER TRACKING ********\n");
1036
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, dm->rf_calibrate_info.thermal_value, priv->pmib->dot11RFEntry.ther);
1037
1038
#ifdef _TRACKING_TABLE_FILE
1039
if (priv->pshare->rf_ft_var.pwr_track_file) {
1040
if (is_increase) { /* thermal is higher than base */
1041
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
1042
switch (p) {
1043
case RF_PATH_B:
1044
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]);
1045
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /* Record delta swing for mix mode power tracking */
1046
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and dm->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1047
break;
1048
1049
case RF_PATH_C:
1050
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]);
1051
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /* Record delta swing for mix mode power tracking */
1052
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and dm->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1053
break;
1054
1055
case RF_PATH_D:
1056
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]);
1057
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /* Record delta swing for mix mode power tracking */
1058
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and dm->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1059
break;
1060
1061
default:
1062
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]);
1063
cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /* Record delta swing for mix mode power tracking */
1064
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is higher and dm->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1065
break;
1066
}
1067
}
1068
} else { /* thermal is lower than base */
1069
for (p = RF_PATH_A; p < c.rf_path_count; p++) {
1070
switch (p) {
1071
case RF_PATH_B:
1072
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]);
1073
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /* Record delta swing for mix mode power tracking */
1074
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and dm->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1075
break;
1076
1077
case RF_PATH_C:
1078
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]);
1079
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /* Record delta swing for mix mode power tracking */
1080
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and dm->absolute_ofdm_swing_idx[RF_PATH_C] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1081
break;
1082
1083
case RF_PATH_D:
1084
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]);
1085
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /* Record delta swing for mix mode power tracking */
1086
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and dm->absolute_ofdm_swing_idx[RF_PATH_D] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1087
break;
1088
1089
default:
1090
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]);
1091
cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /* Record delta swing for mix mode power tracking */
1092
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******Temp is lower and dm->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
1093
break;
1094
}
1095
}
1096
}
1097
1098
if (is_increase) {
1099
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> increse power --->\n");
1100
for (p = RF_PATH_A; p < c.rf_path_count; p++)
1101
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
1102
} else {
1103
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> decrese power --->\n");
1104
for (p = RF_PATH_A; p < c.rf_path_count; p++)
1105
(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
1106
}
1107
}
1108
#endif
1109
1110
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** END:%s() ********\n", __FUNCTION__);
1111
/* update thermal meter value */
1112
dm->rf_calibrate_info.thermal_value = thermal_value;
1113
1114
}
1115
}
1116
#endif
1117
1118
#if (RTL8812A_SUPPORT == 1 || RTL8881A_SUPPORT == 1)
1119
void
1120
odm_txpowertracking_callback_thermal_meter_jaguar_series(
1121
void *dm_void
1122
)
1123
{
1124
struct dm_struct *dm = (struct dm_struct *)dm_void;
1125
unsigned char thermal_value = 0, delta, delta_LCK, channel, is_decrease;
1126
unsigned char thermal_value_avg_count = 0;
1127
unsigned int thermal_value_avg = 0, reg0x18;
1128
unsigned int bb_swing_reg[4] = {0xc1c, 0xe1c, 0x181c, 0x1a1c};
1129
int ele_D, value32;
1130
char OFDM_index[2], index;
1131
unsigned int i = 0, j = 0, rf_path, max_rf_path = 2, rf;
1132
struct rtl8192cd_priv *priv = dm->priv;
1133
unsigned char OFDM_min_index = 7; /* OFDM BB Swing should be less than +2.5dB, which is required by Arthur and Mimic */
1134
struct dm_iqk_info *iqk_info = &dm->IQK_info;
1135
1136
1137
#ifdef MP_TEST
1138
if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
1139
channel = priv->pshare->working_channel;
1140
if (priv->pshare->mp_txpwr_tracking == false)
1141
return;
1142
} else
1143
#endif
1144
{
1145
channel = (priv->pmib->dot11RFEntry.dot11channel);
1146
}
1147
1148
#if RTL8881A_SUPPORT
1149
if (dm->support_ic_type == ODM_RTL8881A) {
1150
max_rf_path = 1;
1151
if ((get_bonding_type_8881A() == BOND_8881AM || get_bonding_type_8881A() == BOND_8881AN)
1152
&& priv->pshare->rf_ft_var.use_intpa8881A && (*dm->band_type == ODM_BAND_2_4G))
1153
OFDM_min_index = 6; /* intPA - upper bond set to +3 dB (base: -2 dB)ot11RFEntry.phy_band_select == PHY_BAND_2G)) */
1154
else
1155
OFDM_min_index = 10; /* OFDM BB Swing should be less than +1dB, which is required by Arthur and Mimic */
1156
}
1157
#endif
1158
1159
1160
thermal_value = (unsigned char)phy_query_rf_reg(priv, RF_PATH_A, 0x42, 0xfc00, 1); /* 0x42: RF Reg[15:10] 88E */
1161
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther);
1162
1163
1164
/* 4 Query OFDM BB swing default setting Bit[31:21] */
1165
for (rf_path = 0 ; rf_path < max_rf_path ; rf_path++) {
1166
ele_D = phy_query_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000);
1167
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "0x%x:0x%x ([31:21] = 0x%x)\n", bb_swing_reg[rf_path], phy_query_bb_reg(priv, bb_swing_reg[rf_path], MASKDWORD), ele_D);
1168
for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {/* 4 */
1169
if (ele_D == ofdm_swing_table_8812[i]) {
1170
OFDM_index[rf_path] = (unsigned char)i;
1171
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "OFDM_index[%d]=%d\n", rf_path, OFDM_index[rf_path]);
1172
break;
1173
}
1174
}
1175
}
1176
#if 0
1177
/* Query OFDM path A default setting Bit[31:21] */
1178
ele_D = phy_query_bb_reg(priv, 0xc1c, 0xffe00000);
1179
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "0xc1c:0x%x ([31:21] = 0x%x)\n", phy_query_bb_reg(priv, 0xc1c, MASKDWORD), ele_D);
1180
for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {/* 4 */
1181
if (ele_D == ofdm_swing_table_8812[i]) {
1182
OFDM_index[0] = (unsigned char)i;
1183
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "OFDM_index[0]=%d\n", OFDM_index[0]);
1184
break;
1185
}
1186
}
1187
/* Query OFDM path B default setting */
1188
if (rf == 2) {
1189
ele_D = phy_query_bb_reg(priv, 0xe1c, 0xffe00000);
1190
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "0xe1c:0x%x ([32:21] = 0x%x)\n", phy_query_bb_reg(priv, 0xe1c, MASKDWORD), ele_D);
1191
for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {
1192
if (ele_D == ofdm_swing_table_8812[i]) {
1193
OFDM_index[1] = (unsigned char)i;
1194
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "OFDM_index[1]=%d\n", OFDM_index[1]);
1195
break;
1196
}
1197
}
1198
}
1199
#endif
1200
/* Initialize */
1201
if (!priv->pshare->thermal_value) {
1202
priv->pshare->thermal_value = priv->pmib->dot11RFEntry.ther;
1203
priv->pshare->thermal_value_lck = thermal_value;
1204
}
1205
1206
/* calculate average thermal meter */
1207
{
1208
priv->pshare->thermal_value_avg_8812[priv->pshare->thermal_value_avg_index_8812] = thermal_value;
1209
priv->pshare->thermal_value_avg_index_8812++;
1210
if (priv->pshare->thermal_value_avg_index_8812 == AVG_THERMAL_NUM_8812)
1211
priv->pshare->thermal_value_avg_index_8812 = 0;
1212
1213
for (i = 0; i < AVG_THERMAL_NUM_8812; i++) {
1214
if (priv->pshare->thermal_value_avg_8812[i]) {
1215
thermal_value_avg += priv->pshare->thermal_value_avg_8812[i];
1216
thermal_value_avg_count++;
1217
}
1218
}
1219
1220
if (thermal_value_avg_count) {
1221
thermal_value = (unsigned char)(thermal_value_avg / thermal_value_avg_count);
1222
/* printk("AVG Thermal Meter = 0x%x\n", thermal_value); */
1223
}
1224
}
1225
1226
1227
/* 4 If necessary, do power tracking */
1228
1229
if (!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/
1230
return;
1231
1232
if (thermal_value != priv->pshare->thermal_value) {
1233
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** START POWER TRACKING ********\n");
1234
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", thermal_value, priv->pshare->thermal_value, priv->pmib->dot11RFEntry.ther);
1235
delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
1236
delta_LCK = RTL_ABS(thermal_value, priv->pshare->thermal_value_lck);
1237
is_decrease = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 1 : 0);
1238
/* if (*dm->band_type == ODM_BAND_5G) */
1239
{
1240
#ifdef _TRACKING_TABLE_FILE
1241
if (priv->pshare->rf_ft_var.pwr_track_file) {
1242
for (rf_path = 0; rf_path < max_rf_path; rf_path++) {
1243
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "diff: (%s)%d ==> get index from table : %d)\n", (is_decrease ? "-" : "+"), delta, get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0));
1244
if (is_decrease) {
1245
OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] + get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0);
1246
OFDM_index[rf_path] = ((OFDM_index[rf_path] > (OFDM_TABLE_SIZE_8812 - 1)) ? (OFDM_TABLE_SIZE_8812 - 1) : OFDM_index[rf_path]);
1247
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> decrese power ---> new OFDM_INDEX:%d (%d + %d)\n", OFDM_index[rf_path], priv->pshare->OFDM_index0[rf_path], get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0));
1248
#if 0/* RTL8881A_SUPPORT */
1249
if (dm->support_ic_type == ODM_RTL8881A) {
1250
if (priv->pshare->rf_ft_var.pwrtrk_tx_agc_enable) {
1251
if (priv->pshare->add_tx_agc) { /* tx_agc has been added */
1252
add_tx_power88xx_ac(priv, 0);
1253
priv->pshare->add_tx_agc = 0;
1254
priv->pshare->add_tx_agc_index = 0;
1255
}
1256
}
1257
}
1258
#endif
1259
} else {
1260
1261
OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] - get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0);
1262
#if 0/* RTL8881A_SUPPORT */
1263
if (dm->support_ic_type == ODM_RTL8881A) {
1264
if (priv->pshare->rf_ft_var.pwrtrk_tx_agc_enable) {
1265
if (OFDM_index[i] < OFDM_min_index) {
1266
priv->pshare->add_tx_agc_index = (OFDM_min_index - OFDM_index[i]) / 2; /* Calculate Remnant tx_agc value, 2 index for 1 tx_agc */
1267
add_tx_power88xx_ac(priv, priv->pshare->add_tx_agc_index);
1268
priv->pshare->add_tx_agc = 1; /* add_tx_agc Flag = 1 */
1269
OFDM_index[i] = OFDM_min_index;
1270
} else {
1271
if (priv->pshare->add_tx_agc) { /* tx_agc been added */
1272
priv->pshare->add_tx_agc = 0;
1273
priv->pshare->add_tx_agc_index = 0;
1274
add_tx_power88xx_ac(priv, 0); /* minus the added TPI */
1275
}
1276
}
1277
}
1278
}
1279
#else
1280
OFDM_index[rf_path] = ((OFDM_index[rf_path] < OFDM_min_index) ? OFDM_min_index : OFDM_index[rf_path]);
1281
#endif
1282
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> increse power ---> new OFDM_INDEX:%d (%d - %d)\n", OFDM_index[rf_path], priv->pshare->OFDM_index0[rf_path], get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0));
1283
}
1284
}
1285
}
1286
#endif
1287
/* 4 Set new BB swing index */
1288
for (rf_path = 0; rf_path < max_rf_path; rf_path++) {
1289
phy_set_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000, ofdm_swing_table_8812[(unsigned int)OFDM_index[rf_path]]);
1290
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Readback 0x%x[31:21] = 0x%x, OFDM_index:%d\n", bb_swing_reg[rf_path], phy_query_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000), OFDM_index[rf_path]);
1291
}
1292
1293
}
1294
if ((delta_LCK > 8) && (!iqk_info->rfk_forbidden)) {
1295
RTL_W8(0x522, 0xff);
1296
reg0x18 = phy_query_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, 1);
1297
phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 1);
1298
phy_set_rf_reg(priv, RF_PATH_A, 0x18, BIT(15), 1);
1299
delay_ms(200); /* frequency deviation */
1300
phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 0);
1301
phy_set_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, reg0x18);
1302
#ifdef CONFIG_RTL_8812_SUPPORT
1303
if (GET_CHIP_VER(priv) == VERSION_8812E)
1304
update_bbrf_val8812(priv, priv->pmib->dot11RFEntry.dot11channel);
1305
#endif
1306
RTL_W8(0x522, 0x0);
1307
priv->pshare->thermal_value_lck = thermal_value;
1308
}
1309
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** END:%s() ********\n", __FUNCTION__);
1310
1311
/* update thermal meter value */
1312
priv->pshare->thermal_value = thermal_value;
1313
for (rf_path = 0; rf_path < max_rf_path; rf_path++)
1314
priv->pshare->OFDM_index[rf_path] = OFDM_index[rf_path];
1315
}
1316
}
1317
1318
#endif
1319
1320
1321
void
1322
odm_txpowertracking_callback_thermal_meter(
1323
void *dm_void
1324
)
1325
{
1326
struct dm_struct *dm = (struct dm_struct *)dm_void;
1327
struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
1328
struct dm_iqk_info *iqk_info = &dm->IQK_info;
1329
1330
1331
#if (RTL8814B_SUPPORT == 1 || RTL8812F_SUPPORT == 1 || RTL8822C_SUPPORT == 1 || RTL8197G_SUPPORT == 1)
1332
if (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8822C | ODM_RTL8197G)) {
1333
odm_txpowertracking_callback_thermal_meter_jaguar_series4(dm);
1334
return;
1335
}
1336
#endif
1337
#if (RTL8197F_SUPPORT == 1 ||RTL8192F_SUPPORT == 1 || RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1 || RTL8198F_SUPPORT == 1)
1338
if (dm->support_ic_type == ODM_RTL8197F || dm->support_ic_type == ODM_RTL8192F || dm->support_ic_type == ODM_RTL8822B
1339
|| dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8198F) {
1340
odm_txpowertracking_callback_thermal_meter_jaguar_series3(dm);
1341
return;
1342
}
1343
#endif
1344
#if (RTL8814A_SUPPORT == 1) /*use this function to do power tracking after 8814 by YuChen*/
1345
if (dm->support_ic_type & ODM_RTL8814A) {
1346
odm_txpowertracking_callback_thermal_meter_jaguar_series2(dm);
1347
return;
1348
}
1349
#endif
1350
#if (RTL8881A_SUPPORT || RTL8812A_SUPPORT == 1)
1351
if (dm->support_ic_type & ODM_RTL8812 || dm->support_ic_type & ODM_RTL8881A) {
1352
odm_txpowertracking_callback_thermal_meter_jaguar_series(dm);
1353
return;
1354
}
1355
#endif
1356
1357
#if (RTL8192E_SUPPORT == 1)
1358
if (dm->support_ic_type == ODM_RTL8192E) {
1359
odm_txpowertracking_callback_thermal_meter_92e(dm);
1360
return;
1361
}
1362
#endif
1363
1364
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
1365
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
1366
/* PMGNT_INFO mgnt_info = &adapter->mgnt_info; */
1367
#endif
1368
1369
1370
u8 thermal_value = 0, delta, delta_LCK, delta_IQK, offset;
1371
u8 thermal_value_avg_count = 0;
1372
u32 thermal_value_avg = 0;
1373
/* s32 ele_A=0, ele_D, TempCCk, X, value32;
1374
* s32 Y, ele_C=0;
1375
* s8 OFDM_index[2], CCK_index=0, OFDM_index_old[2]={0,0}, CCK_index_old=0, index;
1376
* s8 deltaPowerIndex = 0; */
1377
u32 i = 0;/* , j = 0; */
1378
boolean is2T = false;
1379
/* bool bInteralPA = false; */
1380
1381
u8 OFDM_max_index = 34, rf = (is2T) ? 2 : 1; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
1382
u8 indexforchannel = 0;/*get_right_chnl_place_for_iqk(hal_data->current_channel)*/
1383
enum _POWER_DEC_INC { POWER_DEC, POWER_INC };
1384
1385
struct txpwrtrack_cfg c;
1386
1387
1388
/* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
1389
s8 delta_swing_table_idx[2][index_mapping_NUM_88E] = {
1390
/* {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} */
1391
{0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11}, {0, 0, 1, 2, 3, 4, 4, 4, 4, 5, 7, 8, 9, 9, 10}
1392
};
1393
u8 thermal_threshold[2][index_mapping_NUM_88E] = {
1394
/* {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} */
1395
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27}, {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
1396
};
1397
1398
#if (DM_ODM_SUPPORT_TYPE & ODM_AP)
1399
struct rtl8192cd_priv *priv = dm->priv;
1400
#endif
1401
1402
/* 4 2. Initilization ( 7 steps in total ) */
1403
1404
configure_txpower_track(dm, &c);
1405
1406
dm->rf_calibrate_info.txpowertracking_callback_cnt++; /* cosa add for debug */
1407
dm->rf_calibrate_info.is_txpowertracking_init = true;
1408
1409
#if (MP_DRIVER == 1)
1410
dm->rf_calibrate_info.txpowertrack_control = hal_data->txpowertrack_control; /* <Kordan> We should keep updating the control variable according to HalData.
1411
* <Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
1412
dm->rf_calibrate_info.rega24 = 0x090e1317;
1413
#endif
1414
1415
#if (DM_ODM_SUPPORT_TYPE == ODM_AP) && defined(MP_TEST)
1416
if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
1417
if (dm->priv->pshare->mp_txpwr_tracking == false)
1418
return;
1419
}
1420
#endif
1421
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "===>odm_txpowertracking_callback_thermal_meter_8188e, dm->bb_swing_idx_cck_base: %d, dm->bb_swing_idx_ofdm_base: %d\n", cali_info->bb_swing_idx_cck_base, cali_info->bb_swing_idx_ofdm_base);
1422
/*
1423
if (!dm->rf_calibrate_info.tm_trigger) {
1424
odm_set_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, BIT(17) | BIT(16), 0x3);
1425
dm->rf_calibrate_info.tm_trigger = 1;
1426
return;
1427
}
1428
*/
1429
thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
1430
#if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
1431
if (!thermal_value || !dm->rf_calibrate_info.txpowertrack_control)
1432
#else
1433
if (!dm->rf_calibrate_info.txpowertrack_control)
1434
#endif
1435
return;
1436
1437
/* 4 3. Initialize ThermalValues of rf_calibrate_info */
1438
1439
if (!dm->rf_calibrate_info.thermal_value) {
1440
dm->rf_calibrate_info.thermal_value_lck = thermal_value;
1441
dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
1442
}
1443
1444
if (dm->rf_calibrate_info.is_reloadtxpowerindex)
1445
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "reload ofdm index for band switch\n");
1446
1447
/* 4 4. Calculate average thermal meter */
1448
1449
dm->rf_calibrate_info.thermal_value_avg[dm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
1450
dm->rf_calibrate_info.thermal_value_avg_index++;
1451
if (dm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num)
1452
dm->rf_calibrate_info.thermal_value_avg_index = 0;
1453
1454
for (i = 0; i < c.average_thermal_num; i++) {
1455
if (dm->rf_calibrate_info.thermal_value_avg[i]) {
1456
thermal_value_avg += dm->rf_calibrate_info.thermal_value_avg[i];
1457
thermal_value_avg_count++;
1458
}
1459
}
1460
1461
if (thermal_value_avg_count) {
1462
/* Give the new thermo value a weighting */
1463
thermal_value_avg += (thermal_value * 4);
1464
1465
thermal_value = (u8)(thermal_value_avg / (thermal_value_avg_count + 4));
1466
cali_info->thermal_value_delta = thermal_value - priv->pmib->dot11RFEntry.ther;
1467
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "AVG Thermal Meter = 0x%x\n", thermal_value);
1468
}
1469
1470
/* 4 5. Calculate delta, delta_LCK, delta_IQK. */
1471
1472
delta = (thermal_value > dm->rf_calibrate_info.thermal_value) ? (thermal_value - dm->rf_calibrate_info.thermal_value) : (dm->rf_calibrate_info.thermal_value - thermal_value);
1473
delta_LCK = (thermal_value > dm->rf_calibrate_info.thermal_value_lck) ? (thermal_value - dm->rf_calibrate_info.thermal_value_lck) : (dm->rf_calibrate_info.thermal_value_lck - thermal_value);
1474
delta_IQK = (thermal_value > dm->rf_calibrate_info.thermal_value_iqk) ? (thermal_value - dm->rf_calibrate_info.thermal_value_iqk) : (dm->rf_calibrate_info.thermal_value_iqk - thermal_value);
1475
1476
/* 4 6. If necessary, do LCK. */
1477
if (!(dm->support_ic_type & ODM_RTL8821)) {
1478
/*if((delta_LCK > hal_data->delta_lck) && (hal_data->delta_lck != 0))*/
1479
if ((delta_LCK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
1480
/*Delta temperature is equal to or larger than 20 centigrade.*/
1481
dm->rf_calibrate_info.thermal_value_lck = thermal_value;
1482
(*c.phy_lc_calibrate)(dm);
1483
}
1484
}
1485
1486
/* 3 7. If necessary, move the index of swing table to adjust Tx power. */
1487
1488
if (delta > 0 && dm->rf_calibrate_info.txpowertrack_control) {
1489
1490
delta = (thermal_value > dm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - dm->priv->pmib->dot11RFEntry.ther) : (dm->priv->pmib->dot11RFEntry.ther - thermal_value);
1491
1492
/* 4 7.1 The Final Power index = BaseIndex + power_index_offset */
1493
1494
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
1495
CALCULATE_SWINGTALBE_OFFSET(offset, POWER_INC, index_mapping_NUM_88E, delta);
1496
dm->rf_calibrate_info.delta_power_index_last = dm->rf_calibrate_info.delta_power_index;
1497
dm->rf_calibrate_info.delta_power_index = delta_swing_table_idx[POWER_INC][offset];
1498
1499
} else {
1500
1501
CALCULATE_SWINGTALBE_OFFSET(offset, POWER_DEC, index_mapping_NUM_88E, delta);
1502
dm->rf_calibrate_info.delta_power_index_last = dm->rf_calibrate_info.delta_power_index;
1503
dm->rf_calibrate_info.delta_power_index = (-1) * delta_swing_table_idx[POWER_DEC][offset];
1504
}
1505
1506
if (dm->rf_calibrate_info.delta_power_index == dm->rf_calibrate_info.delta_power_index_last)
1507
dm->rf_calibrate_info.power_index_offset = 0;
1508
else
1509
dm->rf_calibrate_info.power_index_offset = dm->rf_calibrate_info.delta_power_index - dm->rf_calibrate_info.delta_power_index_last;
1510
1511
for (i = 0; i < rf; i++)
1512
dm->rf_calibrate_info.OFDM_index[i] = cali_info->bb_swing_idx_ofdm_base + dm->rf_calibrate_info.power_index_offset;
1513
dm->rf_calibrate_info.CCK_index = cali_info->bb_swing_idx_cck_base + dm->rf_calibrate_info.power_index_offset;
1514
1515
cali_info->bb_swing_idx_cck = dm->rf_calibrate_info.CCK_index;
1516
cali_info->bb_swing_idx_ofdm[RF_PATH_A] = dm->rf_calibrate_info.OFDM_index[RF_PATH_A];
1517
1518
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "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, dm->rf_calibrate_info.power_index_offset);
1519
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "The 'OFDM' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_ofdm[RF_PATH_A], cali_info->bb_swing_idx_ofdm_base, dm->rf_calibrate_info.power_index_offset);
1520
1521
/* 4 7.1 Handle boundary conditions of index. */
1522
1523
1524
for (i = 0; i < rf; i++) {
1525
if (dm->rf_calibrate_info.OFDM_index[i] > OFDM_max_index)
1526
dm->rf_calibrate_info.OFDM_index[i] = OFDM_max_index;
1527
else if (dm->rf_calibrate_info.OFDM_index[i] < 0)
1528
dm->rf_calibrate_info.OFDM_index[i] = 0;
1529
}
1530
1531
if (dm->rf_calibrate_info.CCK_index > c.swing_table_size_cck - 1)
1532
dm->rf_calibrate_info.CCK_index = c.swing_table_size_cck - 1;
1533
else if (dm->rf_calibrate_info.CCK_index < 0)
1534
dm->rf_calibrate_info.CCK_index = 0;
1535
} else {
1536
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"The thermal meter is unchanged or TxPowerTracking OFF: thermal_value: %d, dm->rf_calibrate_info.thermal_value: %d)\n", thermal_value, dm->rf_calibrate_info.thermal_value);
1537
dm->rf_calibrate_info.power_index_offset = 0;
1538
}
1539
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n", dm->rf_calibrate_info.CCK_index, cali_info->bb_swing_idx_cck_base);
1540
1541
RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index: %d\n", dm->rf_calibrate_info.OFDM_index[RF_PATH_A], cali_info->bb_swing_idx_ofdm_base);
1542
1543
if (dm->rf_calibrate_info.power_index_offset != 0 && dm->rf_calibrate_info.txpowertrack_control) {
1544
/* 4 7.2 Configure the Swing Table to adjust Tx Power. */
1545
1546
dm->rf_calibrate_info.is_tx_power_changed = true; /* Always true after Tx Power is adjusted by power tracking. */
1547
/* */
1548
/* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
1549
/* to increase TX power. Otherwise, EVM will be bad. */
1550
/* */
1551
/* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
1552
if (thermal_value > dm->rf_calibrate_info.thermal_value) {
1553
/* RF_DBG(dm,DBG_RF_TX_PWR_TRACK, */
1554
/* "Temperature Increasing: delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", */
1555
/* dm->rf_calibrate_info.power_index_offset, delta, thermal_value, hal_data->eeprom_thermal_meter, dm->rf_calibrate_info.thermal_value); */
1556
} else if (thermal_value < dm->rf_calibrate_info.thermal_value) { /* Low temperature */
1557
/* RF_DBG(dm,DBG_RF_TX_PWR_TRACK, */
1558
/* "Temperature Decreasing: delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", */
1559
/* dm->rf_calibrate_info.power_index_offset, delta, thermal_value, hal_data->eeprom_thermal_meter, dm->rf_calibrate_info.thermal_value); */
1560
}
1561
if (thermal_value > dm->priv->pmib->dot11RFEntry.ther)
1562
{
1563
/* RF_DBG(dm,DBG_RF_TX_PWR_TRACK,"Temperature(%d) hugher than PG value(%d), increases the power by tx_agc\n", thermal_value, hal_data->eeprom_thermal_meter); */
1564
(*c.odm_tx_pwr_track_set_pwr)(dm, TXAGC, 0, 0);
1565
} else {
1566
/* RF_DBG(dm,DBG_RF_TX_PWR_TRACK,"Temperature(%d) lower than PG value(%d), increases the power by tx_agc\n", thermal_value, hal_data->eeprom_thermal_meter); */
1567
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, RF_PATH_A, indexforchannel);
1568
if (is2T)
1569
(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, RF_PATH_B, indexforchannel);
1570
}
1571
1572
cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;
1573
cali_info->bb_swing_idx_ofdm_base = cali_info->bb_swing_idx_ofdm[RF_PATH_A];
1574
dm->rf_calibrate_info.thermal_value = thermal_value;
1575
1576
}
1577
1578
RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===dm_TXPowerTrackingCallback_ThermalMeter_8188E\n");
1579
1580
dm->rf_calibrate_info.tx_powercount = 0;
1581
}
1582
1583
/* 3============================================================
1584
* 3 IQ Calibration
1585
* 3============================================================ */
1586
1587
void
1588
odm_reset_iqk_result(
1589
void *dm_void
1590
)
1591
{
1592
return;
1593
}
1594
#if 1/* !(DM_ODM_SUPPORT_TYPE & ODM_AP) */
1595
u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
1596
{
1597
u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
1598
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
1599
};
1600
u8 place = chnl;
1601
1602
1603
if (chnl > 14) {
1604
for (place = 14; place < sizeof(channel_all); place++) {
1605
if (channel_all[place] == chnl)
1606
return place - 13;
1607
}
1608
}
1609
return 0;
1610
1611
}
1612
#endif
1613
1614
void
1615
odm_iq_calibrate(
1616
struct dm_struct *dm
1617
)
1618
{
1619
struct dm_iqk_info *iqk_info = &dm->IQK_info;
1620
1621
if ((dm->is_linked) && (!iqk_info->rfk_forbidden)) {
1622
if ((*dm->channel != dm->pre_channel) && (!*dm->is_scan_in_process)) {
1623
dm->pre_channel = *dm->channel;
1624
dm->linked_interval = 0;
1625
}
1626
1627
if (dm->linked_interval < 3)
1628
dm->linked_interval++;
1629
1630
if (dm->linked_interval == 2)
1631
halrf_iqk_trigger(dm, false);
1632
} else
1633
dm->linked_interval = 0;
1634
1635
}
1636
1637
void phydm_rf_init(void *dm_void)
1638
{
1639
struct dm_struct *dm = (struct dm_struct *)dm_void;
1640
odm_txpowertracking_init(dm);
1641
1642
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
1643
#if (RTL8814A_SUPPORT == 1)
1644
if (dm->support_ic_type & ODM_RTL8814A)
1645
phy_iq_calibrate_8814a_init(dm);
1646
#endif
1647
#endif
1648
1649
}
1650
1651
void phydm_rf_watchdog(void *dm_void)
1652
{
1653
struct dm_struct *dm = (struct dm_struct *)dm_void;
1654
1655
odm_txpowertracking_check(dm);
1656
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
1657
if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1658
odm_iq_calibrate(dm);
1659
#endif
1660
}
1661
1662