• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2016  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,                \
30 				    _delta_thermal)                            \
31 	do {                                                                   \
32 		for (_offset = 0; _offset < _size; _offset++) {                \
33 			if (_delta_thermal <                                   \
34 			    thermal_threshold[_direction][_offset]) {          \
35 				if (_offset != 0)                              \
36 					_offset--;                             \
37 				break;                                         \
38 			}                                                      \
39 		}                                                              \
40 		if (_offset >= _size)                                          \
41 			_offset = _size - 1;                                   \
42 	} while (0)
43 
phydm_set_calibrate_info_up(struct phy_dm_struct * dm,struct txpwrtrack_cfg * c,u8 delta,struct dm_rf_calibration_struct * cali_info,u8 * delta_swing_table_idx_tup_a,u8 * delta_swing_table_idx_tup_b,u8 * delta_swing_table_idx_tup_c,u8 * delta_swing_table_idx_tup_d)44 static inline void phydm_set_calibrate_info_up(
45 	struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta,
46 	struct dm_rf_calibration_struct *cali_info,
47 	u8 *delta_swing_table_idx_tup_a, u8 *delta_swing_table_idx_tup_b,
48 	u8 *delta_swing_table_idx_tup_c, u8 *delta_swing_table_idx_tup_d)
49 {
50 	u8 p = 0;
51 
52 	for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
53 		cali_info->delta_power_index_last[p] =
54 			cali_info->delta_power_index
55 				[p]; /*recording poer index offset*/
56 		switch (p) {
57 		case ODM_RF_PATH_B:
58 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
59 				     "delta_swing_table_idx_tup_b[%d] = %d\n",
60 				     delta, delta_swing_table_idx_tup_b[delta]);
61 
62 			cali_info->delta_power_index[p] =
63 				delta_swing_table_idx_tup_b[delta];
64 			/*Record delta swing for mix mode pwr tracking*/
65 			cali_info->absolute_ofdm_swing_idx[p] =
66 				delta_swing_table_idx_tup_b[delta];
67 			ODM_RT_TRACE(
68 				dm, ODM_COMP_TX_PWR_TRACK,
69 				"******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n",
70 				cali_info->absolute_ofdm_swing_idx[p]);
71 			break;
72 
73 		case ODM_RF_PATH_C:
74 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
75 				     "delta_swing_table_idx_tup_c[%d] = %d\n",
76 				     delta, delta_swing_table_idx_tup_c[delta]);
77 
78 			cali_info->delta_power_index[p] =
79 				delta_swing_table_idx_tup_c[delta];
80 			/*Record delta swing for mix mode pwr tracking*/
81 			cali_info->absolute_ofdm_swing_idx[p] =
82 				delta_swing_table_idx_tup_c[delta];
83 			ODM_RT_TRACE(
84 				dm, ODM_COMP_TX_PWR_TRACK,
85 				"******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n",
86 				cali_info->absolute_ofdm_swing_idx[p]);
87 			break;
88 
89 		case ODM_RF_PATH_D:
90 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
91 				     "delta_swing_table_idx_tup_d[%d] = %d\n",
92 				     delta, delta_swing_table_idx_tup_d[delta]);
93 
94 			cali_info->delta_power_index[p] =
95 				delta_swing_table_idx_tup_d[delta];
96 			/*Record delta swing for mix mode pwr tracking*/
97 			cali_info->absolute_ofdm_swing_idx[p] =
98 				delta_swing_table_idx_tup_d[delta];
99 			ODM_RT_TRACE(
100 				dm, ODM_COMP_TX_PWR_TRACK,
101 				"******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n",
102 				cali_info->absolute_ofdm_swing_idx[p]);
103 			break;
104 
105 		default:
106 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
107 				     "delta_swing_table_idx_tup_a[%d] = %d\n",
108 				     delta, delta_swing_table_idx_tup_a[delta]);
109 
110 			cali_info->delta_power_index[p] =
111 				delta_swing_table_idx_tup_a[delta];
112 			/*Record delta swing for mix mode pwr tracking*/
113 			cali_info->absolute_ofdm_swing_idx[p] =
114 				delta_swing_table_idx_tup_a[delta];
115 			ODM_RT_TRACE(
116 				dm, ODM_COMP_TX_PWR_TRACK,
117 				"******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n",
118 				cali_info->absolute_ofdm_swing_idx[p]);
119 			break;
120 		}
121 	}
122 }
123 
phydm_set_calibrate_info_down(struct phy_dm_struct * dm,struct txpwrtrack_cfg * c,u8 delta,struct dm_rf_calibration_struct * cali_info,u8 * delta_swing_table_idx_tdown_a,u8 * delta_swing_table_idx_tdown_b,u8 * delta_swing_table_idx_tdown_c,u8 * delta_swing_table_idx_tdown_d)124 static inline void phydm_set_calibrate_info_down(
125 	struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta,
126 	struct dm_rf_calibration_struct *cali_info,
127 	u8 *delta_swing_table_idx_tdown_a, u8 *delta_swing_table_idx_tdown_b,
128 	u8 *delta_swing_table_idx_tdown_c, u8 *delta_swing_table_idx_tdown_d)
129 {
130 	u8 p = 0;
131 
132 	for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
133 		cali_info->delta_power_index_last[p] =
134 			cali_info->delta_power_index
135 				[p]; /*recording poer index offset*/
136 
137 		switch (p) {
138 		case ODM_RF_PATH_B:
139 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
140 				     "delta_swing_table_idx_tdown_b[%d] = %d\n",
141 				     delta,
142 				     delta_swing_table_idx_tdown_b[delta]);
143 			cali_info->delta_power_index[p] =
144 				-1 * delta_swing_table_idx_tdown_b[delta];
145 			/*Record delta swing for mix mode pwr tracking*/
146 			cali_info->absolute_ofdm_swing_idx[p] =
147 				-1 * delta_swing_table_idx_tdown_b[delta];
148 			ODM_RT_TRACE(
149 				dm, ODM_COMP_TX_PWR_TRACK,
150 				"******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n",
151 				cali_info->absolute_ofdm_swing_idx[p]);
152 			break;
153 
154 		case ODM_RF_PATH_C:
155 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
156 				     "delta_swing_table_idx_tdown_c[%d] = %d\n",
157 				     delta,
158 				     delta_swing_table_idx_tdown_c[delta]);
159 			cali_info->delta_power_index[p] =
160 				-1 * delta_swing_table_idx_tdown_c[delta];
161 			/*Record delta swing for mix mode pwr tracking*/
162 			cali_info->absolute_ofdm_swing_idx[p] =
163 				-1 * delta_swing_table_idx_tdown_c[delta];
164 			ODM_RT_TRACE(
165 				dm, ODM_COMP_TX_PWR_TRACK,
166 				"******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n",
167 				cali_info->absolute_ofdm_swing_idx[p]);
168 			break;
169 
170 		case ODM_RF_PATH_D:
171 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
172 				     "delta_swing_table_idx_tdown_d[%d] = %d\n",
173 				     delta,
174 				     delta_swing_table_idx_tdown_d[delta]);
175 			cali_info->delta_power_index[p] =
176 				-1 * delta_swing_table_idx_tdown_d[delta];
177 			/*Record delta swing for mix mode pwr tracking*/
178 			cali_info->absolute_ofdm_swing_idx[p] =
179 				-1 * delta_swing_table_idx_tdown_d[delta];
180 			ODM_RT_TRACE(
181 				dm, ODM_COMP_TX_PWR_TRACK,
182 				"******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n",
183 				cali_info->absolute_ofdm_swing_idx[p]);
184 			break;
185 
186 		default:
187 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
188 				     "delta_swing_table_idx_tdown_a[%d] = %d\n",
189 				     delta,
190 				     delta_swing_table_idx_tdown_a[delta]);
191 			cali_info->delta_power_index[p] =
192 				-1 * delta_swing_table_idx_tdown_a[delta];
193 			/*Record delta swing for mix mode pwr tracking*/
194 			cali_info->absolute_ofdm_swing_idx[p] =
195 				-1 * delta_swing_table_idx_tdown_a[delta];
196 			ODM_RT_TRACE(
197 				dm, ODM_COMP_TX_PWR_TRACK,
198 				"******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n",
199 				cali_info->absolute_ofdm_swing_idx[p]);
200 			break;
201 		}
202 	}
203 }
204 
phydm_odm_tx_power_set(struct phy_dm_struct * dm,struct txpwrtrack_cfg * c,u8 indexforchannel,u8 flag)205 static inline void phydm_odm_tx_power_set(struct phy_dm_struct *dm,
206 					  struct txpwrtrack_cfg *c,
207 					  u8 indexforchannel, u8 flag)
208 {
209 	u8 p = 0;
210 
211 	if (dm->support_ic_type == ODM_RTL8188E ||
212 	    dm->support_ic_type == ODM_RTL8192E ||
213 	    dm->support_ic_type == ODM_RTL8821 ||
214 	    dm->support_ic_type == ODM_RTL8812 ||
215 	    dm->support_ic_type == ODM_RTL8723B ||
216 	    dm->support_ic_type == ODM_RTL8814A ||
217 	    dm->support_ic_type == ODM_RTL8703B ||
218 	    dm->support_ic_type == ODM_RTL8188F ||
219 	    dm->support_ic_type == ODM_RTL8822B ||
220 	    dm->support_ic_type == ODM_RTL8723D ||
221 	    dm->support_ic_type == ODM_RTL8821C ||
222 	    dm->support_ic_type == ODM_RTL8710B) { /* JJ ADD 20161014 */
223 
224 		ODM_RT_TRACE(
225 			dm, ODM_COMP_TX_PWR_TRACK,
226 			"**********Enter POWER Tracking MIX_MODE**********\n");
227 		for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) {
228 			if (flag == 0)
229 				(*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
230 							       0);
231 			else
232 				(*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
233 							       indexforchannel);
234 		}
235 	} else {
236 		ODM_RT_TRACE(
237 			dm, ODM_COMP_TX_PWR_TRACK,
238 			"**********Enter POWER Tracking BBSWING_MODE**********\n");
239 		for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++)
240 			(*c->odm_tx_pwr_track_set_pwr)(dm, BBSWING, p,
241 						       indexforchannel);
242 	}
243 }
244 
configure_txpower_track(void * dm_void,struct txpwrtrack_cfg * config)245 void configure_txpower_track(void *dm_void, struct txpwrtrack_cfg *config)
246 {
247 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
248 
249 	/* JJ ADD 20161014 */
250 
251 	if (dm->support_ic_type == ODM_RTL8822B)
252 		configure_txpower_track_8822b(config);
253 }
254 
255 /* **********************************************************************
256  * <20121113, Kordan> This function should be called when tx_agc changed.
257  * Otherwise the previous compensation is gone, because we record the
258  * delta of temperature between two TxPowerTracking watch dogs.
259  *
260  * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
261  * need to call this function.
262  * ***********************************************************************/
odm_clear_txpowertracking_state(void * dm_void)263 void odm_clear_txpowertracking_state(void *dm_void)
264 {
265 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
266 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
267 	struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
268 	u8 p = 0;
269 	struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
270 
271 	cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index;
272 	cali_info->bb_swing_idx_cck = cali_info->default_cck_index;
273 	dm->rf_calibrate_info.CCK_index = 0;
274 
275 	for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
276 		cali_info->bb_swing_idx_ofdm_base[p] =
277 			cali_info->default_ofdm_index;
278 		cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index;
279 		cali_info->OFDM_index[p] = cali_info->default_ofdm_index;
280 
281 		cali_info->power_index_offset[p] = 0;
282 		cali_info->delta_power_index[p] = 0;
283 		cali_info->delta_power_index_last[p] = 0;
284 
285 		cali_info->absolute_ofdm_swing_idx[p] =
286 			0; /* Initial Mix mode power tracking*/
287 		cali_info->remnant_ofdm_swing_idx[p] = 0;
288 		cali_info->kfree_offset[p] = 0;
289 	}
290 
291 	cali_info->modify_tx_agc_flag_path_a =
292 		false; /*Initial at Modify Tx Scaling mode*/
293 	cali_info->modify_tx_agc_flag_path_b =
294 		false; /*Initial at Modify Tx Scaling mode*/
295 	cali_info->modify_tx_agc_flag_path_c =
296 		false; /*Initial at Modify Tx Scaling mode*/
297 	cali_info->modify_tx_agc_flag_path_d =
298 		false; /*Initial at Modify Tx Scaling mode*/
299 	cali_info->remnant_cck_swing_idx = 0;
300 	cali_info->thermal_value = rtlefu->eeprom_thermalmeter;
301 
302 	cali_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */
303 	cali_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */
304 }
305 
odm_txpowertracking_callback_thermal_meter(void * dm_void)306 void odm_txpowertracking_callback_thermal_meter(void *dm_void)
307 {
308 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
309 	struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
310 	struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv);
311 	void *adapter = dm->adapter;
312 
313 	struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
314 
315 	u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
316 	s8 diff_DPK[4]; /* use 'for..loop' to initialize */
317 	u8 thermal_value_avg_count = 0;
318 	u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
319 
320 	/* OFDM BB Swing should be less than +3.0dB (required by Arthur) */
321 	u8 OFDM_min_index = 0;
322 	/* get_right_chnl_place_for_iqk(hal_data->current_channel) */
323 	u8 indexforchannel = 0;
324 	u8 power_tracking_type = 0; /* no specify type */
325 	u8 xtal_offset_eanble = 0;
326 
327 	struct txpwrtrack_cfg c;
328 
329 	/* 4 1. The following TWO tables decide the final index of
330 	 *      OFDM/CCK swing table.
331 	 */
332 	u8 *delta_swing_table_idx_tup_a = NULL;
333 	u8 *delta_swing_table_idx_tdown_a = NULL;
334 	u8 *delta_swing_table_idx_tup_b = NULL;
335 	u8 *delta_swing_table_idx_tdown_b = NULL;
336 	/*for 8814 add by Yu Chen*/
337 	u8 *delta_swing_table_idx_tup_c = NULL;
338 	u8 *delta_swing_table_idx_tdown_c = NULL;
339 	u8 *delta_swing_table_idx_tup_d = NULL;
340 	u8 *delta_swing_table_idx_tdown_d = NULL;
341 	/*for Xtal Offset by James.Tung*/
342 	s8 *delta_swing_table_xtal_up = NULL;
343 	s8 *delta_swing_table_xtal_down = NULL;
344 
345 	/* 4 2. Initialization ( 7 steps in total ) */
346 
347 	configure_txpower_track(dm, &c);
348 
349 	(*c.get_delta_swing_table)(dm, (u8 **)&delta_swing_table_idx_tup_a,
350 				   (u8 **)&delta_swing_table_idx_tdown_a,
351 				   (u8 **)&delta_swing_table_idx_tup_b,
352 				   (u8 **)&delta_swing_table_idx_tdown_b);
353 
354 	if (dm->support_ic_type & ODM_RTL8814A) /*for 8814 path C & D*/
355 		(*c.get_delta_swing_table8814only)(
356 			dm, (u8 **)&delta_swing_table_idx_tup_c,
357 			(u8 **)&delta_swing_table_idx_tdown_c,
358 			(u8 **)&delta_swing_table_idx_tup_d,
359 			(u8 **)&delta_swing_table_idx_tdown_d);
360 	/* JJ ADD 20161014 */
361 	if (dm->support_ic_type &
362 	    (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) /*for Xtal Offset*/
363 		(*c.get_delta_swing_xtal_table)(
364 			dm, (s8 **)&delta_swing_table_xtal_up,
365 			(s8 **)&delta_swing_table_xtal_down);
366 
367 	cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
368 	cali_info->is_txpowertracking_init = true;
369 
370 	/*cali_info->txpowertrack_control = hal_data->txpowertrack_control;
371 	 *<Kordan> We should keep updating ctrl variable according to HalData.
372 	 *<Kordan> rf_calibrate_info.rega24 will be initialized when
373 	 *ODM HW configuring, but MP configures with para files.
374 	 */
375 	if (dm->mp_mode)
376 		cali_info->rega24 = 0x090e1317;
377 
378 	ODM_RT_TRACE(
379 		dm, ODM_COMP_TX_PWR_TRACK,
380 		"===>%s\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",
381 		__func__, cali_info->bb_swing_idx_cck_base,
382 		cali_info->bb_swing_idx_ofdm_base[ODM_RF_PATH_A],
383 		cali_info->default_ofdm_index);
384 
385 	ODM_RT_TRACE(
386 		dm, ODM_COMP_TX_PWR_TRACK,
387 		"cali_info->txpowertrack_control=%d,  rtlefu->eeprom_thermalmeter %d\n",
388 		cali_info->txpowertrack_control, rtlefu->eeprom_thermalmeter);
389 
390 	thermal_value =
391 		(u8)odm_get_rf_reg(dm, ODM_RF_PATH_A, c.thermal_reg_addr,
392 				   0xfc00); /* 0x42: RF Reg[15:10] 88E */
393 
394 	/*add log by zhao he, check c80/c94/c14/ca0 value*/
395 	if (dm->support_ic_type == ODM_RTL8723D) {
396 		regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
397 		regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
398 		regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
399 		regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
400 		ODM_RT_TRACE(
401 			dm, ODM_COMP_CALIBRATION,
402 			"0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n",
403 			regc80, regcd0, regcd4, regab4);
404 	}
405 	/* JJ ADD 20161014 */
406 	if (dm->support_ic_type == ODM_RTL8710B) {
407 		regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD);
408 		regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD);
409 		regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD);
410 		regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF);
411 		ODM_RT_TRACE(
412 			dm, ODM_COMP_CALIBRATION,
413 			"0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n",
414 			regc80, regcd0, regcd4, regab4);
415 	}
416 
417 	if (!cali_info->txpowertrack_control)
418 		return;
419 
420 	/*4 3. Initialize ThermalValues of rf_calibrate_info*/
421 
422 	if (cali_info->is_reloadtxpowerindex)
423 		ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
424 			     "reload ofdm index for band switch\n");
425 
426 	/*4 4. Calculate average thermal meter*/
427 
428 	cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] =
429 		thermal_value;
430 	cali_info->thermal_value_avg_index++;
431 	if (cali_info->thermal_value_avg_index ==
432 	    c.average_thermal_num) /*Average times =  c.average_thermal_num*/
433 		cali_info->thermal_value_avg_index = 0;
434 
435 	for (i = 0; i < c.average_thermal_num; i++) {
436 		if (cali_info->thermal_value_avg[i]) {
437 			thermal_value_avg += cali_info->thermal_value_avg[i];
438 			thermal_value_avg_count++;
439 		}
440 	}
441 
442 	if (thermal_value_avg_count) {
443 		/* Calculate Average thermal_value after average enough times */
444 		thermal_value =
445 			(u8)(thermal_value_avg / thermal_value_avg_count);
446 		cali_info->thermal_value_delta =
447 			thermal_value - rtlefu->eeprom_thermalmeter;
448 		ODM_RT_TRACE(
449 			dm, ODM_COMP_TX_PWR_TRACK,
450 			"AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n",
451 			thermal_value, rtlefu->eeprom_thermalmeter);
452 	}
453 
454 	/* 4 5. Calculate delta, delta_LCK, delta_IQK. */
455 
456 	/* "delta" is used to determine whether thermal value changes or not*/
457 	delta = (thermal_value > cali_info->thermal_value) ?
458 			(thermal_value - cali_info->thermal_value) :
459 			(cali_info->thermal_value - thermal_value);
460 	delta_LCK = (thermal_value > cali_info->thermal_value_lck) ?
461 			    (thermal_value - cali_info->thermal_value_lck) :
462 			    (cali_info->thermal_value_lck - thermal_value);
463 	delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ?
464 			    (thermal_value - cali_info->thermal_value_iqk) :
465 			    (cali_info->thermal_value_iqk - thermal_value);
466 
467 	if (cali_info->thermal_value_iqk ==
468 	    0xff) { /*no PG, use thermal value for IQK*/
469 		cali_info->thermal_value_iqk = thermal_value;
470 		delta_IQK =
471 			(thermal_value > cali_info->thermal_value_iqk) ?
472 				(thermal_value - cali_info->thermal_value_iqk) :
473 				(cali_info->thermal_value_iqk - thermal_value);
474 		ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
475 			     "no PG, use thermal_value for IQK\n");
476 	}
477 
478 	for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
479 		diff_DPK[p] = (s8)thermal_value - (s8)cali_info->dpk_thermal[p];
480 
481 	/*4 6. If necessary, do LCK.*/
482 
483 	if (!(dm->support_ic_type &
484 	      ODM_RTL8821)) { /*no PG, do LCK at initial status*/
485 		if (cali_info->thermal_value_lck == 0xff) {
486 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
487 				     "no PG, do LCK\n");
488 			cali_info->thermal_value_lck = thermal_value;
489 
490 			/*Use RTLCK, so close power tracking driver LCK*/
491 			if (!(dm->support_ic_type & ODM_RTL8814A) &&
492 			    c.phy_lc_calibrate)
493 				(*c.phy_lc_calibrate)(dm);
494 
495 			delta_LCK =
496 				(thermal_value > cali_info->thermal_value_lck) ?
497 					(thermal_value -
498 					 cali_info->thermal_value_lck) :
499 					(cali_info->thermal_value_lck -
500 					 thermal_value);
501 		}
502 
503 		ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
504 			     "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
505 			     delta, delta_LCK, delta_IQK);
506 
507 		/*Delta temperature is equal to or larger than 20 centigrade.*/
508 		if (delta_LCK >= c.threshold_iqk) {
509 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
510 				     "delta_LCK(%d) >= threshold_iqk(%d)\n",
511 				     delta_LCK, c.threshold_iqk);
512 			cali_info->thermal_value_lck = thermal_value;
513 
514 			/*Use RTLCK, so close power tracking driver LCK*/
515 			if (!(dm->support_ic_type & ODM_RTL8814A) &&
516 			    c.phy_lc_calibrate)
517 				(*c.phy_lc_calibrate)(dm);
518 		}
519 	}
520 
521 	/*3 7. If necessary, move the index of swing table to adjust Tx power.*/
522 
523 	if (delta > 0 && cali_info->txpowertrack_control) {
524 		/* "delta" here is used to record the abs value of difference.*/
525 		delta = thermal_value > rtlefu->eeprom_thermalmeter ?
526 				(thermal_value - rtlefu->eeprom_thermalmeter) :
527 				(rtlefu->eeprom_thermalmeter - thermal_value);
528 		if (delta >= TXPWR_TRACK_TABLE_SIZE)
529 			delta = TXPWR_TRACK_TABLE_SIZE - 1;
530 
531 		/*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
532 
533 		if (thermal_value > rtlefu->eeprom_thermalmeter) {
534 			phydm_set_calibrate_info_up(
535 				dm, &c, delta, cali_info,
536 				delta_swing_table_idx_tup_a,
537 				delta_swing_table_idx_tup_b,
538 				delta_swing_table_idx_tup_c,
539 				delta_swing_table_idx_tup_d);
540 			/* JJ ADD 20161014 */
541 			if (dm->support_ic_type &
542 			    (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
543 				/*Save xtal_offset from Xtal table*/
544 
545 				/*recording last Xtal offset*/
546 				cali_info->xtal_offset_last =
547 					cali_info->xtal_offset;
548 				ODM_RT_TRACE(
549 					dm, ODM_COMP_TX_PWR_TRACK,
550 					"[Xtal] delta_swing_table_xtal_up[%d] = %d\n",
551 					delta,
552 					delta_swing_table_xtal_up[delta]);
553 				cali_info->xtal_offset =
554 					delta_swing_table_xtal_up[delta];
555 				xtal_offset_eanble =
556 					(cali_info->xtal_offset_last ==
557 					 cali_info->xtal_offset) ?
558 						0 :
559 						1;
560 			}
561 
562 		} else {
563 			phydm_set_calibrate_info_down(
564 				dm, &c, delta, cali_info,
565 				delta_swing_table_idx_tdown_a,
566 				delta_swing_table_idx_tdown_b,
567 				delta_swing_table_idx_tdown_c,
568 				delta_swing_table_idx_tdown_d);
569 			/* JJ ADD 20161014 */
570 			if (dm->support_ic_type &
571 			    (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) {
572 				/*Save xtal_offset from Xtal table*/
573 
574 				/*recording last Xtal offset*/
575 				cali_info->xtal_offset_last =
576 					cali_info->xtal_offset;
577 				ODM_RT_TRACE(
578 					dm, ODM_COMP_TX_PWR_TRACK,
579 					"[Xtal] delta_swing_table_xtal_down[%d] = %d\n",
580 					delta,
581 					delta_swing_table_xtal_down[delta]);
582 				cali_info->xtal_offset =
583 					delta_swing_table_xtal_down[delta];
584 				xtal_offset_eanble =
585 					(cali_info->xtal_offset_last ==
586 					 cali_info->xtal_offset) ?
587 						0 :
588 						1;
589 			}
590 		}
591 
592 		for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
593 			ODM_RT_TRACE(
594 				dm, ODM_COMP_TX_PWR_TRACK,
595 				"\n\n=========================== [path-%d] Calculating power_index_offset===========================\n",
596 				p);
597 
598 			if (cali_info->delta_power_index[p] ==
599 			    cali_info->delta_power_index_last[p]) {
600 				/* If Thermal value changes but lookup table
601 				 * value still the same
602 				 */
603 				cali_info->power_index_offset[p] = 0;
604 			} else {
605 				/*Power idx diff between 2 times Pwr Tracking*/
606 				cali_info->power_index_offset[p] =
607 					cali_info->delta_power_index[p] -
608 					cali_info->delta_power_index_last[p];
609 			}
610 
611 			ODM_RT_TRACE(
612 				dm, ODM_COMP_TX_PWR_TRACK,
613 				"[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n",
614 				p, cali_info->power_index_offset[p],
615 				cali_info->delta_power_index[p],
616 				cali_info->delta_power_index_last[p]);
617 
618 			cali_info->OFDM_index[p] =
619 				cali_info->bb_swing_idx_ofdm_base[p] +
620 				cali_info->power_index_offset[p];
621 			cali_info->CCK_index =
622 				cali_info->bb_swing_idx_cck_base +
623 				cali_info->power_index_offset[p];
624 
625 			cali_info->bb_swing_idx_cck = cali_info->CCK_index;
626 			cali_info->bb_swing_idx_ofdm[p] =
627 				cali_info->OFDM_index[p];
628 
629 			/*******Print BB Swing base and index Offset**********/
630 
631 			ODM_RT_TRACE(
632 				dm, ODM_COMP_TX_PWR_TRACK,
633 				"The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n",
634 				cali_info->bb_swing_idx_cck,
635 				cali_info->bb_swing_idx_cck_base,
636 				cali_info->power_index_offset[p]);
637 			ODM_RT_TRACE(
638 				dm, ODM_COMP_TX_PWR_TRACK,
639 				"The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n",
640 				cali_info->bb_swing_idx_ofdm[p], p,
641 				cali_info->bb_swing_idx_ofdm_base[p],
642 				cali_info->power_index_offset[p]);
643 
644 			/*4 7.1 Handle boundary conditions of index.*/
645 
646 			if (cali_info->OFDM_index[p] >
647 			    c.swing_table_size_ofdm - 1)
648 				cali_info->OFDM_index[p] =
649 					c.swing_table_size_ofdm - 1;
650 			else if (cali_info->OFDM_index[p] <= OFDM_min_index)
651 				cali_info->OFDM_index[p] = OFDM_min_index;
652 		}
653 
654 		ODM_RT_TRACE(
655 			dm, ODM_COMP_TX_PWR_TRACK,
656 			"\n\n========================================================================================================\n");
657 
658 		if (cali_info->CCK_index > c.swing_table_size_cck - 1)
659 			cali_info->CCK_index = c.swing_table_size_cck - 1;
660 		else if (cali_info->CCK_index <= 0)
661 			cali_info->CCK_index = 0;
662 	} else {
663 		ODM_RT_TRACE(
664 			dm, ODM_COMP_TX_PWR_TRACK,
665 			"The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n",
666 			cali_info->txpowertrack_control, thermal_value,
667 			cali_info->thermal_value);
668 
669 		for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
670 			cali_info->power_index_offset[p] = 0;
671 	}
672 
673 	/*Print Swing base & current*/
674 	ODM_RT_TRACE(
675 		dm, ODM_COMP_TX_PWR_TRACK,
676 		"TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
677 		cali_info->CCK_index, cali_info->bb_swing_idx_cck_base);
678 
679 	for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
680 		ODM_RT_TRACE(
681 			dm, ODM_COMP_TX_PWR_TRACK,
682 			"TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
683 			cali_info->OFDM_index[p], p,
684 			cali_info->bb_swing_idx_ofdm_base[p]);
685 
686 	if ((dm->support_ic_type & ODM_RTL8814A)) {
687 		ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
688 			     "power_tracking_type=%d\n", power_tracking_type);
689 
690 		if (power_tracking_type == 0) {
691 			ODM_RT_TRACE(
692 				dm, ODM_COMP_TX_PWR_TRACK,
693 				"**********Enter POWER Tracking MIX_MODE**********\n");
694 			for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
695 				(*c.odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p,
696 							      0);
697 		} else if (power_tracking_type == 1) {
698 			ODM_RT_TRACE(
699 				dm, ODM_COMP_TX_PWR_TRACK,
700 				"**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n");
701 			for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
702 				(*c.odm_tx_pwr_track_set_pwr)(
703 					dm, MIX_2G_TSSI_5G_MODE, p, 0);
704 		} else if (power_tracking_type == 2) {
705 			ODM_RT_TRACE(
706 				dm, ODM_COMP_TX_PWR_TRACK,
707 				"**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n");
708 			for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
709 				(*c.odm_tx_pwr_track_set_pwr)(
710 					dm, MIX_5G_TSSI_2G_MODE, p, 0);
711 		} else if (power_tracking_type == 3) {
712 			ODM_RT_TRACE(
713 				dm, ODM_COMP_TX_PWR_TRACK,
714 				"**********Enter POWER Tracking TSSI MODE**********\n");
715 			for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
716 				(*c.odm_tx_pwr_track_set_pwr)(dm, TSSI_MODE, p,
717 							      0);
718 		}
719 		/*Record last Power Tracking Thermal value*/
720 		cali_info->thermal_value = thermal_value;
721 
722 	} else if ((cali_info->power_index_offset[ODM_RF_PATH_A] != 0 ||
723 		    cali_info->power_index_offset[ODM_RF_PATH_B] != 0 ||
724 		    cali_info->power_index_offset[ODM_RF_PATH_C] != 0 ||
725 		    cali_info->power_index_offset[ODM_RF_PATH_D] != 0) &&
726 		   cali_info->txpowertrack_control &&
727 		   (rtlefu->eeprom_thermalmeter != 0xff)) {
728 		/* 4 7.2 Configure the Swing Table to adjust Tx Power. */
729 
730 		/*Always true after Tx Power is adjusted by power tracking.*/
731 		cali_info->is_tx_power_changed = true;
732 		/* 2012/04/23 MH According to Luke's suggestion, we can not
733 		 * write BB digital to increase TX power. Otherwise, EVM will
734 		 * be bad.
735 		 */
736 		/* 2012/04/25 MH Add for tx power tracking to set tx power in
737 		 * tx agc for 88E.
738 		 */
739 		if (thermal_value > cali_info->thermal_value) {
740 			for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
741 				/* print temperature increasing */
742 				ODM_RT_TRACE(
743 					dm, ODM_COMP_TX_PWR_TRACK,
744 					"Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
745 					p, cali_info->power_index_offset[p],
746 					delta, thermal_value,
747 					rtlefu->eeprom_thermalmeter,
748 					cali_info->thermal_value);
749 			}
750 		} else if (thermal_value <
751 			   cali_info->thermal_value) { /*Low temperature*/
752 			for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
753 				/* print temperature decreasing */
754 				ODM_RT_TRACE(
755 					dm, ODM_COMP_TX_PWR_TRACK,
756 					"Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
757 					p, cali_info->power_index_offset[p],
758 					delta, thermal_value,
759 					rtlefu->eeprom_thermalmeter,
760 					cali_info->thermal_value);
761 			}
762 		}
763 
764 		if (thermal_value > rtlefu->eeprom_thermalmeter) {
765 			ODM_RT_TRACE(
766 				dm, ODM_COMP_TX_PWR_TRACK,
767 				"Temperature(%d) higher than PG value(%d)\n",
768 				thermal_value, rtlefu->eeprom_thermalmeter);
769 
770 			phydm_odm_tx_power_set(dm, &c, indexforchannel, 0);
771 		} else {
772 			ODM_RT_TRACE(
773 				dm, ODM_COMP_TX_PWR_TRACK,
774 				"Temperature(%d) lower than PG value(%d)\n",
775 				thermal_value, rtlefu->eeprom_thermalmeter);
776 			phydm_odm_tx_power_set(dm, &c, indexforchannel, 1);
777 		}
778 
779 		/*Record last time Power Tracking result as base.*/
780 		cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck;
781 
782 		for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
783 			cali_info->bb_swing_idx_ofdm_base[p] =
784 				cali_info->bb_swing_idx_ofdm[p];
785 
786 		ODM_RT_TRACE(
787 			dm, ODM_COMP_TX_PWR_TRACK,
788 			"cali_info->thermal_value = %d thermal_value= %d\n",
789 			cali_info->thermal_value, thermal_value);
790 
791 		/*Record last Power Tracking Thermal value*/
792 		cali_info->thermal_value = thermal_value;
793 	}
794 
795 	if (dm->support_ic_type == ODM_RTL8703B ||
796 	    dm->support_ic_type == ODM_RTL8723D ||
797 	    dm->support_ic_type == ODM_RTL8710B) { /* JJ ADD 20161014 */
798 
799 		if (xtal_offset_eanble != 0 &&
800 		    cali_info->txpowertrack_control &&
801 		    (rtlefu->eeprom_thermalmeter != 0xff)) {
802 			ODM_RT_TRACE(
803 				dm, ODM_COMP_TX_PWR_TRACK,
804 				"**********Enter Xtal Tracking**********\n");
805 
806 			if (thermal_value > rtlefu->eeprom_thermalmeter) {
807 				ODM_RT_TRACE(
808 					dm, ODM_COMP_TX_PWR_TRACK,
809 					"Temperature(%d) higher than PG value(%d)\n",
810 					thermal_value,
811 					rtlefu->eeprom_thermalmeter);
812 				(*c.odm_txxtaltrack_set_xtal)(dm);
813 			} else {
814 				ODM_RT_TRACE(
815 					dm, ODM_COMP_TX_PWR_TRACK,
816 					"Temperature(%d) lower than PG value(%d)\n",
817 					thermal_value,
818 					rtlefu->eeprom_thermalmeter);
819 				(*c.odm_txxtaltrack_set_xtal)(dm);
820 			}
821 		}
822 		ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
823 			     "**********End Xtal Tracking**********\n");
824 	}
825 
826 	if (!IS_HARDWARE_TYPE_8723B(adapter)) {
827 		/* Delta temperature is equal to or larger than 20 centigrade
828 		 * (When threshold is 8).
829 		 */
830 		if (delta_IQK >= c.threshold_iqk) {
831 			ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
832 				     "delta_IQK(%d) >= threshold_iqk(%d)\n",
833 				     delta_IQK, c.threshold_iqk);
834 			if (!cali_info->is_iqk_in_progress)
835 				(*c.do_iqk)(dm, delta_IQK, thermal_value, 8);
836 		}
837 	}
838 	if (cali_info->dpk_thermal[ODM_RF_PATH_A] != 0) {
839 		if (diff_DPK[ODM_RF_PATH_A] >= c.threshold_dpk) {
840 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
841 			odm_set_bb_reg(
842 				dm, 0xcc4,
843 				BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10),
844 				(diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk));
845 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
846 		} else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.threshold_dpk)) {
847 			s32 value = 0x20 +
848 				    (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk);
849 
850 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
851 			odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) |
852 							  BIT(11) | BIT(10),
853 				       value);
854 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
855 		} else {
856 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
857 			odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) |
858 							  BIT(11) | BIT(10),
859 				       0);
860 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
861 		}
862 	}
863 	if (cali_info->dpk_thermal[ODM_RF_PATH_B] != 0) {
864 		if (diff_DPK[ODM_RF_PATH_B] >= c.threshold_dpk) {
865 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
866 			odm_set_bb_reg(
867 				dm, 0xec4,
868 				BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10),
869 				(diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk));
870 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
871 		} else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.threshold_dpk)) {
872 			s32 value = 0x20 +
873 				    (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk);
874 
875 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
876 			odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) |
877 							  BIT(11) | BIT(10),
878 				       value);
879 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
880 		} else {
881 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1);
882 			odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) |
883 							  BIT(11) | BIT(10),
884 				       0);
885 			odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0);
886 		}
887 	}
888 
889 	ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "<===%s\n", __func__);
890 
891 	cali_info->tx_powercount = 0;
892 }
893 
894 /* 3============================================================
895  * 3 IQ Calibration
896  * 3============================================================
897  */
898 
odm_reset_iqk_result(void * dm_void)899 void odm_reset_iqk_result(void *dm_void) { return; }
900 
odm_get_right_chnl_place_for_iqk(u8 chnl)901 u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
902 {
903 	u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
904 		1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,
905 		13,  14,  36,  38,  40,  42,  44,  46,  48,  50,  52,  54,
906 		56,  58,  60,  62,  64,  100, 102, 104, 106, 108, 110, 112,
907 		114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136,
908 		138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165};
909 	u8 place = chnl;
910 
911 	if (chnl > 14) {
912 		for (place = 14; place < sizeof(channel_all); place++) {
913 			if (channel_all[place] == chnl)
914 				return place - 13;
915 		}
916 	}
917 	return 0;
918 }
919 
odm_iq_calibrate(struct phy_dm_struct * dm)920 static void odm_iq_calibrate(struct phy_dm_struct *dm)
921 {
922 	void *adapter = dm->adapter;
923 
924 	if (IS_HARDWARE_TYPE_8812AU(adapter))
925 		return;
926 
927 	if (dm->is_linked) {
928 		if ((*dm->channel != dm->pre_channel) &&
929 		    (!*dm->is_scan_in_process)) {
930 			dm->pre_channel = *dm->channel;
931 			dm->linked_interval = 0;
932 		}
933 
934 		if (dm->linked_interval < 3)
935 			dm->linked_interval++;
936 
937 		if (dm->linked_interval == 2) {
938 			if (IS_HARDWARE_TYPE_8814A(adapter))
939 				;
940 
941 			else if (IS_HARDWARE_TYPE_8822B(adapter))
942 				phy_iq_calibrate_8822b(dm, false);
943 		}
944 	} else {
945 		dm->linked_interval = 0;
946 	}
947 }
948 
phydm_rf_init(void * dm_void)949 void phydm_rf_init(void *dm_void)
950 {
951 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
952 
953 	odm_txpowertracking_init(dm);
954 
955 	odm_clear_txpowertracking_state(dm);
956 }
957 
phydm_rf_watchdog(void * dm_void)958 void phydm_rf_watchdog(void *dm_void)
959 {
960 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
961 
962 	odm_txpowertracking_check(dm);
963 	if (dm->support_ic_type & ODM_IC_11AC_SERIES)
964 		odm_iq_calibrate(dm);
965 }
966