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