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