1 /******************************************************************************
3 * Copyright(c) 2007 - 2016 Realtek Corporation.
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.
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
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
26 /* ************************************************************
28 * *************************************************************/
29 #include "mp_precomp.h"
30 #include "phydm_precomp.h"
32 static int get_igi_for_diff(int);
34 static inline void phydm_check_ap_write_dig(struct phy_dm_struct *dm,
37 switch (*dm->one_path_cca) {
39 odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
42 if (dm->rf_type > ODM_1T1R)
43 odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
47 odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
49 if (dm->rf_type != ODM_1T1R)
50 odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
51 get_igi_for_diff(current_igi));
54 odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
55 get_igi_for_diff(current_igi));
56 if (dm->rf_type != ODM_1T1R)
57 odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
63 static inline u8 phydm_get_current_igi(u8 dig_max_of_min, u8 rssi_min,
66 if (rssi_min < dig_max_of_min) {
67 if (current_igi < rssi_min)
70 if (current_igi < dig_max_of_min)
71 return dig_max_of_min;
76 void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type,
79 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
80 struct dig_thres *dig_tab = &dm->dm_dig_table;
82 if (dm_type == DIG_TYPE_THRESH_HIGH) {
83 dig_tab->rssi_high_thresh = dm_value;
84 } else if (dm_type == DIG_TYPE_THRESH_LOW) {
85 dig_tab->rssi_low_thresh = dm_value;
86 } else if (dm_type == DIG_TYPE_ENABLE) {
87 dig_tab->dig_enable_flag = true;
88 } else if (dm_type == DIG_TYPE_DISABLE) {
89 dig_tab->dig_enable_flag = false;
90 } else if (dm_type == DIG_TYPE_BACKOFF) {
93 dig_tab->backoff_val = (u8)dm_value;
94 } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
97 dig_tab->rx_gain_range_min = (u8)dm_value;
98 } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
101 dig_tab->rx_gain_range_max = (u8)dm_value;
103 } /* dm_change_dynamic_init_gain_thresh */
105 static int get_igi_for_diff(int value_IGI)
107 #define ONERCCA_LOW_TH 0x30
108 #define ONERCCA_LOW_DIFF 8
110 if (value_IGI < ONERCCA_LOW_TH) {
111 if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF)
112 return ONERCCA_LOW_TH;
114 return value_IGI + ONERCCA_LOW_DIFF;
120 static void odm_fa_threshold_check(void *dm_void, bool is_dfs_band,
121 bool is_performance, u32 rx_tp, u32 tx_tp,
124 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
126 if (dm->is_linked && (is_performance || is_dfs_band)) {
128 dm_FA_thres[0] = DM_DIG_FA_TH0;
129 dm_FA_thres[1] = DM_DIG_FA_TH1;
130 dm_FA_thres[2] = DM_DIG_FA_TH2;
133 /* For DFS band and no link */
134 dm_FA_thres[0] = 250;
135 dm_FA_thres[1] = 1000;
136 dm_FA_thres[2] = 2000;
138 dm_FA_thres[0] = 2000;
139 dm_FA_thres[1] = 4000;
140 dm_FA_thres[2] = 5000;
145 static u8 odm_forbidden_igi_check(void *dm_void, u8 dig_dynamic_min,
148 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
149 struct dig_thres *dig_tab = &dm->dm_dig_table;
150 struct false_alarm_stat *fa_cnt =
151 (struct false_alarm_stat *)phydm_get_structure(
152 dm, PHYDM_FALSEALMCNT);
153 u8 rx_gain_range_min = dig_tab->rx_gain_range_min;
155 if (dig_tab->large_fa_timeout) {
156 if (--dig_tab->large_fa_timeout == 0)
157 dig_tab->large_fa_hit = 0;
160 if (fa_cnt->cnt_all > 10000) {
161 ODM_RT_TRACE(dm, ODM_COMP_DIG,
162 "%s(): Abnormally false alarm case.\n", __func__);
164 if (dig_tab->large_fa_hit != 3)
165 dig_tab->large_fa_hit++;
167 if (dig_tab->forbidden_igi < current_igi) {
168 dig_tab->forbidden_igi = current_igi;
169 dig_tab->large_fa_hit = 1;
170 dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT;
173 if (dig_tab->large_fa_hit >= 3) {
174 if ((dig_tab->forbidden_igi + 2) >
175 dig_tab->rx_gain_range_max)
176 rx_gain_range_min = dig_tab->rx_gain_range_max;
179 (dig_tab->forbidden_igi + 2);
180 dig_tab->recover_cnt = 1800;
183 "%s(): Abnormally false alarm case: recover_cnt = %d\n",
184 __func__, dig_tab->recover_cnt);
188 else if (fa_cnt->cnt_all > 2000) {
189 ODM_RT_TRACE(dm, ODM_COMP_DIG,
190 "Abnormally false alarm case.\n");
193 "cnt_all=%d, cnt_all_pre=%d, current_igi=0x%x, pre_ig_value=0x%x\n",
194 fa_cnt->cnt_all, fa_cnt->cnt_all_pre, current_igi,
195 dig_tab->pre_ig_value);
197 /* fa_cnt->cnt_all = 1.1875*fa_cnt->cnt_all_pre */
198 if ((fa_cnt->cnt_all >
199 (fa_cnt->cnt_all_pre + (fa_cnt->cnt_all_pre >> 3) +
200 (fa_cnt->cnt_all_pre >> 4))) &&
201 (current_igi < dig_tab->pre_ig_value)) {
202 if (dig_tab->large_fa_hit != 3)
203 dig_tab->large_fa_hit++;
205 if (dig_tab->forbidden_igi < current_igi) {
208 "Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n",
209 dig_tab->forbidden_igi, current_igi);
211 dig_tab->forbidden_igi = current_igi;
212 dig_tab->large_fa_hit = 1;
213 dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT;
217 if (dig_tab->large_fa_hit >= 3) {
220 "FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, forbidden_igi=0x%x\n",
221 dig_tab->rx_gain_range_max, rx_gain_range_min,
222 dig_tab->forbidden_igi);
224 if ((dig_tab->forbidden_igi + 1) >
225 dig_tab->rx_gain_range_max)
226 rx_gain_range_min = dig_tab->rx_gain_range_max;
229 (dig_tab->forbidden_igi + 1);
231 dig_tab->recover_cnt = 1200;
234 "Abnormally false alarm case: recover_cnt = %d, rx_gain_range_min = 0x%x\n",
235 dig_tab->recover_cnt, rx_gain_range_min);
238 if (dig_tab->recover_cnt != 0) {
239 dig_tab->recover_cnt--;
240 ODM_RT_TRACE(dm, ODM_COMP_DIG,
241 "%s(): Normal Case: recover_cnt = %d\n",
242 __func__, dig_tab->recover_cnt);
243 return rx_gain_range_min;
246 if (dig_tab->large_fa_hit >= 3) {
247 dig_tab->large_fa_hit = 0;
248 return rx_gain_range_min;
251 if ((dig_tab->forbidden_igi - 2) <
252 dig_dynamic_min) { /* DM_DIG_MIN) */
253 dig_tab->forbidden_igi =
254 dig_dynamic_min; /* DM_DIG_MIN; */
255 rx_gain_range_min = dig_dynamic_min; /* DM_DIG_MIN; */
256 ODM_RT_TRACE(dm, ODM_COMP_DIG,
257 "%s(): Normal Case: At Lower Bound\n",
260 if (dig_tab->large_fa_hit == 0) {
261 dig_tab->forbidden_igi -= 2;
263 (dig_tab->forbidden_igi + 2);
266 "%s(): Normal Case: Approach Lower Bound\n",
272 return rx_gain_range_min;
275 static void phydm_set_big_jump_step(void *dm_void, u8 current_igi)
277 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
278 struct dig_thres *dig_tab = &dm->dm_dig_table;
279 u8 step1[8] = {24, 30, 40, 50, 60, 70, 80, 90};
282 if (dig_tab->enable_adjust_big_jump == 0)
285 for (i = 0; i <= dig_tab->big_jump_step1; i++) {
286 if ((current_igi + step1[i]) >
287 dig_tab->big_jump_lmt[dig_tab->agc_table_idx]) {
291 } else if (i == dig_tab->big_jump_step1) {
295 if (dm->support_ic_type & ODM_RTL8822B)
296 odm_set_bb_reg(dm, 0x8c8, 0xe, i);
297 else if (dm->support_ic_type & ODM_RTL8197F)
298 odm_set_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, 0xe, i);
300 ODM_RT_TRACE(dm, ODM_COMP_DIG,
301 "%s(): bigjump = %d (ori = 0x%x), LMT=0x%x\n", __func__, i,
302 dig_tab->big_jump_step1,
303 dig_tab->big_jump_lmt[dig_tab->agc_table_idx]);
306 void odm_write_dig(void *dm_void, u8 current_igi)
308 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
309 struct dig_thres *dig_tab = &dm->dm_dig_table;
311 if (dig_tab->is_stop_dig) {
312 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Stop Writing IGI\n",
317 ODM_RT_TRACE(dm, ODM_COMP_DIG,
318 "%s(): ODM_REG(IGI_A,dm)=0x%x, ODM_BIT(IGI,dm)=0x%x\n",
319 __func__, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
321 /* 1 Check initial gain by upper bound */
322 if ((!dig_tab->is_psd_in_progress) && dm->is_linked) {
323 if (current_igi > dig_tab->rx_gain_range_max) {
326 "%s(): current_igi(0x%02x) is larger than upper bound !!\n",
327 __func__, current_igi);
328 current_igi = dig_tab->rx_gain_range_max;
330 if (dm->support_ability & ODM_BB_ADAPTIVITY &&
331 dm->adaptivity_flag) {
332 if (current_igi > dm->adaptivity_igi_upper)
333 current_igi = dm->adaptivity_igi_upper;
337 "%s(): adaptivity case: Force upper bound to 0x%x !!!!!!\n",
338 __func__, current_igi);
342 if (dig_tab->cur_ig_value != current_igi) {
343 /* Modify big jump step for 8822B and 8197F */
344 if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F))
345 phydm_set_big_jump_step(dm, current_igi);
347 /* Set IGI value of CCK for new CCK AGC */
348 if (dm->cck_new_agc) {
349 if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE)
350 odm_set_bb_reg(dm, 0xa0c, 0x00003f00,
354 /*Add by YuChen for USB IO too slow issue*/
355 if ((dm->support_ability & ODM_BB_ADAPTIVITY) &&
356 (current_igi > dig_tab->cur_ig_value)) {
357 dig_tab->cur_ig_value = current_igi;
358 phydm_adaptivity(dm);
361 /* 1 Set IGI value */
362 if (dm->support_platform & (ODM_WIN | ODM_CE)) {
363 odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
366 if (dm->rf_type > ODM_1T1R)
367 odm_set_bb_reg(dm, ODM_REG(IGI_B, dm),
368 ODM_BIT(IGI, dm), current_igi);
370 } else if (dm->support_platform & (ODM_AP)) {
371 phydm_check_ap_write_dig(dm, current_igi);
374 dig_tab->cur_ig_value = current_igi;
377 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi(0x%02x).\n", __func__,
381 void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type,
382 enum phydm_pause_level pause_level, u8 igi_value)
384 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
385 struct dig_thres *dig_tab = &dm->dm_dig_table;
388 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
391 if ((dig_tab->pause_dig_level == 0) &&
392 (!(dm->support_ability & ODM_BB_DIG) ||
393 !(dm->support_ability & ODM_BB_FA_CNT))) {
396 "%s(): Return: support_ability DIG or FA is disabled !!\n",
401 if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
402 ODM_RT_TRACE(dm, ODM_COMP_DIG,
403 "%s(): Return: Wrong pause level !!\n", __func__);
407 ODM_RT_TRACE(dm, ODM_COMP_DIG,
408 "%s(): pause level = 0x%x, Current value = 0x%x\n",
409 __func__, dig_tab->pause_dig_level, igi_value);
412 "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
413 __func__, dig_tab->pause_dig_value[7],
414 dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5],
415 dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3],
416 dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1],
417 dig_tab->pause_dig_value[0]);
419 switch (pause_type) {
423 odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
424 dm->support_ability & (~ODM_BB_DIG));
425 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Pause DIG !!\n",
428 /* Backup IGI value */
429 if (dig_tab->pause_dig_level == 0) {
430 dig_tab->igi_backup = dig_tab->cur_ig_value;
433 "%s(): Backup IGI = 0x%x, new IGI = 0x%x\n",
434 __func__, dig_tab->igi_backup, igi_value);
437 /* Record IGI value */
438 dig_tab->pause_dig_value[pause_level] = igi_value;
440 /* Update pause level */
441 dig_tab->pause_dig_level =
442 (dig_tab->pause_dig_level | BIT(pause_level));
444 /* Write new IGI value */
445 if (BIT(pause_level + 1) > dig_tab->pause_dig_level) {
446 odm_write_dig(dm, igi_value);
447 ODM_RT_TRACE(dm, ODM_COMP_DIG,
448 "%s(): IGI of higher level = 0x%x\n",
449 __func__, igi_value);
455 /* check if the level is illegal or not */
456 if ((dig_tab->pause_dig_level & (BIT(pause_level))) != 0) {
457 dig_tab->pause_dig_level = dig_tab->pause_dig_level &
458 (~(BIT(pause_level)));
459 dig_tab->pause_dig_value[pause_level] = 0;
460 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Resume DIG !!\n",
463 ODM_RT_TRACE(dm, ODM_COMP_DIG,
464 "%s(): Wrong resume level !!\n", __func__);
469 if (dig_tab->pause_dig_level == 0) {
470 /* Write backup IGI value */
471 odm_write_dig(dm, dig_tab->igi_backup);
472 dig_tab->is_ignore_dig = true;
473 ODM_RT_TRACE(dm, ODM_COMP_DIG,
474 "%s(): Write original IGI = 0x%x\n",
475 __func__, dig_tab->igi_backup);
478 odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
479 dm->support_ability | ODM_BB_DIG);
483 if (BIT(pause_level) <= dig_tab->pause_dig_level)
486 /* Calculate the maximum level now */
487 for (max_level = (pause_level - 1); max_level >= 0;
489 if ((dig_tab->pause_dig_level & BIT(max_level)) > 0)
493 /* pin max_level to be >= 0 */
494 max_level = max_t(s8, 0, max_level);
495 /* write IGI of lower level */
496 odm_write_dig(dm, dig_tab->pause_dig_value[max_level]);
497 ODM_RT_TRACE(dm, ODM_COMP_DIG,
498 "%s(): Write IGI (0x%x) of level (%d)\n", __func__,
499 dig_tab->pause_dig_value[max_level], max_level);
503 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n",
508 ODM_RT_TRACE(dm, ODM_COMP_DIG,
509 "%s(): pause level = 0x%x, Current value = 0x%x\n",
510 __func__, dig_tab->pause_dig_level, igi_value);
513 "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
514 __func__, dig_tab->pause_dig_value[7],
515 dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5],
516 dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3],
517 dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1],
518 dig_tab->pause_dig_value[0]);
521 static bool odm_dig_abort(void *dm_void)
523 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
524 struct dig_thres *dig_tab = &dm->dm_dig_table;
526 /* support_ability */
527 if (!(dm->support_ability & ODM_BB_FA_CNT)) {
530 "%s(): Return: support_ability ODM_BB_FA_CNT is disabled\n",
535 /* support_ability */
536 if (!(dm->support_ability & ODM_BB_DIG)) {
539 "%s(): Return: support_ability ODM_BB_DIG is disabled\n",
545 if (*dm->is_scan_in_process) {
546 ODM_RT_TRACE(dm, ODM_COMP_DIG,
547 "%s(): Return: In Scan Progress\n", __func__);
551 if (dig_tab->is_ignore_dig) {
552 dig_tab->is_ignore_dig = false;
553 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Return: Ignore DIG\n",
558 /* add by Neil Chen to avoid PSD is processing */
559 if (!dm->is_dm_initial_gain_enable) {
560 ODM_RT_TRACE(dm, ODM_COMP_DIG,
561 "%s(): Return: PSD is Processing\n", __func__);
568 void odm_dig_init(void *dm_void)
570 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
571 struct dig_thres *dig_tab = &dm->dm_dig_table;
575 dig_tab->is_stop_dig = false;
576 dig_tab->is_ignore_dig = false;
577 dig_tab->is_psd_in_progress = false;
578 dig_tab->cur_ig_value =
579 (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm));
580 dig_tab->pre_ig_value = 0;
581 dig_tab->rssi_low_thresh = DM_DIG_THRESH_LOW;
582 dig_tab->rssi_high_thresh = DM_DIG_THRESH_HIGH;
583 dig_tab->fa_low_thresh = DM_FALSEALARM_THRESH_LOW;
584 dig_tab->fa_high_thresh = DM_FALSEALARM_THRESH_HIGH;
585 dig_tab->backoff_val = DM_DIG_BACKOFF_DEFAULT;
586 dig_tab->backoff_val_range_max = DM_DIG_BACKOFF_MAX;
587 dig_tab->backoff_val_range_min = DM_DIG_BACKOFF_MIN;
588 dig_tab->pre_cck_cca_thres = 0xFF;
589 dig_tab->cur_cck_cca_thres = 0x83;
590 dig_tab->forbidden_igi = DM_DIG_MIN_NIC;
591 dig_tab->large_fa_hit = 0;
592 dig_tab->large_fa_timeout = 0;
593 dig_tab->recover_cnt = 0;
594 dig_tab->is_media_connect_0 = false;
595 dig_tab->is_media_connect_1 = false;
597 /*To initialize dm->is_dm_initial_gain_enable==false to avoid DIG err*/
598 dm->is_dm_initial_gain_enable = true;
600 dig_tab->dig_dynamic_min_0 = DM_DIG_MIN_NIC;
601 dig_tab->dig_dynamic_min_1 = DM_DIG_MIN_NIC;
603 /* To Initi BT30 IGI */
604 dig_tab->bt30_cur_igi = 0x32;
606 odm_memory_set(dm, dig_tab->pause_dig_value, 0,
607 (DM_DIG_MAX_PAUSE_TYPE + 1));
608 dig_tab->pause_dig_level = 0;
609 odm_memory_set(dm, dig_tab->pause_cckpd_value, 0,
610 (DM_DIG_MAX_PAUSE_TYPE + 1));
611 dig_tab->pause_cckpd_level = 0;
613 if (dm->board_type & (ODM_BOARD_EXT_PA | ODM_BOARD_EXT_LNA)) {
614 dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC;
615 dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC;
617 dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC;
618 dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC;
621 dig_tab->enable_adjust_big_jump = 1;
622 if (dm->support_ic_type & ODM_RTL8822B) {
623 ret_value = odm_get_bb_reg(dm, 0x8c8, MASKLWORD);
624 dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
625 dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
626 dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
628 } else if (dm->support_ic_type & ODM_RTL8197F) {
630 odm_get_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, MASKLWORD);
631 dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
632 dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
633 dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
635 if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) {
636 for (i = 0; i < sizeof(dig_tab->big_jump_lmt); i++) {
637 if (dig_tab->big_jump_lmt[i] == 0)
638 dig_tab->big_jump_lmt[i] =
639 0x64; /* Set -10dBm as default value */
644 void odm_DIG(void *dm_void)
646 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
648 /* Common parameters */
649 struct dig_thres *dig_tab = &dm->dm_dig_table;
650 struct false_alarm_stat *fa_cnt =
651 (struct false_alarm_stat *)phydm_get_structure(
652 dm, PHYDM_FALSEALMCNT);
653 bool first_connect, first_dis_connect;
654 u8 dig_max_of_min, dig_dynamic_min;
655 u8 dm_dig_max, dm_dig_min;
656 u8 current_igi = dig_tab->cur_ig_value;
659 u32 tx_tp = 0, rx_tp = 0;
660 bool is_dfs_band = false;
661 bool is_performance = true, is_first_tp_target = false,
662 is_first_coverage = false;
664 if (odm_dig_abort(dm))
667 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG Start===>\n");
669 /* 1 Update status */
671 dig_dynamic_min = dig_tab->dig_dynamic_min_0;
672 first_connect = (dm->is_linked) && !dig_tab->is_media_connect_0;
674 (!dm->is_linked) && dig_tab->is_media_connect_0;
677 /* 1 Boundary Decision */
680 if (dm->support_ic_type >= ODM_RTL8188E)
683 dm_dig_max = DM_DIG_MAX_NIC;
685 if (dm->support_ic_type != ODM_RTL8821)
686 dm_dig_min = DM_DIG_MIN_NIC;
690 dig_max_of_min = DM_DIG_MAX_AP;
692 /* Modify lower bound for DFS band */
693 if ((((*dm->channel >= 52) && (*dm->channel <= 64)) ||
694 ((*dm->channel >= 100) && (*dm->channel <= 140))) &&
695 phydm_dfs_master_enabled(dm)) {
697 if (*dm->band_width == ODM_BW20M)
698 dm_dig_min = DM_DIG_MIN_AP_DFS + 2;
700 dm_dig_min = DM_DIG_MIN_AP_DFS;
701 ODM_RT_TRACE(dm, ODM_COMP_DIG,
702 "DIG: ====== In DFS band ======\n");
705 ODM_RT_TRACE(dm, ODM_COMP_DIG,
706 "DIG: Absolutly upper bound = 0x%x, lower bound = 0x%x\n",
707 dm_dig_max, dm_dig_min);
709 if (dm->pu1_forced_igi_lb && (*dm->pu1_forced_igi_lb > 0)) {
710 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Force IGI lb to: 0x%02x\n",
711 *dm->pu1_forced_igi_lb);
712 dm_dig_min = *dm->pu1_forced_igi_lb;
713 dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) :
717 /* 1 Adjust boundary by RSSI */
718 if (dm->is_linked && is_performance) {
719 /* 2 Modify DIG upper bound */
720 /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
721 if ((dm->support_ic_type & (ODM_RTL8192E | ODM_RTL8723B |
722 ODM_RTL8812 | ODM_RTL8821)) &&
723 (dm->is_bt_limited_dig == 1)) {
727 "DIG: Coex. case: Force upper bound to RSSI + %d\n",
733 if ((dm->rssi_min + offset) > dm_dig_max)
734 dig_tab->rx_gain_range_max = dm_dig_max;
735 else if ((dm->rssi_min + offset) < dm_dig_min)
736 dig_tab->rx_gain_range_max = dm_dig_min;
738 dig_tab->rx_gain_range_max = dm->rssi_min + offset;
740 /* 2 Modify DIG lower bound */
741 /* if(dm->is_one_entry_only) */
743 if (dm->rssi_min < dm_dig_min)
744 dig_dynamic_min = dm_dig_min;
745 else if (dm->rssi_min > dig_max_of_min)
746 dig_dynamic_min = dig_max_of_min;
748 dig_dynamic_min = dm->rssi_min;
751 dig_dynamic_min = dm_dig_min;
754 "DIG: DFS band: Force lower bound to 0x%x after link\n",
759 if (is_performance && is_dfs_band) {
760 dig_tab->rx_gain_range_max = 0x28;
763 "DIG: DFS band: Force upper bound to 0x%x before link\n",
764 dig_tab->rx_gain_range_max);
767 dig_tab->rx_gain_range_max = DM_DIG_MAX_OF_MIN;
769 dig_tab->rx_gain_range_max = dm_dig_max;
771 dig_dynamic_min = dm_dig_min;
774 /* 1 Force Lower Bound for AntDiv */
775 if (dm->is_linked && !dm->is_one_entry_only &&
776 (dm->support_ic_type & ODM_ANTDIV_SUPPORT) &&
777 (dm->support_ability & ODM_BB_ANT_DIV)) {
778 if (dm->ant_div_type == CG_TRX_HW_ANTDIV ||
779 dm->ant_div_type == CG_TRX_SMART_ANTDIV) {
780 if (dig_tab->ant_div_rssi_max > dig_max_of_min)
781 dig_dynamic_min = dig_max_of_min;
783 dig_dynamic_min = (u8)dig_tab->ant_div_rssi_max;
786 "DIG: AntDiv case: Force lower bound to 0x%x\n",
788 ODM_RT_TRACE(dm, ODM_COMP_DIG,
789 "DIG: AntDiv case: rssi_max = 0x%x\n",
790 dig_tab->ant_div_rssi_max);
795 "DIG: Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n",
796 dig_tab->rx_gain_range_max, dig_dynamic_min);
799 "DIG: Link status: is_linked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n",
800 dm->is_linked, dm->rssi_min, first_connect, first_dis_connect);
802 /* 1 Modify DIG lower bound, deal with abnormal case */
803 /* 2 Abnormal false alarm case */
805 dig_tab->rx_gain_range_min = dig_dynamic_min;
807 if (!dm->is_linked) {
808 dig_tab->rx_gain_range_min = dig_dynamic_min;
810 if (first_dis_connect)
811 dig_tab->forbidden_igi = dig_dynamic_min;
813 dig_tab->rx_gain_range_min = odm_forbidden_igi_check(
814 dm, dig_dynamic_min, current_igi);
818 /* 2 Abnormal # beacon case */
819 if (dm->is_linked && !first_connect) {
820 ODM_RT_TRACE(dm, ODM_COMP_DIG, "Beacon Num (%d)\n",
821 dm->phy_dbg_info.num_qry_beacon_pkt);
822 if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) &&
824 dig_tab->rx_gain_range_min = 0x1c;
827 "DIG: Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n",
828 dm->phy_dbg_info.num_qry_beacon_pkt,
829 dig_tab->rx_gain_range_min);
833 /* 2 Abnormal lower bound case */
834 if (dig_tab->rx_gain_range_min > dig_tab->rx_gain_range_max) {
835 dig_tab->rx_gain_range_min = dig_tab->rx_gain_range_max;
838 "DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n",
839 dig_tab->rx_gain_range_min);
842 /* 1 False alarm threshold decision */
843 odm_fa_threshold_check(dm, is_dfs_band, is_performance, rx_tp, tx_tp,
845 ODM_RT_TRACE(dm, ODM_COMP_DIG,
846 "DIG: False alarm threshold = %d, %d, %d\n",
847 dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]);
849 /* 1 Adjust initial gain by false alarm */
850 if (dm->is_linked && is_performance) {
852 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI after link\n");
854 if (is_first_tp_target || (first_connect && is_performance)) {
855 dig_tab->large_fa_hit = 0;
858 u8 rssi = dm->rssi_min;
861 (dm->rssi_min > 0x28) ? 0x28 : rssi;
864 "DIG: DFS band: One-shot to 0x28 upmost\n");
866 current_igi = phydm_get_current_igi(
867 dig_max_of_min, dm->rssi_min,
873 "DIG: First connect case: IGI does on-shot to 0x%x\n",
877 if (fa_cnt->cnt_all > dm_FA_thres[2])
878 current_igi = current_igi + 4;
879 else if (fa_cnt->cnt_all > dm_FA_thres[1])
880 current_igi = current_igi + 2;
881 else if (fa_cnt->cnt_all < dm_FA_thres[0])
882 current_igi = current_igi - 2;
884 /* 4 Abnormal # beacon case */
885 if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) &&
886 (fa_cnt->cnt_all < DM_DIG_FA_TH1) &&
888 current_igi = dig_tab->rx_gain_range_min;
891 "DIG: Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
892 dm->phy_dbg_info.num_qry_beacon_pkt,
898 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI before link\n");
900 if (first_dis_connect || is_first_coverage) {
901 current_igi = dm_dig_min;
904 "DIG: First disconnect case: IGI does on-shot to lower bound\n");
906 if (fa_cnt->cnt_all > dm_FA_thres[2])
907 current_igi = current_igi + 4;
908 else if (fa_cnt->cnt_all > dm_FA_thres[1])
909 current_igi = current_igi + 2;
910 else if (fa_cnt->cnt_all < dm_FA_thres[0])
911 current_igi = current_igi - 2;
915 /* 1 Check initial gain by upper/lower bound */
916 if (current_igi < dig_tab->rx_gain_range_min)
917 current_igi = dig_tab->rx_gain_range_min;
919 if (current_igi > dig_tab->rx_gain_range_max)
920 current_igi = dig_tab->rx_gain_range_max;
922 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: cur_ig_value=0x%x, TotalFA = %d\n",
923 current_igi, fa_cnt->cnt_all);
925 /* 1 Update status */
926 if (dm->is_bt_hs_operation) {
928 if (dig_tab->bt30_cur_igi > (current_igi))
929 odm_write_dig(dm, current_igi);
931 odm_write_dig(dm, dig_tab->bt30_cur_igi);
933 dig_tab->is_media_connect_0 = dm->is_linked;
934 dig_tab->dig_dynamic_min_0 = dig_dynamic_min;
936 if (dm->is_link_in_process)
937 odm_write_dig(dm, 0x1c);
938 else if (dm->is_bt_connect_process)
939 odm_write_dig(dm, 0x28);
941 odm_write_dig(dm, dig_tab->bt30_cur_igi);
943 } else { /* BT is not using */
944 odm_write_dig(dm, current_igi);
945 dig_tab->is_media_connect_0 = dm->is_linked;
946 dig_tab->dig_dynamic_min_0 = dig_dynamic_min;
948 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG end\n");
951 void odm_dig_by_rssi_lps(void *dm_void)
953 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
954 struct false_alarm_stat *fa_cnt =
955 (struct false_alarm_stat *)phydm_get_structure(
956 dm, PHYDM_FALSEALMCNT);
958 u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
959 u8 current_igi = dm->rssi_min;
961 if (odm_dig_abort(dm))
964 current_igi = current_igi + RSSI_OFFSET_DIG;
966 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()==>\n", __func__);
968 /* Using FW PS mode to make IGI */
969 /* Adjust by FA in LPS MODE */
970 if (fa_cnt->cnt_all > DM_DIG_FA_TH2_LPS)
971 current_igi = current_igi + 4;
972 else if (fa_cnt->cnt_all > DM_DIG_FA_TH1_LPS)
973 current_igi = current_igi + 2;
974 else if (fa_cnt->cnt_all < DM_DIG_FA_TH0_LPS)
975 current_igi = current_igi - 2;
977 /* Lower bound checking */
979 /* RSSI Lower bound check */
980 if ((dm->rssi_min - 10) > DM_DIG_MIN_NIC)
981 rssi_lower = (dm->rssi_min - 10);
983 rssi_lower = DM_DIG_MIN_NIC;
985 /* Upper and Lower Bound checking */
986 if (current_igi > DM_DIG_MAX_NIC)
987 current_igi = DM_DIG_MAX_NIC;
988 else if (current_igi < rssi_lower)
989 current_igi = rssi_lower;
991 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): fa_cnt->cnt_all = %d\n", __func__,
993 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): dm->rssi_min = %d\n", __func__,
995 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi = 0x%x\n", __func__,
1000 current_igi); /* odm_write_dig(dm, dig_tab->cur_ig_value); */
1003 /* 3============================================================
1004 * 3 FASLE ALARM CHECK
1005 * 3============================================================
1008 void odm_false_alarm_counter_statistics(void *dm_void)
1010 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1011 struct false_alarm_stat *false_alm_cnt =
1012 (struct false_alarm_stat *)phydm_get_structure(
1013 dm, PHYDM_FALSEALMCNT);
1014 struct rt_adcsmp *adc_smp = &dm->adcsmp;
1017 if (!(dm->support_ability & ODM_BB_FA_CNT))
1020 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "%s()======>\n", __func__);
1022 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1023 /* hold ofdm counter */
1024 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31),
1025 1); /* hold page C counter */
1026 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31),
1027 1); /* hold page D counter */
1029 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11N,
1031 false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff);
1032 false_alm_cnt->cnt_sb_search_fail =
1033 ((ret_value & 0xffff0000) >> 16);
1035 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE2_11N,
1037 false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
1038 false_alm_cnt->cnt_parity_fail =
1039 ((ret_value & 0xffff0000) >> 16);
1041 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE3_11N,
1043 false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
1044 false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
1046 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE4_11N,
1048 false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
1050 false_alm_cnt->cnt_ofdm_fail =
1051 false_alm_cnt->cnt_parity_fail +
1052 false_alm_cnt->cnt_rate_illegal +
1053 false_alm_cnt->cnt_crc8_fail +
1054 false_alm_cnt->cnt_mcs_fail +
1055 false_alm_cnt->cnt_fast_fsync +
1056 false_alm_cnt->cnt_sb_search_fail;
1058 /* read CCK CRC32 counter */
1059 false_alm_cnt->cnt_cck_crc32_error = odm_get_bb_reg(
1060 dm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, MASKDWORD);
1061 false_alm_cnt->cnt_cck_crc32_ok = odm_get_bb_reg(
1062 dm, ODM_REG_CCK_CRC32_OK_CNT_11N, MASKDWORD);
1064 /* read OFDM CRC32 counter */
1065 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11N,
1067 false_alm_cnt->cnt_ofdm_crc32_error =
1068 (ret_value & 0xffff0000) >> 16;
1069 false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
1071 /* read HT CRC32 counter */
1073 odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD);
1074 false_alm_cnt->cnt_ht_crc32_error =
1075 (ret_value & 0xffff0000) >> 16;
1076 false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
1078 /* read VHT CRC32 counter */
1079 false_alm_cnt->cnt_vht_crc32_error = 0;
1080 false_alm_cnt->cnt_vht_crc32_ok = 0;
1083 /* hold cck counter */
1084 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
1085 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
1087 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_LSB_11N,
1089 false_alm_cnt->cnt_cck_fail = ret_value;
1091 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_MSB_11N,
1093 false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
1095 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11N,
1097 false_alm_cnt->cnt_cck_cca =
1098 ((ret_value & 0xFF) << 8) |
1099 ((ret_value & 0xFF00) >> 8);
1102 false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all;
1104 false_alm_cnt->cnt_all = (false_alm_cnt->cnt_fast_fsync +
1105 false_alm_cnt->cnt_sb_search_fail +
1106 false_alm_cnt->cnt_parity_fail +
1107 false_alm_cnt->cnt_rate_illegal +
1108 false_alm_cnt->cnt_crc8_fail +
1109 false_alm_cnt->cnt_mcs_fail +
1110 false_alm_cnt->cnt_cck_fail);
1112 false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca +
1113 false_alm_cnt->cnt_cck_cca;
1115 if (dm->support_ic_type >= ODM_RTL8188E) {
1116 /*reset false alarm counter registers*/
1117 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31),
1119 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31),
1121 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
1123 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
1126 /*update ofdm counter*/
1127 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31),
1128 0); /*update page C counter*/
1129 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31),
1130 0); /*update page D counter*/
1132 /*reset CCK CCA counter*/
1133 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1134 BIT(13) | BIT(12), 0);
1135 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1136 BIT(13) | BIT(12), 2);
1138 /*reset CCK FA counter*/
1139 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1140 BIT(15) | BIT(14), 0);
1141 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N,
1142 BIT(15) | BIT(14), 2);
1144 /*reset CRC32 counter*/
1145 odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 1);
1146 odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 0);
1149 /* Get debug port 0 */
1150 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
1151 false_alm_cnt->dbg_port0 =
1152 odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD);
1154 /* Get EDCCA flag */
1155 odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
1156 false_alm_cnt->edcca_flag =
1157 (bool)odm_get_bb_reg(dm, ODM_REG_RPT_11N, BIT(30));
1160 dm, ODM_COMP_FA_CNT,
1161 "[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n",
1162 false_alm_cnt->cnt_parity_fail,
1163 false_alm_cnt->cnt_rate_illegal,
1164 false_alm_cnt->cnt_crc8_fail,
1165 false_alm_cnt->cnt_mcs_fail,
1166 false_alm_cnt->cnt_fast_fsync,
1167 false_alm_cnt->cnt_sb_search_fail);
1170 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1173 /* read OFDM FA counter */
1174 false_alm_cnt->cnt_ofdm_fail =
1175 odm_get_bb_reg(dm, ODM_REG_OFDM_FA_11AC, MASKLWORD);
1177 /* Read CCK FA counter */
1178 false_alm_cnt->cnt_cck_fail =
1179 odm_get_bb_reg(dm, ODM_REG_CCK_FA_11AC, MASKLWORD);
1181 /* read CCK/OFDM CCA counter */
1183 odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11AC, MASKDWORD);
1184 false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff0000) >> 16;
1185 false_alm_cnt->cnt_cck_cca = ret_value & 0xffff;
1187 /* read CCK CRC32 counter */
1188 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CRC32_CNT_11AC,
1190 false_alm_cnt->cnt_cck_crc32_error =
1191 (ret_value & 0xffff0000) >> 16;
1192 false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff;
1194 /* read OFDM CRC32 counter */
1195 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11AC,
1197 false_alm_cnt->cnt_ofdm_crc32_error =
1198 (ret_value & 0xffff0000) >> 16;
1199 false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
1201 /* read HT CRC32 counter */
1202 ret_value = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11AC,
1204 false_alm_cnt->cnt_ht_crc32_error =
1205 (ret_value & 0xffff0000) >> 16;
1206 false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
1208 /* read VHT CRC32 counter */
1209 ret_value = odm_get_bb_reg(dm, ODM_REG_VHT_CRC32_CNT_11AC,
1211 false_alm_cnt->cnt_vht_crc32_error =
1212 (ret_value & 0xffff0000) >> 16;
1213 false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff;
1215 /* reset OFDM FA counter */
1216 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
1217 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
1219 /* reset CCK FA counter */
1220 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
1221 odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
1223 /* reset CCA counter */
1224 odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 1);
1225 odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 0);
1228 odm_get_bb_reg(dm, ODM_REG_BB_RX_PATH_11AC, BIT(28));
1229 if (cck_enable) { /* if(*dm->band_type == ODM_BAND_2_4G) */
1230 false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail +
1231 false_alm_cnt->cnt_cck_fail;
1232 false_alm_cnt->cnt_cca_all =
1233 false_alm_cnt->cnt_cck_cca +
1234 false_alm_cnt->cnt_ofdm_cca;
1236 false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail;
1237 false_alm_cnt->cnt_cca_all =
1238 false_alm_cnt->cnt_ofdm_cca;
1241 if (adc_smp->adc_smp_state == ADCSMP_STATE_IDLE) {
1242 if (phydm_set_bb_dbg_port(
1243 dm, BB_DBGPORT_PRIORITY_1,
1244 0x0)) { /*set debug port to 0x0*/
1245 false_alm_cnt->dbg_port0 =
1246 phydm_get_bb_dbg_port_value(dm);
1247 phydm_release_bb_dbg_port(dm);
1250 if (phydm_set_bb_dbg_port(
1251 dm, BB_DBGPORT_PRIORITY_1,
1252 0x209)) { /*set debug port to 0x0*/
1253 false_alm_cnt->edcca_flag =
1254 (bool)((phydm_get_bb_dbg_port_value(
1258 phydm_release_bb_dbg_port(dm);
1263 false_alm_cnt->cnt_crc32_error_all =
1264 false_alm_cnt->cnt_vht_crc32_error +
1265 false_alm_cnt->cnt_ht_crc32_error +
1266 false_alm_cnt->cnt_ofdm_crc32_error +
1267 false_alm_cnt->cnt_cck_crc32_error;
1268 false_alm_cnt->cnt_crc32_ok_all = false_alm_cnt->cnt_vht_crc32_ok +
1269 false_alm_cnt->cnt_ht_crc32_ok +
1270 false_alm_cnt->cnt_ofdm_crc32_ok +
1271 false_alm_cnt->cnt_cck_crc32_ok;
1273 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1274 "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
1275 false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca,
1276 false_alm_cnt->cnt_cca_all);
1278 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1279 "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
1280 false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail,
1281 false_alm_cnt->cnt_all);
1283 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1284 "[CCK] CRC32 {error, ok}= {%d, %d}\n",
1285 false_alm_cnt->cnt_cck_crc32_error,
1286 false_alm_cnt->cnt_cck_crc32_ok);
1287 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "[OFDM]CRC32 {error, ok}= {%d, %d}\n",
1288 false_alm_cnt->cnt_ofdm_crc32_error,
1289 false_alm_cnt->cnt_ofdm_crc32_ok);
1290 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1291 "[ HT ] CRC32 {error, ok}= {%d, %d}\n",
1292 false_alm_cnt->cnt_ht_crc32_error,
1293 false_alm_cnt->cnt_ht_crc32_ok);
1294 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1295 "[VHT] CRC32 {error, ok}= {%d, %d}\n",
1296 false_alm_cnt->cnt_vht_crc32_error,
1297 false_alm_cnt->cnt_vht_crc32_ok);
1298 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1299 "[VHT] CRC32 {error, ok}= {%d, %d}\n",
1300 false_alm_cnt->cnt_crc32_error_all,
1301 false_alm_cnt->cnt_crc32_ok_all);
1302 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT,
1303 "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n\n",
1304 false_alm_cnt->dbg_port0, false_alm_cnt->edcca_flag);
1307 /* 3============================================================
1308 * 3 CCK Packet Detect threshold
1309 * 3============================================================
1312 void odm_pause_cck_packet_detection(void *dm_void,
1313 enum phydm_pause_type pause_type,
1314 enum phydm_pause_level pause_level,
1315 u8 cck_pd_threshold)
1317 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1318 struct dig_thres *dig_tab = &dm->dm_dig_table;
1321 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
1324 if ((dig_tab->pause_cckpd_level == 0) &&
1325 (!(dm->support_ability & ODM_BB_CCK_PD) ||
1326 !(dm->support_ability & ODM_BB_FA_CNT))) {
1329 "Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n");
1333 if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
1334 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1335 "%s(): Return: Wrong pause level !!\n", __func__);
1339 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1340 "%s(): pause level = 0x%x, Current value = 0x%x\n",
1341 __func__, dig_tab->pause_cckpd_level, cck_pd_threshold);
1344 "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1345 __func__, dig_tab->pause_cckpd_value[7],
1346 dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5],
1347 dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3],
1348 dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1],
1349 dig_tab->pause_cckpd_value[0]);
1351 switch (pause_type) {
1352 /* Pause CCK Packet Detection threshold */
1354 /* Disable CCK PD */
1355 odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
1356 dm->support_ability & (~ODM_BB_CCK_PD));
1357 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1358 "%s(): Pause CCK packet detection threshold !!\n",
1361 /*Backup original CCK PD threshold decided by CCK PD mechanism*/
1362 if (dig_tab->pause_cckpd_level == 0) {
1363 dig_tab->cck_pd_backup = dig_tab->cur_cck_cca_thres;
1366 "%s(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n",
1367 __func__, dig_tab->cck_pd_backup,
1371 /* Update pause level */
1372 dig_tab->pause_cckpd_level =
1373 (dig_tab->pause_cckpd_level | BIT(pause_level));
1375 /* Record CCK PD threshold */
1376 dig_tab->pause_cckpd_value[pause_level] = cck_pd_threshold;
1378 /* Write new CCK PD threshold */
1379 if (BIT(pause_level + 1) > dig_tab->pause_cckpd_level) {
1380 odm_write_cck_cca_thres(dm, cck_pd_threshold);
1381 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1382 "%s(): CCKPD of higher level = 0x%x\n",
1383 __func__, cck_pd_threshold);
1387 /* Resume CCK Packet Detection threshold */
1388 case PHYDM_RESUME: {
1389 /* check if the level is illegal or not */
1390 if ((dig_tab->pause_cckpd_level & (BIT(pause_level))) != 0) {
1391 dig_tab->pause_cckpd_level =
1392 dig_tab->pause_cckpd_level &
1393 (~(BIT(pause_level)));
1394 dig_tab->pause_cckpd_value[pause_level] = 0;
1395 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1396 "%s(): Resume CCK PD !!\n", __func__);
1398 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1399 "%s(): Wrong resume level !!\n", __func__);
1404 if (dig_tab->pause_cckpd_level == 0) {
1405 /* Write backup IGI value */
1406 odm_write_cck_cca_thres(dm, dig_tab->cck_pd_backup);
1407 /* dig_tab->is_ignore_dig = true; */
1408 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1409 "%s(): Write original CCKPD = 0x%x\n",
1410 __func__, dig_tab->cck_pd_backup);
1413 odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
1414 dm->support_ability |
1419 if (BIT(pause_level) <= dig_tab->pause_cckpd_level)
1422 /* Calculate the maximum level now */
1423 for (max_level = (pause_level - 1); max_level >= 0;
1425 if ((dig_tab->pause_cckpd_level & BIT(max_level)) > 0)
1429 /* write CCKPD of lower level */
1430 odm_write_cck_cca_thres(dm,
1431 dig_tab->pause_cckpd_value[max_level]);
1432 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1433 "%s(): Write CCKPD (0x%x) of level (%d)\n",
1434 __func__, dig_tab->pause_cckpd_value[max_level],
1439 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n",
1444 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1445 "%s(): pause level = 0x%x, Current value = 0x%x\n",
1446 __func__, dig_tab->pause_cckpd_level, cck_pd_threshold);
1449 "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1450 __func__, dig_tab->pause_cckpd_value[7],
1451 dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5],
1452 dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3],
1453 dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1],
1454 dig_tab->pause_cckpd_value[0]);
1457 void odm_cck_packet_detection_thresh(void *dm_void)
1459 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1460 struct dig_thres *dig_tab = &dm->dm_dig_table;
1461 struct false_alarm_stat *false_alm_cnt =
1462 (struct false_alarm_stat *)phydm_get_structure(
1463 dm, PHYDM_FALSEALMCNT);
1464 u8 cur_cck_cca_thres = dig_tab->cur_cck_cca_thres, rssi_thd = 35;
1466 if ((!(dm->support_ability & ODM_BB_CCK_PD)) ||
1467 (!(dm->support_ability & ODM_BB_FA_CNT))) {
1468 ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: return==========\n");
1475 ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: ==========>\n");
1477 if (dig_tab->cck_fa_ma == 0xffffffff)
1478 dig_tab->cck_fa_ma = false_alm_cnt->cnt_cck_fail;
1480 dig_tab->cck_fa_ma =
1481 ((dig_tab->cck_fa_ma << 1) + dig_tab->cck_fa_ma +
1482 false_alm_cnt->cnt_cck_fail) >>
1485 ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: CCK FA moving average = %d\n",
1486 dig_tab->cck_fa_ma);
1488 if (dm->is_linked) {
1489 if (dm->rssi_min > rssi_thd) {
1490 cur_cck_cca_thres = 0xcd;
1491 } else if (dm->rssi_min > 20) {
1492 if (dig_tab->cck_fa_ma >
1493 ((DM_DIG_FA_TH1 >> 1) + (DM_DIG_FA_TH1 >> 3)))
1494 cur_cck_cca_thres = 0xcd;
1495 else if (dig_tab->cck_fa_ma < (DM_DIG_FA_TH0 >> 1))
1496 cur_cck_cca_thres = 0x83;
1497 } else if (dm->rssi_min > 7) {
1498 cur_cck_cca_thres = 0x83;
1500 cur_cck_cca_thres = 0x40;
1504 if (dig_tab->cck_fa_ma > 0x400)
1505 cur_cck_cca_thres = 0x83;
1506 else if (dig_tab->cck_fa_ma < 0x200)
1507 cur_cck_cca_thres = 0x40;
1511 odm_write_cck_cca_thres(dm, cur_cck_cca_thres);
1514 ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: cck_cca_th=((0x%x))\n\n",
1518 void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres)
1520 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1521 struct dig_thres *dig_tab = &dm->dm_dig_table;
1523 if (dig_tab->cur_cck_cca_thres !=
1524 cur_cck_cca_thres) { /* modify by Guo.Mingzhi 2012-01-03 */
1525 odm_write_1byte(dm, ODM_REG(CCK_CCA, dm), cur_cck_cca_thres);
1526 dig_tab->cck_fa_ma = 0xffffffff;
1528 dig_tab->pre_cck_cca_thres = dig_tab->cur_cck_cca_thres;
1529 dig_tab->cur_cck_cca_thres = cur_cck_cca_thres;
1532 bool phydm_dig_go_up_check(void *dm_void)