1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
6 ******************************************************************************/
8 #include "odm_precomp.h"
10 void odm_NHMCounterStatisticsInit(void *pDM_VOID)
12 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
14 /* PHY parameters initialize for n series */
15 rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x2710); /* 0x894[31:16]= 0x2710 Time duration for NHM unit: 4us, 0x2710 =40ms */
16 /* rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x4e20); 0x894[31:16]= 0x4e20 Time duration for NHM unit: 4us, 0x4e20 =80ms */
17 rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff); /* 0x890[31:16]= 0xffff th_9, th_10 */
18 /* rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c); 0x898 = 0xffffff5c th_3, th_2, th_1, th_0 */
19 rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52); /* 0x898 = 0xffffff52 th_3, th_2, th_1, th_0 */
20 rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); /* 0x89c = 0xffffffff th_7, th_6, th_5, th_4 */
21 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff); /* 0xe28[7:0]= 0xff th_8 */
22 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7); /* 0x890[9:8]=3 enable CCX */
23 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1); /* 0xc0c[7]= 1 max power among all RX ants */
26 void odm_NHMCounterStatistics(void *pDM_VOID)
28 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
31 odm_GetNHMCounterStatistics(pDM_Odm);
33 /* Reset NHM counter */
34 odm_NHMCounterStatisticsReset(pDM_Odm);
37 void odm_GetNHMCounterStatistics(void *pDM_VOID)
39 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
42 value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_NHM_CNT_11N, bMaskDWord);
44 pDM_Odm->NHM_cnt_0 = (u8)(value32 & bMaskByte0);
47 void odm_NHMCounterStatisticsReset(void *pDM_VOID)
49 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
51 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0);
52 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1);
55 void odm_NHMBBInit(void *pDM_VOID)
57 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
59 pDM_Odm->adaptivity_flag = 0;
60 pDM_Odm->tolerance_cnt = 3;
61 pDM_Odm->NHMLastTxOkcnt = 0;
62 pDM_Odm->NHMLastRxOkcnt = 0;
63 pDM_Odm->NHMCurTxOkcnt = 0;
64 pDM_Odm->NHMCurRxOkcnt = 0;
68 void odm_NHMBB(void *pDM_VOID)
70 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
72 /* struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; */
74 pDM_Odm->NHMCurTxOkcnt =
75 *(pDM_Odm->pNumTxBytesUnicast)-pDM_Odm->NHMLastTxOkcnt;
76 pDM_Odm->NHMCurRxOkcnt =
77 *(pDM_Odm->pNumRxBytesUnicast)-pDM_Odm->NHMLastRxOkcnt;
78 pDM_Odm->NHMLastTxOkcnt =
79 *(pDM_Odm->pNumTxBytesUnicast);
80 pDM_Odm->NHMLastRxOkcnt =
81 *(pDM_Odm->pNumRxBytesUnicast);
84 if ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u64)(pDM_Odm->NHMCurRxOkcnt<<2) + 1) { /* Tx > 4*Rx possible for adaptivity test */
85 if (pDM_Odm->NHM_cnt_0 >= 190 || pDM_Odm->adaptivity_flag == true) {
86 /* Enable EDCCA since it is possible running Adaptivity testing */
87 /* test_status = 1; */
88 pDM_Odm->adaptivity_flag = true;
89 pDM_Odm->tolerance_cnt = 0;
91 if (pDM_Odm->tolerance_cnt < 3)
92 pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
94 pDM_Odm->tolerance_cnt = 4;
95 /* test_status = 5; */
96 if (pDM_Odm->tolerance_cnt > 3) {
97 /* test_status = 3; */
98 pDM_Odm->adaptivity_flag = false;
102 if (pDM_Odm->adaptivity_flag == true && pDM_Odm->NHM_cnt_0 <= 200) {
103 /* test_status = 2; */
104 pDM_Odm->tolerance_cnt = 0;
106 if (pDM_Odm->tolerance_cnt < 3)
107 pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
109 pDM_Odm->tolerance_cnt = 4;
110 /* test_status = 5; */
111 if (pDM_Odm->tolerance_cnt > 3) {
112 /* test_status = 4; */
113 pDM_Odm->adaptivity_flag = false;
119 void odm_SearchPwdBLowerBound(void *pDM_VOID, u8 IGI_target)
121 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
125 s8 TH_L2H_dmc, TH_H2L_dmc;
128 IGI = 0x50; /* find H2L, L2H lower bound */
129 ODM_Write_DIG(pDM_Odm, IGI);
132 Diff = IGI_target-(s8)IGI;
133 TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
136 TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
137 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
138 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
143 for (cnt = 0; cnt < 20; cnt++) {
144 value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_RPT_11N, bMaskDWord);
147 pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
148 else if (value32 & BIT29)
149 pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
151 pDM_Odm->txEdcca0 = pDM_Odm->txEdcca0 + 1;
154 if (pDM_Odm->txEdcca1 > 5) {
156 TH_L2H_dmc = TH_L2H_dmc + 1;
159 TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
160 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
161 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
163 pDM_Odm->TxHangFlg = true;
164 pDM_Odm->txEdcca1 = 0;
165 pDM_Odm->txEdcca0 = 0;
167 if (TH_L2H_dmc == 10) {
169 pDM_Odm->TxHangFlg = false;
170 pDM_Odm->txEdcca1 = 0;
171 pDM_Odm->txEdcca0 = 0;
172 pDM_Odm->H2L_lb = TH_H2L_dmc;
173 pDM_Odm->L2H_lb = TH_L2H_dmc;
174 pDM_Odm->Adaptivity_IGI_upper = IGI;
178 pDM_Odm->TxHangFlg = false;
179 pDM_Odm->txEdcca1 = 0;
180 pDM_Odm->txEdcca0 = 0;
181 pDM_Odm->H2L_lb = TH_H2L_dmc;
182 pDM_Odm->L2H_lb = TH_L2H_dmc;
183 pDM_Odm->Adaptivity_IGI_upper = IGI;
188 void odm_AdaptivityInit(void *pDM_VOID)
190 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
192 if (pDM_Odm->Carrier_Sense_enable == false)
193 pDM_Odm->TH_L2H_ini = 0xf7; /* -7 */
195 pDM_Odm->TH_L2H_ini = 0xa;
197 pDM_Odm->AdapEn_RSSI = 20;
198 pDM_Odm->TH_EDCCA_HL_diff = 7;
200 pDM_Odm->IGI_Base = 0x32;
201 pDM_Odm->IGI_target = 0x1c;
202 pDM_Odm->ForceEDCCA = 0;
203 pDM_Odm->NHM_disable = false;
204 pDM_Odm->TxHangFlg = true;
205 pDM_Odm->txEdcca0 = 0;
206 pDM_Odm->txEdcca1 = 0;
209 pDM_Odm->Adaptivity_IGI_upper = 0;
210 odm_NHMBBInit(pDM_Odm);
212 PHY_SetBBReg(pDM_Odm->Adapter, REG_RD_CTRL, BIT11, 1); /* stop counting if EDCCA is asserted */
216 void odm_Adaptivity(void *pDM_VOID, u8 IGI)
218 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
219 s8 TH_L2H_dmc, TH_H2L_dmc;
221 bool EDCCA_State = false;
223 if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) {
227 if (*pDM_Odm->pBandWidth == ODM_BW20M) /* CHANNEL_WIDTH_20 */
228 IGI_target = pDM_Odm->IGI_Base;
229 else if (*pDM_Odm->pBandWidth == ODM_BW40M)
230 IGI_target = pDM_Odm->IGI_Base + 2;
232 IGI_target = pDM_Odm->IGI_Base;
233 pDM_Odm->IGI_target = (u8) IGI_target;
235 /* Search pwdB lower bound */
236 if (pDM_Odm->TxHangFlg == true) {
237 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208);
238 odm_SearchPwdBLowerBound(pDM_Odm, pDM_Odm->IGI_target);
241 if ((!pDM_Odm->bLinked) || (*pDM_Odm->pChannel > 149)) { /* Band4 doesn't need adaptivity */
242 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, 0x7f);
243 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, 0x7f);
247 if (!pDM_Odm->ForceEDCCA) {
248 if (pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI)
250 else if (pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5))
257 pDM_Odm->Carrier_Sense_enable == false &&
258 pDM_Odm->NHM_disable == false &&
259 pDM_Odm->TxHangFlg == false
264 Diff = IGI_target-(s8)IGI;
265 TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
269 TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
271 /* replace lower bound to prevent EDCCA always equal */
272 if (TH_H2L_dmc < pDM_Odm->H2L_lb)
273 TH_H2L_dmc = pDM_Odm->H2L_lb;
274 if (TH_L2H_dmc < pDM_Odm->L2H_lb)
275 TH_L2H_dmc = pDM_Odm->L2H_lb;
280 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
281 PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
284 void ODM_Write_DIG(void *pDM_VOID, u8 CurrentIGI)
286 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
287 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
289 if (pDM_DigTable->bStopDIG) {
293 if (pDM_DigTable->CurIGValue != CurrentIGI) {
294 /* 1 Check initial gain by upper bound */
295 if (!pDM_DigTable->bPSDInProgress) {
296 if (CurrentIGI > pDM_DigTable->rx_gain_range_max) {
297 CurrentIGI = pDM_DigTable->rx_gain_range_max;
302 /* 1 Set IGI value */
303 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
305 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
307 pDM_DigTable->CurIGValue = CurrentIGI;
314 enum ODM_Pause_DIG_TYPE PauseType,
318 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
319 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
323 (pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY) &&
324 pDM_Odm->TxHangFlg == true
330 !bPaused && (!(pDM_Odm->SupportAbility & ODM_BB_DIG) ||
331 !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
340 ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility & (~ODM_BB_DIG));
342 /* 2 Backup IGI value */
344 pDM_DigTable->IGIBackup = pDM_DigTable->CurIGValue;
348 /* 2 Write new IGI value */
349 ODM_Write_DIG(pDM_Odm, IGIValue);
355 /* 2 Write backup IGI value */
356 ODM_Write_DIG(pDM_Odm, pDM_DigTable->IGIBackup);
360 ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_DIG);
369 bool odm_DigAbort(void *pDM_VOID)
371 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
374 if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) {
379 if (!(pDM_Odm->SupportAbility & ODM_BB_DIG)) {
384 if (*(pDM_Odm->pbScanInProcess)) {
388 /* add by Neil Chen to avoid PSD is processing */
389 if (pDM_Odm->bDMInitialGainEnable == false) {
396 void odm_DIGInit(void *pDM_VOID)
398 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
399 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
401 pDM_DigTable->bStopDIG = false;
402 pDM_DigTable->bPSDInProgress = false;
403 pDM_DigTable->CurIGValue = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm));
404 pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW;
405 pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH;
406 pDM_DigTable->FALowThresh = DMfalseALARM_THRESH_LOW;
407 pDM_DigTable->FAHighThresh = DMfalseALARM_THRESH_HIGH;
408 pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
409 pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
410 pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
411 pDM_DigTable->PreCCK_CCAThres = 0xFF;
412 pDM_DigTable->CurCCK_CCAThres = 0x83;
413 pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC;
414 pDM_DigTable->LargeFAHit = 0;
415 pDM_DigTable->Recover_cnt = 0;
416 pDM_DigTable->bMediaConnect_0 = false;
417 pDM_DigTable->bMediaConnect_1 = false;
419 /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */
420 pDM_Odm->bDMInitialGainEnable = true;
422 pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
423 pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
425 /* To Initi BT30 IGI */
426 pDM_DigTable->BT30_CurIGI = 0x32;
428 pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
429 pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
434 void odm_DIG(void *pDM_VOID)
436 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
438 /* Common parameters */
439 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
440 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
441 bool FirstConnect, FirstDisConnect;
442 u8 DIG_MaxOfMin, DIG_Dynamic_MIN;
443 u8 dm_dig_max, dm_dig_min;
444 u8 CurrentIGI = pDM_DigTable->CurIGValue;
447 u8 Adap_IGI_Upper = 0;
448 u32 TxTp = 0, RxTp = 0;
449 bool bDFSBand = false;
450 bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false;
452 if (odm_DigAbort(pDM_Odm))
455 if (pDM_Odm->adaptivity_flag == true)
456 Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper;
459 /* 1 Update status */
460 DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
461 FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == false);
462 FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == true);
464 /* 1 Boundary Decision */
467 dm_dig_min = DM_DIG_MIN_NIC;
468 DIG_MaxOfMin = DM_DIG_MAX_AP;
470 /* 1 Adjust boundary by RSSI */
471 if (pDM_Odm->bLinked && bPerformance) {
472 /* 2 Modify DIG upper bound */
473 /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
474 if (pDM_Odm->bBtLimitedDig == 1) {
479 if ((pDM_Odm->RSSI_Min + offset) > dm_dig_max)
480 pDM_DigTable->rx_gain_range_max = dm_dig_max;
481 else if ((pDM_Odm->RSSI_Min + offset) < dm_dig_min)
482 pDM_DigTable->rx_gain_range_max = dm_dig_min;
484 pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset;
486 /* 2 Modify DIG lower bound */
487 /* if (pDM_Odm->bOneEntryOnly) */
489 if (pDM_Odm->RSSI_Min < dm_dig_min)
490 DIG_Dynamic_MIN = dm_dig_min;
491 else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
492 DIG_Dynamic_MIN = DIG_MaxOfMin;
494 DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
497 pDM_DigTable->rx_gain_range_max = dm_dig_max;
498 DIG_Dynamic_MIN = dm_dig_min;
501 /* 1 Force Lower Bound for AntDiv */
502 if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) {
503 if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
505 pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV ||
506 pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||
507 pDM_Odm->AntDivType == S0S1_SW_ANTDIV
509 if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin)
510 DIG_Dynamic_MIN = DIG_MaxOfMin;
512 DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max;
517 /* 1 Modify DIG lower bound, deal with abnormal case */
518 /* 2 Abnormal false alarm case */
519 if (FirstDisConnect) {
520 pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN;
521 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
523 pDM_DigTable->rx_gain_range_min =
524 odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI);
526 if (pDM_Odm->bLinked && !FirstConnect) {
528 (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
531 pDM_DigTable->rx_gain_range_min = dm_dig_min;
535 /* 2 Abnormal lower bound case */
536 if (pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) {
537 pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
541 /* 1 False alarm threshold decision */
542 odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres);
544 /* 1 Adjust initial gain by false alarm */
545 if (pDM_Odm->bLinked && bPerformance) {
547 if (bFirstTpTarget || FirstConnect) {
548 pDM_DigTable->LargeFAHit = 0;
550 if (pDM_Odm->RSSI_Min < DIG_MaxOfMin) {
551 if (CurrentIGI < pDM_Odm->RSSI_Min)
552 CurrentIGI = pDM_Odm->RSSI_Min;
554 if (CurrentIGI < DIG_MaxOfMin)
555 CurrentIGI = DIG_MaxOfMin;
559 if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
560 CurrentIGI = CurrentIGI + 4;
561 else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
562 CurrentIGI = CurrentIGI + 2;
563 else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
564 CurrentIGI = CurrentIGI - 2;
567 (pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
568 (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) &&
569 (pDM_Odm->bsta_state)
571 CurrentIGI = pDM_DigTable->rx_gain_range_min;
576 if (FirstDisConnect || bFirstCoverage) {
577 CurrentIGI = dm_dig_min;
579 if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
580 CurrentIGI = CurrentIGI + 4;
581 else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
582 CurrentIGI = CurrentIGI + 2;
583 else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
584 CurrentIGI = CurrentIGI - 2;
588 /* 1 Check initial gain by upper/lower bound */
589 if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
590 CurrentIGI = pDM_DigTable->rx_gain_range_min;
592 if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
593 CurrentIGI = pDM_DigTable->rx_gain_range_max;
595 /* 1 Force upper bound and lower bound for adaptivity */
597 pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY &&
598 pDM_Odm->adaptivity_flag == true
600 if (CurrentIGI > Adap_IGI_Upper)
601 CurrentIGI = Adap_IGI_Upper;
603 if (pDM_Odm->IGI_LowerBound != 0) {
604 if (CurrentIGI < pDM_Odm->IGI_LowerBound)
605 CurrentIGI = pDM_Odm->IGI_LowerBound;
610 /* 1 Update status */
611 if (pDM_Odm->bBtHsOperation) {
612 if (pDM_Odm->bLinked) {
613 if (pDM_DigTable->BT30_CurIGI > (CurrentIGI))
614 ODM_Write_DIG(pDM_Odm, CurrentIGI);
616 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);
618 pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
619 pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
621 if (pDM_Odm->bLinkInProcess)
622 ODM_Write_DIG(pDM_Odm, 0x1c);
623 else if (pDM_Odm->bBtConnectProcess)
624 ODM_Write_DIG(pDM_Odm, 0x28);
626 ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
628 } else { /* BT is not using */
629 ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
630 pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
631 pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
635 void odm_DIGbyRSSI_LPS(void *pDM_VOID)
637 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
638 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
640 u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
641 u8 CurrentIGI = pDM_Odm->RSSI_Min;
643 CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
645 /* Using FW PS mode to make IGI */
646 /* Adjust by FA in LPS MODE */
647 if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
648 CurrentIGI = CurrentIGI+4;
649 else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
650 CurrentIGI = CurrentIGI+2;
651 else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
652 CurrentIGI = CurrentIGI-2;
655 /* Lower bound checking */
657 /* RSSI Lower bound check */
658 if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC)
659 RSSI_Lower = pDM_Odm->RSSI_Min-10;
661 RSSI_Lower = DM_DIG_MIN_NIC;
663 /* Upper and Lower Bound checking */
664 if (CurrentIGI > DM_DIG_MAX_NIC)
665 CurrentIGI = DM_DIG_MAX_NIC;
666 else if (CurrentIGI < RSSI_Lower)
667 CurrentIGI = RSSI_Lower;
669 ODM_Write_DIG(pDM_Odm, CurrentIGI);
670 /* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */
673 /* 3 ============================================================ */
674 /* 3 FASLE ALARM CHECK */
675 /* 3 ============================================================ */
677 void odm_FalseAlarmCounterStatistics(void *pDM_VOID)
679 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
680 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
683 if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
686 /* hold ofdm counter */
687 /* hold page C counter */
688 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1);
689 /* hold page D counter */
690 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1);
692 ret_value = PHY_QueryBBReg(
693 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord
695 FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
696 FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
698 ret_value = PHY_QueryBBReg(
699 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord
701 FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
702 FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
704 ret_value = PHY_QueryBBReg(
705 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord
707 FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
708 FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
710 ret_value = PHY_QueryBBReg(
711 pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord
713 FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
715 FalseAlmCnt->Cnt_Ofdm_fail =
716 FalseAlmCnt->Cnt_Parity_Fail +
717 FalseAlmCnt->Cnt_Rate_Illegal +
718 FalseAlmCnt->Cnt_Crc8_fail +
719 FalseAlmCnt->Cnt_Mcs_fail +
720 FalseAlmCnt->Cnt_Fast_Fsync +
721 FalseAlmCnt->Cnt_SB_Search_fail;
724 /* hold cck counter */
725 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1);
726 PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1);
728 ret_value = PHY_QueryBBReg(
729 pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0
731 FalseAlmCnt->Cnt_Cck_fail = ret_value;
733 ret_value = PHY_QueryBBReg(
734 pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3
736 FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8;
738 ret_value = PHY_QueryBBReg(
739 pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord
741 FalseAlmCnt->Cnt_CCK_CCA =
742 ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
745 FalseAlmCnt->Cnt_all = (
746 FalseAlmCnt->Cnt_Fast_Fsync +
747 FalseAlmCnt->Cnt_SB_Search_fail +
748 FalseAlmCnt->Cnt_Parity_Fail +
749 FalseAlmCnt->Cnt_Rate_Illegal +
750 FalseAlmCnt->Cnt_Crc8_fail +
751 FalseAlmCnt->Cnt_Mcs_fail +
752 FalseAlmCnt->Cnt_Cck_fail
755 FalseAlmCnt->Cnt_CCA_all =
756 FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
760 void odm_FAThresholdCheck(
769 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
771 if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) {
773 dm_FA_thres[0] = DM_DIG_FA_TH0;
774 dm_FA_thres[1] = DM_DIG_FA_TH1;
775 dm_FA_thres[2] = DM_DIG_FA_TH2;
777 dm_FA_thres[0] = 2000;
778 dm_FA_thres[1] = 4000;
779 dm_FA_thres[2] = 5000;
783 u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI)
785 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
786 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
787 struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
788 u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min;
790 if (pFalseAlmCnt->Cnt_all > 10000) {
791 if (pDM_DigTable->LargeFAHit != 3)
792 pDM_DigTable->LargeFAHit++;
794 /* if (pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) */
795 if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
796 pDM_DigTable->ForbiddenIGI = CurrentIGI;
797 /* pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; */
798 pDM_DigTable->LargeFAHit = 1;
801 if (pDM_DigTable->LargeFAHit >= 3) {
802 if ((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max)
803 rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
805 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
806 pDM_DigTable->Recover_cnt = 1800;
809 if (pDM_DigTable->Recover_cnt != 0) {
810 pDM_DigTable->Recover_cnt--;
812 if (pDM_DigTable->LargeFAHit < 3) {
813 if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */
814 pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
815 rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
817 pDM_DigTable->ForbiddenIGI -= 2;
818 rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
821 pDM_DigTable->LargeFAHit = 0;
825 return rx_gain_range_min;
829 /* 3 ============================================================ */
830 /* 3 CCK Packet Detect Threshold */
831 /* 3 ============================================================ */
833 void odm_CCKPacketDetectionThresh(void *pDM_VOID)
835 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
836 struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
841 !(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) ||
842 !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)
850 if (pDM_Odm->bLinked) {
851 if (pDM_Odm->RSSI_Min > 25)
852 CurCCK_CCAThres = 0xcd;
853 else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10))
854 CurCCK_CCAThres = 0x83;
856 if (FalseAlmCnt->Cnt_Cck_fail > 1000)
857 CurCCK_CCAThres = 0x83;
859 CurCCK_CCAThres = 0x40;
862 if (FalseAlmCnt->Cnt_Cck_fail > 1000)
863 CurCCK_CCAThres = 0x83;
865 CurCCK_CCAThres = 0x40;
868 ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
871 void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres)
873 struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
874 struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
876 /* modify by Guo.Mingzhi 2012-01-03 */
877 if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
878 rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres);
880 pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
881 pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;