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