• 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 /* ************************************************************
27  * include files
28  * *************************************************************/
29 
30 #include "mp_precomp.h"
31 #include "phydm_precomp.h"
32 
33 static const u16 db_invert_table[12][8] = {
34 	{1, 1, 1, 2, 2, 2, 2, 3},
35 	{3, 3, 4, 4, 4, 5, 6, 6},
36 	{7, 8, 9, 10, 11, 13, 14, 16},
37 	{18, 20, 22, 25, 28, 32, 35, 40},
38 	{45, 50, 56, 63, 71, 79, 89, 100},
39 	{112, 126, 141, 158, 178, 200, 224, 251},
40 	{282, 316, 355, 398, 447, 501, 562, 631},
41 	{708, 794, 891, 1000, 1122, 1259, 1413, 1585},
42 	{1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981},
43 	{4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000},
44 	{11220, 12589, 14125, 15849, 17783, 19953, 22387, 25119},
45 	{28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535},
46 };
47 
48 /* ************************************************************
49  * Local Function predefine.
50  * *************************************************************/
51 
52 /* START------------COMMON INFO RELATED--------------- */
53 
54 static void odm_update_power_training_state(struct phy_dm_struct *dm);
55 
56 /* ************************************************************
57  * 3 Export Interface
58  * *************************************************************/
59 
60 /*Y = 10*log(X)*/
odm_pwdb_conversion(s32 X,u32 total_bit,u32 decimal_bit)61 s32 odm_pwdb_conversion(s32 X, u32 total_bit, u32 decimal_bit)
62 {
63 	s32 Y, integer = 0, decimal = 0;
64 	u32 i;
65 
66 	if (X == 0)
67 		X = 1; /* log2(x), x can't be 0 */
68 
69 	for (i = (total_bit - 1); i > 0; i--) {
70 		if (X & BIT(i)) {
71 			integer = i;
72 			if (i > 0) {
73 				/* decimal is 0.5dB*3=1.5dB~=2dB */
74 				decimal = (X & BIT(i - 1)) ? 2 : 0;
75 			}
76 			break;
77 		}
78 	}
79 
80 	Y = 3 * (integer - decimal_bit) + decimal; /* 10*log(x)=3*log2(x), */
81 
82 	return Y;
83 }
84 
odm_sign_conversion(s32 value,u32 total_bit)85 s32 odm_sign_conversion(s32 value, u32 total_bit)
86 {
87 	if (value & BIT(total_bit - 1))
88 		value -= BIT(total_bit);
89 	return value;
90 }
91 
phydm_seq_sorting(void * dm_void,u32 * value,u32 * rank_idx,u32 * idx_out,u8 seq_length)92 void phydm_seq_sorting(void *dm_void, u32 *value, u32 *rank_idx, u32 *idx_out,
93 		       u8 seq_length)
94 {
95 	u8 i = 0, j = 0;
96 	u32 tmp_a, tmp_b;
97 	u32 tmp_idx_a, tmp_idx_b;
98 
99 	for (i = 0; i < seq_length; i++) {
100 		rank_idx[i] = i;
101 		/**/
102 	}
103 
104 	for (i = 0; i < (seq_length - 1); i++) {
105 		for (j = 0; j < (seq_length - 1 - i); j++) {
106 			tmp_a = value[j];
107 			tmp_b = value[j + 1];
108 
109 			tmp_idx_a = rank_idx[j];
110 			tmp_idx_b = rank_idx[j + 1];
111 
112 			if (tmp_a < tmp_b) {
113 				value[j] = tmp_b;
114 				value[j + 1] = tmp_a;
115 
116 				rank_idx[j] = tmp_idx_b;
117 				rank_idx[j + 1] = tmp_idx_a;
118 			}
119 		}
120 	}
121 
122 	for (i = 0; i < seq_length; i++) {
123 		idx_out[rank_idx[i]] = i + 1;
124 		/**/
125 	}
126 }
127 
odm_init_mp_driver_status(struct phy_dm_struct * dm)128 void odm_init_mp_driver_status(struct phy_dm_struct *dm)
129 {
130 	dm->mp_mode = false;
131 }
132 
odm_update_mp_driver_status(struct phy_dm_struct * dm)133 static void odm_update_mp_driver_status(struct phy_dm_struct *dm)
134 {
135 	/* Do nothing. */
136 }
137 
phydm_init_trx_antenna_setting(struct phy_dm_struct * dm)138 static void phydm_init_trx_antenna_setting(struct phy_dm_struct *dm)
139 {
140 	/*#if (RTL8814A_SUPPORT == 1)*/
141 
142 	if (dm->support_ic_type & (ODM_RTL8814A)) {
143 		u8 rx_ant = 0, tx_ant = 0;
144 
145 		rx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
146 					    ODM_BIT(BB_RX_PATH, dm));
147 		tx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_TX_PATH, dm),
148 					    ODM_BIT(BB_TX_PATH, dm));
149 		dm->tx_ant_status = (tx_ant & 0xf);
150 		dm->rx_ant_status = (rx_ant & 0xf);
151 	} else if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8821C |
152 					  ODM_RTL8710B)) { /* JJ ADD 20161014 */
153 		dm->tx_ant_status = 0x1;
154 		dm->rx_ant_status = 0x1;
155 	}
156 	/*#endif*/
157 }
158 
phydm_traffic_load_decision(void * dm_void)159 static void phydm_traffic_load_decision(void *dm_void)
160 {
161 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
162 
163 	/*---TP & Trafic-load calculation---*/
164 
165 	if (dm->last_tx_ok_cnt > *dm->num_tx_bytes_unicast)
166 		dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
167 
168 	if (dm->last_rx_ok_cnt > *dm->num_rx_bytes_unicast)
169 		dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
170 
171 	dm->cur_tx_ok_cnt = *dm->num_tx_bytes_unicast - dm->last_tx_ok_cnt;
172 	dm->cur_rx_ok_cnt = *dm->num_rx_bytes_unicast - dm->last_rx_ok_cnt;
173 	dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
174 	dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
175 
176 	dm->tx_tp = ((dm->tx_tp) >> 1) +
177 		    (u32)(((dm->cur_tx_ok_cnt) >> 18) >>
178 			  1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
179 	dm->rx_tp = ((dm->rx_tp) >> 1) +
180 		    (u32)(((dm->cur_rx_ok_cnt) >> 18) >>
181 			  1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
182 	dm->total_tp = dm->tx_tp + dm->rx_tp;
183 
184 	dm->pre_traffic_load = dm->traffic_load;
185 
186 	if (dm->cur_tx_ok_cnt > 1875000 ||
187 	    dm->cur_rx_ok_cnt >
188 		    1875000) { /* ( 1.875M * 8bit ) / 2sec= 7.5M bits /sec )*/
189 
190 		dm->traffic_load = TRAFFIC_HIGH;
191 		/**/
192 	} else if (
193 		dm->cur_tx_ok_cnt > 500000 ||
194 		dm->cur_rx_ok_cnt >
195 			500000) { /*( 0.5M * 8bit ) / 2sec =  2M bits /sec )*/
196 
197 		dm->traffic_load = TRAFFIC_MID;
198 		/**/
199 	} else if (
200 		dm->cur_tx_ok_cnt > 100000 ||
201 		dm->cur_rx_ok_cnt >
202 			100000) { /*( 0.1M * 8bit ) / 2sec =  0.4M bits /sec )*/
203 
204 		dm->traffic_load = TRAFFIC_LOW;
205 		/**/
206 	} else {
207 		dm->traffic_load = TRAFFIC_ULTRA_LOW;
208 		/**/
209 	}
210 }
211 
phydm_config_ofdm_tx_path(struct phy_dm_struct * dm,u32 path)212 static void phydm_config_ofdm_tx_path(struct phy_dm_struct *dm, u32 path) {}
213 
phydm_config_ofdm_rx_path(struct phy_dm_struct * dm,u32 path)214 void phydm_config_ofdm_rx_path(struct phy_dm_struct *dm, u32 path)
215 {
216 	u8 ofdm_rx_path = 0;
217 
218 	if (dm->support_ic_type & (ODM_RTL8192E)) {
219 	} else if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8822B)) {
220 		if (path == PHYDM_A) {
221 			ofdm_rx_path = 1;
222 			/**/
223 		} else if (path == PHYDM_B) {
224 			ofdm_rx_path = 2;
225 			/**/
226 		} else if (path == PHYDM_AB) {
227 			ofdm_rx_path = 3;
228 			/**/
229 		}
230 
231 		odm_set_bb_reg(dm, 0x808, MASKBYTE0,
232 			       ((ofdm_rx_path << 4) | ofdm_rx_path));
233 	}
234 }
235 
phydm_config_cck_rx_antenna_init(struct phy_dm_struct * dm)236 static void phydm_config_cck_rx_antenna_init(struct phy_dm_struct *dm) {}
237 
phydm_config_cck_rx_path(struct phy_dm_struct * dm,u8 path,u8 path_div_en)238 static void phydm_config_cck_rx_path(struct phy_dm_struct *dm, u8 path,
239 				     u8 path_div_en)
240 {
241 }
242 
phydm_config_trx_path(void * dm_void,u32 * const dm_value,u32 * _used,char * output,u32 * _out_len)243 void phydm_config_trx_path(void *dm_void, u32 *const dm_value, u32 *_used,
244 			   char *output, u32 *_out_len)
245 {
246 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
247 	u32 used = *_used;
248 	u32 out_len = *_out_len;
249 
250 	/* CCK */
251 	if (dm_value[0] == 0) {
252 		if (dm_value[1] == 1) { /*TX*/
253 			if (dm_value[2] == 1)
254 				odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x8);
255 			else if (dm_value[2] == 2)
256 				odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4);
257 			else if (dm_value[2] == 3)
258 				odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc);
259 		} else if (dm_value[1] == 2) { /*RX*/
260 
261 			phydm_config_cck_rx_antenna_init(dm);
262 
263 			if (dm_value[2] == 1)
264 				phydm_config_cck_rx_path(dm, PHYDM_A,
265 							 CCA_PATHDIV_DISABLE);
266 			else if (dm_value[2] == 2)
267 				phydm_config_cck_rx_path(dm, PHYDM_B,
268 							 CCA_PATHDIV_DISABLE);
269 			else if (dm_value[2] == 3 &&
270 				 dm_value[3] == 1) /*enable path diversity*/
271 				phydm_config_cck_rx_path(dm, PHYDM_AB,
272 							 CCA_PATHDIV_ENABLE);
273 			else if (dm_value[2] == 3 && dm_value[3] != 1)
274 				phydm_config_cck_rx_path(dm, PHYDM_B,
275 							 CCA_PATHDIV_DISABLE);
276 		}
277 	}
278 	/* OFDM */
279 	else if (dm_value[0] == 1) {
280 		if (dm_value[1] == 1) { /*TX*/
281 			phydm_config_ofdm_tx_path(dm, dm_value[2]);
282 			/**/
283 		} else if (dm_value[1] == 2) { /*RX*/
284 			phydm_config_ofdm_rx_path(dm, dm_value[2]);
285 			/**/
286 		}
287 	}
288 
289 	PHYDM_SNPRINTF(
290 		output + used, out_len - used,
291 		"PHYDM Set path [%s] [%s] = [%s%s%s%s]\n",
292 		(dm_value[0] == 1) ? "OFDM" : "CCK",
293 		(dm_value[1] == 1) ? "TX" : "RX",
294 		(dm_value[2] & 0x1) ? "A" : "", (dm_value[2] & 0x2) ? "B" : "",
295 		(dm_value[2] & 0x4) ? "C" : "", (dm_value[2] & 0x8) ? "D" : "");
296 }
297 
phydm_init_cck_setting(struct phy_dm_struct * dm)298 static void phydm_init_cck_setting(struct phy_dm_struct *dm)
299 {
300 	dm->is_cck_high_power = (bool)odm_get_bb_reg(
301 		dm, ODM_REG(CCK_RPT_FORMAT, dm), ODM_BIT(CCK_RPT_FORMAT, dm));
302 
303 	/* JJ ADD 20161014 */
304 	/* JJ ADD 20161014 */
305 	if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8822B | ODM_RTL8197F |
306 				   ODM_RTL8821C | ODM_RTL8710B))
307 		dm->cck_new_agc = odm_get_bb_reg(dm, 0xa9c, BIT(17)) ?
308 					  true :
309 					  false; /*1: new agc  0: old agc*/
310 	else
311 		dm->cck_new_agc = false;
312 }
313 
phydm_init_soft_ml_setting(struct phy_dm_struct * dm)314 static void phydm_init_soft_ml_setting(struct phy_dm_struct *dm)
315 {
316 	if (!dm->mp_mode) {
317 		if (dm->support_ic_type & ODM_RTL8822B)
318 			odm_set_bb_reg(dm, 0x19a8, MASKDWORD, 0xc10a0000);
319 	}
320 }
321 
phydm_init_hw_info_by_rfe(struct phy_dm_struct * dm)322 static void phydm_init_hw_info_by_rfe(struct phy_dm_struct *dm)
323 {
324 	if (dm->support_ic_type & ODM_RTL8822B)
325 		phydm_init_hw_info_by_rfe_type_8822b(dm);
326 }
327 
odm_common_info_self_init(struct phy_dm_struct * dm)328 static void odm_common_info_self_init(struct phy_dm_struct *dm)
329 {
330 	phydm_init_cck_setting(dm);
331 	dm->rf_path_rx_enable = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
332 						   ODM_BIT(BB_RX_PATH, dm));
333 	odm_init_mp_driver_status(dm);
334 	phydm_init_trx_antenna_setting(dm);
335 	phydm_init_soft_ml_setting(dm);
336 
337 	dm->phydm_period = PHYDM_WATCH_DOG_PERIOD;
338 	dm->phydm_sys_up_time = 0;
339 
340 	if (dm->support_ic_type & ODM_IC_1SS)
341 		dm->num_rf_path = 1;
342 	else if (dm->support_ic_type & ODM_IC_2SS)
343 		dm->num_rf_path = 2;
344 	else if (dm->support_ic_type & ODM_IC_3SS)
345 		dm->num_rf_path = 3;
346 	else if (dm->support_ic_type & ODM_IC_4SS)
347 		dm->num_rf_path = 4;
348 
349 	dm->tx_rate = 0xFF;
350 
351 	dm->number_linked_client = 0;
352 	dm->pre_number_linked_client = 0;
353 	dm->number_active_client = 0;
354 	dm->pre_number_active_client = 0;
355 
356 	dm->last_tx_ok_cnt = 0;
357 	dm->last_rx_ok_cnt = 0;
358 	dm->tx_tp = 0;
359 	dm->rx_tp = 0;
360 	dm->total_tp = 0;
361 	dm->traffic_load = TRAFFIC_LOW;
362 
363 	dm->nbi_set_result = 0;
364 	dm->is_init_hw_info_by_rfe = false;
365 	dm->pre_dbg_priority = BB_DBGPORT_RELEASE;
366 }
367 
odm_common_info_self_update(struct phy_dm_struct * dm)368 static void odm_common_info_self_update(struct phy_dm_struct *dm)
369 {
370 	u8 entry_cnt = 0, num_active_client = 0;
371 	u32 i, one_entry_macid = 0;
372 	struct rtl_sta_info *entry;
373 
374 	/* THis variable cannot be used because it is wrong*/
375 	if (*dm->band_width == ODM_BW40M) {
376 		if (*dm->sec_ch_offset == 1)
377 			dm->control_channel = *dm->channel - 2;
378 		else if (*dm->sec_ch_offset == 2)
379 			dm->control_channel = *dm->channel + 2;
380 	} else {
381 		dm->control_channel = *dm->channel;
382 	}
383 
384 	for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
385 		entry = dm->odm_sta_info[i];
386 		if (IS_STA_VALID(entry)) {
387 			entry_cnt++;
388 			if (entry_cnt == 1)
389 				one_entry_macid = i;
390 		}
391 	}
392 
393 	if (entry_cnt == 1) {
394 		dm->is_one_entry_only = true;
395 		dm->one_entry_macid = one_entry_macid;
396 	} else {
397 		dm->is_one_entry_only = false;
398 	}
399 
400 	dm->pre_number_linked_client = dm->number_linked_client;
401 	dm->pre_number_active_client = dm->number_active_client;
402 
403 	dm->number_linked_client = entry_cnt;
404 	dm->number_active_client = num_active_client;
405 
406 	/* Update MP driver status*/
407 	odm_update_mp_driver_status(dm);
408 
409 	/*Traffic load information update*/
410 	phydm_traffic_load_decision(dm);
411 
412 	dm->phydm_sys_up_time += dm->phydm_period;
413 }
414 
odm_common_info_self_reset(struct phy_dm_struct * dm)415 static void odm_common_info_self_reset(struct phy_dm_struct *dm)
416 {
417 	dm->phy_dbg_info.num_qry_beacon_pkt = 0;
418 }
419 
phydm_get_structure(struct phy_dm_struct * dm,u8 structure_type)420 void *phydm_get_structure(struct phy_dm_struct *dm, u8 structure_type)
421 
422 {
423 	void *p_struct = NULL;
424 
425 	switch (structure_type) {
426 	case PHYDM_FALSEALMCNT:
427 		p_struct = &dm->false_alm_cnt;
428 		break;
429 
430 	case PHYDM_CFOTRACK:
431 		p_struct = &dm->dm_cfo_track;
432 		break;
433 
434 	case PHYDM_ADAPTIVITY:
435 		p_struct = &dm->adaptivity;
436 		break;
437 
438 	default:
439 		break;
440 	}
441 
442 	return p_struct;
443 }
444 
odm_hw_setting(struct phy_dm_struct * dm)445 static void odm_hw_setting(struct phy_dm_struct *dm)
446 {
447 	if (dm->support_ic_type & ODM_RTL8822B)
448 		phydm_hwsetting_8822b(dm);
449 }
450 
phydm_supportability_init(void * dm_void)451 static void phydm_supportability_init(void *dm_void)
452 {
453 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
454 	u32 support_ability = 0;
455 
456 	if (dm->support_ic_type != ODM_RTL8821C)
457 		return;
458 
459 	switch (dm->support_ic_type) {
460 	/*---------------AC Series-------------------*/
461 
462 	case ODM_RTL8822B:
463 		support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
464 				   ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
465 				   ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
466 				   ODM_RF_TX_PWR_TRACK;
467 		break;
468 
469 	default:
470 		support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
471 				   ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
472 				   ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
473 				   ODM_RF_TX_PWR_TRACK;
474 
475 		ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
476 			     "[Warning] Supportability Init Warning !!!\n");
477 		break;
478 	}
479 
480 	if (*dm->enable_antdiv)
481 		support_ability |= ODM_BB_ANT_DIV;
482 
483 	if (*dm->enable_adaptivity) {
484 		ODM_RT_TRACE(dm, ODM_COMP_INIT,
485 			     "ODM adaptivity is set to Enabled!!!\n");
486 
487 		support_ability |= ODM_BB_ADAPTIVITY;
488 
489 	} else {
490 		ODM_RT_TRACE(dm, ODM_COMP_INIT,
491 			     "ODM adaptivity is set to disnabled!!!\n");
492 		/**/
493 	}
494 
495 	ODM_RT_TRACE(dm, ODM_COMP_INIT, "PHYDM support_ability = ((0x%x))\n",
496 		     support_ability);
497 	odm_cmn_info_init(dm, ODM_CMNINFO_ABILITY, support_ability);
498 }
499 
500 /*
501  * 2011/09/21 MH Add to describe different team necessary resource allocate??
502  */
odm_dm_init(struct phy_dm_struct * dm)503 void odm_dm_init(struct phy_dm_struct *dm)
504 {
505 	phydm_supportability_init(dm);
506 	odm_common_info_self_init(dm);
507 	odm_dig_init(dm);
508 	phydm_nhm_counter_statistics_init(dm);
509 	phydm_adaptivity_init(dm);
510 	phydm_ra_info_init(dm);
511 	odm_rate_adaptive_mask_init(dm);
512 	odm_cfo_tracking_init(dm);
513 	odm_edca_turbo_init(dm);
514 	odm_rssi_monitor_init(dm);
515 	phydm_rf_init(dm);
516 	odm_txpowertracking_init(dm);
517 
518 	if (dm->support_ic_type & ODM_RTL8822B)
519 		phydm_txcurrentcalibration(dm);
520 
521 	odm_antenna_diversity_init(dm);
522 	odm_auto_channel_select_init(dm);
523 	odm_dynamic_tx_power_init(dm);
524 	phydm_init_ra_info(dm);
525 	adc_smp_init(dm);
526 
527 	phydm_beamforming_init(dm);
528 
529 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
530 		/* 11n series */
531 		odm_dynamic_bb_power_saving_init(dm);
532 	}
533 
534 	phydm_psd_init(dm);
535 }
536 
odm_dm_reset(struct phy_dm_struct * dm)537 void odm_dm_reset(struct phy_dm_struct *dm)
538 {
539 	struct dig_thres *dig_tab = &dm->dm_dig_table;
540 
541 	odm_ant_div_reset(dm);
542 	phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value);
543 }
544 
phydm_support_ability_debug(void * dm_void,u32 * const dm_value,u32 * _used,char * output,u32 * _out_len)545 void phydm_support_ability_debug(void *dm_void, u32 *const dm_value, u32 *_used,
546 				 char *output, u32 *_out_len)
547 {
548 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
549 	u32 pre_support_ability;
550 	u32 used = *_used;
551 	u32 out_len = *_out_len;
552 
553 	pre_support_ability = dm->support_ability;
554 	PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n",
555 		       "================================");
556 	if (dm_value[0] == 100) {
557 		PHYDM_SNPRINTF(output + used, out_len - used,
558 			       "[Supportability] PhyDM Selection\n");
559 		PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
560 			       "================================");
561 		PHYDM_SNPRINTF(
562 			output + used, out_len - used, "00. (( %s ))DIG\n",
563 			((dm->support_ability & ODM_BB_DIG) ? ("V") : (".")));
564 		PHYDM_SNPRINTF(
565 			output + used, out_len - used, "01. (( %s ))RA_MASK\n",
566 			((dm->support_ability & ODM_BB_RA_MASK) ? ("V") :
567 								  (".")));
568 		PHYDM_SNPRINTF(output + used, out_len - used,
569 			       "02. (( %s ))DYNAMIC_TXPWR\n",
570 			       ((dm->support_ability & ODM_BB_DYNAMIC_TXPWR) ?
571 					("V") :
572 					(".")));
573 		PHYDM_SNPRINTF(output + used, out_len - used,
574 			       "03. (( %s ))FA_CNT\n",
575 			       ((dm->support_ability & ODM_BB_FA_CNT) ? ("V") :
576 									(".")));
577 		PHYDM_SNPRINTF(output + used, out_len - used,
578 			       "04. (( %s ))RSSI_MONITOR\n",
579 			       ((dm->support_ability & ODM_BB_RSSI_MONITOR) ?
580 					("V") :
581 					(".")));
582 		PHYDM_SNPRINTF(output + used, out_len - used,
583 			       "05. (( %s ))CCK_PD\n",
584 			       ((dm->support_ability & ODM_BB_CCK_PD) ? ("V") :
585 									(".")));
586 		PHYDM_SNPRINTF(
587 			output + used, out_len - used, "06. (( %s ))ANT_DIV\n",
588 			((dm->support_ability & ODM_BB_ANT_DIV) ? ("V") :
589 								  (".")));
590 		PHYDM_SNPRINTF(output + used, out_len - used,
591 			       "08. (( %s ))PWR_TRAIN\n",
592 			       ((dm->support_ability & ODM_BB_PWR_TRAIN) ?
593 					("V") :
594 					(".")));
595 		PHYDM_SNPRINTF(output + used, out_len - used,
596 			       "09. (( %s ))RATE_ADAPTIVE\n",
597 			       ((dm->support_ability & ODM_BB_RATE_ADAPTIVE) ?
598 					("V") :
599 					(".")));
600 		PHYDM_SNPRINTF(
601 			output + used, out_len - used, "10. (( %s ))PATH_DIV\n",
602 			((dm->support_ability & ODM_BB_PATH_DIV) ? ("V") :
603 								   (".")));
604 		PHYDM_SNPRINTF(output + used, out_len - used,
605 			       "13. (( %s ))ADAPTIVITY\n",
606 			       ((dm->support_ability & ODM_BB_ADAPTIVITY) ?
607 					("V") :
608 					(".")));
609 		PHYDM_SNPRINTF(output + used, out_len - used,
610 			       "14. (( %s ))struct cfo_tracking\n",
611 			       ((dm->support_ability & ODM_BB_CFO_TRACKING) ?
612 					("V") :
613 					(".")));
614 		PHYDM_SNPRINTF(
615 			output + used, out_len - used, "15. (( %s ))NHM_CNT\n",
616 			((dm->support_ability & ODM_BB_NHM_CNT) ? ("V") :
617 								  (".")));
618 		PHYDM_SNPRINTF(output + used, out_len - used,
619 			       "16. (( %s ))PRIMARY_CCA\n",
620 			       ((dm->support_ability & ODM_BB_PRIMARY_CCA) ?
621 					("V") :
622 					(".")));
623 		PHYDM_SNPRINTF(
624 			output + used, out_len - used, "17. (( %s ))TXBF\n",
625 			((dm->support_ability & ODM_BB_TXBF) ? ("V") : (".")));
626 		PHYDM_SNPRINTF(output + used, out_len - used,
627 			       "18. (( %s ))DYNAMIC_ARFR\n",
628 			       ((dm->support_ability & ODM_BB_DYNAMIC_ARFR) ?
629 					("V") :
630 					(".")));
631 		PHYDM_SNPRINTF(output + used, out_len - used,
632 			       "20. (( %s ))EDCA_TURBO\n",
633 			       ((dm->support_ability & ODM_MAC_EDCA_TURBO) ?
634 					("V") :
635 					(".")));
636 		PHYDM_SNPRINTF(output + used, out_len - used,
637 			       "21. (( %s ))DYNAMIC_RX_PATH\n",
638 			       ((dm->support_ability & ODM_BB_DYNAMIC_RX_PATH) ?
639 					("V") :
640 					(".")));
641 		PHYDM_SNPRINTF(output + used, out_len - used,
642 			       "24. (( %s ))TX_PWR_TRACK\n",
643 			       ((dm->support_ability & ODM_RF_TX_PWR_TRACK) ?
644 					("V") :
645 					(".")));
646 		PHYDM_SNPRINTF(output + used, out_len - used,
647 			       "25. (( %s ))RX_GAIN_TRACK\n",
648 			       ((dm->support_ability & ODM_RF_RX_GAIN_TRACK) ?
649 					("V") :
650 					(".")));
651 		PHYDM_SNPRINTF(output + used, out_len - used,
652 			       "26. (( %s ))RF_CALIBRATION\n",
653 			       ((dm->support_ability & ODM_RF_CALIBRATION) ?
654 					("V") :
655 					(".")));
656 		PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
657 			       "================================");
658 	} else {
659 		if (dm_value[1] == 1) { /* enable */
660 			dm->support_ability |= BIT(dm_value[0]);
661 		} else if (dm_value[1] == 2) /* disable */
662 			dm->support_ability &= ~(BIT(dm_value[0]));
663 		else {
664 			PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
665 				       "[Warning!!!]  1:enable,  2:disable");
666 		}
667 	}
668 	PHYDM_SNPRINTF(output + used, out_len - used,
669 		       "pre-support_ability  =  0x%x\n", pre_support_ability);
670 	PHYDM_SNPRINTF(output + used, out_len - used,
671 		       "Curr-support_ability =  0x%x\n", dm->support_ability);
672 	PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
673 		       "================================");
674 }
675 
phydm_watchdog_mp(struct phy_dm_struct * dm)676 void phydm_watchdog_mp(struct phy_dm_struct *dm) {}
677 /*
678  * 2011/09/20 MH This is the entry pointer for all team to execute HW outsrc DM.
679  * You can not add any dummy function here, be care, you can only use DM struct
680  * to perform any new ODM_DM.
681  */
odm_dm_watchdog(struct phy_dm_struct * dm)682 void odm_dm_watchdog(struct phy_dm_struct *dm)
683 {
684 	odm_common_info_self_update(dm);
685 	phydm_basic_dbg_message(dm);
686 	odm_hw_setting(dm);
687 
688 	odm_false_alarm_counter_statistics(dm);
689 	phydm_noisy_detection(dm);
690 
691 	odm_rssi_monitor_check(dm);
692 
693 	if (*dm->is_power_saving) {
694 		odm_dig_by_rssi_lps(dm);
695 		phydm_adaptivity(dm);
696 		odm_antenna_diversity(
697 			dm); /*enable AntDiv in PS mode, request from SD4 Jeff*/
698 		ODM_RT_TRACE(dm, ODM_COMP_COMMON,
699 			     "DMWatchdog in power saving mode\n");
700 		return;
701 	}
702 
703 	phydm_check_adaptivity(dm);
704 	odm_update_power_training_state(dm);
705 	odm_DIG(dm);
706 	phydm_adaptivity(dm);
707 	odm_cck_packet_detection_thresh(dm);
708 
709 	phydm_ra_info_watchdog(dm);
710 	odm_edca_turbo_check(dm);
711 	odm_cfo_tracking(dm);
712 	odm_dynamic_tx_power(dm);
713 	odm_antenna_diversity(dm);
714 
715 	phydm_beamforming_watchdog(dm);
716 
717 	phydm_rf_watchdog(dm);
718 
719 	odm_dtc(dm);
720 
721 	odm_common_info_self_reset(dm);
722 }
723 
724 /*
725  * Init /.. Fixed HW value. Only init time.
726  */
odm_cmn_info_init(struct phy_dm_struct * dm,enum odm_cmninfo cmn_info,u32 value)727 void odm_cmn_info_init(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
728 		       u32 value)
729 {
730 	/* This section is used for init value */
731 	switch (cmn_info) {
732 	/* Fixed ODM value. */
733 	case ODM_CMNINFO_ABILITY:
734 		dm->support_ability = (u32)value;
735 		break;
736 
737 	case ODM_CMNINFO_RF_TYPE:
738 		dm->rf_type = (u8)value;
739 		break;
740 
741 	case ODM_CMNINFO_PLATFORM:
742 		dm->support_platform = (u8)value;
743 		break;
744 
745 	case ODM_CMNINFO_INTERFACE:
746 		dm->support_interface = (u8)value;
747 		break;
748 
749 	case ODM_CMNINFO_MP_TEST_CHIP:
750 		dm->is_mp_chip = (u8)value;
751 		break;
752 
753 	case ODM_CMNINFO_IC_TYPE:
754 		dm->support_ic_type = value;
755 		break;
756 
757 	case ODM_CMNINFO_CUT_VER:
758 		dm->cut_version = (u8)value;
759 		break;
760 
761 	case ODM_CMNINFO_FAB_VER:
762 		dm->fab_version = (u8)value;
763 		break;
764 
765 	case ODM_CMNINFO_RFE_TYPE:
766 		dm->rfe_type = (u8)value;
767 		phydm_init_hw_info_by_rfe(dm);
768 		break;
769 
770 	case ODM_CMNINFO_RF_ANTENNA_TYPE:
771 		dm->ant_div_type = (u8)value;
772 		break;
773 
774 	case ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH:
775 		dm->with_extenal_ant_switch = (u8)value;
776 		break;
777 
778 	case ODM_CMNINFO_BE_FIX_TX_ANT:
779 		dm->dm_fat_table.b_fix_tx_ant = (u8)value;
780 		break;
781 
782 	case ODM_CMNINFO_BOARD_TYPE:
783 		if (!dm->is_init_hw_info_by_rfe)
784 			dm->board_type = (u8)value;
785 		break;
786 
787 	case ODM_CMNINFO_PACKAGE_TYPE:
788 		if (!dm->is_init_hw_info_by_rfe)
789 			dm->package_type = (u8)value;
790 		break;
791 
792 	case ODM_CMNINFO_EXT_LNA:
793 		if (!dm->is_init_hw_info_by_rfe)
794 			dm->ext_lna = (u8)value;
795 		break;
796 
797 	case ODM_CMNINFO_5G_EXT_LNA:
798 		if (!dm->is_init_hw_info_by_rfe)
799 			dm->ext_lna_5g = (u8)value;
800 		break;
801 
802 	case ODM_CMNINFO_EXT_PA:
803 		if (!dm->is_init_hw_info_by_rfe)
804 			dm->ext_pa = (u8)value;
805 		break;
806 
807 	case ODM_CMNINFO_5G_EXT_PA:
808 		if (!dm->is_init_hw_info_by_rfe)
809 			dm->ext_pa_5g = (u8)value;
810 		break;
811 
812 	case ODM_CMNINFO_GPA:
813 		if (!dm->is_init_hw_info_by_rfe)
814 			dm->type_gpa = (u16)value;
815 		break;
816 
817 	case ODM_CMNINFO_APA:
818 		if (!dm->is_init_hw_info_by_rfe)
819 			dm->type_apa = (u16)value;
820 		break;
821 
822 	case ODM_CMNINFO_GLNA:
823 		if (!dm->is_init_hw_info_by_rfe)
824 			dm->type_glna = (u16)value;
825 		break;
826 
827 	case ODM_CMNINFO_ALNA:
828 		if (!dm->is_init_hw_info_by_rfe)
829 			dm->type_alna = (u16)value;
830 		break;
831 
832 	case ODM_CMNINFO_EXT_TRSW:
833 		if (!dm->is_init_hw_info_by_rfe)
834 			dm->ext_trsw = (u8)value;
835 		break;
836 	case ODM_CMNINFO_EXT_LNA_GAIN:
837 		dm->ext_lna_gain = (u8)value;
838 		break;
839 	case ODM_CMNINFO_PATCH_ID:
840 		dm->patch_id = (u8)value;
841 		break;
842 	case ODM_CMNINFO_BINHCT_TEST:
843 		dm->is_in_hct_test = (bool)value;
844 		break;
845 	case ODM_CMNINFO_BWIFI_TEST:
846 		dm->wifi_test = (u8)value;
847 		break;
848 	case ODM_CMNINFO_SMART_CONCURRENT:
849 		dm->is_dual_mac_smart_concurrent = (bool)value;
850 		break;
851 	case ODM_CMNINFO_DOMAIN_CODE_2G:
852 		dm->odm_regulation_2_4g = (u8)value;
853 		break;
854 	case ODM_CMNINFO_DOMAIN_CODE_5G:
855 		dm->odm_regulation_5g = (u8)value;
856 		break;
857 	case ODM_CMNINFO_CONFIG_BB_RF:
858 		dm->config_bbrf = (bool)value;
859 		break;
860 	case ODM_CMNINFO_IQKFWOFFLOAD:
861 		dm->iqk_fw_offload = (u8)value;
862 		break;
863 	case ODM_CMNINFO_IQKPAOFF:
864 		dm->rf_calibrate_info.is_iqk_pa_off = (bool)value;
865 		break;
866 	case ODM_CMNINFO_REGRFKFREEENABLE:
867 		dm->rf_calibrate_info.reg_rf_kfree_enable = (u8)value;
868 		break;
869 	case ODM_CMNINFO_RFKFREEENABLE:
870 		dm->rf_calibrate_info.rf_kfree_enable = (u8)value;
871 		break;
872 	case ODM_CMNINFO_NORMAL_RX_PATH_CHANGE:
873 		dm->normal_rx_path = (u8)value;
874 		break;
875 	case ODM_CMNINFO_EFUSE0X3D8:
876 		dm->efuse0x3d8 = (u8)value;
877 		break;
878 	case ODM_CMNINFO_EFUSE0X3D7:
879 		dm->efuse0x3d7 = (u8)value;
880 		break;
881 	/* To remove the compiler warning, must add an empty default statement
882 	 * to handle the other values.
883 	 */
884 	default:
885 		/* do nothing */
886 		break;
887 	}
888 }
889 
odm_cmn_info_hook(struct phy_dm_struct * dm,enum odm_cmninfo cmn_info,void * value)890 void odm_cmn_info_hook(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
891 		       void *value)
892 {
893 	/*  */
894 	/* Hook call by reference pointer. */
895 	/*  */
896 	switch (cmn_info) {
897 	/*  */
898 	/* Dynamic call by reference pointer. */
899 	/*  */
900 	case ODM_CMNINFO_MAC_PHY_MODE:
901 		dm->mac_phy_mode = (u8 *)value;
902 		break;
903 
904 	case ODM_CMNINFO_TX_UNI:
905 		dm->num_tx_bytes_unicast = (u64 *)value;
906 		break;
907 
908 	case ODM_CMNINFO_RX_UNI:
909 		dm->num_rx_bytes_unicast = (u64 *)value;
910 		break;
911 
912 	case ODM_CMNINFO_WM_MODE:
913 		dm->wireless_mode = (u8 *)value;
914 		break;
915 
916 	case ODM_CMNINFO_BAND:
917 		dm->band_type = (u8 *)value;
918 		break;
919 
920 	case ODM_CMNINFO_SEC_CHNL_OFFSET:
921 		dm->sec_ch_offset = (u8 *)value;
922 		break;
923 
924 	case ODM_CMNINFO_SEC_MODE:
925 		dm->security = (u8 *)value;
926 		break;
927 
928 	case ODM_CMNINFO_BW:
929 		dm->band_width = (u8 *)value;
930 		break;
931 
932 	case ODM_CMNINFO_CHNL:
933 		dm->channel = (u8 *)value;
934 		break;
935 
936 	case ODM_CMNINFO_DMSP_GET_VALUE:
937 		dm->is_get_value_from_other_mac = (bool *)value;
938 		break;
939 
940 	case ODM_CMNINFO_BUDDY_ADAPTOR:
941 		dm->buddy_adapter = (void **)value;
942 		break;
943 
944 	case ODM_CMNINFO_DMSP_IS_MASTER:
945 		dm->is_master_of_dmsp = (bool *)value;
946 		break;
947 
948 	case ODM_CMNINFO_SCAN:
949 		dm->is_scan_in_process = (bool *)value;
950 		break;
951 
952 	case ODM_CMNINFO_POWER_SAVING:
953 		dm->is_power_saving = (bool *)value;
954 		break;
955 
956 	case ODM_CMNINFO_ONE_PATH_CCA:
957 		dm->one_path_cca = (u8 *)value;
958 		break;
959 
960 	case ODM_CMNINFO_DRV_STOP:
961 		dm->is_driver_stopped = (bool *)value;
962 		break;
963 
964 	case ODM_CMNINFO_PNP_IN:
965 		dm->is_driver_is_going_to_pnp_set_power_sleep = (bool *)value;
966 		break;
967 
968 	case ODM_CMNINFO_INIT_ON:
969 		dm->pinit_adpt_in_progress = (bool *)value;
970 		break;
971 
972 	case ODM_CMNINFO_ANT_TEST:
973 		dm->antenna_test = (u8 *)value;
974 		break;
975 
976 	case ODM_CMNINFO_NET_CLOSED:
977 		dm->is_net_closed = (bool *)value;
978 		break;
979 
980 	case ODM_CMNINFO_FORCED_RATE:
981 		dm->forced_data_rate = (u16 *)value;
982 		break;
983 	case ODM_CMNINFO_ANT_DIV:
984 		dm->enable_antdiv = (u8 *)value;
985 		break;
986 	case ODM_CMNINFO_ADAPTIVITY:
987 		dm->enable_adaptivity = (u8 *)value;
988 		break;
989 	case ODM_CMNINFO_FORCED_IGI_LB:
990 		dm->pu1_forced_igi_lb = (u8 *)value;
991 		break;
992 
993 	case ODM_CMNINFO_P2P_LINK:
994 		dm->dm_dig_table.is_p2p_in_process = (u8 *)value;
995 		break;
996 
997 	case ODM_CMNINFO_IS1ANTENNA:
998 		dm->is_1_antenna = (bool *)value;
999 		break;
1000 
1001 	case ODM_CMNINFO_RFDEFAULTPATH:
1002 		dm->rf_default_path = (u8 *)value;
1003 		break;
1004 
1005 	case ODM_CMNINFO_FCS_MODE:
1006 		dm->is_fcs_mode_enable = (bool *)value;
1007 		break;
1008 	/*add by YuChen for beamforming PhyDM*/
1009 	case ODM_CMNINFO_HUBUSBMODE:
1010 		dm->hub_usb_mode = (u8 *)value;
1011 		break;
1012 	case ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS:
1013 		dm->is_fw_dw_rsvd_page_in_progress = (bool *)value;
1014 		break;
1015 	case ODM_CMNINFO_TX_TP:
1016 		dm->current_tx_tp = (u32 *)value;
1017 		break;
1018 	case ODM_CMNINFO_RX_TP:
1019 		dm->current_rx_tp = (u32 *)value;
1020 		break;
1021 	case ODM_CMNINFO_SOUNDING_SEQ:
1022 		dm->sounding_seq = (u8 *)value;
1023 		break;
1024 	case ODM_CMNINFO_FORCE_TX_ANT_BY_TXDESC:
1025 		dm->dm_fat_table.p_force_tx_ant_by_desc = (u8 *)value;
1026 		break;
1027 	case ODM_CMNINFO_SET_S0S1_DEFAULT_ANTENNA:
1028 		dm->dm_fat_table.p_default_s0_s1 = (u8 *)value;
1029 		break;
1030 
1031 	default:
1032 		/*do nothing*/
1033 		break;
1034 	}
1035 }
1036 
odm_cmn_info_ptr_array_hook(struct phy_dm_struct * dm,enum odm_cmninfo cmn_info,u16 index,void * value)1037 void odm_cmn_info_ptr_array_hook(struct phy_dm_struct *dm,
1038 				 enum odm_cmninfo cmn_info, u16 index,
1039 				 void *value)
1040 {
1041 	/*Hook call by reference pointer.*/
1042 	switch (cmn_info) {
1043 	/*Dynamic call by reference pointer.	*/
1044 	case ODM_CMNINFO_STA_STATUS:
1045 		dm->odm_sta_info[index] = (struct rtl_sta_info *)value;
1046 
1047 		if (IS_STA_VALID(dm->odm_sta_info[index]))
1048 			dm->platform2phydm_macid_table[index] = index;
1049 
1050 		break;
1051 	/* To remove the compiler warning, must add an empty default statement
1052 	 * to handle the other values.
1053 	 */
1054 	default:
1055 		/* do nothing */
1056 		break;
1057 	}
1058 }
1059 
1060 /*
1061  * Update band/CHannel/.. The values are dynamic but non-per-packet.
1062  */
odm_cmn_info_update(struct phy_dm_struct * dm,u32 cmn_info,u64 value)1063 void odm_cmn_info_update(struct phy_dm_struct *dm, u32 cmn_info, u64 value)
1064 {
1065 	/* This init variable may be changed in run time. */
1066 	switch (cmn_info) {
1067 	case ODM_CMNINFO_LINK_IN_PROGRESS:
1068 		dm->is_link_in_process = (bool)value;
1069 		break;
1070 
1071 	case ODM_CMNINFO_ABILITY:
1072 		dm->support_ability = (u32)value;
1073 		break;
1074 
1075 	case ODM_CMNINFO_RF_TYPE:
1076 		dm->rf_type = (u8)value;
1077 		break;
1078 
1079 	case ODM_CMNINFO_WIFI_DIRECT:
1080 		dm->is_wifi_direct = (bool)value;
1081 		break;
1082 
1083 	case ODM_CMNINFO_WIFI_DISPLAY:
1084 		dm->is_wifi_display = (bool)value;
1085 		break;
1086 
1087 	case ODM_CMNINFO_LINK:
1088 		dm->is_linked = (bool)value;
1089 		break;
1090 
1091 	case ODM_CMNINFO_CMW500LINK:
1092 		dm->is_linkedcmw500 = (bool)value;
1093 		break;
1094 
1095 	case ODM_CMNINFO_LPSPG:
1096 		dm->is_in_lps_pg = (bool)value;
1097 		break;
1098 
1099 	case ODM_CMNINFO_STATION_STATE:
1100 		dm->bsta_state = (bool)value;
1101 		break;
1102 
1103 	case ODM_CMNINFO_RSSI_MIN:
1104 		dm->rssi_min = (u8)value;
1105 		break;
1106 
1107 	case ODM_CMNINFO_DBG_COMP:
1108 		dm->debug_components = (u32)value;
1109 		break;
1110 
1111 	case ODM_CMNINFO_DBG_LEVEL:
1112 		dm->debug_level = (u32)value;
1113 		break;
1114 	case ODM_CMNINFO_RA_THRESHOLD_HIGH:
1115 		dm->rate_adaptive.high_rssi_thresh = (u8)value;
1116 		break;
1117 
1118 	case ODM_CMNINFO_RA_THRESHOLD_LOW:
1119 		dm->rate_adaptive.low_rssi_thresh = (u8)value;
1120 		break;
1121 	/* The following is for BT HS mode and BT coexist mechanism. */
1122 	case ODM_CMNINFO_BT_ENABLED:
1123 		dm->is_bt_enabled = (bool)value;
1124 		break;
1125 
1126 	case ODM_CMNINFO_BT_HS_CONNECT_PROCESS:
1127 		dm->is_bt_connect_process = (bool)value;
1128 		break;
1129 
1130 	case ODM_CMNINFO_BT_HS_RSSI:
1131 		dm->bt_hs_rssi = (u8)value;
1132 		break;
1133 
1134 	case ODM_CMNINFO_BT_OPERATION:
1135 		dm->is_bt_hs_operation = (bool)value;
1136 		break;
1137 
1138 	case ODM_CMNINFO_BT_LIMITED_DIG:
1139 		dm->is_bt_limited_dig = (bool)value;
1140 		break;
1141 
1142 	case ODM_CMNINFO_BT_DIG:
1143 		dm->bt_hs_dig_val = (u8)value;
1144 		break;
1145 
1146 	case ODM_CMNINFO_BT_BUSY:
1147 		dm->is_bt_busy = (bool)value;
1148 		break;
1149 
1150 	case ODM_CMNINFO_BT_DISABLE_EDCA:
1151 		dm->is_bt_disable_edca_turbo = (bool)value;
1152 		break;
1153 
1154 	case ODM_CMNINFO_AP_TOTAL_NUM:
1155 		dm->ap_total_num = (u8)value;
1156 		break;
1157 
1158 	case ODM_CMNINFO_POWER_TRAINING:
1159 		dm->is_disable_power_training = (bool)value;
1160 		break;
1161 
1162 	default:
1163 		/* do nothing */
1164 		break;
1165 	}
1166 }
1167 
phydm_cmn_info_query(struct phy_dm_struct * dm,enum phydm_info_query info_type)1168 u32 phydm_cmn_info_query(struct phy_dm_struct *dm,
1169 			 enum phydm_info_query info_type)
1170 {
1171 	struct false_alarm_stat *false_alm_cnt =
1172 		(struct false_alarm_stat *)phydm_get_structure(
1173 			dm, PHYDM_FALSEALMCNT);
1174 
1175 	switch (info_type) {
1176 	case PHYDM_INFO_FA_OFDM:
1177 		return false_alm_cnt->cnt_ofdm_fail;
1178 
1179 	case PHYDM_INFO_FA_CCK:
1180 		return false_alm_cnt->cnt_cck_fail;
1181 
1182 	case PHYDM_INFO_FA_TOTAL:
1183 		return false_alm_cnt->cnt_all;
1184 
1185 	case PHYDM_INFO_CCA_OFDM:
1186 		return false_alm_cnt->cnt_ofdm_cca;
1187 
1188 	case PHYDM_INFO_CCA_CCK:
1189 		return false_alm_cnt->cnt_cck_cca;
1190 
1191 	case PHYDM_INFO_CCA_ALL:
1192 		return false_alm_cnt->cnt_cca_all;
1193 
1194 	case PHYDM_INFO_CRC32_OK_VHT:
1195 		return false_alm_cnt->cnt_vht_crc32_ok;
1196 
1197 	case PHYDM_INFO_CRC32_OK_HT:
1198 		return false_alm_cnt->cnt_ht_crc32_ok;
1199 
1200 	case PHYDM_INFO_CRC32_OK_LEGACY:
1201 		return false_alm_cnt->cnt_ofdm_crc32_ok;
1202 
1203 	case PHYDM_INFO_CRC32_OK_CCK:
1204 		return false_alm_cnt->cnt_cck_crc32_ok;
1205 
1206 	case PHYDM_INFO_CRC32_ERROR_VHT:
1207 		return false_alm_cnt->cnt_vht_crc32_error;
1208 
1209 	case PHYDM_INFO_CRC32_ERROR_HT:
1210 		return false_alm_cnt->cnt_ht_crc32_error;
1211 
1212 	case PHYDM_INFO_CRC32_ERROR_LEGACY:
1213 		return false_alm_cnt->cnt_ofdm_crc32_error;
1214 
1215 	case PHYDM_INFO_CRC32_ERROR_CCK:
1216 		return false_alm_cnt->cnt_cck_crc32_error;
1217 
1218 	case PHYDM_INFO_EDCCA_FLAG:
1219 		return false_alm_cnt->edcca_flag;
1220 
1221 	case PHYDM_INFO_OFDM_ENABLE:
1222 		return false_alm_cnt->ofdm_block_enable;
1223 
1224 	case PHYDM_INFO_CCK_ENABLE:
1225 		return false_alm_cnt->cck_block_enable;
1226 
1227 	case PHYDM_INFO_DBG_PORT_0:
1228 		return false_alm_cnt->dbg_port0;
1229 
1230 	default:
1231 		return 0xffffffff;
1232 	}
1233 }
1234 
odm_init_all_timers(struct phy_dm_struct * dm)1235 void odm_init_all_timers(struct phy_dm_struct *dm) {}
1236 
odm_cancel_all_timers(struct phy_dm_struct * dm)1237 void odm_cancel_all_timers(struct phy_dm_struct *dm) {}
1238 
odm_release_all_timers(struct phy_dm_struct * dm)1239 void odm_release_all_timers(struct phy_dm_struct *dm) {}
1240 
1241 /* 3============================================================
1242  * 3 Tx Power Tracking
1243  * 3============================================================
1244  */
1245 
1246 /* need to ODM CE Platform
1247  * move to here for ANT detection mechanism using
1248  */
1249 
odm_convert_to_db(u32 value)1250 u32 odm_convert_to_db(u32 value)
1251 {
1252 	u8 i;
1253 	u8 j;
1254 	u32 dB;
1255 
1256 	value = value & 0xFFFF;
1257 
1258 	for (i = 0; i < 12; i++) {
1259 		if (value <= db_invert_table[i][7])
1260 			break;
1261 	}
1262 
1263 	if (i >= 12)
1264 		return 96; /* maximum 96 dB */
1265 
1266 	for (j = 0; j < 8; j++) {
1267 		if (value <= db_invert_table[i][j])
1268 			break;
1269 	}
1270 
1271 	dB = (i << 3) + j + 1;
1272 
1273 	return dB;
1274 }
1275 
odm_convert_to_linear(u32 value)1276 u32 odm_convert_to_linear(u32 value)
1277 {
1278 	u8 i;
1279 	u8 j;
1280 	u32 linear;
1281 
1282 	/* 1dB~96dB */
1283 
1284 	value = value & 0xFF;
1285 
1286 	i = (u8)((value - 1) >> 3);
1287 	j = (u8)(value - 1) - (i << 3);
1288 
1289 	linear = db_invert_table[i][j];
1290 
1291 	return linear;
1292 }
1293 
1294 /*
1295  * ODM multi-port consideration, added by Roger, 2013.10.01.
1296  */
odm_asoc_entry_init(struct phy_dm_struct * dm)1297 void odm_asoc_entry_init(struct phy_dm_struct *dm) {}
1298 
1299 /* Justin: According to the current RRSI to adjust Response Frame TX power */
odm_dtc(struct phy_dm_struct * dm)1300 void odm_dtc(struct phy_dm_struct *dm) {}
1301 
odm_update_power_training_state(struct phy_dm_struct * dm)1302 static void odm_update_power_training_state(struct phy_dm_struct *dm)
1303 {
1304 	struct false_alarm_stat *false_alm_cnt =
1305 		(struct false_alarm_stat *)phydm_get_structure(
1306 			dm, PHYDM_FALSEALMCNT);
1307 	struct dig_thres *dig_tab = &dm->dm_dig_table;
1308 	u32 score = 0;
1309 
1310 	if (!(dm->support_ability & ODM_BB_PWR_TRAIN))
1311 		return;
1312 
1313 	ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s()============>\n", __func__);
1314 	dm->is_change_state = false;
1315 
1316 	/* Debug command */
1317 	if (dm->force_power_training_state) {
1318 		if (dm->force_power_training_state == 1 &&
1319 		    !dm->is_disable_power_training) {
1320 			dm->is_change_state = true;
1321 			dm->is_disable_power_training = true;
1322 		} else if (dm->force_power_training_state == 2 &&
1323 			   dm->is_disable_power_training) {
1324 			dm->is_change_state = true;
1325 			dm->is_disable_power_training = false;
1326 		}
1327 
1328 		dm->PT_score = 0;
1329 		dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1330 		dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1331 		ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1332 			     "%s(): force_power_training_state = %d\n",
1333 			     __func__, dm->force_power_training_state);
1334 		return;
1335 	}
1336 
1337 	if (!dm->is_linked)
1338 		return;
1339 
1340 	/* First connect */
1341 	if ((dm->is_linked) && !dig_tab->is_media_connect_0) {
1342 		dm->PT_score = 0;
1343 		dm->is_change_state = true;
1344 		dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1345 		dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1346 		ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): First Connect\n",
1347 			     __func__);
1348 		return;
1349 	}
1350 
1351 	/* Compute score */
1352 	if (dm->nhm_cnt_0 >= 215) {
1353 		score = 2;
1354 	} else if (dm->nhm_cnt_0 >= 190) {
1355 		score = 1; /* unknown state */
1356 	} else {
1357 		u32 rx_pkt_cnt;
1358 
1359 		rx_pkt_cnt = (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm) +
1360 			     (u32)(dm->phy_dbg_info.num_qry_phy_status_cck);
1361 
1362 		if ((false_alm_cnt->cnt_cca_all > 31 && rx_pkt_cnt > 31) &&
1363 		    (false_alm_cnt->cnt_cca_all >= rx_pkt_cnt)) {
1364 			if ((rx_pkt_cnt + (rx_pkt_cnt >> 1)) <=
1365 			    false_alm_cnt->cnt_cca_all)
1366 				score = 0;
1367 			else if ((rx_pkt_cnt + (rx_pkt_cnt >> 2)) <=
1368 				 false_alm_cnt->cnt_cca_all)
1369 				score = 1;
1370 			else
1371 				score = 2;
1372 		}
1373 		ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1374 			     "%s(): rx_pkt_cnt = %d, cnt_cca_all = %d\n",
1375 			     __func__, rx_pkt_cnt, false_alm_cnt->cnt_cca_all);
1376 	}
1377 	ODM_RT_TRACE(
1378 		dm, ODM_COMP_RA_MASK,
1379 		"%s(): num_qry_phy_status_ofdm = %d, num_qry_phy_status_cck = %d\n",
1380 		__func__, (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm),
1381 		(u32)(dm->phy_dbg_info.num_qry_phy_status_cck));
1382 	ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): nhm_cnt_0 = %d, score = %d\n",
1383 		     __func__, dm->nhm_cnt_0, score);
1384 
1385 	/* smoothing */
1386 	dm->PT_score = (score << 4) + (dm->PT_score >> 1) + (dm->PT_score >> 2);
1387 	score = (dm->PT_score + 32) >> 6;
1388 	ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1389 		     "%s(): PT_score = %d, score after smoothing = %d\n",
1390 		     __func__, dm->PT_score, score);
1391 
1392 	/* mode decision */
1393 	if (score == 2) {
1394 		if (dm->is_disable_power_training) {
1395 			dm->is_change_state = true;
1396 			dm->is_disable_power_training = false;
1397 			ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1398 				     "%s(): Change state\n", __func__);
1399 		}
1400 		ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1401 			     "%s(): Enable Power Training\n", __func__);
1402 	} else if (score == 0) {
1403 		if (!dm->is_disable_power_training) {
1404 			dm->is_change_state = true;
1405 			dm->is_disable_power_training = true;
1406 			ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1407 				     "%s(): Change state\n", __func__);
1408 		}
1409 		ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1410 			     "%s(): Disable Power Training\n", __func__);
1411 	}
1412 
1413 	dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1414 	dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1415 }
1416 
1417 /*===========================================================*/
1418 /* The following is for compile only*/
1419 /*===========================================================*/
1420 /*#define TARGET_CHNL_NUM_2G_5G	59*/
1421 /*===========================================================*/
1422 
phydm_noisy_detection(struct phy_dm_struct * dm)1423 void phydm_noisy_detection(struct phy_dm_struct *dm)
1424 {
1425 	u32 total_fa_cnt, total_cca_cnt;
1426 	u32 score = 0, i, score_smooth;
1427 
1428 	total_cca_cnt = dm->false_alm_cnt.cnt_cca_all;
1429 	total_fa_cnt = dm->false_alm_cnt.cnt_all;
1430 
1431 	for (i = 0; i <= 16; i++) {
1432 		if (total_fa_cnt * 16 >= total_cca_cnt * (16 - i)) {
1433 			score = 16 - i;
1434 			break;
1435 		}
1436 	}
1437 
1438 	/* noisy_decision_smooth = noisy_decision_smooth>>1 + (score<<3)>>1; */
1439 	dm->noisy_decision_smooth =
1440 		(dm->noisy_decision_smooth >> 1) + (score << 2);
1441 
1442 	/* Round the noisy_decision_smooth: +"3" comes from (2^3)/2-1 */
1443 	score_smooth = (total_cca_cnt >= 300) ?
1444 			       ((dm->noisy_decision_smooth + 3) >> 3) :
1445 			       0;
1446 
1447 	dm->noisy_decision = (score_smooth >= 3) ? 1 : 0;
1448 	ODM_RT_TRACE(
1449 		dm, ODM_COMP_NOISY_DETECT,
1450 		"[NoisyDetection] total_cca_cnt=%d, total_fa_cnt=%d, noisy_decision_smooth=%d, score=%d, score_smooth=%d, dm->noisy_decision=%d\n",
1451 		total_cca_cnt, total_fa_cnt, dm->noisy_decision_smooth, score,
1452 		score_smooth, dm->noisy_decision);
1453 }
1454 
phydm_set_ext_switch(void * dm_void,u32 * const dm_value,u32 * _used,char * output,u32 * _out_len)1455 void phydm_set_ext_switch(void *dm_void, u32 *const dm_value, u32 *_used,
1456 			  char *output, u32 *_out_len)
1457 {
1458 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1459 	u32 ext_ant_switch = dm_value[0];
1460 
1461 	if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
1462 		/*Output Pin Settings*/
1463 		odm_set_mac_reg(dm, 0x4C, BIT(23),
1464 				0); /*select DPDT_P and DPDT_N as output pin*/
1465 		odm_set_mac_reg(dm, 0x4C, BIT(24), 1); /*by WLAN control*/
1466 
1467 		odm_set_bb_reg(dm, 0xCB4, 0xF, 7); /*DPDT_P = 1b'0*/
1468 		odm_set_bb_reg(dm, 0xCB4, 0xF0, 7); /*DPDT_N = 1b'0*/
1469 
1470 		if (ext_ant_switch == MAIN_ANT) {
1471 			odm_set_bb_reg(dm, 0xCB4, (BIT(29) | BIT(28)), 1);
1472 			ODM_RT_TRACE(
1473 				dm, ODM_COMP_API,
1474 				"***8821A set ant switch = 2b'01 (Main)\n");
1475 		} else if (ext_ant_switch == AUX_ANT) {
1476 			odm_set_bb_reg(dm, 0xCB4, BIT(29) | BIT(28), 2);
1477 			ODM_RT_TRACE(dm, ODM_COMP_API,
1478 				     "***8821A set ant switch = 2b'10 (Aux)\n");
1479 		}
1480 	}
1481 }
1482 
phydm_csi_mask_enable(void * dm_void,u32 enable)1483 static void phydm_csi_mask_enable(void *dm_void, u32 enable)
1484 {
1485 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1486 	u32 reg_value = 0;
1487 
1488 	reg_value = (enable == CSI_MASK_ENABLE) ? 1 : 0;
1489 
1490 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1491 		odm_set_bb_reg(dm, 0xD2C, BIT(28), reg_value);
1492 		ODM_RT_TRACE(dm, ODM_COMP_API,
1493 			     "Enable CSI Mask:  Reg 0xD2C[28] = ((0x%x))\n",
1494 			     reg_value);
1495 
1496 	} else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1497 		odm_set_bb_reg(dm, 0x874, BIT(0), reg_value);
1498 		ODM_RT_TRACE(dm, ODM_COMP_API,
1499 			     "Enable CSI Mask:  Reg 0x874[0] = ((0x%x))\n",
1500 			     reg_value);
1501 	}
1502 }
1503 
phydm_clean_all_csi_mask(void * dm_void)1504 static void phydm_clean_all_csi_mask(void *dm_void)
1505 {
1506 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1507 
1508 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1509 		odm_set_bb_reg(dm, 0xD40, MASKDWORD, 0);
1510 		odm_set_bb_reg(dm, 0xD44, MASKDWORD, 0);
1511 		odm_set_bb_reg(dm, 0xD48, MASKDWORD, 0);
1512 		odm_set_bb_reg(dm, 0xD4c, MASKDWORD, 0);
1513 
1514 	} else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1515 		odm_set_bb_reg(dm, 0x880, MASKDWORD, 0);
1516 		odm_set_bb_reg(dm, 0x884, MASKDWORD, 0);
1517 		odm_set_bb_reg(dm, 0x888, MASKDWORD, 0);
1518 		odm_set_bb_reg(dm, 0x88c, MASKDWORD, 0);
1519 		odm_set_bb_reg(dm, 0x890, MASKDWORD, 0);
1520 		odm_set_bb_reg(dm, 0x894, MASKDWORD, 0);
1521 		odm_set_bb_reg(dm, 0x898, MASKDWORD, 0);
1522 		odm_set_bb_reg(dm, 0x89c, MASKDWORD, 0);
1523 	}
1524 }
1525 
phydm_set_csi_mask_reg(void * dm_void,u32 tone_idx_tmp,u8 tone_direction)1526 static void phydm_set_csi_mask_reg(void *dm_void, u32 tone_idx_tmp,
1527 				   u8 tone_direction)
1528 {
1529 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1530 	u8 byte_offset, bit_offset;
1531 	u32 target_reg;
1532 	u8 reg_tmp_value;
1533 	u32 tone_num = 64;
1534 	u32 tone_num_shift = 0;
1535 	u32 csi_mask_reg_p = 0, csi_mask_reg_n = 0;
1536 
1537 	/* calculate real tone idx*/
1538 	if ((tone_idx_tmp % 10) >= 5)
1539 		tone_idx_tmp += 10;
1540 
1541 	tone_idx_tmp = (tone_idx_tmp / 10);
1542 
1543 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1544 		tone_num = 64;
1545 		csi_mask_reg_p = 0xD40;
1546 		csi_mask_reg_n = 0xD48;
1547 
1548 	} else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1549 		tone_num = 128;
1550 		csi_mask_reg_p = 0x880;
1551 		csi_mask_reg_n = 0x890;
1552 	}
1553 
1554 	if (tone_direction == FREQ_POSITIVE) {
1555 		if (tone_idx_tmp >= (tone_num - 1))
1556 			tone_idx_tmp = (tone_num - 1);
1557 
1558 		byte_offset = (u8)(tone_idx_tmp >> 3);
1559 		bit_offset = (u8)(tone_idx_tmp & 0x7);
1560 		target_reg = csi_mask_reg_p + byte_offset;
1561 
1562 	} else {
1563 		tone_num_shift = tone_num;
1564 
1565 		if (tone_idx_tmp >= tone_num)
1566 			tone_idx_tmp = tone_num;
1567 
1568 		tone_idx_tmp = tone_num - tone_idx_tmp;
1569 
1570 		byte_offset = (u8)(tone_idx_tmp >> 3);
1571 		bit_offset = (u8)(tone_idx_tmp & 0x7);
1572 		target_reg = csi_mask_reg_n + byte_offset;
1573 	}
1574 
1575 	reg_tmp_value = odm_read_1byte(dm, target_reg);
1576 	ODM_RT_TRACE(dm, ODM_COMP_API,
1577 		     "Pre Mask tone idx[%d]:  Reg0x%x = ((0x%x))\n",
1578 		     (tone_idx_tmp + tone_num_shift), target_reg,
1579 		     reg_tmp_value);
1580 	reg_tmp_value |= BIT(bit_offset);
1581 	odm_write_1byte(dm, target_reg, reg_tmp_value);
1582 	ODM_RT_TRACE(dm, ODM_COMP_API,
1583 		     "New Mask tone idx[%d]:  Reg0x%x = ((0x%x))\n",
1584 		     (tone_idx_tmp + tone_num_shift), target_reg,
1585 		     reg_tmp_value);
1586 }
1587 
phydm_set_nbi_reg(void * dm_void,u32 tone_idx_tmp,u32 bw)1588 static void phydm_set_nbi_reg(void *dm_void, u32 tone_idx_tmp, u32 bw)
1589 {
1590 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1591 	u32 nbi_table_128[NBI_TABLE_SIZE_128] = {
1592 		25, 55, 85, 115, 135, 155, 185, 205, 225, 245,
1593 		/*1~10*/ /*tone_idx X 10*/
1594 		265, 285, 305, 335, 355, 375, 395, 415, 435, 455, /*11~20*/
1595 		485, 505, 525, 555, 585, 615, 635}; /*21~27*/
1596 
1597 	u32 nbi_table_256[NBI_TABLE_SIZE_256] = {
1598 		25,   55,   85,   115,  135,  155,  175,  195,  225,
1599 		245, /*1~10*/
1600 		265,  285,  305,  325,  345,  365,  385,  405,  425,
1601 		445, /*11~20*/
1602 		465,  485,  505,  525,  545,  565,  585,  605,  625,
1603 		645, /*21~30*/
1604 		665,  695,  715,  735,  755,  775,  795,  815,  835,
1605 		855, /*31~40*/
1606 		875,  895,  915,  935,  955,  975,  995,  1015, 1035,
1607 		1055, /*41~50*/
1608 		1085, 1105, 1125, 1145, 1175, 1195, 1225, 1255, 1275}; /*51~59*/
1609 
1610 	u32 reg_idx = 0;
1611 	u32 i;
1612 	u8 nbi_table_idx = FFT_128_TYPE;
1613 
1614 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1615 		nbi_table_idx = FFT_128_TYPE;
1616 	} else if (dm->support_ic_type & ODM_IC_11AC_1_SERIES) {
1617 		nbi_table_idx = FFT_256_TYPE;
1618 	} else if (dm->support_ic_type & ODM_IC_11AC_2_SERIES) {
1619 		if (bw == 80)
1620 			nbi_table_idx = FFT_256_TYPE;
1621 		else /*20M, 40M*/
1622 			nbi_table_idx = FFT_128_TYPE;
1623 	}
1624 
1625 	if (nbi_table_idx == FFT_128_TYPE) {
1626 		for (i = 0; i < NBI_TABLE_SIZE_128; i++) {
1627 			if (tone_idx_tmp < nbi_table_128[i]) {
1628 				reg_idx = i + 1;
1629 				break;
1630 			}
1631 		}
1632 
1633 	} else if (nbi_table_idx == FFT_256_TYPE) {
1634 		for (i = 0; i < NBI_TABLE_SIZE_256; i++) {
1635 			if (tone_idx_tmp < nbi_table_256[i]) {
1636 				reg_idx = i + 1;
1637 				break;
1638 			}
1639 		}
1640 	}
1641 
1642 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1643 		odm_set_bb_reg(dm, 0xc40, 0x1f000000, reg_idx);
1644 		ODM_RT_TRACE(dm, ODM_COMP_API,
1645 			     "Set tone idx:  Reg0xC40[28:24] = ((0x%x))\n",
1646 			     reg_idx);
1647 		/**/
1648 	} else {
1649 		odm_set_bb_reg(dm, 0x87c, 0xfc000, reg_idx);
1650 		ODM_RT_TRACE(dm, ODM_COMP_API,
1651 			     "Set tone idx: Reg0x87C[19:14] = ((0x%x))\n",
1652 			     reg_idx);
1653 		/**/
1654 	}
1655 }
1656 
phydm_nbi_enable(void * dm_void,u32 enable)1657 static void phydm_nbi_enable(void *dm_void, u32 enable)
1658 {
1659 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1660 	u32 reg_value = 0;
1661 
1662 	reg_value = (enable == NBI_ENABLE) ? 1 : 0;
1663 
1664 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1665 		odm_set_bb_reg(dm, 0xc40, BIT(9), reg_value);
1666 		ODM_RT_TRACE(dm, ODM_COMP_API,
1667 			     "Enable NBI Reg0xC40[9] = ((0x%x))\n", reg_value);
1668 
1669 	} else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1670 		odm_set_bb_reg(dm, 0x87c, BIT(13), reg_value);
1671 		ODM_RT_TRACE(dm, ODM_COMP_API,
1672 			     "Enable NBI Reg0x87C[13] = ((0x%x))\n", reg_value);
1673 	}
1674 }
1675 
phydm_calculate_fc(void * dm_void,u32 channel,u32 bw,u32 second_ch,u32 * fc_in)1676 static u8 phydm_calculate_fc(void *dm_void, u32 channel, u32 bw, u32 second_ch,
1677 			     u32 *fc_in)
1678 {
1679 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1680 	u32 fc = *fc_in;
1681 	u32 start_ch_per_40m[NUM_START_CH_40M + 1] = {
1682 		36,  44,  52,  60,  100, 108, 116,     124,
1683 		132, 140, 149, 157, 165, 173, 173 + 8,
1684 	};
1685 	u32 start_ch_per_80m[NUM_START_CH_80M + 1] = {
1686 		36, 52, 100, 116, 132, 149, 165, 165 + 16,
1687 	};
1688 	u32 *start_ch = &start_ch_per_40m[0];
1689 	u32 num_start_channel = NUM_START_CH_40M;
1690 	u32 channel_offset = 0;
1691 	u32 i;
1692 
1693 	/*2.4G*/
1694 	if (channel <= 14 && channel > 0) {
1695 		if (bw == 80)
1696 			return SET_ERROR;
1697 
1698 		fc = 2412 + (channel - 1) * 5;
1699 
1700 		if (bw == 40 && (second_ch == PHYDM_ABOVE)) {
1701 			if (channel >= 10) {
1702 				ODM_RT_TRACE(
1703 					dm, ODM_COMP_API,
1704 					"CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
1705 					channel, second_ch);
1706 				return SET_ERROR;
1707 			}
1708 			fc += 10;
1709 		} else if (bw == 40 && (second_ch == PHYDM_BELOW)) {
1710 			if (channel <= 2) {
1711 				ODM_RT_TRACE(
1712 					dm, ODM_COMP_API,
1713 					"CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
1714 					channel, second_ch);
1715 				return SET_ERROR;
1716 			}
1717 			fc -= 10;
1718 		}
1719 	}
1720 	/*5G*/
1721 	else if (channel >= 36 && channel <= 177) {
1722 		if (bw == 20) {
1723 			fc = 5180 + (channel - 36) * 5;
1724 			*fc_in = fc;
1725 			return SET_SUCCESS;
1726 		}
1727 
1728 		if (bw == 40) {
1729 			num_start_channel = NUM_START_CH_40M;
1730 			start_ch = &start_ch_per_40m[0];
1731 			channel_offset = CH_OFFSET_40M;
1732 		} else if (bw == 80) {
1733 			num_start_channel = NUM_START_CH_80M;
1734 			start_ch = &start_ch_per_80m[0];
1735 			channel_offset = CH_OFFSET_80M;
1736 		}
1737 
1738 		for (i = 0; i < num_start_channel; i++) {
1739 			if (channel < start_ch[i + 1]) {
1740 				channel = start_ch[i] + channel_offset;
1741 				break;
1742 			}
1743 		}
1744 
1745 		ODM_RT_TRACE(dm, ODM_COMP_API, "Mod_CH = ((%d))\n", channel);
1746 
1747 		fc = 5180 + (channel - 36) * 5;
1748 
1749 	} else {
1750 		ODM_RT_TRACE(dm, ODM_COMP_API, "CH = ((%d)) Error setting\n",
1751 			     channel);
1752 		return SET_ERROR;
1753 	}
1754 
1755 	*fc_in = fc;
1756 
1757 	return SET_SUCCESS;
1758 }
1759 
phydm_calculate_intf_distance(void * dm_void,u32 bw,u32 fc,u32 f_interference,u32 * tone_idx_tmp_in)1760 static u8 phydm_calculate_intf_distance(void *dm_void, u32 bw, u32 fc,
1761 					u32 f_interference,
1762 					u32 *tone_idx_tmp_in)
1763 {
1764 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1765 	u32 bw_up, bw_low;
1766 	u32 int_distance;
1767 	u32 tone_idx_tmp;
1768 	u8 set_result = SET_NO_NEED;
1769 
1770 	bw_up = fc + bw / 2;
1771 	bw_low = fc - bw / 2;
1772 
1773 	ODM_RT_TRACE(dm, ODM_COMP_API,
1774 		     "[f_l, fc, fh] = [ %d, %d, %d ], f_int = ((%d))\n", bw_low,
1775 		     fc, bw_up, f_interference);
1776 
1777 	if ((f_interference >= bw_low) && (f_interference <= bw_up)) {
1778 		int_distance = (fc >= f_interference) ? (fc - f_interference) :
1779 							(f_interference - fc);
1780 		tone_idx_tmp =
1781 			(int_distance << 5); /* =10*(int_distance /0.3125) */
1782 		ODM_RT_TRACE(
1783 			dm, ODM_COMP_API,
1784 			"int_distance = ((%d MHz)) Mhz, tone_idx_tmp = ((%d.%d))\n",
1785 			int_distance, (tone_idx_tmp / 10), (tone_idx_tmp % 10));
1786 		*tone_idx_tmp_in = tone_idx_tmp;
1787 		set_result = SET_SUCCESS;
1788 	}
1789 
1790 	return set_result;
1791 }
1792 
phydm_csi_mask_setting(void * dm_void,u32 enable,u32 channel,u32 bw,u32 f_interference,u32 second_ch)1793 static u8 phydm_csi_mask_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
1794 				 u32 f_interference, u32 second_ch)
1795 {
1796 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1797 	u32 fc;
1798 	u8 tone_direction;
1799 	u32 tone_idx_tmp;
1800 	u8 set_result = SET_SUCCESS;
1801 
1802 	if (enable == CSI_MASK_DISABLE) {
1803 		set_result = SET_SUCCESS;
1804 		phydm_clean_all_csi_mask(dm);
1805 
1806 	} else {
1807 		ODM_RT_TRACE(
1808 			dm, ODM_COMP_API,
1809 			"[Set CSI MASK_] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1810 			channel, bw, f_interference,
1811 			(((bw == 20) || (channel > 14)) ?
1812 				 "Don't care" :
1813 				 (second_ch == PHYDM_ABOVE) ? "H" : "L"));
1814 
1815 		/*calculate fc*/
1816 		if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
1817 		    SET_ERROR) {
1818 			set_result = SET_ERROR;
1819 		} else {
1820 			/*calculate interference distance*/
1821 			if (phydm_calculate_intf_distance(
1822 				    dm, bw, fc, f_interference,
1823 				    &tone_idx_tmp) == SET_SUCCESS) {
1824 				tone_direction = (f_interference >= fc) ?
1825 							 FREQ_POSITIVE :
1826 							 FREQ_NEGATIVE;
1827 				phydm_set_csi_mask_reg(dm, tone_idx_tmp,
1828 						       tone_direction);
1829 				set_result = SET_SUCCESS;
1830 			} else {
1831 				set_result = SET_NO_NEED;
1832 			}
1833 		}
1834 	}
1835 
1836 	if (set_result == SET_SUCCESS)
1837 		phydm_csi_mask_enable(dm, enable);
1838 	else
1839 		phydm_csi_mask_enable(dm, CSI_MASK_DISABLE);
1840 
1841 	return set_result;
1842 }
1843 
phydm_nbi_setting(void * dm_void,u32 enable,u32 channel,u32 bw,u32 f_interference,u32 second_ch)1844 u8 phydm_nbi_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
1845 		     u32 f_interference, u32 second_ch)
1846 {
1847 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1848 	u32 fc;
1849 	u32 tone_idx_tmp;
1850 	u8 set_result = SET_SUCCESS;
1851 
1852 	if (enable == NBI_DISABLE) {
1853 		set_result = SET_SUCCESS;
1854 	} else {
1855 		ODM_RT_TRACE(
1856 			dm, ODM_COMP_API,
1857 			"[Set NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1858 			channel, bw, f_interference,
1859 			(((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
1860 			  (channel > 14)) ?
1861 				 "Don't care" :
1862 				 (second_ch == PHYDM_ABOVE) ? "H" : "L"));
1863 
1864 		/*calculate fc*/
1865 		if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
1866 		    SET_ERROR) {
1867 			set_result = SET_ERROR;
1868 		} else {
1869 			/*calculate interference distance*/
1870 			if (phydm_calculate_intf_distance(
1871 				    dm, bw, fc, f_interference,
1872 				    &tone_idx_tmp) == SET_SUCCESS) {
1873 				phydm_set_nbi_reg(dm, tone_idx_tmp, bw);
1874 				set_result = SET_SUCCESS;
1875 			} else {
1876 				set_result = SET_NO_NEED;
1877 			}
1878 		}
1879 	}
1880 
1881 	if (set_result == SET_SUCCESS)
1882 		phydm_nbi_enable(dm, enable);
1883 	else
1884 		phydm_nbi_enable(dm, NBI_DISABLE);
1885 
1886 	return set_result;
1887 }
1888 
phydm_api_debug(void * dm_void,u32 function_map,u32 * const dm_value,u32 * _used,char * output,u32 * _out_len)1889 void phydm_api_debug(void *dm_void, u32 function_map, u32 *const dm_value,
1890 		     u32 *_used, char *output, u32 *_out_len)
1891 {
1892 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1893 	u32 used = *_used;
1894 	u32 out_len = *_out_len;
1895 	u32 channel = dm_value[1];
1896 	u32 bw = dm_value[2];
1897 	u32 f_interference = dm_value[3];
1898 	u32 second_ch = dm_value[4];
1899 	u8 set_result = 0;
1900 
1901 	/*PHYDM_API_NBI*/
1902 	/*--------------------------------------------------------------------*/
1903 	if (function_map == PHYDM_API_NBI) {
1904 		if (dm_value[0] == 100) {
1905 			PHYDM_SNPRINTF(
1906 				output + used, out_len - used,
1907 				"[HELP-NBI]  EN(on=1, off=2)   CH   BW(20/40/80)  f_intf(Mhz)    Scnd_CH(L=1, H=2)\n");
1908 			return;
1909 
1910 		} else if (dm_value[0] == NBI_ENABLE) {
1911 			PHYDM_SNPRINTF(
1912 				output + used, out_len - used,
1913 				"[Enable NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1914 				channel, bw, f_interference,
1915 				((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
1916 				 (channel > 14)) ?
1917 					"Don't care" :
1918 					((second_ch == PHYDM_ABOVE) ? "H" :
1919 								      "L"));
1920 			set_result =
1921 				phydm_nbi_setting(dm, NBI_ENABLE, channel, bw,
1922 						  f_interference, second_ch);
1923 
1924 		} else if (dm_value[0] == NBI_DISABLE) {
1925 			PHYDM_SNPRINTF(output + used, out_len - used,
1926 				       "[Disable NBI]\n");
1927 			set_result =
1928 				phydm_nbi_setting(dm, NBI_DISABLE, channel, bw,
1929 						  f_interference, second_ch);
1930 
1931 		} else {
1932 			set_result = SET_ERROR;
1933 		}
1934 
1935 		PHYDM_SNPRINTF(
1936 			output + used, out_len - used, "[NBI set result: %s]\n",
1937 			(set_result == SET_SUCCESS) ?
1938 				"Success" :
1939 				((set_result == SET_NO_NEED) ? "No need" :
1940 							       "Error"));
1941 	}
1942 
1943 	/*PHYDM_CSI_MASK*/
1944 	/*--------------------------------------------------------------------*/
1945 	else if (function_map == PHYDM_API_CSI_MASK) {
1946 		if (dm_value[0] == 100) {
1947 			PHYDM_SNPRINTF(
1948 				output + used, out_len - used,
1949 				"[HELP-CSI MASK]  EN(on=1, off=2)   CH   BW(20/40/80)  f_intf(Mhz)    Scnd_CH(L=1, H=2)\n");
1950 			return;
1951 
1952 		} else if (dm_value[0] == CSI_MASK_ENABLE) {
1953 			PHYDM_SNPRINTF(
1954 				output + used, out_len - used,
1955 				"[Enable CSI MASK] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1956 				channel, bw, f_interference,
1957 				(channel > 14) ?
1958 					"Don't care" :
1959 					(((second_ch == PHYDM_DONT_CARE) ||
1960 					  (bw == 20) || (channel > 14)) ?
1961 						 "H" :
1962 						 "L"));
1963 			set_result = phydm_csi_mask_setting(
1964 				dm, CSI_MASK_ENABLE, channel, bw,
1965 				f_interference, second_ch);
1966 
1967 		} else if (dm_value[0] == CSI_MASK_DISABLE) {
1968 			PHYDM_SNPRINTF(output + used, out_len - used,
1969 				       "[Disable CSI MASK]\n");
1970 			set_result = phydm_csi_mask_setting(
1971 				dm, CSI_MASK_DISABLE, channel, bw,
1972 				f_interference, second_ch);
1973 
1974 		} else {
1975 			set_result = SET_ERROR;
1976 		}
1977 
1978 		PHYDM_SNPRINTF(output + used, out_len - used,
1979 			       "[CSI MASK set result: %s]\n",
1980 			       (set_result == SET_SUCCESS) ?
1981 				       "Success" :
1982 				       ((set_result == SET_NO_NEED) ?
1983 						"No need" :
1984 						"Error"));
1985 	}
1986 }
1987