xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8822cs/hal/phydm/halrf/halphyrf_ap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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