1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2016 Realtek Corporation.
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
11 * Larry Finger <Larry.Finger@lwfinger.net>
13 *****************************************************************************/
15 /* ************************************************************
17 * *************************************************************/
18 #include "mp_precomp.h"
19 #include "phydm_precomp.h"
21 static int get_igi_for_diff(int);
23 static inline void phydm_check_ap_write_dig(struct phy_dm_struct *dm,
26 switch (*dm->one_path_cca) {
28 odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
31 if (dm->rf_type > ODM_1T1R)
32 odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm),
36 odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm),
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));
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),
52 static inline u8 phydm_get_current_igi(u8 dig_max_of_min, u8 rssi_min,
55 if (rssi_min < dig_max_of_min) {
56 if (current_igi < rssi_min)
59 if (current_igi < dig_max_of_min)
60 return dig_max_of_min;
65 void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type,
68 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
69 struct dig_thres *dig_tab = &dm->dm_dig_table;
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) {
82 dig_tab->backoff_val = (u8)dm_value;
83 } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
86 dig_tab->rx_gain_range_min = (u8)dm_value;
87 } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
90 dig_tab->rx_gain_range_max = (u8)dm_value;
92 } /* dm_change_dynamic_init_gain_thresh */
94 static int get_igi_for_diff(int value_IGI)
96 #define ONERCCA_LOW_TH 0x30
97 #define ONERCCA_LOW_DIFF 8
99 if (value_IGI < ONERCCA_LOW_TH) {
100 if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF)
101 return ONERCCA_LOW_TH;
103 return value_IGI + ONERCCA_LOW_DIFF;
109 static void odm_fa_threshold_check(void *dm_void, bool is_dfs_band,
110 bool is_performance, u32 rx_tp, u32 tx_tp,
113 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
115 if (dm->is_linked && (is_performance || is_dfs_band)) {
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;
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;
127 dm_FA_thres[0] = 2000;
128 dm_FA_thres[1] = 4000;
129 dm_FA_thres[2] = 5000;
134 static u8 odm_forbidden_igi_check(void *dm_void, u8 dig_dynamic_min,
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;
144 if (dig_tab->large_fa_timeout) {
145 if (--dig_tab->large_fa_timeout == 0)
146 dig_tab->large_fa_hit = 0;
149 if (fa_cnt->cnt_all > 10000) {
150 ODM_RT_TRACE(dm, ODM_COMP_DIG,
151 "%s(): Abnormally false alarm case.\n", __func__);
153 if (dig_tab->large_fa_hit != 3)
154 dig_tab->large_fa_hit++;
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;
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;
168 (dig_tab->forbidden_igi + 2);
169 dig_tab->recover_cnt = 1800;
172 "%s(): Abnormally false alarm case: recover_cnt = %d\n",
173 __func__, dig_tab->recover_cnt);
177 else if (fa_cnt->cnt_all > 2000) {
178 ODM_RT_TRACE(dm, ODM_COMP_DIG,
179 "Abnormally false alarm case.\n");
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);
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++;
194 if (dig_tab->forbidden_igi < current_igi) {
197 "Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n",
198 dig_tab->forbidden_igi, current_igi);
200 dig_tab->forbidden_igi = current_igi;
201 dig_tab->large_fa_hit = 1;
202 dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT;
206 if (dig_tab->large_fa_hit >= 3) {
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);
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;
218 (dig_tab->forbidden_igi + 1);
220 dig_tab->recover_cnt = 1200;
223 "Abnormally false alarm case: recover_cnt = %d, rx_gain_range_min = 0x%x\n",
224 dig_tab->recover_cnt, rx_gain_range_min);
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;
235 if (dig_tab->large_fa_hit >= 3) {
236 dig_tab->large_fa_hit = 0;
237 return rx_gain_range_min;
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",
249 if (dig_tab->large_fa_hit == 0) {
250 dig_tab->forbidden_igi -= 2;
252 (dig_tab->forbidden_igi + 2);
255 "%s(): Normal Case: Approach Lower Bound\n",
261 return rx_gain_range_min;
264 static void phydm_set_big_jump_step(void *dm_void, u8 current_igi)
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};
271 if (dig_tab->enable_adjust_big_jump == 0)
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]) {
280 } else if (i == dig_tab->big_jump_step1) {
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);
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]);
295 void odm_write_dig(void *dm_void, u8 current_igi)
297 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
298 struct dig_thres *dig_tab = &dm->dm_dig_table;
300 if (dig_tab->is_stop_dig) {
301 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Stop Writing IGI\n",
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));
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) {
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;
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;
326 "%s(): adaptivity case: Force upper bound to 0x%x !!!!!!\n",
327 __func__, current_igi);
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);
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,
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);
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),
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);
359 } else if (dm->support_platform & (ODM_AP)) {
360 phydm_check_ap_write_dig(dm, current_igi);
363 dig_tab->cur_ig_value = current_igi;
366 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi(0x%02x).\n", __func__,
370 void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type,
371 enum phydm_pause_level pause_level, u8 igi_value)
373 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
374 struct dig_thres *dig_tab = &dm->dm_dig_table;
377 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
380 if (dig_tab->pause_dig_level == 0 &&
381 (!(dm->support_ability & ODM_BB_DIG) ||
382 !(dm->support_ability & ODM_BB_FA_CNT))) {
385 "%s(): Return: support_ability DIG or FA is disabled !!\n",
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__);
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);
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]);
408 switch (pause_type) {
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",
417 /* Backup IGI value */
418 if (dig_tab->pause_dig_level == 0) {
419 dig_tab->igi_backup = dig_tab->cur_ig_value;
422 "%s(): Backup IGI = 0x%x, new IGI = 0x%x\n",
423 __func__, dig_tab->igi_backup, igi_value);
426 /* Record IGI value */
427 dig_tab->pause_dig_value[pause_level] = igi_value;
429 /* Update pause level */
430 dig_tab->pause_dig_level =
431 (dig_tab->pause_dig_level | BIT(pause_level));
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);
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",
452 ODM_RT_TRACE(dm, ODM_COMP_DIG,
453 "%s(): Wrong resume level !!\n", __func__);
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);
467 odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
468 dm->support_ability | ODM_BB_DIG);
472 if (BIT(pause_level) <= dig_tab->pause_dig_level)
475 /* Calculate the maximum level now */
476 for (max_level = (pause_level - 1); max_level >= 0;
478 if ((dig_tab->pause_dig_level & BIT(max_level)) > 0)
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);
492 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n",
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);
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]);
510 static bool odm_dig_abort(void *dm_void)
512 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
513 struct dig_thres *dig_tab = &dm->dm_dig_table;
515 /* support_ability */
516 if (!(dm->support_ability & ODM_BB_FA_CNT)) {
519 "%s(): Return: support_ability ODM_BB_FA_CNT is disabled\n",
524 /* support_ability */
525 if (!(dm->support_ability & ODM_BB_DIG)) {
528 "%s(): Return: support_ability ODM_BB_DIG is disabled\n",
534 if (*dm->is_scan_in_process) {
535 ODM_RT_TRACE(dm, ODM_COMP_DIG,
536 "%s(): Return: In Scan Progress\n", __func__);
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",
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__);
557 void odm_dig_init(void *dm_void)
559 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
560 struct dig_thres *dig_tab = &dm->dm_dig_table;
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;
586 /*To initialize dm->is_dm_initial_gain_enable==false to avoid DIG err*/
587 dm->is_dm_initial_gain_enable = true;
589 dig_tab->dig_dynamic_min_0 = DM_DIG_MIN_NIC;
590 dig_tab->dig_dynamic_min_1 = DM_DIG_MIN_NIC;
592 /* To Initi BT30 IGI */
593 dig_tab->bt30_cur_igi = 0x32;
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;
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;
606 dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC;
607 dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC;
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;
617 } else if (dm->support_ic_type & ODM_RTL8197F) {
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;
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 */
633 void odm_DIG(void *dm_void)
635 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
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;
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;
653 if (odm_dig_abort(dm))
656 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG Start===>\n");
658 /* 1 Update status */
660 dig_dynamic_min = dig_tab->dig_dynamic_min_0;
661 first_connect = (dm->is_linked) && !dig_tab->is_media_connect_0;
663 (!dm->is_linked) && dig_tab->is_media_connect_0;
666 /* 1 Boundary Decision */
669 if (dm->support_ic_type >= ODM_RTL8188E)
672 dm_dig_max = DM_DIG_MAX_NIC;
674 if (dm->support_ic_type != ODM_RTL8821)
675 dm_dig_min = DM_DIG_MIN_NIC;
679 dig_max_of_min = DM_DIG_MAX_AP;
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)) {
686 if (*dm->band_width == ODM_BW20M)
687 dm_dig_min = DM_DIG_MIN_AP_DFS + 2;
689 dm_dig_min = DM_DIG_MIN_AP_DFS;
690 ODM_RT_TRACE(dm, ODM_COMP_DIG,
691 "DIG: ====== In DFS band ======\n");
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);
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) :
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) {
716 "DIG: Coex. case: Force upper bound to RSSI + %d\n",
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;
727 dig_tab->rx_gain_range_max = dm->rssi_min + offset;
729 /* 2 Modify DIG lower bound */
730 /* if(dm->is_one_entry_only) */
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;
737 dig_dynamic_min = dm->rssi_min;
740 dig_dynamic_min = dm_dig_min;
743 "DIG: DFS band: Force lower bound to 0x%x after link\n",
748 if (is_performance && is_dfs_band) {
749 dig_tab->rx_gain_range_max = 0x28;
752 "DIG: DFS band: Force upper bound to 0x%x before link\n",
753 dig_tab->rx_gain_range_max);
756 dig_tab->rx_gain_range_max = DM_DIG_MAX_OF_MIN;
758 dig_tab->rx_gain_range_max = dm_dig_max;
760 dig_dynamic_min = dm_dig_min;
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;
772 dig_dynamic_min = (u8)dig_tab->ant_div_rssi_max;
775 "DIG: AntDiv case: Force lower bound to 0x%x\n",
777 ODM_RT_TRACE(dm, ODM_COMP_DIG,
778 "DIG: AntDiv case: rssi_max = 0x%x\n",
779 dig_tab->ant_div_rssi_max);
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);
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);
791 /* 1 Modify DIG lower bound, deal with abnormal case */
792 /* 2 Abnormal false alarm case */
794 dig_tab->rx_gain_range_min = dig_dynamic_min;
796 if (!dm->is_linked) {
797 dig_tab->rx_gain_range_min = dig_dynamic_min;
799 if (first_dis_connect)
800 dig_tab->forbidden_igi = dig_dynamic_min;
802 dig_tab->rx_gain_range_min = odm_forbidden_igi_check(
803 dm, dig_dynamic_min, current_igi);
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 &&
813 dig_tab->rx_gain_range_min = 0x1c;
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);
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;
827 "DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n",
828 dig_tab->rx_gain_range_min);
831 /* 1 False alarm threshold decision */
832 odm_fa_threshold_check(dm, is_dfs_band, is_performance, rx_tp, tx_tp,
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]);
838 /* 1 Adjust initial gain by false alarm */
839 if (dm->is_linked && is_performance) {
841 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI after link\n");
843 if (is_first_tp_target || (first_connect && is_performance)) {
844 dig_tab->large_fa_hit = 0;
847 u8 rssi = dm->rssi_min;
850 (dm->rssi_min > 0x28) ? 0x28 : rssi;
853 "DIG: DFS band: One-shot to 0x28 upmost\n");
855 current_igi = phydm_get_current_igi(
856 dig_max_of_min, dm->rssi_min,
862 "DIG: First connect case: IGI does on-shot to 0x%x\n",
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;
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 &&
877 current_igi = dig_tab->rx_gain_range_min;
880 "DIG: Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
881 dm->phy_dbg_info.num_qry_beacon_pkt,
887 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI before link\n");
889 if (first_dis_connect || is_first_coverage) {
890 current_igi = dm_dig_min;
893 "DIG: First disconnect case: IGI does on-shot to lower bound\n");
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;
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;
908 if (current_igi > dig_tab->rx_gain_range_max)
909 current_igi = dig_tab->rx_gain_range_max;
911 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: cur_ig_value=0x%x, TotalFA = %d\n",
912 current_igi, fa_cnt->cnt_all);
914 /* 1 Update status */
915 if (dm->is_bt_hs_operation) {
917 if (dig_tab->bt30_cur_igi > (current_igi))
918 odm_write_dig(dm, current_igi);
920 odm_write_dig(dm, dig_tab->bt30_cur_igi);
922 dig_tab->is_media_connect_0 = dm->is_linked;
923 dig_tab->dig_dynamic_min_0 = dig_dynamic_min;
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);
930 odm_write_dig(dm, dig_tab->bt30_cur_igi);
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;
937 ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG end\n");
940 void odm_dig_by_rssi_lps(void *dm_void)
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);
947 u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
948 u8 current_igi = dm->rssi_min;
950 if (odm_dig_abort(dm))
953 current_igi = current_igi + RSSI_OFFSET_DIG;
955 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()==>\n", __func__);
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;
966 /* Lower bound checking */
968 /* RSSI Lower bound check */
969 if ((dm->rssi_min - 10) > DM_DIG_MIN_NIC)
970 rssi_lower = (dm->rssi_min - 10);
972 rssi_lower = DM_DIG_MIN_NIC;
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;
980 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): fa_cnt->cnt_all = %d\n", __func__,
982 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): dm->rssi_min = %d\n", __func__,
984 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi = 0x%x\n", __func__,
989 current_igi); /* odm_write_dig(dm, dig_tab->cur_ig_value); */
992 /* 3============================================================
993 * 3 FASLE ALARM CHECK
994 * 3============================================================
997 void odm_false_alarm_counter_statistics(void *dm_void)
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;
1006 if (!(dm->support_ability & ODM_BB_FA_CNT))
1009 ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "%s()======>\n", __func__);
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 */
1018 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11N,
1020 false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff);
1021 false_alm_cnt->cnt_sb_search_fail =
1022 ((ret_value & 0xffff0000) >> 16);
1024 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE2_11N,
1026 false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
1027 false_alm_cnt->cnt_parity_fail =
1028 ((ret_value & 0xffff0000) >> 16);
1030 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE3_11N,
1032 false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
1033 false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
1035 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE4_11N,
1037 false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
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;
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);
1053 /* read OFDM CRC32 counter */
1054 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11N,
1056 false_alm_cnt->cnt_ofdm_crc32_error =
1057 (ret_value & 0xffff0000) >> 16;
1058 false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
1060 /* read HT CRC32 counter */
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;
1067 /* read VHT CRC32 counter */
1068 false_alm_cnt->cnt_vht_crc32_error = 0;
1069 false_alm_cnt->cnt_vht_crc32_ok = 0;
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);
1076 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_LSB_11N,
1078 false_alm_cnt->cnt_cck_fail = ret_value;
1080 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_MSB_11N,
1082 false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
1084 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11N,
1086 false_alm_cnt->cnt_cck_cca =
1087 ((ret_value & 0xFF) << 8) |
1088 ((ret_value & 0xFF00) >> 8);
1091 false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all;
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);
1101 false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca +
1102 false_alm_cnt->cnt_cck_cca;
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),
1108 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31),
1110 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
1112 odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27),
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*/
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);
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);
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);
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);
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));
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);
1159 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1162 /* read OFDM FA counter */
1163 false_alm_cnt->cnt_ofdm_fail =
1164 odm_get_bb_reg(dm, ODM_REG_OFDM_FA_11AC, MASKLWORD);
1166 /* Read CCK FA counter */
1167 false_alm_cnt->cnt_cck_fail =
1168 odm_get_bb_reg(dm, ODM_REG_CCK_FA_11AC, MASKLWORD);
1170 /* read CCK/OFDM CCA counter */
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;
1176 /* read CCK CRC32 counter */
1177 ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CRC32_CNT_11AC,
1179 false_alm_cnt->cnt_cck_crc32_error =
1180 (ret_value & 0xffff0000) >> 16;
1181 false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff;
1183 /* read OFDM CRC32 counter */
1184 ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11AC,
1186 false_alm_cnt->cnt_ofdm_crc32_error =
1187 (ret_value & 0xffff0000) >> 16;
1188 false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
1190 /* read HT CRC32 counter */
1191 ret_value = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11AC,
1193 false_alm_cnt->cnt_ht_crc32_error =
1194 (ret_value & 0xffff0000) >> 16;
1195 false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
1197 /* read VHT CRC32 counter */
1198 ret_value = odm_get_bb_reg(dm, ODM_REG_VHT_CRC32_CNT_11AC,
1200 false_alm_cnt->cnt_vht_crc32_error =
1201 (ret_value & 0xffff0000) >> 16;
1202 false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff;
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);
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);
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);
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;
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;
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);
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(
1247 phydm_release_bb_dbg_port(dm);
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;
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);
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);
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);
1296 /* 3============================================================
1297 * 3 CCK Packet Detect threshold
1298 * 3============================================================
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)
1306 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1307 struct dig_thres *dig_tab = &dm->dm_dig_table;
1310 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__,
1313 if (dig_tab->pause_cckpd_level == 0 &&
1314 (!(dm->support_ability & ODM_BB_CCK_PD) ||
1315 !(dm->support_ability & ODM_BB_FA_CNT))) {
1318 "Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n");
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__);
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);
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]);
1340 switch (pause_type) {
1341 /* Pause CCK Packet Detection threshold */
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",
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;
1355 "%s(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n",
1356 __func__, dig_tab->cck_pd_backup,
1360 /* Update pause level */
1361 dig_tab->pause_cckpd_level =
1362 (dig_tab->pause_cckpd_level | BIT(pause_level));
1364 /* Record CCK PD threshold */
1365 dig_tab->pause_cckpd_value[pause_level] = cck_pd_threshold;
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);
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__);
1387 ODM_RT_TRACE(dm, ODM_COMP_DIG,
1388 "%s(): Wrong resume level !!\n", __func__);
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);
1402 odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY,
1403 dm->support_ability |
1408 if (BIT(pause_level) <= dig_tab->pause_cckpd_level)
1411 /* Calculate the maximum level now */
1412 for (max_level = (pause_level - 1); max_level >= 0;
1414 if ((dig_tab->pause_cckpd_level & BIT(max_level)) > 0)
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],
1428 ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n",
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);
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]);
1446 void odm_cck_packet_detection_thresh(void *dm_void)
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;
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");
1464 ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: ==========>\n");
1466 if (dig_tab->cck_fa_ma == 0xffffffff)
1467 dig_tab->cck_fa_ma = false_alm_cnt->cnt_cck_fail;
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) >>
1474 ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: CCK FA moving average = %d\n",
1475 dig_tab->cck_fa_ma);
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;
1489 cur_cck_cca_thres = 0x40;
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;
1500 odm_write_cck_cca_thres(dm, cur_cck_cca_thres);
1503 ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: cck_cca_th=((0x%x))\n\n",
1507 void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres)
1509 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1510 struct dig_thres *dig_tab = &dm->dm_dig_table;
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;
1517 dig_tab->pre_cck_cca_thres = dig_tab->cur_cck_cca_thres;
1518 dig_tab->cur_cck_cca_thres = cur_cck_cca_thres;
1521 bool phydm_dig_go_up_check(void *dm_void)