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