xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8188fu/hal/phydm/halrf/halphyrf_iot.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  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 
26 #include "mp_precomp.h"
27 #include "phydm_precomp.h"
28 
29 #define	CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
30 	do {\
31 		for (_offset = 0; _offset < _size; _offset++) { \
32 			if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
33 				if (_offset != 0)\
34 					_offset--;\
35 				break;\
36 			} \
37 		}			\
38 		if (_offset >= _size)\
39 			_offset = _size-1;\
40 	} while (0)
41 
configure_txpower_track(void * dm_void,struct txpwrtrack_cfg * config)42 void configure_txpower_track(
43 	void					*dm_void,
44 	struct txpwrtrack_cfg	*config
45 )
46 {
47 	struct dm_struct *dm = (struct dm_struct *)dm_void;
48 #if RTL8195B_SUPPORT
49 	if (dm->support_ic_type == ODM_RTL8195B)
50 		configure_txpower_track_8195b(config);
51 #endif
52 #if RTL8710C_SUPPORT
53 	if (dm->support_ic_type == ODM_RTL8710C)
54 		configure_txpower_track_8710c(config);
55 #endif
56 #if RTL8721D_SUPPORT
57 	if (dm->support_ic_type == ODM_RTL8721D)
58 		configure_txpower_track_8721d(config);
59 #endif
60 
61 }
62 
63 /* **********************************************************************
64  * <20121113, Kordan> This function should be called when tx_agc changed.
65  * Otherwise the previous compensation is gone, because we record the
66  * delta of temperature between two TxPowerTracking watch dogs.
67  *
68  * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
69  * need to call this function.
70  * ********************************************************************** */
71 void
odm_clear_txpowertracking_state(void * dm_void)72 odm_clear_txpowertracking_state(
73 	void					*dm_void
74 )
75 {
76 	struct dm_struct *dm = (struct dm_struct *)dm_void;
77 	struct _hal_rf_ *rf = &dm->rf_table;
78 	u8			p = 0;
79 	struct dm_rf_calibration_struct	*cali_info = &dm->rf_calibrate_info;
80 
81 	cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
82 	cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
83 	dm->rf_calibrate_info.CCK_index = 0;
84 
85 	for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) {
86 		cali_info->bb_swing_idx_ofdm_base[p] = cali_info->default_ofdm_index;
87 		cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
88 		cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
89 
90 		cali_info->power_index_offset[p] = 0;
91 		cali_info->delta_power_index[p] = 0;
92 		cali_info->delta_power_index_last[p] = 0;
93 
94 		cali_info->absolute_ofdm_swing_idx[p] = 0;
95 		cali_info->remnant_ofdm_swing_idx[p] = 0;
96 		cali_info->kfree_offset[p] = 0;
97 	}
98 
99 	cali_info->modify_tx_agc_flag_path_a = false;
100 	cali_info->modify_tx_agc_flag_path_b = false;
101 	cali_info->modify_tx_agc_flag_path_c = false;
102 	cali_info->modify_tx_agc_flag_path_d = false;
103 	cali_info->remnant_cck_swing_idx = 0;
104 	cali_info->thermal_value = rf->eeprom_thermal;
105 	cali_info->modify_tx_agc_value_cck = 0;
106 	cali_info->modify_tx_agc_value_ofdm = 0;
107 }
108 
109 void
odm_txpowertracking_callback_thermal_meter(void * dm_void)110 odm_txpowertracking_callback_thermal_meter(
111 	void	*dm_void
112 )
113 {
114 	struct dm_struct *dm = (struct dm_struct *)dm_void;
115 	struct _hal_rf_ *rf = &dm->rf_table;
116 	struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
117 	struct	dm_iqk_info *iqk_info = &dm->IQK_info;
118 
119 	u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
120 	u8 thermal_value_avg_count = 0;
121 	u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
122 
123 	u8 OFDM_min_index = 0;  /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
124 	u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(hal_data->current_channel) */
125 	u8 power_tracking_type = rf->pwt_type;
126 	u8 xtal_offset_eanble = 0;
127 	s8 thermal_value_temp = 0;
128 
129 	struct txpwrtrack_cfg	c = {0};
130 
131 	/* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
132 	u8 *delta_swing_table_idx_tup_a = NULL;
133 	u8 *delta_swing_table_idx_tdown_a = NULL;
134 	u8 *delta_swing_table_idx_tup_b = NULL;
135 	u8 *delta_swing_table_idx_tdown_b = NULL;
136 #if (RTL8721D_SUPPORT == 1)
137 	u8 *delta_swing_table_idx_tup_a_cck = NULL;
138 	u8 *delta_swing_table_idx_tdown_a_cck = NULL;
139 	u8 *delta_swing_table_idx_tup_b_cck = NULL;
140 	u8 *delta_swing_table_idx_tdown_b_cck = NULL;
141 #endif
142 	/*for Xtal Offset by James.Tung*/
143 	s8 *delta_swing_table_xtal_up = NULL;
144 	s8 *delta_swing_table_xtal_down = NULL;
145 
146 	/* 4 2. Initialization ( 7 steps in total ) */
147 	indexforchannel = odm_get_right_chnl_place_for_iqk(*dm->channel);
148 	configure_txpower_track(dm, &c);
149 #if (RTL8721D_SUPPORT == 1)
150 	(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
151 		(u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b,
152 		(u8 **)&delta_swing_table_idx_tup_a_cck, (u8 **)&delta_swing_table_idx_tdown_a_cck,
153 		(u8 **)&delta_swing_table_idx_tup_b_cck, (u8 **)&delta_swing_table_idx_tdown_b_cck);
154 #else
155 	(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
156 		(u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
157 #endif
158 
159 	/*for Xtal Offset*/
160 	if (dm->support_ic_type == ODM_RTL8195B ||
161 	    dm->support_ic_type == ODM_RTL8721D ||
162 	    dm->support_ic_type == ODM_RTL8710C)
163 		(*c.get_delta_swing_xtal_table)(dm,
164 		 (s8 **)&delta_swing_table_xtal_up,
165 		 (s8 **)&delta_swing_table_xtal_down);
166 
167 	cali_info->txpowertracking_callback_cnt++;	/*cosa add for debug*/
168 	cali_info->is_txpowertracking_init = true;
169 
170 	RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
171 	       "===>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",
172 	       cali_info->bb_swing_idx_cck_base,
173 	       cali_info->bb_swing_idx_ofdm_base[RF_PATH_A],
174 	       cali_info->default_ofdm_index);
175 
176 	RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
177 	       "cali_info->txpowertrack_control = %d, hal_data->eeprom_thermal_meter %d\n",
178 	       cali_info->txpowertrack_control, rf->eeprom_thermal);
179 
180 	if (dm->support_ic_type == ODM_RTL8721D
181 		|| dm->support_ic_type == ODM_RTL8710C)
182 		thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A,
183 						   c.thermal_reg_addr, 0x7e0);
184 		/* 0x42: RF Reg[10:5] 8721D */
185 	else
186 		thermal_value = (u8)odm_get_rf_reg(dm, RF_PATH_A,
187 						   c.thermal_reg_addr, 0xfc00);
188 		/* 0x42: RF Reg[15:10] 88E */
189 
190 	thermal_value_temp = thermal_value + phydm_get_thermal_offset(dm);
191 
192 	RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
193 	       "thermal_value_temp(%d) = thermal_value(%d) + power_trim_thermal(%d)\n", thermal_value_temp, thermal_value, phydm_get_thermal_offset(dm));
194 
195 	if (thermal_value_temp > 63)
196 		thermal_value = 63;
197 	else if (thermal_value_temp < 0)
198 		thermal_value = 0;
199 	else
200 		thermal_value = thermal_value_temp;
201 
202 	if (!cali_info->txpowertrack_control)
203 		return;
204 
205 	if (rf->eeprom_thermal == 0xff) {
206 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "no pg, hal_data->eeprom_thermal_meter = 0x%x\n", rf->eeprom_thermal);
207 		return;
208 	}
209 #if 0
210 	/*4 3. Initialize ThermalValues of rf_calibrate_info*/
211 	//if (cali_info->is_reloadtxpowerindex)
212 	//	RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "reload ofdm index for band switch\n");
213 #endif
214 	/*4 4. Calculate average thermal meter*/
215 
216 	cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] = thermal_value;
217 	cali_info->thermal_value_avg_index++;
218 	if (cali_info->thermal_value_avg_index == c.average_thermal_num)   /*Average times =  c.average_thermal_num*/
219 		cali_info->thermal_value_avg_index = 0;
220 
221 	for (i = 0; i < c.average_thermal_num; i++) {
222 		if (cali_info->thermal_value_avg[i]) {
223 			thermal_value_avg += cali_info->thermal_value_avg[i];
224 			thermal_value_avg_count++;
225 		}
226 	}
227 
228 	if (thermal_value_avg_count) {			  /* Calculate Average thermal_value after average enough times */
229 		thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
230 		cali_info->thermal_value_delta = thermal_value - rf->eeprom_thermal;
231 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
232 		       "AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, rf->eeprom_thermal);
233 	}
234 
235 	/* 4 5. Calculate delta, delta_LCK, delta_IQK. */
236 	/* "delta" here is used to determine whether thermal value changes or not. */
237 	delta	= (thermal_value > cali_info->thermal_value) ? (thermal_value - cali_info->thermal_value) : (cali_info->thermal_value - thermal_value);
238 	delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? (thermal_value - cali_info->thermal_value_lck) : (cali_info->thermal_value_lck - thermal_value);
239 	delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? (thermal_value - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value);
240 
241 	/*4 6. If necessary, do LCK.*/
242 	RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK);
243 
244 	/* Wait sacn to do LCK by RF Jenyu*/
245 	if ((!*dm->is_scan_in_process) && !iqk_info->rfk_forbidden &&
246 	    (!*dm->is_tdma)) {
247 		/* Delta temperature is equal to or larger than 20 centigrade.*/
248 		if (delta_LCK >= c.threshold_iqk) {
249 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk);
250 			cali_info->thermal_value_lck = thermal_value;
251 
252 			/*Use RTLCK, so close power tracking driver LCK*/
253 			(*c.phy_lc_calibrate)(dm);
254 		}
255 	}
256 
257 	/*3 7. If necessary, move the index of swing table to adjust Tx power.*/
258 	if (delta > 0 && cali_info->txpowertrack_control) {
259 		/* "delta" here is used to record the absolute value of difference. */
260 		delta = thermal_value > rf->eeprom_thermal ? (thermal_value - rf->eeprom_thermal) : (rf->eeprom_thermal - thermal_value);
261 
262 		if (delta >= TXPWR_TRACK_TABLE_SIZE)
263 			delta = TXPWR_TRACK_TABLE_SIZE - 1;
264 
265 		/*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
266 		if (thermal_value > rf->eeprom_thermal) {
267 			for (p = RF_PATH_A; p < c.rf_path_count; p++) {
268 				cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
269 				switch (p) {
270 				case RF_PATH_B:
271 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
272 					       "delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]);
273 #if (RTL8721D_SUPPORT == 1)
274 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
275 					       "delta_swing_table_idx_tup_b_cck[%d] = %d\n", delta, delta_swing_table_idx_tup_b_cck[delta]);
276 
277 					cali_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_b_cck[delta];
278 
279 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
280 					       "******Temp is higher and cali_info->absolute_cck_swing_idx[RF_PATH_B] = %d\n",
281 					       cali_info->absolute_cck_swing_idx[p]);
282 #endif
283 					cali_info->delta_power_index[p] =
284 						delta_swing_table_idx_tup_b
285 						[delta];
286 					cali_info->absolute_ofdm_swing_idx[p] =
287 						delta_swing_table_idx_tup_b
288 						[delta];
289 					/*Record delta swing for mix mode*/
290 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
291 					       "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
292 					break;
293 
294 				default:
295 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
296 					       "delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]);
297 #if (RTL8721D_SUPPORT == 1)
298 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
299 					       "delta_swing_table_idx_tup_a_cck[%d] = %d\n", delta, delta_swing_table_idx_tup_a_cck[delta]);
300 
301 					cali_info->absolute_cck_swing_idx[p] = delta_swing_table_idx_tup_a_cck[delta];
302 
303 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
304 					       "******Temp is higher and cali_info->absolute_cck_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_cck_swing_idx[p]);
305 #endif
306 					cali_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
307 					cali_info->absolute_ofdm_swing_idx[p] =
308 					delta_swing_table_idx_tup_a[delta];
309 					/*Record delta swing*/
310 					/*for mix mode power tracking*/
311 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
312 					       "******Temp is higher and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
313 					break;
314 				}
315 			}
316 			/* JJ ADD 20161014 */
317 			if (dm->support_ic_type == ODM_RTL8195B ||
318 			    dm->support_ic_type == ODM_RTL8721D ||
319 			    dm->support_ic_type == ODM_RTL8710C) {
320 				/*Save xtal_offset from Xtal table*/
321 				cali_info->xtal_offset_last = cali_info->xtal_offset;	/*recording last Xtal offset*/
322 				RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
323 				       "[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]);
324 				cali_info->xtal_offset = delta_swing_table_xtal_up[delta];
325 				xtal_offset_eanble = (cali_info->xtal_offset_last != cali_info->xtal_offset);
326 			}
327 
328 		} else {
329 			for (p = RF_PATH_A; p < c.rf_path_count; p++) {
330 				cali_info->delta_power_index_last[p] = cali_info->delta_power_index[p]; /*recording poer index offset*/
331 
332 				switch (p) {
333 				case RF_PATH_B:
334 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
335 					       "delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]);
336 #if (RTL8721D_SUPPORT == 1)
337 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
338 					       "delta_swing_table_idx_tdown_b_cck[%d] = %d\n", delta, delta_swing_table_idx_tdown_b_cck[delta]);
339 
340 					cali_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b_cck[delta];
341 
342 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
343 					       "******Temp is lower and cali_info->absolute_cck_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_cck_swing_idx[p]);
344 #endif
345 					cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
346 					cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/
347 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
348 					       "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_B] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
349 					break;
350 
351 				default:
352 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
353 					       "delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]);
354 #if (RTL8721D_SUPPORT == 1)
355 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
356 					       "delta_swing_table_idx_tdown_a_cck[%d] = %d\n", delta, delta_swing_table_idx_tdown_a_cck[delta]);
357 
358 					cali_info->absolute_cck_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a_cck[delta];
359 
360 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
361 					       "******Temp is lower and cali_info->absolute_cck_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_cck_swing_idx[p]);
362 #endif
363 					cali_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
364 					cali_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/
365 					RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
366 					       "******Temp is lower and cali_info->absolute_ofdm_swing_idx[RF_PATH_A] = %d\n", cali_info->absolute_ofdm_swing_idx[p]);
367 					break;
368 				}
369 			}
370 			/* JJ ADD 20161014 */
371 
372 			if (dm->support_ic_type == ODM_RTL8195B ||
373 			    dm->support_ic_type == ODM_RTL8721D ||
374 			    dm->support_ic_type == ODM_RTL8710C) {
375 				/*Save xtal_offset from Xtal table*/
376 				cali_info->xtal_offset_last = cali_info->xtal_offset;	/*recording last Xtal offset*/
377 				RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
378 				       "[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]);
379 				cali_info->xtal_offset = delta_swing_table_xtal_down[delta];
380 				xtal_offset_eanble = (cali_info->xtal_offset_last != cali_info->xtal_offset);
381 			}
382 		}
383 #if 0
384 		for (p = RF_PATH_A; p < c.rf_path_count; p++) {
385 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
386 			       "\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p);
387 
388 			if (cali_info->delta_power_index[p] == cali_info->delta_power_index_last[p])		 /*If Thermal value changes but lookup table value still the same*/
389 				cali_info->power_index_offset[p] = 0;
390 			else
391 				cali_info->power_index_offset[p] = cali_info->delta_power_index[p] - cali_info->delta_power_index_last[p];		/*Power index diff between 2 times Power Tracking*/
392 
393 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
394 			       "[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", p, cali_info->power_index_offset[p], cali_info->delta_power_index[p], cali_info->delta_power_index_last[p]);
395 
396 			cali_info->OFDM_index[p] = cali_info->bb_swing_idx_ofdm_base[p] + cali_info->power_index_offset[p];
397 			cali_info->CCK_index = cali_info->bb_swing_idx_cck_base + cali_info->power_index_offset[p];
398 
399 			cali_info->bb_swing_idx_cck = cali_info->CCK_index;
400 			cali_info->bb_swing_idx_ofdm[p] = cali_info->OFDM_index[p];
401 
402 			/*************Print BB Swing base and index Offset*************/
403 
404 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
405 			       "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, cali_info->power_index_offset[p]);
406 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
407 			       "The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", cali_info->bb_swing_idx_ofdm[p], p, cali_info->bb_swing_idx_ofdm_base[p], cali_info->power_index_offset[p]);
408 
409 			/*4 7.1 Handle boundary conditions of index.*/
410 
411 			if (cali_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
412 				cali_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
413 			else if (cali_info->OFDM_index[p] <= OFDM_min_index)
414 				cali_info->OFDM_index[p] = OFDM_min_index;
415 		}
416 
417 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
418 		       "\n\n========================================================================================================\n");
419 
420 		if (cali_info->CCK_index > c.swing_table_size_cck - 1)
421 			cali_info->CCK_index = c.swing_table_size_cck - 1;
422 		else if (cali_info->CCK_index <= 0)
423 			cali_info->CCK_index = 0;
424 #endif
425 	} else {
426 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
427 		       "The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
428 		       cali_info->txpowertrack_control, thermal_value, cali_info->thermal_value);
429 
430 		for (p = RF_PATH_A; p < c.rf_path_count; p++)
431 			cali_info->power_index_offset[p] = 0;
432 	}
433 #if 0
434 	RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
435 	       "TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
436 	       cali_info->CCK_index, cali_info->bb_swing_idx_cck_base);	   /*Print Swing base & current*/
437 
438 	for (p = RF_PATH_A; p < c.rf_path_count; p++) {
439 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
440 		       "TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
441 		       cali_info->OFDM_index[p], p, cali_info->bb_swing_idx_ofdm_base[p]);
442 	}
443 #endif
444 
445 #if (RTL8721D_SUPPORT == 1)
446 	if (thermal_value != cali_info->thermal_value) {
447 		if (thermal_value > rf->eeprom_thermal)
448 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
449 			       "Temperature(%d) higher than PG value(%d)\n",
450 			       thermal_value, rf->eeprom_thermal);
451 		else if (thermal_value < rf->eeprom_thermal)
452 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
453 			       "Temperature(%d) lower than PG value(%d)\n",
454 			       thermal_value, rf->eeprom_thermal);
455 
456 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
457 		       "**********Enter POWER Tracking MIX_MODE**********\n");
458 		for (p = RF_PATH_A; p < c.rf_path_count; p++)
459 			(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
460 						      indexforchannel);
461 
462 		/*Record last time Power Tracking result as base.*/
463 		cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;
464 		for (p = RF_PATH_A; p < c.rf_path_count; p++)
465 			cali_info->bb_swing_idx_ofdm_base[p] =
466 			cali_info->bb_swing_idx_ofdm[p];
467 
468 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
469 		       "cali_info->thermal_value = %d thermal_value= %d\n",
470 		       cali_info->thermal_value, thermal_value);
471 		/*Record last Power Tracking Thermal value*/
472 		cali_info->thermal_value = thermal_value;
473 	}
474 
475 #else
476 	if (thermal_value > rf->eeprom_thermal) {
477 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
478 		       "Temperature(%d) higher than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
479 
480 		if (dm->support_ic_type == ODM_RTL8188E ||
481 		    dm->support_ic_type == ODM_RTL8192E ||
482 		    dm->support_ic_type == ODM_RTL8821 ||
483 		    dm->support_ic_type == ODM_RTL8812 ||
484 		    dm->support_ic_type == ODM_RTL8723B ||
485 		    dm->support_ic_type == ODM_RTL8814A ||
486 		    dm->support_ic_type == ODM_RTL8703B ||
487 		    dm->support_ic_type == ODM_RTL8188F ||
488 		    dm->support_ic_type == ODM_RTL8822B ||
489 		    dm->support_ic_type == ODM_RTL8723D ||
490 		    dm->support_ic_type == ODM_RTL8821C ||
491 		    dm->support_ic_type == ODM_RTL8710B ||
492 		    dm->support_ic_type == ODM_RTL8192F ||
493 		    dm->support_ic_type == ODM_RTL8195B ||
494 		    dm->support_ic_type == ODM_RTL8710C){
495 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
496 			for (p = RF_PATH_A; p < c.rf_path_count; p++)
497 				(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, 0);
498 		} else {
499 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
500 			for (p = RF_PATH_A; p < c.rf_path_count; p++)
501 				(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
502 		}
503 	} else {
504 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
505 		       "Temperature(%d) lower than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
506 
507 		if (dm->support_ic_type == ODM_RTL8188E ||
508 		    dm->support_ic_type == ODM_RTL8192E ||
509 		    dm->support_ic_type == ODM_RTL8821 ||
510 		    dm->support_ic_type == ODM_RTL8812 ||
511 		    dm->support_ic_type == ODM_RTL8723B ||
512 		    dm->support_ic_type == ODM_RTL8814A ||
513 		    dm->support_ic_type == ODM_RTL8703B ||
514 		    dm->support_ic_type == ODM_RTL8188F ||
515 		    dm->support_ic_type == ODM_RTL8822B ||
516 		    dm->support_ic_type == ODM_RTL8723D ||
517 		    dm->support_ic_type == ODM_RTL8821C ||
518 		    dm->support_ic_type == ODM_RTL8710B ||
519 		    dm->support_ic_type == ODM_RTL8192F ||
520 		    dm->support_ic_type == ODM_RTL8195B ||
521 		    dm->support_ic_type == ODM_RTL8710C) {
522 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking MIX_MODE**********\n");
523 			for (p = RF_PATH_A; p < c.rf_path_count; p++)
524 				(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, indexforchannel);
525 		} else {
526 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter POWER Tracking BBSWING_MODE**********\n");
527 			for (p = RF_PATH_A; p < c.rf_path_count; p++)
528 				(*c.odm_tx_pwr_track_set_pwr)(dm, BBSWING, p, indexforchannel);
529 		}
530 
531 		cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;    /*Record last time Power Tracking result as base.*/
532 		for (p = RF_PATH_A; p < c.rf_path_count; p++)
533 			cali_info->bb_swing_idx_ofdm_base[p] = cali_info->bb_swing_idx_ofdm[p];
534 
535 		RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
536 		       "cali_info->thermal_value = %d thermal_value= %d\n", cali_info->thermal_value, thermal_value);
537 
538 		cali_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
539 	}
540 #endif
541 	/* JJ ADD 20161014 */
542 	if (dm->support_ic_type == ODM_RTL8195B ||
543 	    dm->support_ic_type == ODM_RTL8721D ||
544 	    dm->support_ic_type == ODM_RTL8710C) {
545 		if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (rf->eeprom_thermal != 0xff)) {
546 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n");
547 
548 			if (thermal_value > rf->eeprom_thermal) {
549 				RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
550 				       "Temperature(%d) higher than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
551 				(*c.odm_txxtaltrack_set_xtal)(dm);
552 			} else {
553 				RF_DBG(dm, DBG_RF_TX_PWR_TRACK,
554 				       "Temperature(%d) lower than PG value(%d)\n", thermal_value, rf->eeprom_thermal);
555 				(*c.odm_txxtaltrack_set_xtal)(dm);
556 			}
557 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********End Xtal Tracking**********\n");
558 		}
559 	}
560 #if (!RTL8721D_SUPPORT)
561 	/* Wait sacn to do IQK by RF Jenyu*/
562 	if ((!*dm->is_scan_in_process) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) {
563 		/*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
564 		if (delta_IQK >= c.threshold_iqk) {
565 			cali_info->thermal_value_iqk = thermal_value;
566 			RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "delta_IQK(%d) >= threshold_iqk(%d)\n", delta_IQK, c.threshold_iqk);
567 			if (!cali_info->is_iqk_in_progress)
568 				(*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
569 		}
570 	}
571 #endif
572 	RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "<===odm_txpowertracking_callback_thermal_meter\n");
573 
574 	cali_info->tx_powercount = 0;
575 }
576 
577 /* 3============================================================
578  * 3 IQ Calibration
579  * 3============================================================
580  */
581 
582 void
odm_reset_iqk_result(void * dm_void)583 odm_reset_iqk_result(
584 	void					*dm_void
585 )
586 {
587 	return;
588 }
589 
590 #if !(DM_ODM_SUPPORT_TYPE & ODM_AP)
odm_get_right_chnl_place_for_iqk(u8 chnl)591 u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
592 {
593 	u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
594 		1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
595 		36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
596 		100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
597 		124, 126, 128, 130, 132, 134, 136, 138, 140,
598 		149, 151, 153, 155, 157, 159, 161, 163, 165};
599 	u8 place = chnl;
600 
601 	if (chnl > 14) {
602 		for (place = 14; place < sizeof(channel_all); place++) {
603 			if (channel_all[place] == chnl)
604 				return place - 13;
605 		}
606 	}
607 	return 0;
608 }
609 #endif
610 
611 void
odm_rf_calibrate(struct dm_struct * dm)612 odm_rf_calibrate(struct dm_struct *dm)
613 {
614 #if (RTL8721D_SUPPORT == 1)
615 	struct dm_iqk_info	*iqk_info = &dm->IQK_info;
616 
617 	if (dm->is_linked && !iqk_info->rfk_forbidden) {
618 		if ((*dm->channel != dm->pre_channel) &&
619 		    (!*dm->is_scan_in_process)) {
620 			dm->pre_channel = *dm->channel;
621 			dm->linked_interval = 0;
622 		}
623 
624 		if (dm->linked_interval < 3)
625 			dm->linked_interval++;
626 
627 		if (dm->linked_interval == 2)
628 			halrf_rf_k_connect_trigger(dm, 0, SEGMENT_FREE);
629 	} else {
630 		dm->linked_interval = 0;
631 	}
632 #endif
633 }
634 
phydm_rf_init(void * dm_void)635 void phydm_rf_init(void		*dm_void)
636 {
637 	struct dm_struct	*dm = (struct dm_struct *)dm_void;
638 
639 	odm_txpowertracking_init(dm);
640 
641 	odm_clear_txpowertracking_state(dm);
642 }
643 
phydm_rf_watchdog(void * dm_void)644 void phydm_rf_watchdog(void		*dm_void)
645 {
646 	struct dm_struct		*dm = (struct dm_struct *)dm_void;
647 
648 	odm_txpowertracking_check(dm);
649 #if (RTL8721D_SUPPORT == 1)
650 	odm_rf_calibrate(dm);
651 #endif
652 }
653