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
odm_clear_txpowertracking_state(void * dm_void)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
configure_txpower_track(void * dm_void,struct txpwrtrack_cfg * config)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
odm_txpowertracking_callback_thermal_meter_92e(void * dm_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
odm_txpowertracking_callback_thermal_meter_jaguar_series4(void * dm_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)) {
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 if (dm->support_ic_type == ODM_RTL8197G) {
440 for (i = 0; i < c.rf_path_count; i++)
441 thermal_value[i] = (u8)odm_get_rf_reg(dm, i, RF_0xf6, 0x7E000);
442 } else {
443 for (i = 0; i < c.rf_path_count; i++) {
444 thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
445
446 if (dm->support_ic_type == ODM_RTL8814B) {
447 thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_multi_thermal_offset(dm, i);
448 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
449 "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + multi_thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_multi_thermal_offset(dm, i));
450 } else {
451 thermal_value_temp[i] = (s8)thermal_value[i] + phydm_get_thermal_offset(dm);
452 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
453 "thermal_value_temp[%d](%d) = thermal_value[%d](%d) + thermal_trim(%d)\n", i, thermal_value_temp[i], i, thermal_value[i], phydm_get_thermal_offset(dm));
454 }
455
456 if (thermal_value_temp[i] > 63)
457 thermal_value[i] = 63;
458 else if (thermal_value_temp[i] < 0)
459 thermal_value[i] = 0;
460 else
461 thermal_value[i] = thermal_value_temp[i];
462 }
463 }
464
465 for (j = 0; j < c.rf_path_count; j++) {
466 cali_info->thermal_value_avg_path[j][cali_info->thermal_value_avg_index_path[j]] = thermal_value[j];
467 cali_info->thermal_value_avg_index_path[j]++;
468 if (cali_info->thermal_value_avg_index_path[j] == c.average_thermal_num) /*Average times = c.average_thermal_num*/
469 cali_info->thermal_value_avg_index_path[j] = 0;
470
471
472 for (i = 0; i < c.average_thermal_num; i++) {
473 if (cali_info->thermal_value_avg_path[j][i]) {
474 thermal_value_avg[j] += cali_info->thermal_value_avg_path[j][i];
475 thermal_value_avg_count[j]++;
476 }
477 }
478
479 if (thermal_value_avg_count[j]) { /* Calculate Average thermal_value after average enough times */
480 thermal_value[j] = (u8)(thermal_value_avg[j] / thermal_value_avg_count[j]);
481 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
482 "PGthermal[%d] = 0x%x(%d), AVG Thermal Meter = 0x%x(%d)\n", j,
483 priv->pmib->dot11RFEntry.thermal[j],
484 priv->pmib->dot11RFEntry.thermal[j],
485 thermal_value[j],
486 thermal_value[j]);
487 }
488 /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
489
490 /* "delta" here is used to determine whether thermal value changes or not. */
491 delta[j] = RTL_ABS(thermal_value[j], priv->pmib->dot11RFEntry.thermal[j]);
492 delta_LCK = RTL_ABS(thermal_value[RF_PATH_A], dm->rf_calibrate_info.thermal_value_lck);
493 delta_IQK = RTL_ABS(thermal_value[RF_PATH_A], dm->rf_calibrate_info.thermal_value_iqk);
494 }
495
496 /*4 6. If necessary, do LCK.*/
497 for (i = 0; i < c.rf_path_count; i++)
498 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);
499
500 /* Wait sacn to do LCK by RF Jenyu*/
501 if( (*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden)) {
502 /* Delta temperature is equal to or larger than 20 centigrade.*/
503 if (delta_LCK >= c.threshold_iqk) {
504 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
505 cali_info->thermal_value_lck = thermal_value[RF_PATH_A];
506
507 /*Use RTLCK, so close power tracking driver LCK*/
508 if ((!(dm->support_ic_type & ODM_RTL8814A)) && (!(dm->support_ic_type & ODM_RTL8822B))) {
509 if (c.phy_lc_calibrate)
510 (*c.phy_lc_calibrate)(dm);
511 } else
512 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do not do LCK\n");
513 }
514 }
515
516 /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
517 #ifdef _TRACKING_TABLE_FILE
518 for (i = 0; i < c.rf_path_count; i++) {
519 if (i == RF_PATH_B) {
520 odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_b, DELTA_SWINGIDX_SIZE);
521 odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_b, DELTA_SWINGIDX_SIZE);
522 } else if (i == RF_PATH_C) {
523 odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_c, DELTA_SWINGIDX_SIZE);
524 odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_c, DELTA_SWINGIDX_SIZE);
525 } else if (i == RF_PATH_D) {
526 odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_d, DELTA_SWINGIDX_SIZE);
527 odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_d, DELTA_SWINGIDX_SIZE);
528 } else {
529 odm_move_memory(dm, delta_swing_table_idx_tup, pwrtrk_tab_up_a, DELTA_SWINGIDX_SIZE);
530 odm_move_memory(dm, delta_swing_table_idx_tdown, pwrtrk_tab_down_a, DELTA_SWINGIDX_SIZE);
531 }
532
533 cali_info->delta_power_index_last_path[i] = cali_info->delta_power_index_path[i]; /*recording poer index offset*/
534 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]);
535
536 if (delta[i] >= TXPWR_TRACK_TABLE_SIZE)
537 delta[i] = TXPWR_TRACK_TABLE_SIZE - 1;
538
539 if (thermal_value[i] > priv->pmib->dot11RFEntry.thermal[i]) {
540 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
541 "delta_swing_table_idx_tup[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tup[delta[i]], i);
542
543 cali_info->delta_power_index_path[i] = delta_swing_table_idx_tup[delta[i]];
544 cali_info->absolute_ofdm_swing_idx[i] = delta_swing_table_idx_tup[delta[i]]; /*Record delta swing for mix mode power tracking*/
545 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
546 "******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);
547 } else {
548 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
549 "delta_swing_table_idx_tdown[%d]=%d Path=%d\n", delta[i], delta_swing_table_idx_tdown[delta[i]], i);
550 cali_info->delta_power_index_path[i] = -1 * delta_swing_table_idx_tdown[delta[i]];
551 cali_info->absolute_ofdm_swing_idx[i] = -1 * delta_swing_table_idx_tdown[delta[i]]; /*Record delta swing for mix mode power tracking*/
552 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
553 "******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);
554 }
555 }
556
557 #endif
558
559 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
560 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*/
561 cali_info->power_index_offset_path[p] = 0;
562 else
563 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*/
564 }
565
566 #if 0
567 if (dm->support_ic_type == ODM_RTL8814B) {
568 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
569 for (p = RF_PATH_A; p < c.rf_path_count; p++)
570 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
571 } else {
572 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
573 for (p = RF_PATH_A; p < c.rf_path_count; p++)
574 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);
575 }
576 #else
577 if (*dm->mp_mode == 1) {
578 if (cali_info->txpowertrack_control == 1) {
579 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
580 tracking_method = MIX_MODE;
581 } else if (cali_info->txpowertrack_control == 3) {
582 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");
583 tracking_method = TSSI_MODE;
584 }
585 } else {
586 if (dm->priv->pmib->dot11RFEntry.tssi_enable == 0) {
587 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
588 tracking_method = MIX_MODE;
589 } else if (dm->priv->pmib->dot11RFEntry.tssi_enable == 1) {
590 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking TSSI_MODE**********\n");
591 tracking_method = TSSI_MODE;
592 }
593 }
594
595 if (dm->support_ic_type == ODM_RTL8822C || dm->support_ic_type == ODM_RTL8812F ||
596 dm->support_ic_type == ODM_RTL8814B || dm->support_ic_type == ODM_RTL8197G)
597 for (p = RF_PATH_A; p < c.rf_path_count; p++)
598 (*c.odm_tx_pwr_track_set_pwr)(dm, tracking_method, p, 0);
599
600 #endif
601 /* Wait sacn to do IQK by RF Jenyu*/
602 if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) {
603 /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
604 if (delta_IQK >= c.threshold_iqk) {
605 cali_info->thermal_value_iqk = thermal_value[RF_PATH_A];
606 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
607
608 /*if (!cali_info->is_iqk_in_progress)*/
609 /* (*c.do_iqk)(dm, delta_IQK, thermal_value[RF_PATH_A], 8);*/
610 /*RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do IQK\n");*/
611
612 /*if (!cali_info->is_iqk_in_progress)*/
613 /* (*c.do_tssi_dck)(dm, true);*/
614 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Do TSSI DCK\n");
615 }
616 }
617
618 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===%s\n", __func__);
619
620 cali_info->tx_powercount = 0;
621 }
622 #endif
623
624 #if (RTL8197F_SUPPORT == 1 || RTL8192F_SUPPORT == 1 || RTL8822B_SUPPORT == 1 ||\
625 RTL8821C_SUPPORT == 1 || RTL8198F_SUPPORT == 1)
626 void
odm_txpowertracking_callback_thermal_meter_jaguar_series3(void * dm_void)627 odm_txpowertracking_callback_thermal_meter_jaguar_series3(
628 void *dm_void
629 )
630 {
631 #if 1
632 struct dm_struct *dm = (struct dm_struct *)dm_void;
633 u8 thermal_value = 0, delta, delta_LCK, delta_IQK, channel, is_increase;
634 u8 thermal_value_avg_count = 0, p = 0, i = 0;
635 u32 thermal_value_avg = 0;
636 struct rtl8192cd_priv *priv = dm->priv;
637 struct txpwrtrack_cfg c;
638 struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
639 struct dm_iqk_info *iqk_info = &dm->IQK_info;
640 struct _hal_rf_ *rf = &dm->rf_table;
641 /*The following tables decide the final index of OFDM/CCK swing table.*/
642 u8 *pwrtrk_tab_up_a = NULL, *pwrtrk_tab_down_a = NULL;
643 u8 *pwrtrk_tab_up_b = NULL, *pwrtrk_tab_down_b = NULL;
644 u8 *pwrtrk_tab_up_cck_a = NULL, *pwrtrk_tab_down_cck_a = NULL;
645 u8 *pwrtrk_tab_up_cck_b = NULL, *pwrtrk_tab_down_cck_b = NULL;
646 /*for 8814 add by Yu Chen*/
647 u8 *pwrtrk_tab_up_c = NULL, *pwrtrk_tab_down_c = NULL;
648 u8 *pwrtrk_tab_up_d = NULL, *pwrtrk_tab_down_d = NULL;
649 u8 *pwrtrk_tab_up_cck_c = NULL, *pwrtrk_tab_down_cck_c = NULL;
650 u8 *pwrtrk_tab_up_cck_d = NULL, *pwrtrk_tab_down_cck_d = NULL;
651 s8 thermal_value_temp = 0;
652
653 #ifdef MP_TEST
654 if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
655 channel = priv->pshare->working_channel;
656 if (priv->pshare->mp_txpwr_tracking == false)
657 return;
658 } else
659 #endif
660 {
661 channel = (priv->pmib->dot11RFEntry.dot11channel);
662 }
663
664 configure_txpower_track(dm, &c);
665
666 (*c.get_delta_all_swing_table)(dm,
667 (u8 **)&pwrtrk_tab_up_a, (u8 **)&pwrtrk_tab_down_a,
668 (u8 **)&pwrtrk_tab_up_b, (u8 **)&pwrtrk_tab_down_b,
669 (u8 **)&pwrtrk_tab_up_cck_a, (u8 **)&pwrtrk_tab_down_cck_a,
670 (u8 **)&pwrtrk_tab_up_cck_b, (u8 **)&pwrtrk_tab_down_cck_b);
671
672 if (GET_CHIP_VER(priv) == VERSION_8198F) {
673 (*c.get_delta_all_swing_table_ex)(dm,
674 (u8 **)&pwrtrk_tab_up_c, (u8 **)&pwrtrk_tab_down_c,
675 (u8 **)&pwrtrk_tab_up_d, (u8 **)&pwrtrk_tab_down_d,
676 (u8 **)&pwrtrk_tab_up_cck_c, (u8 **)&pwrtrk_tab_down_cck_c,
677 (u8 **)&pwrtrk_tab_up_cck_d, (u8 **)&pwrtrk_tab_down_cck_d);
678 }
679 /*0x42: RF Reg[15:10] 88E*/
680 thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00);
681 #ifdef THER_TRIM
682 if (GET_CHIP_VER(priv) == VERSION_8197F) {
683 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);
684
685 thermal_value += priv->pshare->rf_ft_var.ther_trim_val;
686
687 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"after thermal trim, thermal_value=%d\n", thermal_value);
688 }
689
690 if (GET_CHIP_VER(priv) == VERSION_8198F) {
691 thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);
692
693 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
694 "thermal_value_temp(%d) = ther_value(%d) + ther_trim_ther(%d)\n",
695 thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));
696
697 if (thermal_value_temp > 63)
698 thermal_value = 63;
699 else if (thermal_value_temp < 0)
700 thermal_value = 0;
701 else
702 thermal_value = thermal_value_temp;
703 }
704 #endif
705
706 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"\n\n\nCurrent Thermal = 0x%x(%d) EEPROMthermalmeter 0x%x(%d)\n"
707 , thermal_value, thermal_value, priv->pmib->dot11RFEntry.ther, priv->pmib->dot11RFEntry.ther);
708
709 /* Initialize */
710 if (!dm->rf_calibrate_info.thermal_value)
711 dm->rf_calibrate_info.thermal_value = priv->pmib->dot11RFEntry.ther;
712
713 if (!dm->rf_calibrate_info.thermal_value_lck)
714 dm->rf_calibrate_info.thermal_value_lck = priv->pmib->dot11RFEntry.ther;
715
716 if (!dm->rf_calibrate_info.thermal_value_iqk)
717 dm->rf_calibrate_info.thermal_value_iqk = priv->pmib->dot11RFEntry.ther;
718
719 /* calculate average thermal meter */
720 dm->rf_calibrate_info.thermal_value_avg[dm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
721 dm->rf_calibrate_info.thermal_value_avg_index++;
722
723 if (dm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
724 dm->rf_calibrate_info.thermal_value_avg_index = 0;
725
726 for (i = 0; i < c.average_thermal_num; i++) {
727 if (dm->rf_calibrate_info.thermal_value_avg[i]) {
728 thermal_value_avg += dm->rf_calibrate_info.thermal_value_avg[i];
729 thermal_value_avg_count++;
730 }
731 }
732
733 if (thermal_value_avg_count) {/*Calculate Average thermal_value after average enough times*/
734 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"thermal_value_avg=0x%x(%d) thermal_value_avg_count = %d\n"
735 , thermal_value_avg, thermal_value_avg, thermal_value_avg_count);
736
737 thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
738
739 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);
740 }
741
742 /*4 Calculate delta, delta_LCK, delta_IQK.*/
743 delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
744 delta_LCK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_lck);
745 delta_IQK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_iqk);
746 is_increase = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 0 : 1);
747
748 if (delta > 29) { /* power track table index(thermal diff.) upper bound*/
749 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta(%d) > 29, set delta to 29\n", delta);
750 delta = 29;
751 }
752
753 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);
754
755 /*4 if necessary, do LCK.*/
756 if ((delta_LCK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
757 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
758 dm->rf_calibrate_info.thermal_value_lck = thermal_value;
759 #if (RTL8822B_SUPPORT != 1)
760 if (!(dm->support_ic_type & ODM_RTL8822B)) {
761 if (c.phy_lc_calibrate)
762 (*c.phy_lc_calibrate)(dm);
763 }
764 #endif
765 }
766
767 if (!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/
768 return;
769
770 /*4 Do Power Tracking*/
771
772 if (thermal_value != dm->rf_calibrate_info.thermal_value) {
773 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"******** START POWER TRACKING ********\n");
774 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"Readback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n",
775 thermal_value, dm->rf_calibrate_info.thermal_value, priv->pmib->dot11RFEntry.ther);
776
777 #ifdef _TRACKING_TABLE_FILE
778 if (priv->pshare->rf_ft_var.pwr_track_file) {
779 if (is_increase) { /*thermal is higher than base*/
780 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
781 switch (p) {
782 case RF_PATH_B:
783 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]);
784 cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_b[delta];
785 cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_b[delta];
786 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]);
787 break;
788
789 case RF_PATH_C:
790 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]);
791 cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_c[delta];
792 cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_c[delta];
793 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]);
794 break;
795
796 case RF_PATH_D:
797 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]);
798 cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_d[delta];
799 cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_d[delta];
800 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]);
801 break;
802 default:
803 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]);
804 cali_info->absolute_ofdm_swing_idx[p] = pwrtrk_tab_up_a[delta];
805 cali_info->absolute_cck_swing_idx[p] = pwrtrk_tab_up_cck_a[delta];
806 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]);
807 break;
808 }
809 }
810 } else { /* thermal is lower than base*/
811 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
812 switch (p) {
813 case RF_PATH_B:
814 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]);
815 cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_b[delta];
816 cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_b[delta];
817 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]);
818 break;
819
820 case RF_PATH_C:
821 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]);
822 cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_c[delta];
823 cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_c[delta];
824 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]);
825 break;
826
827 case RF_PATH_D:
828 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]);
829 cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_d[delta];
830 cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_d[delta];
831 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]);
832 break;
833
834 default:
835 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]);
836 cali_info->absolute_ofdm_swing_idx[p] = -1 * pwrtrk_tab_down_a[delta];
837 cali_info->absolute_cck_swing_idx[p] = -1 * pwrtrk_tab_down_cck_a[delta];
838 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]);
839 break;
840 }
841 }
842 }
843
844 if (is_increase) {
845 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> increse power --->\n");
846 if (GET_CHIP_VER(priv) == VERSION_8197F) {
847 for (p = RF_PATH_A; p < c.rf_path_count; p++)
848 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);
849 } else if (GET_CHIP_VER(priv) == VERSION_8192F) {
850 for (p = RF_PATH_A; p < c.rf_path_count; p++)
851 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
852 } else if (GET_CHIP_VER(priv) == VERSION_8822B) {
853 for (p = RF_PATH_A; p < c.rf_path_count; p++)
854 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
855 } else if (GET_CHIP_VER(priv) == VERSION_8821C) {
856 for (p = RF_PATH_A; p < c.rf_path_count; p++)
857 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
858 } else if (GET_CHIP_VER(priv) == VERSION_8198F) {
859 for (p = RF_PATH_A; p < c.rf_path_count; p++)
860 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
861 } else if (GET_CHIP_VER(priv) == VERSION_8192F) {
862 for (p = RF_PATH_A; p < c.rf_path_count; p++)
863 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
864 }
865 } else {
866 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> decrese power --->\n");
867 if (GET_CHIP_VER(priv) == VERSION_8197F) {
868 for (p = RF_PATH_A; p < c.rf_path_count; p++)
869 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, 0);
870 } else if (GET_CHIP_VER(priv) == VERSION_8192F) {
871 for (p = RF_PATH_A; p < c.rf_path_count; p++)
872 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
873 } else if (GET_CHIP_VER(priv) == VERSION_8822B) {
874 for (p = RF_PATH_A; p < c.rf_path_count; p++)
875 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
876 } else if (GET_CHIP_VER(priv) == VERSION_8821C) {
877 for (p = RF_PATH_A; p < c.rf_path_count; p++)
878 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
879 } else if (GET_CHIP_VER(priv) == VERSION_8198F) {
880 for (p = RF_PATH_A; p < c.rf_path_count; p++)
881 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
882 } else if (GET_CHIP_VER(priv) == VERSION_8192F) {
883 for (p = RF_PATH_A; p < c.rf_path_count; p++)
884 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
885 }
886 }
887 }
888 #endif
889
890 if (GET_CHIP_VER(priv) != VERSION_8198F) {
891 if ((delta_IQK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden) && dm->is_linked) {
892 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
893 dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
894 if (!(dm->support_ic_type & ODM_RTL8197F)) {
895 if (c.do_iqk)
896 (*c.do_iqk)(dm, false, thermal_value, 0);
897 }
898 }
899 }
900
901 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** END:%s() ********\n\n", __func__);
902 /*update thermal meter value*/
903 dm->rf_calibrate_info.thermal_value = thermal_value;
904
905 }
906
907 #endif
908 }
909 #endif
910
911 /*#if (RTL8814A_SUPPORT == 1)*/
912 #if (RTL8814A_SUPPORT == 1)
913
914 void
odm_txpowertracking_callback_thermal_meter_jaguar_series2(void * dm_void)915 odm_txpowertracking_callback_thermal_meter_jaguar_series2(
916 void *dm_void
917 )
918 {
919 struct dm_struct *dm = (struct dm_struct *)dm_void;
920 u8 thermal_value = 0, delta, delta_LCK, delta_IQK, channel, is_increase;
921 u8 thermal_value_avg_count = 0, p = 0, i = 0;
922 u32 thermal_value_avg = 0, reg0x18;
923 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};
924 s32 ele_D;
925 u32 bb_swing_idx;
926 struct rtl8192cd_priv *priv = dm->priv;
927 struct txpwrtrack_cfg c;
928 boolean is_tssi_enable = false;
929 struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
930 struct dm_iqk_info *iqk_info = &dm->IQK_info;
931
932 /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
933 u8 *delta_swing_table_idx_tup_a = NULL, *delta_swing_table_idx_tdown_a = NULL;
934 u8 *delta_swing_table_idx_tup_b = NULL, *delta_swing_table_idx_tdown_b = NULL;
935 /* for 8814 add by Yu Chen */
936 u8 *delta_swing_table_idx_tup_c = NULL, *delta_swing_table_idx_tdown_c = NULL;
937 u8 *delta_swing_table_idx_tup_d = NULL, *delta_swing_table_idx_tdown_d = NULL;
938
939 #ifdef MP_TEST
940 if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
941 channel = priv->pshare->working_channel;
942 if (priv->pshare->mp_txpwr_tracking == false)
943 return;
944 } else
945 #endif
946 {
947 channel = (priv->pmib->dot11RFEntry.dot11channel);
948 }
949
950 configure_txpower_track(dm, &c);
951 cali_info->default_ofdm_index = priv->pshare->OFDM_index0[RF_PATH_A];
952
953 (*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
954 (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
955
956 if (dm->support_ic_type & ODM_RTL8814A) /* for 8814 path C & D */
957 (*c.get_delta_swing_table8814only)(dm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
958 (u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
959
960 thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
961 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);
962
963 /* Initialize */
964 if (!dm->rf_calibrate_info.thermal_value)
965 dm->rf_calibrate_info.thermal_value = priv->pmib->dot11RFEntry.ther;
966
967 if (!dm->rf_calibrate_info.thermal_value_lck)
968 dm->rf_calibrate_info.thermal_value_lck = priv->pmib->dot11RFEntry.ther;
969
970 if (!dm->rf_calibrate_info.thermal_value_iqk)
971 dm->rf_calibrate_info.thermal_value_iqk = priv->pmib->dot11RFEntry.ther;
972
973 is_tssi_enable = (boolean)odm_get_rf_reg(dm, RF_PATH_A, REG_RF_TX_GAIN_OFFSET, BIT(7)); /* check TSSI enable */
974
975 /* 4 Query OFDM BB swing default setting Bit[31:21] */
976 for (p = RF_PATH_A ; p < c.rf_path_count ; p++) {
977 ele_D = odm_get_bb_reg(dm, bb_swing_reg[p], 0xffe00000);
978 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);
979
980 for (bb_swing_idx = 0; bb_swing_idx < TXSCALE_TABLE_SIZE; bb_swing_idx++) {/* 4 */
981 if (ele_D == tx_scaling_table_jaguar[bb_swing_idx]) {
982 dm->rf_calibrate_info.OFDM_index[p] = (u8)bb_swing_idx;
983 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"OFDM_index[%d]=%d\n", p, dm->rf_calibrate_info.OFDM_index[p]);
984 break;
985 }
986 }
987 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "kfree_offset[%d]=%d\n", p, cali_info->kfree_offset[p]);
988
989 }
990
991 /* calculate average thermal meter */
992 dm->rf_calibrate_info.thermal_value_avg[dm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
993 dm->rf_calibrate_info.thermal_value_avg_index++;
994 if (dm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num) /* Average times = c.average_thermal_num */
995 dm->rf_calibrate_info.thermal_value_avg_index = 0;
996
997 for (i = 0; i < c.average_thermal_num; i++) {
998 if (dm->rf_calibrate_info.thermal_value_avg[i]) {
999 thermal_value_avg += dm->rf_calibrate_info.thermal_value_avg[i];
1000 thermal_value_avg_count++;
1001 }
1002 }
1003
1004 if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
1005 thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
1006 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"AVG Thermal Meter = 0x%X, EEPROMthermalmeter = 0x%X\n", thermal_value, priv->pmib->dot11RFEntry.ther);
1007 }
1008
1009 /* 4 Calculate delta, delta_LCK, delta_IQK. */
1010 delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
1011 delta_LCK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_lck);
1012 delta_IQK = RTL_ABS(thermal_value, dm->rf_calibrate_info.thermal_value_iqk);
1013 is_increase = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 0 : 1);
1014
1015 /* 4 if necessary, do LCK. */
1016 if (!(dm->support_ic_type & ODM_RTL8821)) {
1017 if ((delta_LCK > c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
1018 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
1019 dm->rf_calibrate_info.thermal_value_lck = thermal_value;
1020
1021 /*Use RTLCK, so close power tracking driver LCK*/
1022 #if (RTL8814A_SUPPORT != 1)
1023 if (!(dm->support_ic_type & ODM_RTL8814A)) {
1024 if (c.phy_lc_calibrate)
1025 (*c.phy_lc_calibrate)(dm);
1026 }
1027 #endif
1028 }
1029 }
1030
1031 if ((delta_IQK > c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
1032 panic_printk("%s(%d)\n", __FUNCTION__, __LINE__);
1033 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
1034 dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
1035 if (c.do_iqk)
1036 (*c.do_iqk)(dm, true, 0, 0);
1037 }
1038
1039 if (!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/
1040 return;
1041
1042 /* 4 Do Power Tracking */
1043
1044 if (is_tssi_enable == true) {
1045 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter PURE TSSI MODE**********\n");
1046 for (p = RF_PATH_A; p < c.rf_path_count; p++)
1047 (*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p, 0);
1048 } else if (thermal_value != dm->rf_calibrate_info.thermal_value) {
1049 RF_DBG(dm, DBG_RF_TX_PWR_TRACK,"\n******** START POWER TRACKING ********\n");
1050 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);
1051
1052 #ifdef _TRACKING_TABLE_FILE
1053 if (priv->pshare->rf_ft_var.pwr_track_file) {
1054 if (is_increase) { /* thermal is higher than base */
1055 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
1056 switch (p) {
1057 case RF_PATH_B:
1058 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]);
1059 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /* Record delta swing for mix mode power tracking */
1060 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]);
1061 break;
1062
1063 case RF_PATH_C:
1064 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]);
1065 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /* Record delta swing for mix mode power tracking */
1066 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]);
1067 break;
1068
1069 case RF_PATH_D:
1070 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]);
1071 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /* Record delta swing for mix mode power tracking */
1072 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]);
1073 break;
1074
1075 default:
1076 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]);
1077 cali_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /* Record delta swing for mix mode power tracking */
1078 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]);
1079 break;
1080 }
1081 }
1082 } else { /* thermal is lower than base */
1083 for (p = RF_PATH_A; p < c.rf_path_count; p++) {
1084 switch (p) {
1085 case RF_PATH_B:
1086 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]);
1087 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /* Record delta swing for mix mode power tracking */
1088 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]);
1089 break;
1090
1091 case RF_PATH_C:
1092 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]);
1093 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /* Record delta swing for mix mode power tracking */
1094 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]);
1095 break;
1096
1097 case RF_PATH_D:
1098 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]);
1099 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /* Record delta swing for mix mode power tracking */
1100 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]);
1101 break;
1102
1103 default:
1104 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]);
1105 cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /* Record delta swing for mix mode power tracking */
1106 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]);
1107 break;
1108 }
1109 }
1110 }
1111
1112 if (is_increase) {
1113 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> increse power --->\n");
1114 for (p = RF_PATH_A; p < c.rf_path_count; p++)
1115 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
1116 } else {
1117 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, ">>> decrese power --->\n");
1118 for (p = RF_PATH_A; p < c.rf_path_count; p++)
1119 (*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
1120 }
1121 }
1122 #endif
1123
1124 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** END:%s() ********\n", __FUNCTION__);
1125 /* update thermal meter value */
1126 dm->rf_calibrate_info.thermal_value = thermal_value;
1127
1128 }
1129 }
1130 #endif
1131
1132 #if (RTL8812A_SUPPORT == 1 || RTL8881A_SUPPORT == 1)
1133 void
odm_txpowertracking_callback_thermal_meter_jaguar_series(void * dm_void)1134 odm_txpowertracking_callback_thermal_meter_jaguar_series(
1135 void *dm_void
1136 )
1137 {
1138 struct dm_struct *dm = (struct dm_struct *)dm_void;
1139 unsigned char thermal_value = 0, delta, delta_LCK, channel, is_decrease;
1140 unsigned char thermal_value_avg_count = 0;
1141 unsigned int thermal_value_avg = 0, reg0x18;
1142 unsigned int bb_swing_reg[4] = {0xc1c, 0xe1c, 0x181c, 0x1a1c};
1143 int ele_D, value32;
1144 char OFDM_index[2], index;
1145 unsigned int i = 0, j = 0, rf_path, max_rf_path = 2, rf;
1146 struct rtl8192cd_priv *priv = dm->priv;
1147 unsigned char OFDM_min_index = 7; /* OFDM BB Swing should be less than +2.5dB, which is required by Arthur and Mimic */
1148 struct dm_iqk_info *iqk_info = &dm->IQK_info;
1149
1150
1151 #ifdef MP_TEST
1152 if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
1153 channel = priv->pshare->working_channel;
1154 if (priv->pshare->mp_txpwr_tracking == false)
1155 return;
1156 } else
1157 #endif
1158 {
1159 channel = (priv->pmib->dot11RFEntry.dot11channel);
1160 }
1161
1162 #if RTL8881A_SUPPORT
1163 if (dm->support_ic_type == ODM_RTL8881A) {
1164 max_rf_path = 1;
1165 if ((get_bonding_type_8881A() == BOND_8881AM || get_bonding_type_8881A() == BOND_8881AN)
1166 && priv->pshare->rf_ft_var.use_intpa8881A && (*dm->band_type == ODM_BAND_2_4G))
1167 OFDM_min_index = 6; /* intPA - upper bond set to +3 dB (base: -2 dB)ot11RFEntry.phy_band_select == PHY_BAND_2G)) */
1168 else
1169 OFDM_min_index = 10; /* OFDM BB Swing should be less than +1dB, which is required by Arthur and Mimic */
1170 }
1171 #endif
1172
1173
1174 thermal_value = (unsigned char)phy_query_rf_reg(priv, RF_PATH_A, 0x42, 0xfc00, 1); /* 0x42: RF Reg[15:10] 88E */
1175 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);
1176
1177
1178 /* 4 Query OFDM BB swing default setting Bit[31:21] */
1179 for (rf_path = 0 ; rf_path < max_rf_path ; rf_path++) {
1180 ele_D = phy_query_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000);
1181 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);
1182 for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {/* 4 */
1183 if (ele_D == ofdm_swing_table_8812[i]) {
1184 OFDM_index[rf_path] = (unsigned char)i;
1185 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "OFDM_index[%d]=%d\n", rf_path, OFDM_index[rf_path]);
1186 break;
1187 }
1188 }
1189 }
1190 #if 0
1191 /* Query OFDM path A default setting Bit[31:21] */
1192 ele_D = phy_query_bb_reg(priv, 0xc1c, 0xffe00000);
1193 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);
1194 for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {/* 4 */
1195 if (ele_D == ofdm_swing_table_8812[i]) {
1196 OFDM_index[0] = (unsigned char)i;
1197 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "OFDM_index[0]=%d\n", OFDM_index[0]);
1198 break;
1199 }
1200 }
1201 /* Query OFDM path B default setting */
1202 if (rf == 2) {
1203 ele_D = phy_query_bb_reg(priv, 0xe1c, 0xffe00000);
1204 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);
1205 for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {
1206 if (ele_D == ofdm_swing_table_8812[i]) {
1207 OFDM_index[1] = (unsigned char)i;
1208 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "OFDM_index[1]=%d\n", OFDM_index[1]);
1209 break;
1210 }
1211 }
1212 }
1213 #endif
1214 /* Initialize */
1215 if (!priv->pshare->thermal_value) {
1216 priv->pshare->thermal_value = priv->pmib->dot11RFEntry.ther;
1217 priv->pshare->thermal_value_lck = thermal_value;
1218 }
1219
1220 /* calculate average thermal meter */
1221 {
1222 priv->pshare->thermal_value_avg_8812[priv->pshare->thermal_value_avg_index_8812] = thermal_value;
1223 priv->pshare->thermal_value_avg_index_8812++;
1224 if (priv->pshare->thermal_value_avg_index_8812 == AVG_THERMAL_NUM_8812)
1225 priv->pshare->thermal_value_avg_index_8812 = 0;
1226
1227 for (i = 0; i < AVG_THERMAL_NUM_8812; i++) {
1228 if (priv->pshare->thermal_value_avg_8812[i]) {
1229 thermal_value_avg += priv->pshare->thermal_value_avg_8812[i];
1230 thermal_value_avg_count++;
1231 }
1232 }
1233
1234 if (thermal_value_avg_count) {
1235 thermal_value = (unsigned char)(thermal_value_avg / thermal_value_avg_count);
1236 /* printk("AVG Thermal Meter = 0x%x\n", thermal_value); */
1237 }
1238 }
1239
1240
1241 /* 4 If necessary, do power tracking */
1242
1243 if (!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/
1244 return;
1245
1246 if (thermal_value != priv->pshare->thermal_value) {
1247 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** START POWER TRACKING ********\n");
1248 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);
1249 delta = RTL_ABS(thermal_value, priv->pmib->dot11RFEntry.ther);
1250 delta_LCK = RTL_ABS(thermal_value, priv->pshare->thermal_value_lck);
1251 is_decrease = ((thermal_value < priv->pmib->dot11RFEntry.ther) ? 1 : 0);
1252 /* if (*dm->band_type == ODM_BAND_5G) */
1253 {
1254 #ifdef _TRACKING_TABLE_FILE
1255 if (priv->pshare->rf_ft_var.pwr_track_file) {
1256 for (rf_path = 0; rf_path < max_rf_path; rf_path++) {
1257 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));
1258 if (is_decrease) {
1259 OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] + get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0);
1260 OFDM_index[rf_path] = ((OFDM_index[rf_path] > (OFDM_TABLE_SIZE_8812 - 1)) ? (OFDM_TABLE_SIZE_8812 - 1) : OFDM_index[rf_path]);
1261 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));
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 (priv->pshare->add_tx_agc) { /* tx_agc has been added */
1266 add_tx_power88xx_ac(priv, 0);
1267 priv->pshare->add_tx_agc = 0;
1268 priv->pshare->add_tx_agc_index = 0;
1269 }
1270 }
1271 }
1272 #endif
1273 } else {
1274
1275 OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] - get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0);
1276 #if 0/* RTL8881A_SUPPORT */
1277 if (dm->support_ic_type == ODM_RTL8881A) {
1278 if (priv->pshare->rf_ft_var.pwrtrk_tx_agc_enable) {
1279 if (OFDM_index[i] < OFDM_min_index) {
1280 priv->pshare->add_tx_agc_index = (OFDM_min_index - OFDM_index[i]) / 2; /* Calculate Remnant tx_agc value, 2 index for 1 tx_agc */
1281 add_tx_power88xx_ac(priv, priv->pshare->add_tx_agc_index);
1282 priv->pshare->add_tx_agc = 1; /* add_tx_agc Flag = 1 */
1283 OFDM_index[i] = OFDM_min_index;
1284 } else {
1285 if (priv->pshare->add_tx_agc) { /* tx_agc been added */
1286 priv->pshare->add_tx_agc = 0;
1287 priv->pshare->add_tx_agc_index = 0;
1288 add_tx_power88xx_ac(priv, 0); /* minus the added TPI */
1289 }
1290 }
1291 }
1292 }
1293 #else
1294 OFDM_index[rf_path] = ((OFDM_index[rf_path] < OFDM_min_index) ? OFDM_min_index : OFDM_index[rf_path]);
1295 #endif
1296 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));
1297 }
1298 }
1299 }
1300 #endif
1301 /* 4 Set new BB swing index */
1302 for (rf_path = 0; rf_path < max_rf_path; rf_path++) {
1303 phy_set_bb_reg(priv, bb_swing_reg[rf_path], 0xffe00000, ofdm_swing_table_8812[(unsigned int)OFDM_index[rf_path]]);
1304 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]);
1305 }
1306
1307 }
1308 if ((delta_LCK > 8) && (!iqk_info->rfk_forbidden)) {
1309 RTL_W8(0x522, 0xff);
1310 reg0x18 = phy_query_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, 1);
1311 phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 1);
1312 phy_set_rf_reg(priv, RF_PATH_A, 0x18, BIT(15), 1);
1313 delay_ms(200); /* frequency deviation */
1314 phy_set_rf_reg(priv, RF_PATH_A, 0xB4, BIT(14), 0);
1315 phy_set_rf_reg(priv, RF_PATH_A, 0x18, MASK20BITS, reg0x18);
1316 #ifdef CONFIG_RTL_8812_SUPPORT
1317 if (GET_CHIP_VER(priv) == VERSION_8812E)
1318 update_bbrf_val8812(priv, priv->pmib->dot11RFEntry.dot11channel);
1319 #endif
1320 RTL_W8(0x522, 0x0);
1321 priv->pshare->thermal_value_lck = thermal_value;
1322 }
1323 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "\n******** END:%s() ********\n", __FUNCTION__);
1324
1325 /* update thermal meter value */
1326 priv->pshare->thermal_value = thermal_value;
1327 for (rf_path = 0; rf_path < max_rf_path; rf_path++)
1328 priv->pshare->OFDM_index[rf_path] = OFDM_index[rf_path];
1329 }
1330 }
1331
1332 #endif
1333
1334
1335 void
odm_txpowertracking_callback_thermal_meter(void * dm_void)1336 odm_txpowertracking_callback_thermal_meter(
1337 void *dm_void
1338 )
1339 {
1340 struct dm_struct *dm = (struct dm_struct *)dm_void;
1341 struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info);
1342 struct dm_iqk_info *iqk_info = &dm->IQK_info;
1343
1344
1345 #if (RTL8814B_SUPPORT == 1 || RTL8812F_SUPPORT == 1 || RTL8822C_SUPPORT == 1 || RTL8197G_SUPPORT == 1)
1346 if (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8822C | ODM_RTL8197G)) {
1347 odm_txpowertracking_callback_thermal_meter_jaguar_series4(dm);
1348 return;
1349 }
1350 #endif
1351 #if (RTL8197F_SUPPORT == 1 ||RTL8192F_SUPPORT == 1 || RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1 || RTL8198F_SUPPORT == 1)
1352 if (dm->support_ic_type == ODM_RTL8197F || dm->support_ic_type == ODM_RTL8192F || dm->support_ic_type == ODM_RTL8822B
1353 || dm->support_ic_type == ODM_RTL8821C || dm->support_ic_type == ODM_RTL8198F) {
1354 odm_txpowertracking_callback_thermal_meter_jaguar_series3(dm);
1355 return;
1356 }
1357 #endif
1358 #if (RTL8814A_SUPPORT == 1) /*use this function to do power tracking after 8814 by YuChen*/
1359 if (dm->support_ic_type & ODM_RTL8814A) {
1360 odm_txpowertracking_callback_thermal_meter_jaguar_series2(dm);
1361 return;
1362 }
1363 #endif
1364 #if (RTL8881A_SUPPORT || RTL8812A_SUPPORT == 1)
1365 if (dm->support_ic_type & ODM_RTL8812 || dm->support_ic_type & ODM_RTL8881A) {
1366 odm_txpowertracking_callback_thermal_meter_jaguar_series(dm);
1367 return;
1368 }
1369 #endif
1370
1371 #if (RTL8192E_SUPPORT == 1)
1372 if (dm->support_ic_type == ODM_RTL8192E) {
1373 odm_txpowertracking_callback_thermal_meter_92e(dm);
1374 return;
1375 }
1376 #endif
1377
1378 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
1379 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
1380 /* PMGNT_INFO mgnt_info = &adapter->mgnt_info; */
1381 #endif
1382
1383
1384 u8 thermal_value = 0, delta, delta_LCK, delta_IQK, offset;
1385 u8 thermal_value_avg_count = 0;
1386 u32 thermal_value_avg = 0;
1387 /* s32 ele_A=0, ele_D, TempCCk, X, value32;
1388 * s32 Y, ele_C=0;
1389 * s8 OFDM_index[2], CCK_index=0, OFDM_index_old[2]={0,0}, CCK_index_old=0, index;
1390 * s8 deltaPowerIndex = 0; */
1391 u32 i = 0;/* , j = 0; */
1392 boolean is2T = false;
1393 /* bool bInteralPA = false; */
1394
1395 u8 OFDM_max_index = 34, rf = (is2T) ? 2 : 1; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
1396 u8 indexforchannel = 0;/*get_right_chnl_place_for_iqk(hal_data->current_channel)*/
1397 enum _POWER_DEC_INC { POWER_DEC, POWER_INC };
1398
1399 struct txpwrtrack_cfg c;
1400
1401
1402 /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
1403 s8 delta_swing_table_idx[2][index_mapping_NUM_88E] = {
1404 /* {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} */
1405 {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}
1406 };
1407 u8 thermal_threshold[2][index_mapping_NUM_88E] = {
1408 /* {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} */
1409 {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}
1410 };
1411
1412 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
1413 struct rtl8192cd_priv *priv = dm->priv;
1414 #endif
1415
1416 /* 4 2. Initilization ( 7 steps in total ) */
1417
1418 configure_txpower_track(dm, &c);
1419
1420 dm->rf_calibrate_info.txpowertracking_callback_cnt++; /* cosa add for debug */
1421 dm->rf_calibrate_info.is_txpowertracking_init = true;
1422
1423 #if (MP_DRIVER == 1)
1424 dm->rf_calibrate_info.txpowertrack_control = hal_data->txpowertrack_control; /* <Kordan> We should keep updating the control variable according to HalData.
1425 * <Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
1426 dm->rf_calibrate_info.rega24 = 0x090e1317;
1427 #endif
1428
1429 #if (DM_ODM_SUPPORT_TYPE == ODM_AP) && defined(MP_TEST)
1430 if ((OPMODE & WIFI_MP_STATE) || *(dm->mp_mode)) {
1431 if (dm->priv->pshare->mp_txpwr_tracking == false)
1432 return;
1433 }
1434 #endif
1435 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);
1436 /*
1437 if (!dm->rf_calibrate_info.tm_trigger) {
1438 odm_set_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, BIT(17) | BIT(16), 0x3);
1439 dm->rf_calibrate_info.tm_trigger = 1;
1440 return;
1441 }
1442 */
1443 thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
1444 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
1445 if (!thermal_value || !dm->rf_calibrate_info.txpowertrack_control)
1446 #else
1447 if (!dm->rf_calibrate_info.txpowertrack_control)
1448 #endif
1449 return;
1450
1451 /* 4 3. Initialize ThermalValues of rf_calibrate_info */
1452
1453 if (!dm->rf_calibrate_info.thermal_value) {
1454 dm->rf_calibrate_info.thermal_value_lck = thermal_value;
1455 dm->rf_calibrate_info.thermal_value_iqk = thermal_value;
1456 }
1457
1458 if (dm->rf_calibrate_info.is_reloadtxpowerindex)
1459 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "reload ofdm index for band switch\n");
1460
1461 /* 4 4. Calculate average thermal meter */
1462
1463 dm->rf_calibrate_info.thermal_value_avg[dm->rf_calibrate_info.thermal_value_avg_index] = thermal_value;
1464 dm->rf_calibrate_info.thermal_value_avg_index++;
1465 if (dm->rf_calibrate_info.thermal_value_avg_index == c.average_thermal_num)
1466 dm->rf_calibrate_info.thermal_value_avg_index = 0;
1467
1468 for (i = 0; i < c.average_thermal_num; i++) {
1469 if (dm->rf_calibrate_info.thermal_value_avg[i]) {
1470 thermal_value_avg += dm->rf_calibrate_info.thermal_value_avg[i];
1471 thermal_value_avg_count++;
1472 }
1473 }
1474
1475 if (thermal_value_avg_count) {
1476 /* Give the new thermo value a weighting */
1477 thermal_value_avg += (thermal_value * 4);
1478
1479 thermal_value = (u8)(thermal_value_avg / (thermal_value_avg_count + 4));
1480 cali_info->thermal_value_delta = thermal_value - priv->pmib->dot11RFEntry.ther;
1481 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "AVG Thermal Meter = 0x%x\n", thermal_value);
1482 }
1483
1484 /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
1485
1486 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);
1487 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);
1488 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);
1489
1490 /* 4 6. If necessary, do LCK. */
1491 if (!(dm->support_ic_type & ODM_RTL8821)) {
1492 /*if((delta_LCK > hal_data->delta_lck) && (hal_data->delta_lck != 0))*/
1493 if ((delta_LCK >= c.threshold_iqk) && (!iqk_info->rfk_forbidden)) {
1494 /*Delta temperature is equal to or larger than 20 centigrade.*/
1495 dm->rf_calibrate_info.thermal_value_lck = thermal_value;
1496 (*c.phy_lc_calibrate)(dm);
1497 }
1498 }
1499
1500 /* 3 7. If necessary, move the index of swing table to adjust Tx power. */
1501
1502 if (delta > 0 && dm->rf_calibrate_info.txpowertrack_control) {
1503
1504 delta = (thermal_value > dm->priv->pmib->dot11RFEntry.ther) ? (thermal_value - dm->priv->pmib->dot11RFEntry.ther) : (dm->priv->pmib->dot11RFEntry.ther - thermal_value);
1505
1506 /* 4 7.1 The Final Power index = BaseIndex + power_index_offset */
1507
1508 if (thermal_value > dm->priv->pmib->dot11RFEntry.ther) {
1509 CALCULATE_SWINGTALBE_OFFSET(offset, POWER_INC, index_mapping_NUM_88E, delta);
1510 dm->rf_calibrate_info.delta_power_index_last = dm->rf_calibrate_info.delta_power_index;
1511 dm->rf_calibrate_info.delta_power_index = delta_swing_table_idx[POWER_INC][offset];
1512
1513 } else {
1514
1515 CALCULATE_SWINGTALBE_OFFSET(offset, POWER_DEC, index_mapping_NUM_88E, delta);
1516 dm->rf_calibrate_info.delta_power_index_last = dm->rf_calibrate_info.delta_power_index;
1517 dm->rf_calibrate_info.delta_power_index = (-1) * delta_swing_table_idx[POWER_DEC][offset];
1518 }
1519
1520 if (dm->rf_calibrate_info.delta_power_index == dm->rf_calibrate_info.delta_power_index_last)
1521 dm->rf_calibrate_info.power_index_offset = 0;
1522 else
1523 dm->rf_calibrate_info.power_index_offset = dm->rf_calibrate_info.delta_power_index - dm->rf_calibrate_info.delta_power_index_last;
1524
1525 for (i = 0; i < rf; i++)
1526 dm->rf_calibrate_info.OFDM_index[i] = cali_info->bb_swing_idx_ofdm_base + dm->rf_calibrate_info.power_index_offset;
1527 dm->rf_calibrate_info.CCK_index = cali_info->bb_swing_idx_cck_base + dm->rf_calibrate_info.power_index_offset;
1528
1529 cali_info->bb_swing_idx_cck = dm->rf_calibrate_info.CCK_index;
1530 cali_info->bb_swing_idx_ofdm[RF_PATH_A] = dm->rf_calibrate_info.OFDM_index[RF_PATH_A];
1531
1532 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);
1533 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);
1534
1535 /* 4 7.1 Handle boundary conditions of index. */
1536
1537
1538 for (i = 0; i < rf; i++) {
1539 if (dm->rf_calibrate_info.OFDM_index[i] > OFDM_max_index)
1540 dm->rf_calibrate_info.OFDM_index[i] = OFDM_max_index;
1541 else if (dm->rf_calibrate_info.OFDM_index[i] < 0)
1542 dm->rf_calibrate_info.OFDM_index[i] = 0;
1543 }
1544
1545 if (dm->rf_calibrate_info.CCK_index > c.swing_table_size_cck - 1)
1546 dm->rf_calibrate_info.CCK_index = c.swing_table_size_cck - 1;
1547 else if (dm->rf_calibrate_info.CCK_index < 0)
1548 dm->rf_calibrate_info.CCK_index = 0;
1549 } else {
1550 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);
1551 dm->rf_calibrate_info.power_index_offset = 0;
1552 }
1553 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);
1554
1555 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);
1556
1557 if (dm->rf_calibrate_info.power_index_offset != 0 && dm->rf_calibrate_info.txpowertrack_control) {
1558 /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
1559
1560 dm->rf_calibrate_info.is_tx_power_changed = true; /* Always true after Tx Power is adjusted by power tracking. */
1561 /* */
1562 /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
1563 /* to increase TX power. Otherwise, EVM will be bad. */
1564 /* */
1565 /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
1566 if (thermal_value > dm->rf_calibrate_info.thermal_value) {
1567 /* RF_DBG(dm,DBG_RF_TX_PWR_TRACK, */
1568 /* "Temperature Increasing: delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", */
1569 /* dm->rf_calibrate_info.power_index_offset, delta, thermal_value, hal_data->eeprom_thermal_meter, dm->rf_calibrate_info.thermal_value); */
1570 } else if (thermal_value < dm->rf_calibrate_info.thermal_value) { /* Low temperature */
1571 /* RF_DBG(dm,DBG_RF_TX_PWR_TRACK, */
1572 /* "Temperature Decreasing: delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", */
1573 /* dm->rf_calibrate_info.power_index_offset, delta, thermal_value, hal_data->eeprom_thermal_meter, dm->rf_calibrate_info.thermal_value); */
1574 }
1575 if (thermal_value > dm->priv->pmib->dot11RFEntry.ther)
1576 {
1577 /* 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); */
1578 (*c.odm_tx_pwr_track_set_pwr)(dm, TXAGC, 0, 0);
1579 } else {
1580 /* 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); */
1581 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, RF_PATH_A, indexforchannel);
1582 if (is2T)
1583 (*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, RF_PATH_B, indexforchannel);
1584 }
1585
1586 cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;
1587 cali_info->bb_swing_idx_ofdm_base = cali_info->bb_swing_idx_ofdm[RF_PATH_A];
1588 dm->rf_calibrate_info.thermal_value = thermal_value;
1589
1590 }
1591
1592 RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===dm_TXPowerTrackingCallback_ThermalMeter_8188E\n");
1593
1594 dm->rf_calibrate_info.tx_powercount = 0;
1595 }
1596
1597 /* 3============================================================
1598 * 3 IQ Calibration
1599 * 3============================================================ */
1600
1601 void
odm_reset_iqk_result(void * dm_void)1602 odm_reset_iqk_result(
1603 void *dm_void
1604 )
1605 {
1606 return;
1607 }
1608 #if 1/* !(DM_ODM_SUPPORT_TYPE & ODM_AP) */
odm_get_right_chnl_place_for_iqk(u8 chnl)1609 u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
1610 {
1611 u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
1612 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
1613 };
1614 u8 place = chnl;
1615
1616
1617 if (chnl > 14) {
1618 for (place = 14; place < sizeof(channel_all); place++) {
1619 if (channel_all[place] == chnl)
1620 return place - 13;
1621 }
1622 }
1623 return 0;
1624
1625 }
1626 #endif
1627
1628 void
odm_iq_calibrate(struct dm_struct * dm)1629 odm_iq_calibrate(
1630 struct dm_struct *dm
1631 )
1632 {
1633 struct dm_iqk_info *iqk_info = &dm->IQK_info;
1634
1635 if ((dm->is_linked) && (!iqk_info->rfk_forbidden)) {
1636 if ((*dm->channel != dm->pre_channel) && (!*dm->is_scan_in_process)) {
1637 dm->pre_channel = *dm->channel;
1638 dm->linked_interval = 0;
1639 }
1640
1641 if (dm->linked_interval < 3)
1642 dm->linked_interval++;
1643
1644 if (dm->linked_interval == 2)
1645 halrf_iqk_trigger(dm, false);
1646 } else
1647 dm->linked_interval = 0;
1648
1649 }
1650
phydm_rf_init(void * dm_void)1651 void phydm_rf_init(void *dm_void)
1652 {
1653 struct dm_struct *dm = (struct dm_struct *)dm_void;
1654 odm_txpowertracking_init(dm);
1655
1656 #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
1657 #if (RTL8814A_SUPPORT == 1)
1658 if (dm->support_ic_type & ODM_RTL8814A)
1659 phy_iq_calibrate_8814a_init(dm);
1660 #endif
1661 #endif
1662
1663 }
1664
phydm_rf_watchdog(void * dm_void)1665 void phydm_rf_watchdog(void *dm_void)
1666 {
1667 struct dm_struct *dm = (struct dm_struct *)dm_void;
1668
1669 odm_txpowertracking_check(dm);
1670 #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
1671 if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1672 odm_iq_calibrate(dm);
1673 #endif
1674 }
1675