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