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 /* ************************************************************
16  * include files
17  * *************************************************************/
18 #include "mp_precomp.h"
19 #include "phydm_precomp.h"
20 
21 static int get_igi_for_diff(int);
22 
phydm_check_ap_write_dig(struct phy_dm_struct * dm,u8 current_igi)23 static inline void phydm_check_ap_write_dig(struct phy_dm_struct *dm,
24 					    u8 current_igi)
25 {
26 	switch (*dm->one_path_cca) {
27 	case ODM_CCA_2R:
28 		odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
29 			       current_igi);
30 
31 		if (dm->rf_type > ODM_1T1R)
32 			odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
33 				       current_igi);
34 		break;
35 	case ODM_CCA_1R_A:
36 		odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
37 			       current_igi);
38 		if (dm->rf_type != ODM_1T1R)
39 			odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
40 				       get_igi_for_diff(current_igi));
41 		break;
42 	case ODM_CCA_1R_B:
43 		odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
44 			       get_igi_for_diff(current_igi));
45 		if (dm->rf_type != ODM_1T1R)
46 			odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
47 				       current_igi);
48 		break;
49 	}
50 }
51 
phydm_get_current_igi(u8 dig_max_of_min,u8 rssi_min,u8 current_igi)52 static inline u8 phydm_get_current_igi(u8 dig_max_of_min, u8 rssi_min,
53 				       u8 current_igi)
54 {
55 	if (rssi_min < dig_max_of_min) {
56 		if (current_igi < rssi_min)
57 			return rssi_min;
58 	} else {
59 		if (current_igi < dig_max_of_min)
60 			return dig_max_of_min;
61 	}
62 	return current_igi;
63 }
64 
odm_change_dynamic_init_gain_thresh(void * dm_void,u32 dm_type,u32 dm_value)65 void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type,
66 					 u32 dm_value)
67 {
68 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
69 	struct dig_thres *dig_tab = &dm->dm_dig_table;
70 
71 	if (dm_type == DIG_TYPE_THRESH_HIGH) {
72 		dig_tab->rssi_high_thresh = dm_value;
73 	} else if (dm_type == DIG_TYPE_THRESH_LOW) {
74 		dig_tab->rssi_low_thresh = dm_value;
75 	} else if (dm_type == DIG_TYPE_ENABLE) {
76 		dig_tab->dig_enable_flag = true;
77 	} else if (dm_type == DIG_TYPE_DISABLE) {
78 		dig_tab->dig_enable_flag = false;
79 	} else if (dm_type == DIG_TYPE_BACKOFF) {
80 		if (dm_value > 30)
81 			dm_value = 30;
82 		dig_tab->backoff_val = (u8)dm_value;
83 	} else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
84 		if (dm_value == 0)
85 			dm_value = 0x1;
86 		dig_tab->rx_gain_range_min = (u8)dm_value;
87 	} else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
88 		if (dm_value > 0x50)
89 			dm_value = 0x50;
90 		dig_tab->rx_gain_range_max = (u8)dm_value;
91 	}
92 } /* dm_change_dynamic_init_gain_thresh */
93 
get_igi_for_diff(int value_IGI)94 static int get_igi_for_diff(int value_IGI)
95 {
96 #define ONERCCA_LOW_TH 0x30
97 #define ONERCCA_LOW_DIFF 8
98 
99 	if (value_IGI < ONERCCA_LOW_TH) {
100 		if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF)
101 			return ONERCCA_LOW_TH;
102 		else
103 			return value_IGI + ONERCCA_LOW_DIFF;
104 	}
105 
106 	return value_IGI;
107 }
108 
odm_fa_threshold_check(void * dm_void,bool is_dfs_band,bool is_performance,u32 rx_tp,u32 tx_tp,u32 * dm_FA_thres)109 static void odm_fa_threshold_check(void *dm_void, bool is_dfs_band,
110 				   bool is_performance, u32 rx_tp, u32 tx_tp,
111 				   u32 *dm_FA_thres)
112 {
113 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
114 
115 	if (dm->is_linked && (is_performance || is_dfs_band)) {
116 		/*For NIC*/
117 		dm_FA_thres[0] = DM_DIG_FA_TH0;
118 		dm_FA_thres[1] = DM_DIG_FA_TH1;
119 		dm_FA_thres[2] = DM_DIG_FA_TH2;
120 	} else {
121 		if (is_dfs_band) {
122 			/* For DFS band and no link */
123 			dm_FA_thres[0] = 250;
124 			dm_FA_thres[1] = 1000;
125 			dm_FA_thres[2] = 2000;
126 		} else {
127 			dm_FA_thres[0] = 2000;
128 			dm_FA_thres[1] = 4000;
129 			dm_FA_thres[2] = 5000;
130 		}
131 	}
132 }
133 
odm_forbidden_igi_check(void * dm_void,u8 dig_dynamic_min,u8 current_igi)134 static u8 odm_forbidden_igi_check(void *dm_void, u8 dig_dynamic_min,
135 				  u8 current_igi)
136 {
137 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
138 	struct dig_thres *dig_tab = &dm->dm_dig_table;
139 	struct false_alarm_stat *fa_cnt =
140 		(struct false_alarm_stat *)phydm_get_structure(
141 			dm, PHYDM_FALSEALMCNT);
142 	u8 rx_gain_range_min = dig_tab->rx_gain_range_min;
143 
144 	if (dig_tab->large_fa_timeout) {
145 		if (--dig_tab->large_fa_timeout == 0)
146 			dig_tab->large_fa_hit = 0;
147 	}
148 
149 	if (fa_cnt->cnt_all > 10000) {
150 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
151 			     "%s(): Abnormally false alarm case.\n", __func__);
152 
153 		if (dig_tab->large_fa_hit != 3)
154 			dig_tab->large_fa_hit++;
155 
156 		if (dig_tab->forbidden_igi < current_igi) {
157 			dig_tab->forbidden_igi = current_igi;
158 			dig_tab->large_fa_hit = 1;
159 			dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT;
160 		}
161 
162 		if (dig_tab->large_fa_hit >= 3) {
163 			if ((dig_tab->forbidden_igi + 2) >
164 			    dig_tab->rx_gain_range_max)
165 				rx_gain_range_min = dig_tab->rx_gain_range_max;
166 			else
167 				rx_gain_range_min =
168 					(dig_tab->forbidden_igi + 2);
169 			dig_tab->recover_cnt = 1800;
170 			ODM_RT_TRACE(
171 				dm, ODM_COMP_DIG,
172 				"%s(): Abnormally false alarm case: recover_cnt = %d\n",
173 				__func__, dig_tab->recover_cnt);
174 		}
175 	}
176 
177 	else if (fa_cnt->cnt_all > 2000) {
178 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
179 			     "Abnormally false alarm case.\n");
180 		ODM_RT_TRACE(
181 			dm, ODM_COMP_DIG,
182 			"cnt_all=%d, cnt_all_pre=%d, current_igi=0x%x, pre_ig_value=0x%x\n",
183 			fa_cnt->cnt_all, fa_cnt->cnt_all_pre, current_igi,
184 			dig_tab->pre_ig_value);
185 
186 		/* fa_cnt->cnt_all = 1.1875*fa_cnt->cnt_all_pre */
187 		if ((fa_cnt->cnt_all >
188 		     (fa_cnt->cnt_all_pre + (fa_cnt->cnt_all_pre >> 3) +
189 		      (fa_cnt->cnt_all_pre >> 4))) &&
190 		    current_igi < dig_tab->pre_ig_value) {
191 			if (dig_tab->large_fa_hit != 3)
192 				dig_tab->large_fa_hit++;
193 
194 			if (dig_tab->forbidden_igi < current_igi) {
195 				ODM_RT_TRACE(
196 					dm, ODM_COMP_DIG,
197 					"Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n",
198 					dig_tab->forbidden_igi, current_igi);
199 
200 				dig_tab->forbidden_igi = current_igi;
201 				dig_tab->large_fa_hit = 1;
202 				dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT;
203 			}
204 		}
205 
206 		if (dig_tab->large_fa_hit >= 3) {
207 			ODM_RT_TRACE(
208 				dm, ODM_COMP_DIG,
209 				"FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, forbidden_igi=0x%x\n",
210 				dig_tab->rx_gain_range_max, rx_gain_range_min,
211 				dig_tab->forbidden_igi);
212 
213 			if ((dig_tab->forbidden_igi + 1) >
214 			    dig_tab->rx_gain_range_max)
215 				rx_gain_range_min = dig_tab->rx_gain_range_max;
216 			else
217 				rx_gain_range_min =
218 					(dig_tab->forbidden_igi + 1);
219 
220 			dig_tab->recover_cnt = 1200;
221 			ODM_RT_TRACE(
222 				dm, ODM_COMP_DIG,
223 				"Abnormally false alarm case: recover_cnt = %d,  rx_gain_range_min = 0x%x\n",
224 				dig_tab->recover_cnt, rx_gain_range_min);
225 		}
226 	} else {
227 		if (dig_tab->recover_cnt != 0) {
228 			dig_tab->recover_cnt--;
229 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
230 				     "%s(): Normal Case: recover_cnt = %d\n",
231 				     __func__, dig_tab->recover_cnt);
232 			return rx_gain_range_min;
233 		}
234 
235 		if (dig_tab->large_fa_hit >= 3) {
236 			dig_tab->large_fa_hit = 0;
237 			return rx_gain_range_min;
238 		}
239 
240 		if ((dig_tab->forbidden_igi - 2) <
241 		    dig_dynamic_min) { /* DM_DIG_MIN) */
242 			dig_tab->forbidden_igi =
243 				dig_dynamic_min; /* DM_DIG_MIN; */
244 			rx_gain_range_min = dig_dynamic_min; /* DM_DIG_MIN; */
245 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
246 				     "%s(): Normal Case: At Lower Bound\n",
247 				     __func__);
248 		} else {
249 			if (dig_tab->large_fa_hit == 0) {
250 				dig_tab->forbidden_igi -= 2;
251 				rx_gain_range_min =
252 					(dig_tab->forbidden_igi + 2);
253 				ODM_RT_TRACE(
254 					dm, ODM_COMP_DIG,
255 					"%s(): Normal Case: Approach Lower Bound\n",
256 					__func__);
257 			}
258 		}
259 	}
260 
261 	return rx_gain_range_min;
262 }
263 
phydm_set_big_jump_step(void * dm_void,u8 current_igi)264 static void phydm_set_big_jump_step(void *dm_void, u8 current_igi)
265 {
266 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
267 	struct dig_thres *dig_tab = &dm->dm_dig_table;
268 	u8 step1[8] = {24, 30, 40, 50, 60, 70, 80, 90};
269 	u8 i;
270 
271 	if (dig_tab->enable_adjust_big_jump == 0)
272 		return;
273 
274 	for (i = 0; i <= dig_tab->big_jump_step1; i++) {
275 		if ((current_igi + step1[i]) >
276 		    dig_tab->big_jump_lmt[dig_tab->agc_table_idx]) {
277 			if (i != 0)
278 				i = i - 1;
279 			break;
280 		} else if (i == dig_tab->big_jump_step1) {
281 			break;
282 		}
283 	}
284 	if (dm->support_ic_type & ODM_RTL8822B)
285 		odm_set_bb_reg(dm, 0x8c8, 0xe, i);
286 	else if (dm->support_ic_type & ODM_RTL8197F)
287 		odm_set_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, 0xe, i);
288 
289 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
290 		     "%s(): bigjump = %d (ori = 0x%x), LMT=0x%x\n", __func__, i,
291 		     dig_tab->big_jump_step1,
292 		     dig_tab->big_jump_lmt[dig_tab->agc_table_idx]);
293 }
294 
odm_write_dig(void * dm_void,u8 current_igi)295 void odm_write_dig(void *dm_void, u8 current_igi)
296 {
297 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
298 	struct dig_thres *dig_tab = &dm->dm_dig_table;
299 
300 	if (dig_tab->is_stop_dig) {
301 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Stop Writing IGI\n",
302 			     __func__);
303 		return;
304 	}
305 
306 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
307 		     "%s(): ODM_REG(IGI_A,dm)=0x%x, ODM_BIT(IGI,dm)=0x%x\n",
308 		     __func__, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
309 
310 	/* 1 Check initial gain by upper bound */
311 	if (!dig_tab->is_psd_in_progress && dm->is_linked) {
312 		if (current_igi > dig_tab->rx_gain_range_max) {
313 			ODM_RT_TRACE(
314 				dm, ODM_COMP_DIG,
315 				"%s(): current_igi(0x%02x) is larger than upper bound !!\n",
316 				__func__, current_igi);
317 			current_igi = dig_tab->rx_gain_range_max;
318 		}
319 		if (dm->support_ability & ODM_BB_ADAPTIVITY &&
320 		    dm->adaptivity_flag) {
321 			if (current_igi > dm->adaptivity_igi_upper)
322 				current_igi = dm->adaptivity_igi_upper;
323 
324 			ODM_RT_TRACE(
325 				dm, ODM_COMP_DIG,
326 				"%s(): adaptivity case: Force upper bound to 0x%x !!!!!!\n",
327 				__func__, current_igi);
328 		}
329 	}
330 
331 	if (dig_tab->cur_ig_value != current_igi) {
332 		/* Modify big jump step for 8822B and 8197F */
333 		if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F))
334 			phydm_set_big_jump_step(dm, current_igi);
335 
336 		/* Set IGI value of CCK for new CCK AGC */
337 		if (dm->cck_new_agc) {
338 			if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE)
339 				odm_set_bb_reg(dm, 0xa0c, 0x00003f00,
340 					       (current_igi >> 1));
341 		}
342 
343 		/*Add by YuChen for USB IO too slow issue*/
344 		if ((dm->support_ability & ODM_BB_ADAPTIVITY) &&
345 		    current_igi > dig_tab->cur_ig_value) {
346 			dig_tab->cur_ig_value = current_igi;
347 			phydm_adaptivity(dm);
348 		}
349 
350 		/* 1 Set IGI value */
351 		if (dm->support_platform & (ODM_WIN | ODM_CE)) {
352 			odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
353 				       current_igi);
354 
355 			if (dm->rf_type > ODM_1T1R)
356 				odm_set_bb_reg(dm, ODM_REG(IGI_B, dm),
357 					       ODM_BIT(IGI, dm), current_igi);
358 
359 		} else if (dm->support_platform & (ODM_AP)) {
360 			phydm_check_ap_write_dig(dm, current_igi);
361 		}
362 
363 		dig_tab->cur_ig_value = current_igi;
364 	}
365 
366 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi(0x%02x).\n", __func__,
367 		     current_igi);
368 }
369 
odm_pause_dig(void * dm_void,enum phydm_pause_type pause_type,enum phydm_pause_level pause_level,u8 igi_value)370 void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type,
371 		   enum phydm_pause_level pause_level, u8 igi_value)
372 {
373 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
374 	struct dig_thres *dig_tab = &dm->dm_dig_table;
375 	s8 max_level;
376 
377 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
378 		     pause_level);
379 
380 	if (dig_tab->pause_dig_level == 0 &&
381 	    (!(dm->support_ability & ODM_BB_DIG) ||
382 	     !(dm->support_ability & ODM_BB_FA_CNT))) {
383 		ODM_RT_TRACE(
384 			dm, ODM_COMP_DIG,
385 			"%s(): Return: support_ability DIG or FA is disabled !!\n",
386 			__func__);
387 		return;
388 	}
389 
390 	if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
391 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
392 			     "%s(): Return: Wrong pause level !!\n", __func__);
393 		return;
394 	}
395 
396 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
397 		     "%s(): pause level = 0x%x, Current value = 0x%x\n",
398 		     __func__, dig_tab->pause_dig_level, igi_value);
399 	ODM_RT_TRACE(
400 		dm, ODM_COMP_DIG,
401 		"%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
402 		__func__, dig_tab->pause_dig_value[7],
403 		dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5],
404 		dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3],
405 		dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1],
406 		dig_tab->pause_dig_value[0]);
407 
408 	switch (pause_type) {
409 	/* Pause DIG */
410 	case PHYDM_PAUSE: {
411 		/* Disable DIG */
412 		odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
413 				    dm->support_ability & (~ODM_BB_DIG));
414 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Pause DIG !!\n",
415 			     __func__);
416 
417 		/* Backup IGI value */
418 		if (dig_tab->pause_dig_level == 0) {
419 			dig_tab->igi_backup = dig_tab->cur_ig_value;
420 			ODM_RT_TRACE(
421 				dm, ODM_COMP_DIG,
422 				"%s(): Backup IGI  = 0x%x, new IGI = 0x%x\n",
423 				__func__, dig_tab->igi_backup, igi_value);
424 		}
425 
426 		/* Record IGI value */
427 		dig_tab->pause_dig_value[pause_level] = igi_value;
428 
429 		/* Update pause level */
430 		dig_tab->pause_dig_level =
431 			(dig_tab->pause_dig_level | BIT(pause_level));
432 
433 		/* Write new IGI value */
434 		if (BIT(pause_level + 1) > dig_tab->pause_dig_level) {
435 			odm_write_dig(dm, igi_value);
436 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
437 				     "%s(): IGI of higher level = 0x%x\n",
438 				     __func__, igi_value);
439 		}
440 		break;
441 	}
442 	/* Resume DIG */
443 	case PHYDM_RESUME: {
444 		/* check if the level is illegal or not */
445 		if ((dig_tab->pause_dig_level & (BIT(pause_level))) != 0) {
446 			dig_tab->pause_dig_level = dig_tab->pause_dig_level &
447 						   (~(BIT(pause_level)));
448 			dig_tab->pause_dig_value[pause_level] = 0;
449 			ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Resume DIG !!\n",
450 				     __func__);
451 		} else {
452 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
453 				     "%s(): Wrong resume level !!\n", __func__);
454 			break;
455 		}
456 
457 		/* Resume DIG */
458 		if (dig_tab->pause_dig_level == 0) {
459 			/* Write backup IGI value */
460 			odm_write_dig(dm, dig_tab->igi_backup);
461 			dig_tab->is_ignore_dig = true;
462 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
463 				     "%s(): Write original IGI = 0x%x\n",
464 				     __func__, dig_tab->igi_backup);
465 
466 			/* Enable DIG */
467 			odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
468 					    dm->support_ability | ODM_BB_DIG);
469 			break;
470 		}
471 
472 		if (BIT(pause_level) <= dig_tab->pause_dig_level)
473 			break;
474 
475 		/* Calculate the maximum level now */
476 		for (max_level = (pause_level - 1); max_level >= 0;
477 		     max_level--) {
478 			if ((dig_tab->pause_dig_level & BIT(max_level)) > 0)
479 				break;
480 		}
481 
482 		/* pin max_level to be >= 0 */
483 		max_level = max_t(s8, 0, max_level);
484 		/* write IGI of lower level */
485 		odm_write_dig(dm, dig_tab->pause_dig_value[max_level]);
486 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
487 			     "%s(): Write IGI (0x%x) of level (%d)\n", __func__,
488 			     dig_tab->pause_dig_value[max_level], max_level);
489 		break;
490 	}
491 	default:
492 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong  type !!\n",
493 			     __func__);
494 		break;
495 	}
496 
497 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
498 		     "%s(): pause level = 0x%x, Current value = 0x%x\n",
499 		     __func__, dig_tab->pause_dig_level, igi_value);
500 	ODM_RT_TRACE(
501 		dm, ODM_COMP_DIG,
502 		"%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
503 		__func__, dig_tab->pause_dig_value[7],
504 		dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5],
505 		dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3],
506 		dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1],
507 		dig_tab->pause_dig_value[0]);
508 }
509 
odm_dig_abort(void * dm_void)510 static bool odm_dig_abort(void *dm_void)
511 {
512 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
513 	struct dig_thres *dig_tab = &dm->dm_dig_table;
514 
515 	/* support_ability */
516 	if (!(dm->support_ability & ODM_BB_FA_CNT)) {
517 		ODM_RT_TRACE(
518 			dm, ODM_COMP_DIG,
519 			"%s(): Return: support_ability ODM_BB_FA_CNT is disabled\n",
520 			__func__);
521 		return true;
522 	}
523 
524 	/* support_ability */
525 	if (!(dm->support_ability & ODM_BB_DIG)) {
526 		ODM_RT_TRACE(
527 			dm, ODM_COMP_DIG,
528 			"%s(): Return: support_ability ODM_BB_DIG is disabled\n",
529 			__func__);
530 		return true;
531 	}
532 
533 	/* ScanInProcess */
534 	if (*dm->is_scan_in_process) {
535 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
536 			     "%s(): Return: In Scan Progress\n", __func__);
537 		return true;
538 	}
539 
540 	if (dig_tab->is_ignore_dig) {
541 		dig_tab->is_ignore_dig = false;
542 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Return: Ignore DIG\n",
543 			     __func__);
544 		return true;
545 	}
546 
547 	/* add by Neil Chen to avoid PSD is processing */
548 	if (!dm->is_dm_initial_gain_enable) {
549 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
550 			     "%s(): Return: PSD is Processing\n", __func__);
551 		return true;
552 	}
553 
554 	return false;
555 }
556 
odm_dig_init(void * dm_void)557 void odm_dig_init(void *dm_void)
558 {
559 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
560 	struct dig_thres *dig_tab = &dm->dm_dig_table;
561 	u32 ret_value;
562 	u8 i;
563 
564 	dig_tab->is_stop_dig = false;
565 	dig_tab->is_ignore_dig = false;
566 	dig_tab->is_psd_in_progress = false;
567 	dig_tab->cur_ig_value =
568 		(u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
569 	dig_tab->pre_ig_value = 0;
570 	dig_tab->rssi_low_thresh = DM_DIG_THRESH_LOW;
571 	dig_tab->rssi_high_thresh = DM_DIG_THRESH_HIGH;
572 	dig_tab->fa_low_thresh = DM_FALSEALARM_THRESH_LOW;
573 	dig_tab->fa_high_thresh = DM_FALSEALARM_THRESH_HIGH;
574 	dig_tab->backoff_val = DM_DIG_BACKOFF_DEFAULT;
575 	dig_tab->backoff_val_range_max = DM_DIG_BACKOFF_MAX;
576 	dig_tab->backoff_val_range_min = DM_DIG_BACKOFF_MIN;
577 	dig_tab->pre_cck_cca_thres = 0xFF;
578 	dig_tab->cur_cck_cca_thres = 0x83;
579 	dig_tab->forbidden_igi = DM_DIG_MIN_NIC;
580 	dig_tab->large_fa_hit = 0;
581 	dig_tab->large_fa_timeout = 0;
582 	dig_tab->recover_cnt = 0;
583 	dig_tab->is_media_connect_0 = false;
584 	dig_tab->is_media_connect_1 = false;
585 
586 	/*To initialize dm->is_dm_initial_gain_enable==false to avoid DIG err*/
587 	dm->is_dm_initial_gain_enable = true;
588 
589 	dig_tab->dig_dynamic_min_0 = DM_DIG_MIN_NIC;
590 	dig_tab->dig_dynamic_min_1 = DM_DIG_MIN_NIC;
591 
592 	/* To Initi BT30 IGI */
593 	dig_tab->bt30_cur_igi = 0x32;
594 
595 	odm_memory_set(dm, dig_tab->pause_dig_value, 0,
596 		       (DM_DIG_MAX_PAUSE_TYPE + 1));
597 	dig_tab->pause_dig_level = 0;
598 	odm_memory_set(dm, dig_tab->pause_cckpd_value, 0,
599 		       (DM_DIG_MAX_PAUSE_TYPE + 1));
600 	dig_tab->pause_cckpd_level = 0;
601 
602 	if (dm->board_type & (ODM_BOARD_EXT_PA | ODM_BOARD_EXT_LNA)) {
603 		dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC;
604 		dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC;
605 	} else {
606 		dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC;
607 		dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC;
608 	}
609 
610 	dig_tab->enable_adjust_big_jump = 1;
611 	if (dm->support_ic_type & ODM_RTL8822B) {
612 		ret_value = odm_get_bb_reg(dm, 0x8c8, MASKLWORD);
613 		dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
614 		dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
615 		dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
616 
617 	} else if (dm->support_ic_type & ODM_RTL8197F) {
618 		ret_value =
619 			odm_get_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, MASKLWORD);
620 		dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
621 		dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
622 		dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
623 	}
624 	if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) {
625 		for (i = 0; i < sizeof(dig_tab->big_jump_lmt); i++) {
626 			if (dig_tab->big_jump_lmt[i] == 0)
627 				dig_tab->big_jump_lmt[i] =
628 					0x64; /* Set -10dBm as default value */
629 		}
630 	}
631 }
632 
odm_DIG(void * dm_void)633 void odm_DIG(void *dm_void)
634 {
635 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
636 
637 	/* Common parameters */
638 	struct dig_thres *dig_tab = &dm->dm_dig_table;
639 	struct false_alarm_stat *fa_cnt =
640 		(struct false_alarm_stat *)phydm_get_structure(
641 			dm, PHYDM_FALSEALMCNT);
642 	bool first_connect, first_dis_connect;
643 	u8 dig_max_of_min, dig_dynamic_min;
644 	u8 dm_dig_max, dm_dig_min;
645 	u8 current_igi = dig_tab->cur_ig_value;
646 	u8 offset;
647 	u32 dm_FA_thres[3];
648 	u32 tx_tp = 0, rx_tp = 0;
649 	bool is_dfs_band = false;
650 	bool is_performance = true, is_first_tp_target = false,
651 	     is_first_coverage = false;
652 
653 	if (odm_dig_abort(dm))
654 		return;
655 
656 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG Start===>\n");
657 
658 	/* 1 Update status */
659 	{
660 		dig_dynamic_min = dig_tab->dig_dynamic_min_0;
661 		first_connect = (dm->is_linked) && !dig_tab->is_media_connect_0;
662 		first_dis_connect =
663 			(!dm->is_linked) && dig_tab->is_media_connect_0;
664 	}
665 
666 	/* 1 Boundary Decision */
667 	{
668 		/* 2 For WIN\CE */
669 		if (dm->support_ic_type >= ODM_RTL8188E)
670 			dm_dig_max = 0x5A;
671 		else
672 			dm_dig_max = DM_DIG_MAX_NIC;
673 
674 		if (dm->support_ic_type != ODM_RTL8821)
675 			dm_dig_min = DM_DIG_MIN_NIC;
676 		else
677 			dm_dig_min = 0x1C;
678 
679 		dig_max_of_min = DM_DIG_MAX_AP;
680 
681 		/* Modify lower bound for DFS band */
682 		if ((((*dm->channel >= 52) && (*dm->channel <= 64)) ||
683 		     ((*dm->channel >= 100) && (*dm->channel <= 140))) &&
684 		    phydm_dfs_master_enabled(dm)) {
685 			is_dfs_band = true;
686 			if (*dm->band_width == ODM_BW20M)
687 				dm_dig_min = DM_DIG_MIN_AP_DFS + 2;
688 			else
689 				dm_dig_min = DM_DIG_MIN_AP_DFS;
690 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
691 				     "DIG: ====== In DFS band ======\n");
692 		}
693 	}
694 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
695 		     "DIG: Absolutly upper bound = 0x%x, lower bound = 0x%x\n",
696 		     dm_dig_max, dm_dig_min);
697 
698 	if (dm->pu1_forced_igi_lb && (*dm->pu1_forced_igi_lb > 0)) {
699 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Force IGI lb to: 0x%02x\n",
700 			     *dm->pu1_forced_igi_lb);
701 		dm_dig_min = *dm->pu1_forced_igi_lb;
702 		dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) :
703 							  (dm_dig_min + 1);
704 	}
705 
706 	/* 1 Adjust boundary by RSSI */
707 	if (dm->is_linked && is_performance) {
708 		/* 2 Modify DIG upper bound */
709 		/* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
710 		if ((dm->support_ic_type & (ODM_RTL8192E | ODM_RTL8723B |
711 					    ODM_RTL8812 | ODM_RTL8821)) &&
712 		    dm->is_bt_limited_dig == 1) {
713 			offset = 10;
714 			ODM_RT_TRACE(
715 				dm, ODM_COMP_DIG,
716 				"DIG: Coex. case: Force upper bound to RSSI + %d\n",
717 				offset);
718 		} else {
719 			offset = 15;
720 		}
721 
722 		if ((dm->rssi_min + offset) > dm_dig_max)
723 			dig_tab->rx_gain_range_max = dm_dig_max;
724 		else if ((dm->rssi_min + offset) < dm_dig_min)
725 			dig_tab->rx_gain_range_max = dm_dig_min;
726 		else
727 			dig_tab->rx_gain_range_max = dm->rssi_min + offset;
728 
729 		/* 2 Modify DIG lower bound */
730 		/* if(dm->is_one_entry_only) */
731 		{
732 			if (dm->rssi_min < dm_dig_min)
733 				dig_dynamic_min = dm_dig_min;
734 			else if (dm->rssi_min > dig_max_of_min)
735 				dig_dynamic_min = dig_max_of_min;
736 			else
737 				dig_dynamic_min = dm->rssi_min;
738 
739 			if (is_dfs_band) {
740 				dig_dynamic_min = dm_dig_min;
741 				ODM_RT_TRACE(
742 					dm, ODM_COMP_DIG,
743 					"DIG: DFS band: Force lower bound to 0x%x after link\n",
744 					dm_dig_min);
745 			}
746 		}
747 	} else {
748 		if (is_performance && is_dfs_band) {
749 			dig_tab->rx_gain_range_max = 0x28;
750 			ODM_RT_TRACE(
751 				dm, ODM_COMP_DIG,
752 				"DIG: DFS band: Force upper bound to 0x%x before link\n",
753 				dig_tab->rx_gain_range_max);
754 		} else {
755 			if (is_performance)
756 				dig_tab->rx_gain_range_max = DM_DIG_MAX_OF_MIN;
757 			else
758 				dig_tab->rx_gain_range_max = dm_dig_max;
759 		}
760 		dig_dynamic_min = dm_dig_min;
761 	}
762 
763 	/* 1 Force Lower Bound for AntDiv */
764 	if (dm->is_linked && !dm->is_one_entry_only &&
765 	    (dm->support_ic_type & ODM_ANTDIV_SUPPORT) &&
766 	    (dm->support_ability & ODM_BB_ANT_DIV)) {
767 		if (dm->ant_div_type == CG_TRX_HW_ANTDIV ||
768 		    dm->ant_div_type == CG_TRX_SMART_ANTDIV) {
769 			if (dig_tab->ant_div_rssi_max > dig_max_of_min)
770 				dig_dynamic_min = dig_max_of_min;
771 			else
772 				dig_dynamic_min = (u8)dig_tab->ant_div_rssi_max;
773 			ODM_RT_TRACE(
774 				dm, ODM_COMP_DIG,
775 				"DIG: AntDiv case: Force lower bound to 0x%x\n",
776 				dig_dynamic_min);
777 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
778 				     "DIG: AntDiv case: rssi_max = 0x%x\n",
779 				     dig_tab->ant_div_rssi_max);
780 		}
781 	}
782 	ODM_RT_TRACE(
783 		dm, ODM_COMP_DIG,
784 		"DIG: Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n",
785 		dig_tab->rx_gain_range_max, dig_dynamic_min);
786 	ODM_RT_TRACE(
787 		dm, ODM_COMP_DIG,
788 		"DIG: Link status: is_linked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n",
789 		dm->is_linked, dm->rssi_min, first_connect, first_dis_connect);
790 
791 	/* 1 Modify DIG lower bound, deal with abnormal case */
792 	/* 2 Abnormal false alarm case */
793 	if (is_dfs_band) {
794 		dig_tab->rx_gain_range_min = dig_dynamic_min;
795 	} else {
796 		if (!dm->is_linked) {
797 			dig_tab->rx_gain_range_min = dig_dynamic_min;
798 
799 			if (first_dis_connect)
800 				dig_tab->forbidden_igi = dig_dynamic_min;
801 		} else {
802 			dig_tab->rx_gain_range_min = odm_forbidden_igi_check(
803 				dm, dig_dynamic_min, current_igi);
804 		}
805 	}
806 
807 	/* 2 Abnormal # beacon case */
808 	if (dm->is_linked && !first_connect) {
809 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "Beacon Num (%d)\n",
810 			     dm->phy_dbg_info.num_qry_beacon_pkt);
811 		if (dm->phy_dbg_info.num_qry_beacon_pkt < 5 &&
812 		    dm->bsta_state) {
813 			dig_tab->rx_gain_range_min = 0x1c;
814 			ODM_RT_TRACE(
815 				dm, ODM_COMP_DIG,
816 				"DIG: Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n",
817 				dm->phy_dbg_info.num_qry_beacon_pkt,
818 				dig_tab->rx_gain_range_min);
819 		}
820 	}
821 
822 	/* 2 Abnormal lower bound case */
823 	if (dig_tab->rx_gain_range_min > dig_tab->rx_gain_range_max) {
824 		dig_tab->rx_gain_range_min = dig_tab->rx_gain_range_max;
825 		ODM_RT_TRACE(
826 			dm, ODM_COMP_DIG,
827 			"DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n",
828 			dig_tab->rx_gain_range_min);
829 	}
830 
831 	/* 1 False alarm threshold decision */
832 	odm_fa_threshold_check(dm, is_dfs_band, is_performance, rx_tp, tx_tp,
833 			       dm_FA_thres);
834 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
835 		     "DIG: False alarm threshold = %d, %d, %d\n",
836 		     dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]);
837 
838 	/* 1 Adjust initial gain by false alarm */
839 	if (dm->is_linked && is_performance) {
840 		/* 2 After link */
841 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI after link\n");
842 
843 		if (is_first_tp_target || (first_connect && is_performance)) {
844 			dig_tab->large_fa_hit = 0;
845 
846 			if (is_dfs_band) {
847 				u8 rssi = dm->rssi_min;
848 
849 				current_igi =
850 					(dm->rssi_min > 0x28) ? 0x28 : rssi;
851 				ODM_RT_TRACE(
852 					dm, ODM_COMP_DIG,
853 					"DIG: DFS band: One-shot to 0x28 upmost\n");
854 			} else {
855 				current_igi = phydm_get_current_igi(
856 					dig_max_of_min, dm->rssi_min,
857 					current_igi);
858 			}
859 
860 			ODM_RT_TRACE(
861 				dm, ODM_COMP_DIG,
862 				"DIG: First connect case: IGI does on-shot to 0x%x\n",
863 				current_igi);
864 
865 		} else {
866 			if (fa_cnt->cnt_all > dm_FA_thres[2])
867 				current_igi = current_igi + 4;
868 			else if (fa_cnt->cnt_all > dm_FA_thres[1])
869 				current_igi = current_igi + 2;
870 			else if (fa_cnt->cnt_all < dm_FA_thres[0])
871 				current_igi = current_igi - 2;
872 
873 			/* 4 Abnormal # beacon case */
874 			if (dm->phy_dbg_info.num_qry_beacon_pkt < 5 &&
875 			    fa_cnt->cnt_all < DM_DIG_FA_TH1 &&
876 			    dm->bsta_state) {
877 				current_igi = dig_tab->rx_gain_range_min;
878 				ODM_RT_TRACE(
879 					dm, ODM_COMP_DIG,
880 					"DIG: Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
881 					dm->phy_dbg_info.num_qry_beacon_pkt,
882 					current_igi);
883 			}
884 		}
885 	} else {
886 		/* 2 Before link */
887 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI before link\n");
888 
889 		if (first_dis_connect || is_first_coverage) {
890 			current_igi = dm_dig_min;
891 			ODM_RT_TRACE(
892 				dm, ODM_COMP_DIG,
893 				"DIG: First disconnect case: IGI does on-shot to lower bound\n");
894 		} else {
895 			if (fa_cnt->cnt_all > dm_FA_thres[2])
896 				current_igi = current_igi + 4;
897 			else if (fa_cnt->cnt_all > dm_FA_thres[1])
898 				current_igi = current_igi + 2;
899 			else if (fa_cnt->cnt_all < dm_FA_thres[0])
900 				current_igi = current_igi - 2;
901 		}
902 	}
903 
904 	/* 1 Check initial gain by upper/lower bound */
905 	if (current_igi < dig_tab->rx_gain_range_min)
906 		current_igi = dig_tab->rx_gain_range_min;
907 
908 	if (current_igi > dig_tab->rx_gain_range_max)
909 		current_igi = dig_tab->rx_gain_range_max;
910 
911 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: cur_ig_value=0x%x, TotalFA = %d\n",
912 		     current_igi, fa_cnt->cnt_all);
913 
914 	/* 1 Update status */
915 	if (dm->is_bt_hs_operation) {
916 		if (dm->is_linked) {
917 			if (dig_tab->bt30_cur_igi > (current_igi))
918 				odm_write_dig(dm, current_igi);
919 			else
920 				odm_write_dig(dm, dig_tab->bt30_cur_igi);
921 
922 			dig_tab->is_media_connect_0 = dm->is_linked;
923 			dig_tab->dig_dynamic_min_0 = dig_dynamic_min;
924 		} else {
925 			if (dm->is_link_in_process)
926 				odm_write_dig(dm, 0x1c);
927 			else if (dm->is_bt_connect_process)
928 				odm_write_dig(dm, 0x28);
929 			else
930 				odm_write_dig(dm, dig_tab->bt30_cur_igi);
931 		}
932 	} else { /* BT is not using */
933 		odm_write_dig(dm, current_igi);
934 		dig_tab->is_media_connect_0 = dm->is_linked;
935 		dig_tab->dig_dynamic_min_0 = dig_dynamic_min;
936 	}
937 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG end\n");
938 }
939 
odm_dig_by_rssi_lps(void * dm_void)940 void odm_dig_by_rssi_lps(void *dm_void)
941 {
942 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
943 	struct false_alarm_stat *fa_cnt =
944 		(struct false_alarm_stat *)phydm_get_structure(
945 			dm, PHYDM_FALSEALMCNT);
946 
947 	u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
948 	u8 current_igi = dm->rssi_min;
949 
950 	if (odm_dig_abort(dm))
951 		return;
952 
953 	current_igi = current_igi + RSSI_OFFSET_DIG;
954 
955 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()==>\n", __func__);
956 
957 	/* Using FW PS mode to make IGI */
958 	/* Adjust by  FA in LPS MODE */
959 	if (fa_cnt->cnt_all > DM_DIG_FA_TH2_LPS)
960 		current_igi = current_igi + 4;
961 	else if (fa_cnt->cnt_all > DM_DIG_FA_TH1_LPS)
962 		current_igi = current_igi + 2;
963 	else if (fa_cnt->cnt_all < DM_DIG_FA_TH0_LPS)
964 		current_igi = current_igi - 2;
965 
966 	/* Lower bound checking */
967 
968 	/* RSSI Lower bound check */
969 	if ((dm->rssi_min - 10) > DM_DIG_MIN_NIC)
970 		rssi_lower = (dm->rssi_min - 10);
971 	else
972 		rssi_lower = DM_DIG_MIN_NIC;
973 
974 	/* Upper and Lower Bound checking */
975 	if (current_igi > DM_DIG_MAX_NIC)
976 		current_igi = DM_DIG_MAX_NIC;
977 	else if (current_igi < rssi_lower)
978 		current_igi = rssi_lower;
979 
980 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): fa_cnt->cnt_all = %d\n", __func__,
981 		     fa_cnt->cnt_all);
982 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): dm->rssi_min = %d\n", __func__,
983 		     dm->rssi_min);
984 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi = 0x%x\n", __func__,
985 		     current_igi);
986 
987 	odm_write_dig(
988 		dm,
989 		current_igi); /* odm_write_dig(dm, dig_tab->cur_ig_value); */
990 }
991 
992 /* 3============================================================
993  * 3 FASLE ALARM CHECK
994  * 3============================================================
995  */
996 
odm_false_alarm_counter_statistics(void * dm_void)997 void odm_false_alarm_counter_statistics(void *dm_void)
998 {
999 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1000 	struct false_alarm_stat *false_alm_cnt =
1001 		(struct false_alarm_stat *)phydm_get_structure(
1002 			dm, PHYDM_FALSEALMCNT);
1003 	struct rt_adcsmp *adc_smp = &dm->adcsmp;
1004 	u32 ret_value;
1005 
1006 	if (!(dm->support_ability & ODM_BB_FA_CNT))
1007 		return;
1008 
1009 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "%s()======>\n", __func__);
1010 
1011 	if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1012 		/* hold ofdm counter */
1013 		odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31),
1014 			       1); /* hold page C counter */
1015 		odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31),
1016 			       1); /* hold page D counter */
1017 
1018 		ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11N,
1019 					   MASKDWORD);
1020 		false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff);
1021 		false_alm_cnt->cnt_sb_search_fail =
1022 			((ret_value & 0xffff0000) >> 16);
1023 
1024 		ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE2_11N,
1025 					   MASKDWORD);
1026 		false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
1027 		false_alm_cnt->cnt_parity_fail =
1028 			((ret_value & 0xffff0000) >> 16);
1029 
1030 		ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE3_11N,
1031 					   MASKDWORD);
1032 		false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
1033 		false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
1034 
1035 		ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE4_11N,
1036 					   MASKDWORD);
1037 		false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
1038 
1039 		false_alm_cnt->cnt_ofdm_fail =
1040 			false_alm_cnt->cnt_parity_fail +
1041 			false_alm_cnt->cnt_rate_illegal +
1042 			false_alm_cnt->cnt_crc8_fail +
1043 			false_alm_cnt->cnt_mcs_fail +
1044 			false_alm_cnt->cnt_fast_fsync +
1045 			false_alm_cnt->cnt_sb_search_fail;
1046 
1047 		/* read CCK CRC32 counter */
1048 		false_alm_cnt->cnt_cck_crc32_error = odm_get_bb_reg(
1049 			dm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, MASKDWORD);
1050 		false_alm_cnt->cnt_cck_crc32_ok = odm_get_bb_reg(
1051 			dm, ODM_REG_CCK_CRC32_OK_CNT_11N, MASKDWORD);
1052 
1053 		/* read OFDM CRC32 counter */
1054 		ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11N,
1055 					   MASKDWORD);
1056 		false_alm_cnt->cnt_ofdm_crc32_error =
1057 			(ret_value & 0xffff0000) >> 16;
1058 		false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
1059 
1060 		/* read HT CRC32 counter */
1061 		ret_value =
1062 			odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD);
1063 		false_alm_cnt->cnt_ht_crc32_error =
1064 			(ret_value & 0xffff0000) >> 16;
1065 		false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
1066 
1067 		/* read VHT CRC32 counter */
1068 		false_alm_cnt->cnt_vht_crc32_error = 0;
1069 		false_alm_cnt->cnt_vht_crc32_ok = 0;
1070 
1071 		{
1072 			/* hold cck counter */
1073 			odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
1074 			odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
1075 
1076 			ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_LSB_11N,
1077 						   MASKBYTE0);
1078 			false_alm_cnt->cnt_cck_fail = ret_value;
1079 
1080 			ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_MSB_11N,
1081 						   MASKBYTE3);
1082 			false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
1083 
1084 			ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11N,
1085 						   MASKDWORD);
1086 			false_alm_cnt->cnt_cck_cca =
1087 				((ret_value & 0xFF) << 8) |
1088 				((ret_value & 0xFF00) >> 8);
1089 		}
1090 
1091 		false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all;
1092 
1093 		false_alm_cnt->cnt_all = (false_alm_cnt->cnt_fast_fsync +
1094 					  false_alm_cnt->cnt_sb_search_fail +
1095 					  false_alm_cnt->cnt_parity_fail +
1096 					  false_alm_cnt->cnt_rate_illegal +
1097 					  false_alm_cnt->cnt_crc8_fail +
1098 					  false_alm_cnt->cnt_mcs_fail +
1099 					  false_alm_cnt->cnt_cck_fail);
1100 
1101 		false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca +
1102 					     false_alm_cnt->cnt_cck_cca;
1103 
1104 		if (dm->support_ic_type >= ODM_RTL8188E) {
1105 			/*reset false alarm counter registers*/
1106 			odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31),
1107 				       1);
1108 			odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31),
1109 				       0);
1110 			odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
1111 				       1);
1112 			odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
1113 				       0);
1114 
1115 			/*update ofdm counter*/
1116 			odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31),
1117 				       0); /*update page C counter*/
1118 			odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31),
1119 				       0); /*update page D counter*/
1120 
1121 			/*reset CCK CCA counter*/
1122 			odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1123 				       BIT(13) | BIT(12), 0);
1124 			odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1125 				       BIT(13) | BIT(12), 2);
1126 
1127 			/*reset CCK FA counter*/
1128 			odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1129 				       BIT(15) | BIT(14), 0);
1130 			odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1131 				       BIT(15) | BIT(14), 2);
1132 
1133 			/*reset CRC32 counter*/
1134 			odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 1);
1135 			odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 0);
1136 		}
1137 
1138 		/* Get debug port 0 */
1139 		odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
1140 		false_alm_cnt->dbg_port0 =
1141 			odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD);
1142 
1143 		/* Get EDCCA flag */
1144 		odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
1145 		false_alm_cnt->edcca_flag =
1146 			(bool)odm_get_bb_reg(dm, ODM_REG_RPT_11N, BIT(30));
1147 
1148 		ODM_RT_TRACE(
1149 			dm, ODM_COMP_FA_CNT,
1150 			"[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n",
1151 			false_alm_cnt->cnt_parity_fail,
1152 			false_alm_cnt->cnt_rate_illegal,
1153 			false_alm_cnt->cnt_crc8_fail,
1154 			false_alm_cnt->cnt_mcs_fail,
1155 			false_alm_cnt->cnt_fast_fsync,
1156 			false_alm_cnt->cnt_sb_search_fail);
1157 	}
1158 
1159 	if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1160 		u32 cck_enable;
1161 
1162 		/* read OFDM FA counter */
1163 		false_alm_cnt->cnt_ofdm_fail =
1164 			odm_get_bb_reg(dm, ODM_REG_OFDM_FA_11AC, MASKLWORD);
1165 
1166 		/* Read CCK FA counter */
1167 		false_alm_cnt->cnt_cck_fail =
1168 			odm_get_bb_reg(dm, ODM_REG_CCK_FA_11AC, MASKLWORD);
1169 
1170 		/* read CCK/OFDM CCA counter */
1171 		ret_value =
1172 			odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11AC, MASKDWORD);
1173 		false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff0000) >> 16;
1174 		false_alm_cnt->cnt_cck_cca = ret_value & 0xffff;
1175 
1176 		/* read CCK CRC32 counter */
1177 		ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CRC32_CNT_11AC,
1178 					   MASKDWORD);
1179 		false_alm_cnt->cnt_cck_crc32_error =
1180 			(ret_value & 0xffff0000) >> 16;
1181 		false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff;
1182 
1183 		/* read OFDM CRC32 counter */
1184 		ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11AC,
1185 					   MASKDWORD);
1186 		false_alm_cnt->cnt_ofdm_crc32_error =
1187 			(ret_value & 0xffff0000) >> 16;
1188 		false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
1189 
1190 		/* read HT CRC32 counter */
1191 		ret_value = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11AC,
1192 					   MASKDWORD);
1193 		false_alm_cnt->cnt_ht_crc32_error =
1194 			(ret_value & 0xffff0000) >> 16;
1195 		false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
1196 
1197 		/* read VHT CRC32 counter */
1198 		ret_value = odm_get_bb_reg(dm, ODM_REG_VHT_CRC32_CNT_11AC,
1199 					   MASKDWORD);
1200 		false_alm_cnt->cnt_vht_crc32_error =
1201 			(ret_value & 0xffff0000) >> 16;
1202 		false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff;
1203 
1204 		/* reset OFDM FA counter */
1205 		odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
1206 		odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
1207 
1208 		/* reset CCK FA counter */
1209 		odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
1210 		odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
1211 
1212 		/* reset CCA counter */
1213 		odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 1);
1214 		odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 0);
1215 
1216 		cck_enable =
1217 			odm_get_bb_reg(dm, ODM_REG_BB_RX_PATH_11AC, BIT(28));
1218 		if (cck_enable) { /* if(*dm->band_type == ODM_BAND_2_4G) */
1219 			false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail +
1220 						 false_alm_cnt->cnt_cck_fail;
1221 			false_alm_cnt->cnt_cca_all =
1222 				false_alm_cnt->cnt_cck_cca +
1223 				false_alm_cnt->cnt_ofdm_cca;
1224 		} else {
1225 			false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail;
1226 			false_alm_cnt->cnt_cca_all =
1227 				false_alm_cnt->cnt_ofdm_cca;
1228 		}
1229 
1230 		if (adc_smp->adc_smp_state == ADCSMP_STATE_IDLE) {
1231 			if (phydm_set_bb_dbg_port(
1232 				    dm, BB_DBGPORT_PRIORITY_1,
1233 				    0x0)) { /*set debug port to 0x0*/
1234 				false_alm_cnt->dbg_port0 =
1235 					phydm_get_bb_dbg_port_value(dm);
1236 				phydm_release_bb_dbg_port(dm);
1237 			}
1238 
1239 			if (phydm_set_bb_dbg_port(
1240 				    dm, BB_DBGPORT_PRIORITY_1,
1241 				    0x209)) { /*set debug port to 0x0*/
1242 				false_alm_cnt->edcca_flag =
1243 					(bool)((phydm_get_bb_dbg_port_value(
1244 							dm) &
1245 						BIT(30)) >>
1246 					       30);
1247 				phydm_release_bb_dbg_port(dm);
1248 			}
1249 		}
1250 	}
1251 
1252 	false_alm_cnt->cnt_crc32_error_all =
1253 		false_alm_cnt->cnt_vht_crc32_error +
1254 		false_alm_cnt->cnt_ht_crc32_error +
1255 		false_alm_cnt->cnt_ofdm_crc32_error +
1256 		false_alm_cnt->cnt_cck_crc32_error;
1257 	false_alm_cnt->cnt_crc32_ok_all = false_alm_cnt->cnt_vht_crc32_ok +
1258 					  false_alm_cnt->cnt_ht_crc32_ok +
1259 					  false_alm_cnt->cnt_ofdm_crc32_ok +
1260 					  false_alm_cnt->cnt_cck_crc32_ok;
1261 
1262 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1263 		     "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
1264 		     false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca,
1265 		     false_alm_cnt->cnt_cca_all);
1266 
1267 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1268 		     "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
1269 		     false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail,
1270 		     false_alm_cnt->cnt_all);
1271 
1272 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1273 		     "[CCK]  CRC32 {error, ok}= {%d, %d}\n",
1274 		     false_alm_cnt->cnt_cck_crc32_error,
1275 		     false_alm_cnt->cnt_cck_crc32_ok);
1276 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "[OFDM]CRC32 {error, ok}= {%d, %d}\n",
1277 		     false_alm_cnt->cnt_ofdm_crc32_error,
1278 		     false_alm_cnt->cnt_ofdm_crc32_ok);
1279 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1280 		     "[ HT ]  CRC32 {error, ok}= {%d, %d}\n",
1281 		     false_alm_cnt->cnt_ht_crc32_error,
1282 		     false_alm_cnt->cnt_ht_crc32_ok);
1283 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1284 		     "[VHT]  CRC32 {error, ok}= {%d, %d}\n",
1285 		     false_alm_cnt->cnt_vht_crc32_error,
1286 		     false_alm_cnt->cnt_vht_crc32_ok);
1287 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1288 		     "[VHT]  CRC32 {error, ok}= {%d, %d}\n",
1289 		     false_alm_cnt->cnt_crc32_error_all,
1290 		     false_alm_cnt->cnt_crc32_ok_all);
1291 	ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1292 		     "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n\n",
1293 		     false_alm_cnt->dbg_port0, false_alm_cnt->edcca_flag);
1294 }
1295 
1296 /* 3============================================================
1297  * 3 CCK Packet Detect threshold
1298  * 3============================================================
1299  */
1300 
odm_pause_cck_packet_detection(void * dm_void,enum phydm_pause_type pause_type,enum phydm_pause_level pause_level,u8 cck_pd_threshold)1301 void odm_pause_cck_packet_detection(void *dm_void,
1302 				    enum phydm_pause_type pause_type,
1303 				    enum phydm_pause_level pause_level,
1304 				    u8 cck_pd_threshold)
1305 {
1306 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1307 	struct dig_thres *dig_tab = &dm->dm_dig_table;
1308 	s8 max_level;
1309 
1310 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
1311 		     pause_level);
1312 
1313 	if (dig_tab->pause_cckpd_level == 0 &&
1314 	    (!(dm->support_ability & ODM_BB_CCK_PD) ||
1315 	     !(dm->support_ability & ODM_BB_FA_CNT))) {
1316 		ODM_RT_TRACE(
1317 			dm, ODM_COMP_DIG,
1318 			"Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n");
1319 		return;
1320 	}
1321 
1322 	if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
1323 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
1324 			     "%s(): Return: Wrong pause level !!\n", __func__);
1325 		return;
1326 	}
1327 
1328 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
1329 		     "%s(): pause level = 0x%x, Current value = 0x%x\n",
1330 		     __func__, dig_tab->pause_cckpd_level, cck_pd_threshold);
1331 	ODM_RT_TRACE(
1332 		dm, ODM_COMP_DIG,
1333 		"%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1334 		__func__, dig_tab->pause_cckpd_value[7],
1335 		dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5],
1336 		dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3],
1337 		dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1],
1338 		dig_tab->pause_cckpd_value[0]);
1339 
1340 	switch (pause_type) {
1341 	/* Pause CCK Packet Detection threshold */
1342 	case PHYDM_PAUSE: {
1343 		/* Disable CCK PD */
1344 		odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
1345 				    dm->support_ability & (~ODM_BB_CCK_PD));
1346 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
1347 			     "%s(): Pause CCK packet detection threshold !!\n",
1348 			     __func__);
1349 
1350 		/*Backup original CCK PD threshold decided by CCK PD mechanism*/
1351 		if (dig_tab->pause_cckpd_level == 0) {
1352 			dig_tab->cck_pd_backup = dig_tab->cur_cck_cca_thres;
1353 			ODM_RT_TRACE(
1354 				dm, ODM_COMP_DIG,
1355 				"%s(): Backup CCKPD  = 0x%x, new CCKPD = 0x%x\n",
1356 				__func__, dig_tab->cck_pd_backup,
1357 				cck_pd_threshold);
1358 		}
1359 
1360 		/* Update pause level */
1361 		dig_tab->pause_cckpd_level =
1362 			(dig_tab->pause_cckpd_level | BIT(pause_level));
1363 
1364 		/* Record CCK PD threshold */
1365 		dig_tab->pause_cckpd_value[pause_level] = cck_pd_threshold;
1366 
1367 		/* Write new CCK PD threshold */
1368 		if (BIT(pause_level + 1) > dig_tab->pause_cckpd_level) {
1369 			odm_write_cck_cca_thres(dm, cck_pd_threshold);
1370 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
1371 				     "%s(): CCKPD of higher level = 0x%x\n",
1372 				     __func__, cck_pd_threshold);
1373 		}
1374 		break;
1375 	}
1376 	/* Resume CCK Packet Detection threshold */
1377 	case PHYDM_RESUME: {
1378 		/* check if the level is illegal or not */
1379 		if ((dig_tab->pause_cckpd_level & (BIT(pause_level))) != 0) {
1380 			dig_tab->pause_cckpd_level =
1381 				dig_tab->pause_cckpd_level &
1382 				(~(BIT(pause_level)));
1383 			dig_tab->pause_cckpd_value[pause_level] = 0;
1384 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
1385 				     "%s(): Resume CCK PD !!\n", __func__);
1386 		} else {
1387 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
1388 				     "%s(): Wrong resume level !!\n", __func__);
1389 			break;
1390 		}
1391 
1392 		/* Resume DIG */
1393 		if (dig_tab->pause_cckpd_level == 0) {
1394 			/* Write backup IGI value */
1395 			odm_write_cck_cca_thres(dm, dig_tab->cck_pd_backup);
1396 			/* dig_tab->is_ignore_dig = true; */
1397 			ODM_RT_TRACE(dm, ODM_COMP_DIG,
1398 				     "%s(): Write original CCKPD = 0x%x\n",
1399 				     __func__, dig_tab->cck_pd_backup);
1400 
1401 			/* Enable DIG */
1402 			odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
1403 					    dm->support_ability |
1404 						    ODM_BB_CCK_PD);
1405 			break;
1406 		}
1407 
1408 		if (BIT(pause_level) <= dig_tab->pause_cckpd_level)
1409 			break;
1410 
1411 		/* Calculate the maximum level now */
1412 		for (max_level = (pause_level - 1); max_level >= 0;
1413 		     max_level--) {
1414 			if ((dig_tab->pause_cckpd_level & BIT(max_level)) > 0)
1415 				break;
1416 		}
1417 
1418 		/* write CCKPD of lower level */
1419 		odm_write_cck_cca_thres(dm,
1420 					dig_tab->pause_cckpd_value[max_level]);
1421 		ODM_RT_TRACE(dm, ODM_COMP_DIG,
1422 			     "%s(): Write CCKPD (0x%x) of level (%d)\n",
1423 			     __func__, dig_tab->pause_cckpd_value[max_level],
1424 			     max_level);
1425 		break;
1426 	}
1427 	default:
1428 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong  type !!\n",
1429 			     __func__);
1430 		break;
1431 	}
1432 
1433 	ODM_RT_TRACE(dm, ODM_COMP_DIG,
1434 		     "%s(): pause level = 0x%x, Current value = 0x%x\n",
1435 		     __func__, dig_tab->pause_cckpd_level, cck_pd_threshold);
1436 	ODM_RT_TRACE(
1437 		dm, ODM_COMP_DIG,
1438 		"%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1439 		__func__, dig_tab->pause_cckpd_value[7],
1440 		dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5],
1441 		dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3],
1442 		dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1],
1443 		dig_tab->pause_cckpd_value[0]);
1444 }
1445 
odm_cck_packet_detection_thresh(void * dm_void)1446 void odm_cck_packet_detection_thresh(void *dm_void)
1447 {
1448 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1449 	struct dig_thres *dig_tab = &dm->dm_dig_table;
1450 	struct false_alarm_stat *false_alm_cnt =
1451 		(struct false_alarm_stat *)phydm_get_structure(
1452 			dm, PHYDM_FALSEALMCNT);
1453 	u8 cur_cck_cca_thres = dig_tab->cur_cck_cca_thres, rssi_thd = 35;
1454 
1455 	if ((!(dm->support_ability & ODM_BB_CCK_PD)) ||
1456 	    (!(dm->support_ability & ODM_BB_FA_CNT))) {
1457 		ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: return==========\n");
1458 		return;
1459 	}
1460 
1461 	if (dm->ext_lna)
1462 		return;
1463 
1464 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: ==========>\n");
1465 
1466 	if (dig_tab->cck_fa_ma == 0xffffffff)
1467 		dig_tab->cck_fa_ma = false_alm_cnt->cnt_cck_fail;
1468 	else
1469 		dig_tab->cck_fa_ma =
1470 			((dig_tab->cck_fa_ma << 1) + dig_tab->cck_fa_ma +
1471 			 false_alm_cnt->cnt_cck_fail) >>
1472 			2;
1473 
1474 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: CCK FA moving average = %d\n",
1475 		     dig_tab->cck_fa_ma);
1476 
1477 	if (dm->is_linked) {
1478 		if (dm->rssi_min > rssi_thd) {
1479 			cur_cck_cca_thres = 0xcd;
1480 		} else if (dm->rssi_min > 20) {
1481 			if (dig_tab->cck_fa_ma >
1482 			    ((DM_DIG_FA_TH1 >> 1) + (DM_DIG_FA_TH1 >> 3)))
1483 				cur_cck_cca_thres = 0xcd;
1484 			else if (dig_tab->cck_fa_ma < (DM_DIG_FA_TH0 >> 1))
1485 				cur_cck_cca_thres = 0x83;
1486 		} else if (dm->rssi_min > 7) {
1487 			cur_cck_cca_thres = 0x83;
1488 		} else {
1489 			cur_cck_cca_thres = 0x40;
1490 		}
1491 
1492 	} else {
1493 		if (dig_tab->cck_fa_ma > 0x400)
1494 			cur_cck_cca_thres = 0x83;
1495 		else if (dig_tab->cck_fa_ma < 0x200)
1496 			cur_cck_cca_thres = 0x40;
1497 	}
1498 
1499 	{
1500 		odm_write_cck_cca_thres(dm, cur_cck_cca_thres);
1501 	}
1502 
1503 	ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: cck_cca_th=((0x%x))\n\n",
1504 		     cur_cck_cca_thres);
1505 }
1506 
odm_write_cck_cca_thres(void * dm_void,u8 cur_cck_cca_thres)1507 void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres)
1508 {
1509 	struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1510 	struct dig_thres *dig_tab = &dm->dm_dig_table;
1511 
1512 	if (dig_tab->cur_cck_cca_thres !=
1513 	    cur_cck_cca_thres) { /* modify by Guo.Mingzhi 2012-01-03 */
1514 		odm_write_1byte(dm, ODM_REG(CCK_CCA, dm), cur_cck_cca_thres);
1515 		dig_tab->cck_fa_ma = 0xffffffff;
1516 	}
1517 	dig_tab->pre_cck_cca_thres = dig_tab->cur_cck_cca_thres;
1518 	dig_tab->cur_cck_cca_thres = cur_cck_cca_thres;
1519 }
1520 
phydm_dig_go_up_check(void * dm_void)1521 bool phydm_dig_go_up_check(void *dm_void)
1522 {
1523 	bool ret = true;
1524 
1525 	return ret;
1526 }
1527