/****************************************************************************** * * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * ******************************************************************************/ //============================================================ // include files //============================================================ #include "mp_precomp.h" #include "phydm_precomp.h" VOID ODM_ChangeDynamicInitGainThresh( IN PVOID pDM_VOID, IN u4Byte DM_Type, IN u4Byte DM_Value ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; if (DM_Type == DIG_TYPE_THRESH_HIGH) { pDM_DigTable->RssiHighThresh = DM_Value; } else if (DM_Type == DIG_TYPE_THRESH_LOW) { pDM_DigTable->RssiLowThresh = DM_Value; } else if (DM_Type == DIG_TYPE_ENABLE) { pDM_DigTable->Dig_Enable_Flag = TRUE; } else if (DM_Type == DIG_TYPE_DISABLE) { pDM_DigTable->Dig_Enable_Flag = FALSE; } else if (DM_Type == DIG_TYPE_BACKOFF) { if(DM_Value > 30) DM_Value = 30; pDM_DigTable->BackoffVal = (u1Byte)DM_Value; } else if(DM_Type == DIG_TYPE_RX_GAIN_MIN) { if(DM_Value == 0) DM_Value = 0x1; pDM_DigTable->rx_gain_range_min = (u1Byte)DM_Value; } else if(DM_Type == DIG_TYPE_RX_GAIN_MAX) { if(DM_Value > 0x50) DM_Value = 0x50; pDM_DigTable->rx_gain_range_max = (u1Byte)DM_Value; } } // DM_ChangeDynamicInitGainThresh // int getIGIForDiff(int value_IGI) { #define ONERCCA_LOW_TH 0x30 #define ONERCCA_LOW_DIFF 8 if (value_IGI < ONERCCA_LOW_TH) { if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF) return ONERCCA_LOW_TH; else return value_IGI + ONERCCA_LOW_DIFF; } else { return value_IGI; } } VOID odm_FAThresholdCheck( IN PVOID pDM_VOID, IN BOOLEAN bDFSBand, IN BOOLEAN bPerformance, IN u4Byte RxTp, IN u4Byte TxTp, OUT u4Byte* dm_FA_thres ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; if(pDM_Odm->bLinked && (bPerformance||bDFSBand)) { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) /*For AP*/ if ((RxTp>>2) > TxTp && RxTp < 10000 && RxTp > 500) { /*10Mbps & 0.5Mbps*/ dm_FA_thres[0] = 0x080; dm_FA_thres[1] = 0x100; dm_FA_thres[2] = 0x200; } else { dm_FA_thres[0] = 0x100; dm_FA_thres[1] = 0x200; dm_FA_thres[2] = 0x300; } #else /*For NIC*/ dm_FA_thres[0] = DM_DIG_FA_TH0; dm_FA_thres[1] = DM_DIG_FA_TH1; dm_FA_thres[2] = DM_DIG_FA_TH2; #endif } else { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_CE)) if(bDFSBand) { // For DFS band and no link dm_FA_thres[0] = 250; dm_FA_thres[1] = 1000; dm_FA_thres[2] = 2000; } else #endif { dm_FA_thres[0] = 2000; dm_FA_thres[1] = 4000; dm_FA_thres[2] = 5000; } } return; } u1Byte odm_ForbiddenIGICheck( IN PVOID pDM_VOID, IN u1Byte DIG_Dynamic_MIN, IN u1Byte CurrentIGI ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); u1Byte rx_gain_range_min = pDM_DigTable->rx_gain_range_min; if (pDM_DigTable->LargeFA_Timeout) { if (--pDM_DigTable->LargeFA_Timeout == 0) pDM_DigTable->LargeFAHit = 0; } if (pFalseAlmCnt->Cnt_all > 10000) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case.\n")); if(pDM_DigTable->LargeFAHit != 3) pDM_DigTable->LargeFAHit++; if(pDM_DigTable->ForbiddenIGI < CurrentIGI)//if(pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue) { pDM_DigTable->ForbiddenIGI = CurrentIGI;//pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue; pDM_DigTable->LargeFAHit = 1; pDM_DigTable->LargeFA_Timeout = LARGE_FA_TIMEOUT; } if(pDM_DigTable->LargeFAHit >= 3) { if((pDM_DigTable->ForbiddenIGI + 2) > pDM_DigTable->rx_gain_range_max) rx_gain_range_min = pDM_DigTable->rx_gain_range_max; else rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); pDM_DigTable->Recover_cnt = 1800; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case: Recover_cnt = %d\n", pDM_DigTable->Recover_cnt)); } } else if (pFalseAlmCnt->Cnt_all > 2000) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Abnormally false alarm case.\n")); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Cnt_all=%d, Cnt_all_pre=%d, CurrentIGI=0x%x, PreIGValue=0x%x\n", pFalseAlmCnt->Cnt_all, pFalseAlmCnt->Cnt_all_pre, CurrentIGI, pDM_DigTable->PreIGValue)); /* pFalseAlmCnt->Cnt_all = 1.1875*pFalseAlmCnt->Cnt_all_pre */ if ((pFalseAlmCnt->Cnt_all > (pFalseAlmCnt->Cnt_all_pre + (pFalseAlmCnt->Cnt_all_pre >> 3) + (pFalseAlmCnt->Cnt_all_pre >> 4))) && (CurrentIGI < pDM_DigTable->PreIGValue)) { if (pDM_DigTable->LargeFAHit != 3) pDM_DigTable->LargeFAHit++; if (pDM_DigTable->ForbiddenIGI < CurrentIGI) { /*if(pDM_DigTable->ForbiddenIGI < pDM_DigTable->CurIGValue)*/ ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Updating ForbiddenIGI by CurrentIGI, ForbiddenIGI=0x%x, CurrentIGI=0x%x\n", pDM_DigTable->ForbiddenIGI, CurrentIGI)); pDM_DigTable->ForbiddenIGI = CurrentIGI; /*pDM_DigTable->ForbiddenIGI = pDM_DigTable->CurIGValue;*/ pDM_DigTable->LargeFAHit = 1; pDM_DigTable->LargeFA_Timeout = LARGE_FA_TIMEOUT; } } if (pDM_DigTable->LargeFAHit >= 3) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, ForbiddenIGI=0x%x\n", pDM_DigTable->rx_gain_range_max, rx_gain_range_min, pDM_DigTable->ForbiddenIGI)); if ((pDM_DigTable->ForbiddenIGI + 1) > pDM_DigTable->rx_gain_range_max) rx_gain_range_min = pDM_DigTable->rx_gain_range_max; else rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); pDM_DigTable->Recover_cnt = 1200; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Abnormally false alarm case: Recover_cnt = %d, rx_gain_range_min = 0x%x\n", pDM_DigTable->Recover_cnt, rx_gain_range_min)); } } else { if (pDM_DigTable->Recover_cnt != 0) { pDM_DigTable->Recover_cnt --; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Recover_cnt = %d\n", pDM_DigTable->Recover_cnt)); } else { if(pDM_DigTable->LargeFAHit < 3) { if((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) //DM_DIG_MIN) { pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; //DM_DIG_MIN; rx_gain_range_min = DIG_Dynamic_MIN; //DM_DIG_MIN; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: At Lower Bound\n")); } else { if (pDM_DigTable->LargeFAHit == 0) { pDM_DigTable->ForbiddenIGI -= 2; rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Approach Lower Bound\n")); } } } else { pDM_DigTable->LargeFAHit = 0; } } } return rx_gain_range_min; } VOID odm_InbandNoiseCalculate ( IN PVOID pDM_VOID ) { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; u1Byte IGIBackup, TimeCnt = 0, ValidCnt = 0; BOOLEAN bTimeout = TRUE; s1Byte sNoise_A, sNoise_B; s4Byte NoiseRpt_A = 0,NoiseRpt_B = 0; u4Byte tmp = 0; static u1Byte failCnt = 0; if(!(pDM_Odm->SupportICType & (ODM_RTL8192E))) return; if(pDM_Odm->RFType == ODM_1T1R || *(pDM_Odm->pOnePathCCA) != ODM_CCA_2R) return; if(!pDM_DigTable->bNoiseEst) return; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_InbandNoiseEstimate()========>\n")); //1 Set initial gain. IGIBackup = pDM_DigTable->CurIGValue; pDM_DigTable->IGIOffset_A = 0; pDM_DigTable->IGIOffset_B = 0; ODM_Write_DIG(pDM_Odm, 0x24); //1 Update idle time power report if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) ODM_SetBBReg(pDM_Odm, ODM_REG_TX_ANT_CTRL_11N, BIT25, 0x0); delay_ms(2); //1 Get noise power level while(1) { //2 Read Noise Floor Report if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) tmp = ODM_GetBBReg(pDM_Odm, 0x8f8, bMaskLWord); sNoise_A = (s1Byte)(tmp & 0xff); sNoise_B = (s1Byte)((tmp & 0xff00)>>8); //ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("sNoise_A = %d, sNoise_B = %d\n",sNoise_A, sNoise_B)); if((sNoise_A < 20 && sNoise_A >= -70) && (sNoise_B < 20 && sNoise_B >= -70)) { ValidCnt++; NoiseRpt_A += sNoise_A; NoiseRpt_B += sNoise_B; //ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("sNoise_A = %d, sNoise_B = %d\n",sNoise_A, sNoise_B)); } TimeCnt++; bTimeout = (TimeCnt >= 150)?TRUE:FALSE; if(ValidCnt == 20 || bTimeout) break; delay_ms(2); } //1 Keep idle time power report if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) ODM_SetBBReg(pDM_Odm, ODM_REG_TX_ANT_CTRL_11N, BIT25, 0x1); //1 Recover IGI ODM_Write_DIG(pDM_Odm, IGIBackup); //1 Calculate Noise Floor if(ValidCnt != 0) { NoiseRpt_A /= (ValidCnt<<1); NoiseRpt_B /= (ValidCnt<<1); } if(bTimeout) { NoiseRpt_A = 0; NoiseRpt_B = 0; failCnt ++; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("Noise estimate fail time = %d\n", failCnt)); if(failCnt == 3) { failCnt = 0; pDM_DigTable->bNoiseEst = FALSE; } } else { NoiseRpt_A = -110 + 0x24 + NoiseRpt_A -6; NoiseRpt_B = -110 + 0x24 + NoiseRpt_B -6; pDM_DigTable->bNoiseEst = FALSE; failCnt = 0; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("NoiseRpt_A = %d, NoiseRpt_B = %d\n", NoiseRpt_A, NoiseRpt_B)); } //1 Calculate IGI Offset if(NoiseRpt_A > NoiseRpt_B) { pDM_DigTable->IGIOffset_A = NoiseRpt_A - NoiseRpt_B; pDM_DigTable->IGIOffset_B = 0; } else { pDM_DigTable->IGIOffset_A = 0; pDM_DigTable->IGIOffset_B = NoiseRpt_B - NoiseRpt_A; } #endif return; } VOID odm_DigForBtHsMode( IN PVOID pDM_VOID ) { #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable=&pDM_Odm->DM_DigTable; u1Byte digForBtHs=0; u1Byte digUpBound=0x5a; if (pDM_Odm->bBtConnectProcess) { digForBtHs = 0x22; } else { // // Decide DIG value by BT HS RSSI. // digForBtHs = pDM_Odm->btHsRssi+4; //DIG Bound if(digForBtHs > digUpBound) digForBtHs = digUpBound; if(digForBtHs < 0x1c) digForBtHs = 0x1c; // update Current IGI pDM_DigTable->BT30_CurIGI = digForBtHs; } ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DigForBtHsMode() : set DigValue=0x%x\n", digForBtHs)); #endif } VOID phydm_setBigJumpStep( IN PVOID pDM_VOID, IN u1Byte CurrentIGI ) { #if (RTL8822B_SUPPORT == 1 || RTL8197F_SUPPORT == 1) PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; u1Byte step1[8] = {24, 30, 40, 50, 60, 70, 80, 90}; u1Byte i; if (pDM_DigTable->enableAdjustBigJump == 0) return; for (i = 0; i <= pDM_DigTable->bigJumpStep1; i++) { if ((CurrentIGI + step1[i]) > pDM_DigTable->bigJumpLmt[pDM_DigTable->agcTableIdx]) { if (i != 0) i = i - 1; break; } else if (i == pDM_DigTable->bigJumpStep1) break; } if (pDM_Odm->SupportICType & ODM_RTL8822B) ODM_SetBBReg(pDM_Odm, 0x8c8, 0xe, i); else if (pDM_Odm->SupportICType & ODM_RTL8197F) ODM_SetBBReg(pDM_Odm, ODM_REG_BB_AGC_SET_2_11N, 0xe, i); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_setBigJumpStep(): bigjump = %d (ori = 0x%d), LMT=0x%x\n", i, pDM_DigTable->bigJumpStep1, pDM_DigTable->bigJumpLmt[pDM_DigTable->agcTableIdx])); #endif } VOID ODM_Write_DIG( IN PVOID pDM_VOID, IN u1Byte CurrentIGI ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; if (pDM_DigTable->bStopDIG) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("ODM_Write_DIG(): Stop Writing IGI\n")); return; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("ODM_Write_DIG(): ODM_REG(IGI_A,pDM_Odm)=0x%x, ODM_BIT(IGI,pDM_Odm)=0x%x\n", ODM_REG(IGI_A,pDM_Odm),ODM_BIT(IGI,pDM_Odm))); //1 Check initial gain by upper bound if ((!pDM_DigTable->bPSDInProgress) && pDM_Odm->bLinked) { if (CurrentIGI > pDM_DigTable->rx_gain_range_max) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("ODM_Write_DIG(): CurrentIGI(0x%02x) is larger than upper bound !!\n", CurrentIGI)); CurrentIGI = pDM_DigTable->rx_gain_range_max; } if (pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY && pDM_Odm->adaptivity_flag == TRUE) { if(CurrentIGI > pDM_Odm->Adaptivity_IGI_upper) CurrentIGI = pDM_Odm->Adaptivity_IGI_upper; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("ODM_Write_DIG(): Adaptivity case: Force upper bound to 0x%x !!!!!!\n", CurrentIGI)); } } if(pDM_DigTable->CurIGValue != CurrentIGI) { #if (RTL8822B_SUPPORT == 1 | RTL8197F_SUPPORT == 1) /* Modify big jump step for 8822B and 8197F */ if (pDM_Odm->SupportICType & (ODM_RTL8822B|ODM_RTL8197F)) phydm_setBigJumpStep(pDM_Odm, CurrentIGI); #endif #if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) /* Set IGI value of CCK for new CCK AGC */ if (pDM_Odm->cck_new_agc) { if (pDM_Odm->SupportICType & ODM_IC_PHY_STATUE_NEW_TYPE) ODM_SetBBReg(pDM_Odm, 0xa0c, 0x00003f00, (CurrentIGI>>1)); } #endif /*Add by YuChen for USB IO too slow issue*/ if ((pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY) && (CurrentIGI > pDM_DigTable->CurIGValue)) Phydm_Adaptivity(pDM_Odm, CurrentIGI); //1 Set IGI value if (pDM_Odm->SupportPlatform & (ODM_WIN|ODM_CE)) { ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); if(pDM_Odm->RFType > ODM_1T1R) ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); #if (RTL8814A_SUPPORT == 1) if (pDM_Odm->SupportICType & ODM_RTL8814A) { ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_C,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_D,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); } #endif } else if (pDM_Odm->SupportPlatform & (ODM_AP)) { switch(*(pDM_Odm->pOnePathCCA)) { case ODM_CCA_2R: ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); if(pDM_Odm->RFType > ODM_1T1R) ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); #if (RTL8814A_SUPPORT == 1) if (pDM_Odm->SupportICType & ODM_RTL8814A) { ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_C,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_D,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); } #endif break; case ODM_CCA_1R_A: ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); if(pDM_Odm->RFType != ODM_1T1R) ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), getIGIForDiff(CurrentIGI)); break; case ODM_CCA_1R_B: ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm), getIGIForDiff(CurrentIGI)); if(pDM_Odm->RFType != ODM_1T1R) ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B,pDM_Odm), ODM_BIT(IGI,pDM_Odm), CurrentIGI); break; } } pDM_DigTable->CurIGValue = CurrentIGI; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("ODM_Write_DIG(): CurrentIGI(0x%02x).\n", CurrentIGI)); } VOID odm_PauseDIG( IN PVOID pDM_VOID, IN PHYDM_PAUSE_TYPE PauseType, IN PHYDM_PAUSE_LEVEL pause_level, IN u1Byte IGIValue ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG()=========> level = %d\n", pause_level)); if ((pDM_DigTable->pause_dig_level == 0) && (!(pDM_Odm->SupportAbility & ODM_BB_DIG) || !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Return: SupportAbility DIG or FA is disabled !!\n")); return; } if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Return: Wrong pause level !!\n")); return; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_dig_level, IGIValue)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", pDM_DigTable->pause_dig_value[7], pDM_DigTable->pause_dig_value[6], pDM_DigTable->pause_dig_value[5], pDM_DigTable->pause_dig_value[4], pDM_DigTable->pause_dig_value[3], pDM_DigTable->pause_dig_value[2], pDM_DigTable->pause_dig_value[1], pDM_DigTable->pause_dig_value[0])); switch (PauseType) { /* Pause DIG */ case PHYDM_PAUSE: { /* Disable DIG */ ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility & (~ODM_BB_DIG)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Pause DIG !!\n")); /* Backup IGI value */ if (pDM_DigTable->pause_dig_level == 0) { pDM_DigTable->IGIBackup = pDM_DigTable->CurIGValue; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Backup IGI = 0x%x, new IGI = 0x%x\n", pDM_DigTable->IGIBackup, IGIValue)); } /* Record IGI value */ pDM_DigTable->pause_dig_value[pause_level] = IGIValue; /* Update pause level */ pDM_DigTable->pause_dig_level = (pDM_DigTable->pause_dig_level | BIT(pause_level)); /* Write new IGI value */ if (BIT(pause_level + 1) > pDM_DigTable->pause_dig_level) { ODM_Write_DIG(pDM_Odm, IGIValue); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): IGI of higher level = 0x%x\n", IGIValue)); } break; } /* Resume DIG */ case PHYDM_RESUME: { /* check if the level is illegal or not */ if ((pDM_DigTable->pause_dig_level & (BIT(pause_level))) != 0) { pDM_DigTable->pause_dig_level = pDM_DigTable->pause_dig_level & (~(BIT(pause_level))); pDM_DigTable->pause_dig_value[pause_level] = 0; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Resume DIG !!\n")); } else { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Wrong resume level !!\n")); break; } /* Resume DIG */ if (pDM_DigTable->pause_dig_level == 0) { /* Write backup IGI value */ ODM_Write_DIG(pDM_Odm, pDM_DigTable->IGIBackup); pDM_DigTable->bIgnoreDIG = TRUE; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Write original IGI = 0x%x\n", pDM_DigTable->IGIBackup)); /* Enable DIG */ ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_DIG); break; } if (BIT(pause_level) > pDM_DigTable->pause_dig_level) { s1Byte max_level; /* Calculate the maximum level now */ for (max_level = (pause_level - 1); max_level >= 0; max_level--) { if ((pDM_DigTable->pause_dig_level & BIT(max_level)) > 0) break; } /* write IGI of lower level */ ODM_Write_DIG(pDM_Odm, pDM_DigTable->pause_dig_value[max_level]); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Write IGI (0x%x) of level (%d)\n", pDM_DigTable->pause_dig_value[max_level], max_level)); break; } break; } default: ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Wrong type !!\n")); break; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_dig_level, IGIValue)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", pDM_DigTable->pause_dig_value[7], pDM_DigTable->pause_dig_value[6], pDM_DigTable->pause_dig_value[5], pDM_DigTable->pause_dig_value[4], pDM_DigTable->pause_dig_value[3], pDM_DigTable->pause_dig_value[2], pDM_DigTable->pause_dig_value[1], pDM_DigTable->pause_dig_value[0])); } BOOLEAN odm_DigAbort( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) prtl8192cd_priv priv = pDM_Odm->priv; #elif(DM_ODM_SUPPORT_TYPE & ODM_WIN) PADAPTER pAdapter = pDM_Odm->Adapter; #endif //SupportAbility if(!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) { ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: SupportAbility ODM_BB_FA_CNT is disabled\n")); return TRUE; } //SupportAbility if(!(pDM_Odm->SupportAbility & ODM_BB_DIG)) { ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: SupportAbility ODM_BB_DIG is disabled\n")); return TRUE; } //ScanInProcess if(*(pDM_Odm->pbScanInProcess)) { ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: In Scan Progress \n")); return TRUE; } if(pDM_DigTable->bIgnoreDIG) { pDM_DigTable->bIgnoreDIG = FALSE; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Ignore DIG \n")); return TRUE; } //add by Neil Chen to avoid PSD is processing if(pDM_Odm->bDMInitialGainEnable == FALSE) { ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: PSD is Processing \n")); return TRUE; } #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) #if OS_WIN_FROM_WIN7(OS_VERSION) if(IsAPModeExist( pAdapter) && pAdapter->bInHctTest) { ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Is AP mode or In HCT Test \n")); return TRUE; } #endif if(pDM_Odm->bBtHsOperation) { odm_DigForBtHsMode(pDM_Odm); } #elif (DM_ODM_SUPPORT_TYPE == ODM_CE) #ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV if((pDM_Odm->bLinked) && (pDM_Odm->Adapter->registrypriv.force_igi !=0)) { printk("pDM_Odm->RSSI_Min=%d \n",pDM_Odm->RSSI_Min); ODM_Write_DIG(pDM_Odm,pDM_Odm->Adapter->registrypriv.force_igi); return TRUE; } #endif #else if (!(priv->up_time > 5)) { ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Not In DIG Operation Period \n")); return TRUE; } #endif return FALSE; } VOID odm_DIGInit( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); #endif u4Byte ret_value; u1Byte i; pDM_DigTable->bStopDIG = FALSE; pDM_DigTable->bIgnoreDIG = FALSE; pDM_DigTable->bPSDInProgress = FALSE; pDM_DigTable->CurIGValue = (u1Byte) ODM_GetBBReg(pDM_Odm, ODM_REG(IGI_A,pDM_Odm), ODM_BIT(IGI,pDM_Odm)); pDM_DigTable->PreIGValue = 0; pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; pDM_DigTable->FALowThresh = DM_FALSEALARM_THRESH_LOW; pDM_DigTable->FAHighThresh = DM_FALSEALARM_THRESH_HIGH; pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; pDM_DigTable->PreCCK_CCAThres = 0xFF; pDM_DigTable->CurCCK_CCAThres = 0x83; pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC; pDM_DigTable->LargeFAHit = 0; pDM_DigTable->LargeFA_Timeout = 0; pDM_DigTable->Recover_cnt = 0; pDM_DigTable->bMediaConnect_0 = FALSE; pDM_DigTable->bMediaConnect_1 = FALSE; //To Initialize pDM_Odm->bDMInitialGainEnable == FALSE to avoid DIG error pDM_Odm->bDMInitialGainEnable = TRUE; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) pDM_DigTable->DIG_Dynamic_MIN_0 = 0x25; pDM_DigTable->DIG_Dynamic_MIN_1 = 0x25; // For AP\ ADSL modified DIG pDM_DigTable->bTpTarget = FALSE; pDM_DigTable->bNoiseEst = TRUE; pDM_DigTable->IGIOffset_A = 0; pDM_DigTable->IGIOffset_B = 0; pDM_DigTable->TpTrainTH_min = 0; // For RTL8881A FalseAlmCnt->Cnt_Ofdm_fail_pre = 0; //Dyanmic EDCCA if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { ODM_SetBBReg(pDM_Odm, 0xC50, 0xFFFF0000, 0xfafd); } #else pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC; pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC; //To Initi BT30 IGI pDM_DigTable->BT30_CurIGI=0x32; ODM_Memory_Set(pDM_Odm, pDM_DigTable->pause_dig_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1)); pDM_DigTable->pause_dig_level = 0; ODM_Memory_Set(pDM_Odm, pDM_DigTable->pause_cckpd_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1)); pDM_DigTable->pause_cckpd_level = 0; #endif if(pDM_Odm->BoardType & (ODM_BOARD_EXT_PA|ODM_BOARD_EXT_LNA)) { pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; } else { pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; } #if (RTL8822B_SUPPORT == 1 || RTL8197F_SUPPORT == 1) pDM_DigTable->enableAdjustBigJump = 1; if (pDM_Odm->SupportICType & ODM_RTL8822B) { ret_value = ODM_GetBBReg(pDM_Odm, 0x8c8, bMaskLWord); pDM_DigTable->bigJumpStep1 = (u1Byte)(ret_value & 0xe) >> 1; pDM_DigTable->bigJumpStep2 = (u1Byte)(ret_value & 0x30)>>4; pDM_DigTable->bigJumpStep3 = (u1Byte)(ret_value & 0xc0)>>6; } else if (pDM_Odm->SupportICType & ODM_RTL8197F) { ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_BB_AGC_SET_2_11N, bMaskLWord); pDM_DigTable->bigJumpStep1 = (u1Byte)(ret_value & 0xe) >> 1; pDM_DigTable->bigJumpStep2 = (u1Byte)(ret_value & 0x30)>>4; pDM_DigTable->bigJumpStep3 = (u1Byte)(ret_value & 0xc0)>>6; } if (pDM_Odm->SupportICType & (ODM_RTL8822B|ODM_RTL8197F)) { for (i = 0; i < sizeof(pDM_DigTable->bigJumpLmt); i++) { if (pDM_DigTable->bigJumpLmt[i] == 0) pDM_DigTable->bigJumpLmt[i] = 0x64; /* Set -10dBm as default value */ } } #endif } VOID odm_DIG( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) PADAPTER pAdapter = pDM_Odm->Adapter; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pDM_Odm->Adapter); #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) prtl8192cd_priv priv = pDM_Odm->priv; PSTA_INFO_T pEntry; #endif // Common parameters pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); BOOLEAN FirstConnect,FirstDisConnect; u1Byte DIG_MaxOfMin, DIG_Dynamic_MIN; u1Byte dm_dig_max, dm_dig_min; u1Byte CurrentIGI = pDM_DigTable->CurIGValue; u1Byte offset; u4Byte dm_FA_thres[3]; u4Byte TxTp = 0, RxTp = 0; BOOLEAN DIG_GoUpCheck = TRUE; BOOLEAN bDFSBand = FALSE; BOOLEAN bPerformance = TRUE, bFirstTpTarget = FALSE, bFirstCoverage = FALSE; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) u4Byte TpTrainTH_MIN = DM_DIG_TP_Target_TH0; static u1Byte TimeCnt = 0; u1Byte i; #endif if(odm_DigAbort(pDM_Odm) == TRUE) return; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG()===========================>\n\n")); //1 Update status { DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == FALSE); FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == TRUE); } #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) //1 Noise Floor Estimate //pDM_DigTable->bNoiseEst = (FirstConnect)?TRUE:pDM_DigTable->bNoiseEst; //odm_InbandNoiseCalculate (pDM_Odm); //1 Mode decision if(pDM_Odm->bLinked) { //2 Calculate total TP for (i=0; ipODM_StaInfo[i]; if(IS_STA_VALID(pEntry)) { RxTp += (u4Byte)(pEntry->rx_byte_cnt_LowMAW>>7); TxTp += (u4Byte)(pEntry->tx_byte_cnt_LowMAW>>7); //Kbps } } ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): TX TP = %dkbps, RX TP = %dkbps\n", TxTp, RxTp)); } switch(pDM_Odm->priv->pshare->rf_ft_var.dig_cov_enable) { case 0: { bPerformance = TRUE; break; } case 1: { bPerformance = FALSE; break; } case 2: { if(pDM_Odm->bLinked) { if(pDM_DigTable->TpTrainTH_min > DM_DIG_TP_Target_TH0) TpTrainTH_MIN = pDM_DigTable->TpTrainTH_min; if(pDM_DigTable->TpTrainTH_min > DM_DIG_TP_Target_TH1) TpTrainTH_MIN = DM_DIG_TP_Target_TH1; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): TP training mode lower bound = %dkbps\n", TpTrainTH_MIN)); //2 Decide DIG mode by total TP if((TxTp + RxTp) > DM_DIG_TP_Target_TH1) // change to performance mode { bFirstTpTarget = (!pDM_DigTable->bTpTarget)?TRUE:FALSE; pDM_DigTable->bTpTarget = TRUE; bPerformance = TRUE; } else if((TxTp + RxTp) < TpTrainTH_MIN) // change to coverage mode { bFirstCoverage = (pDM_DigTable->bTpTarget)?TRUE:FALSE; if(TimeCnt < DM_DIG_TP_Training_Period) { pDM_DigTable->bTpTarget = FALSE; bPerformance = FALSE; TimeCnt++; } else { pDM_DigTable->bTpTarget = TRUE; bPerformance = TRUE; bFirstTpTarget = TRUE; TimeCnt = 0; } } else // remain previous mode { bPerformance = pDM_DigTable->bTpTarget; if(!bPerformance) { if(TimeCnt < DM_DIG_TP_Training_Period) TimeCnt++; else { pDM_DigTable->bTpTarget = TRUE; bPerformance = TRUE; bFirstTpTarget = TRUE; TimeCnt = 0; } } } if(!bPerformance) pDM_DigTable->TpTrainTH_min = RxTp + TxTp; } else { bPerformance = FALSE; pDM_DigTable->TpTrainTH_min = 0; } break; } default: bPerformance = TRUE; } ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("====== DIG mode = %d ======\n", pDM_Odm->priv->pshare->rf_ft_var.dig_cov_enable)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("====== bPerformance = %d ======\n", bPerformance)); #endif //1 Boundary Decision { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) //2 For AP\ADSL if(!bPerformance) { dm_dig_max = DM_DIG_MAX_AP_COVERAGR; dm_dig_min = DM_DIG_MIN_AP_COVERAGE; DIG_MaxOfMin = DM_DIG_MAX_OF_MIN_COVERAGE; } else { if (pDM_Odm->RFType == ODM_1T1R) dm_dig_max = DM_DIG_MAX_AP - 6; else dm_dig_max = DM_DIG_MAX_AP; dm_dig_min = DM_DIG_MIN_AP; DIG_MaxOfMin = DM_DIG_MAX_OF_MIN; } //4 TX2path if (priv->pmib->dot11RFEntry.tx2path && !bDFSBand && (*(pDM_Odm->pWirelessMode) == ODM_WM_B)) dm_dig_max = 0x2A; #if RTL8192E_SUPPORT #ifdef HIGH_POWER_EXT_LNA if ((pDM_Odm->SupportICType & (ODM_RTL8192E)) && (pDM_Odm->ExtLNA)) dm_dig_max = 0x42; #endif #endif if (pDM_Odm->IGI_LowerBound) { if (dm_dig_min < pDM_Odm->IGI_LowerBound) dm_dig_min = pDM_Odm->IGI_LowerBound; if (DIG_MaxOfMin < pDM_Odm->IGI_LowerBound) DIG_MaxOfMin = pDM_Odm->IGI_LowerBound; } if (pDM_Odm->IGI_UpperBound) { if (dm_dig_max > pDM_Odm->IGI_UpperBound) dm_dig_max = pDM_Odm->IGI_UpperBound; if (DIG_MaxOfMin > pDM_Odm->IGI_UpperBound) DIG_MaxOfMin = pDM_Odm->IGI_UpperBound; } #else //2 For WIN\CE if(pDM_Odm->SupportICType >= ODM_RTL8188E) dm_dig_max = 0x5A; else dm_dig_max = DM_DIG_MAX_NIC; if(pDM_Odm->SupportICType != ODM_RTL8821) dm_dig_min = DM_DIG_MIN_NIC; else dm_dig_min = 0x1C; DIG_MaxOfMin = DM_DIG_MAX_AP; #endif #if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_CE)) /* Modify lower bound for DFS band */ if ((((*pDM_Odm->pChannel >= 52) && (*pDM_Odm->pChannel <= 64)) || ((*pDM_Odm->pChannel >= 100) && (*pDM_Odm->pChannel <= 140))) #if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) && phydm_dfs_master_enabled(pDM_Odm) == TRUE #endif ) { bDFSBand = TRUE; if (*pDM_Odm->pBandWidth == ODM_BW20M) dm_dig_min = DM_DIG_MIN_AP_DFS+2; else dm_dig_min = DM_DIG_MIN_AP_DFS; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): ====== In DFS band ======\n")); } #endif } ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Absolutly upper bound = 0x%x, lower bound = 0x%x\n",dm_dig_max, dm_dig_min)); #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) if (pDM_Odm->pu1ForcedIgiLb && (0 < *pDM_Odm->pu1ForcedIgiLb)) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Force IGI lb to: 0x%02x !!!!!!\n", *pDM_Odm->pu1ForcedIgiLb)); dm_dig_min = *pDM_Odm->pu1ForcedIgiLb; dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) : (dm_dig_min + 1); } #endif //1 Adjust boundary by RSSI if(pDM_Odm->bLinked && bPerformance) { //2 Modify DIG upper bound #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) offset = 15; #else //4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT if ((pDM_Odm->SupportICType & (ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8812|ODM_RTL8821)) && (pDM_Odm->bBtLimitedDig == 1)) { offset = 10; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Coex. case: Force upper bound to RSSI + %d !!!!!!\n", offset)); } else offset = 15; #endif if((pDM_Odm->RSSI_Min + offset) > dm_dig_max ) pDM_DigTable->rx_gain_range_max = dm_dig_max; else if((pDM_Odm->RSSI_Min + offset) < dm_dig_min ) pDM_DigTable->rx_gain_range_max = dm_dig_min; else pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + offset; #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) //2 Modify DIG lower bound //if(pDM_Odm->bOneEntryOnly) { if(pDM_Odm->RSSI_Min < dm_dig_min) DIG_Dynamic_MIN = dm_dig_min; else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) DIG_Dynamic_MIN = DIG_MaxOfMin; else DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; #if (DM_ODM_SUPPORT_TYPE & ODM_CE) if (bDFSBand) { DIG_Dynamic_MIN = dm_dig_min; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: Force lower bound to 0x%x after link !!!!!!\n", dm_dig_min)); } #endif } #else { //4 For AP #ifdef __ECOS HAL_REORDER_BARRIER(); #else rmb(); #endif if (bDFSBand) { DIG_Dynamic_MIN = dm_dig_min; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: Force lower bound to 0x%x after link !!!!!!\n", dm_dig_min)); } else { if(pDM_Odm->RSSI_Min < dm_dig_min) DIG_Dynamic_MIN = dm_dig_min; else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) DIG_Dynamic_MIN = DIG_MaxOfMin; else DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; } } #endif } else { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_CE)) if(bPerformance && bDFSBand) { pDM_DigTable->rx_gain_range_max = 0x28; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: Force upper bound to 0x%x before link !!!!!!\n", pDM_DigTable->rx_gain_range_max)); } else #endif { if (bPerformance) pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_OF_MIN; else pDM_DigTable->rx_gain_range_max = dm_dig_max; } DIG_Dynamic_MIN = dm_dig_min; } //1 Force Lower Bound for AntDiv if(pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) { if((pDM_Odm->SupportICType & ODM_ANTDIV_SUPPORT) && (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) { if (pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV || pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV) { if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin) DIG_Dynamic_MIN = DIG_MaxOfMin; else DIG_Dynamic_MIN = (u1Byte) pDM_DigTable->AntDiv_RSSI_max; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Antenna diversity case: Force lower bound to 0x%x !!!!!!\n", DIG_Dynamic_MIN)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Antenna diversity case: RSSI_max = 0x%x !!!!!!\n", pDM_DigTable->AntDiv_RSSI_max)); } } } ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n", pDM_DigTable->rx_gain_range_max, DIG_Dynamic_MIN)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Link status: bLinked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n\n", pDM_Odm->bLinked, pDM_Odm->RSSI_Min, FirstConnect, FirstDisConnect)); //1 Modify DIG lower bound, deal with abnormal case //2 Abnormal false alarm case #if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_CE)) if(bDFSBand) { pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; } else #endif { if(!pDM_Odm->bLinked) { pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; if (FirstDisConnect) pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; } else pDM_DigTable->rx_gain_range_min = odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI); } //2 Abnormal # beacon case #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) if(pDM_Odm->bLinked && !FirstConnect) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Beacon Num (%d)\n", pDM_Odm->PhyDbgInfo.NumQryBeaconPkt)); if((pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && (pDM_Odm->bsta_state)) { pDM_DigTable->rx_gain_range_min = 0x1c; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x !!!!!!\n\n", pDM_Odm->PhyDbgInfo.NumQryBeaconPkt, pDM_DigTable->rx_gain_range_min)); } } #endif //2 Abnormal lower bound case if(pDM_DigTable->rx_gain_range_min > pDM_DigTable->rx_gain_range_max) { pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnrormal lower bound case: Force lower bound to 0x%x !!!!!!\n\n",pDM_DigTable->rx_gain_range_min)); } //1 False alarm threshold decision odm_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): False alarm threshold = %d, %d, %d \n\n", dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2])); //1 Adjust initial gain by false alarm if(pDM_Odm->bLinked && bPerformance) { //2 After link ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust IGI after link\n")); if(bFirstTpTarget || (FirstConnect && bPerformance)) { pDM_DigTable->LargeFAHit = 0; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_CE)) if(bDFSBand) { if(pDM_Odm->RSSI_Min > 0x28) CurrentIGI = 0x28; else CurrentIGI = pDM_Odm->RSSI_Min; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: One-shot to 0x28 upmost!!!!!!\n")); } else #endif { if(pDM_Odm->RSSI_Min < DIG_MaxOfMin) { if(CurrentIGI < pDM_Odm->RSSI_Min) CurrentIGI = pDM_Odm->RSSI_Min; } else { if(CurrentIGI < DIG_MaxOfMin) CurrentIGI = DIG_MaxOfMin; } #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) #if (RTL8812A_SUPPORT==1) if(pDM_Odm->SupportICType == ODM_RTL8812) ODM_ConfigBBWithHeaderFile(pDM_Odm, CONFIG_BB_AGC_TAB_DIFF); #endif #endif } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): First connect case: IGI does on-shot to 0x%x\n", CurrentIGI)); } else { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) if (priv->pshare->rf_ft_var.dig_upcheck_enable) DIG_GoUpCheck = phydm_DIG_GoUpCheck(pDM_Odm); #endif if((pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) && DIG_GoUpCheck) CurrentIGI = CurrentIGI + 4; else if ((pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) && DIG_GoUpCheck) CurrentIGI = CurrentIGI + 2; else if(pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) CurrentIGI = CurrentIGI - 2; //4 Abnormal # beacon case #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) if((pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) && (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) && (pDM_Odm->bsta_state)) { CurrentIGI = pDM_DigTable->rx_gain_range_min; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n", pDM_Odm->PhyDbgInfo.NumQryBeaconPkt, CurrentIGI)); } #endif } } else { //2 Before link ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust IGI before link\n")); if(FirstDisConnect || bFirstCoverage) { CurrentIGI = dm_dig_min; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): First disconnect case: IGI does on-shot to lower bound\n")); } else { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) if (priv->pshare->rf_ft_var.dig_upcheck_enable) DIG_GoUpCheck = phydm_DIG_GoUpCheck(pDM_Odm); #endif if((pFalseAlmCnt->Cnt_all > dm_FA_thres[2]) && DIG_GoUpCheck) CurrentIGI = CurrentIGI + 4; else if ((pFalseAlmCnt->Cnt_all > dm_FA_thres[1]) && DIG_GoUpCheck) CurrentIGI = CurrentIGI + 2; else if(pFalseAlmCnt->Cnt_all < dm_FA_thres[0]) CurrentIGI = CurrentIGI - 2; } } //1 Check initial gain by upper/lower bound if(CurrentIGI < pDM_DigTable->rx_gain_range_min) CurrentIGI = pDM_DigTable->rx_gain_range_min; if(CurrentIGI > pDM_DigTable->rx_gain_range_max) CurrentIGI = pDM_DigTable->rx_gain_range_max; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): CurIGValue=0x%x, TotalFA = %d\n\n", CurrentIGI, pFalseAlmCnt->Cnt_all)); //1 Update status { #if ((DM_ODM_SUPPORT_TYPE & ODM_WIN) || ((DM_ODM_SUPPORT_TYPE & ODM_CE) && (ODM_CONFIG_BT_COEXIST == 1))) if(pDM_Odm->bBtHsOperation) { if(pDM_Odm->bLinked) { if(pDM_DigTable->BT30_CurIGI > (CurrentIGI)) ODM_Write_DIG(pDM_Odm, CurrentIGI); else ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI); pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; } else { if(pDM_Odm->bLinkInProcess) ODM_Write_DIG(pDM_Odm, 0x1c); else if(pDM_Odm->bBtConnectProcess) ODM_Write_DIG(pDM_Odm, 0x28); else ODM_Write_DIG(pDM_Odm, pDM_DigTable->BT30_CurIGI);//ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); } } else // BT is not using #endif { ODM_Write_DIG(pDM_Odm, CurrentIGI);//ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; } } } VOID odm_DIGbyRSSI_LPS( IN PVOID pDM_VOID ) { #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); u1Byte RSSI_Lower=DM_DIG_MIN_NIC; //0x1E or 0x1C u1Byte CurrentIGI=pDM_Odm->RSSI_Min; if(odm_DigAbort(pDM_Odm) == TRUE) return; CurrentIGI=CurrentIGI+RSSI_OFFSET_DIG; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS()==>\n")); // Using FW PS mode to make IGI //Adjust by FA in LPS MODE if(pFalseAlmCnt->Cnt_all> DM_DIG_FA_TH2_LPS) CurrentIGI = CurrentIGI+4; else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS) CurrentIGI = CurrentIGI+2; else if(pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS) CurrentIGI = CurrentIGI-2; //Lower bound checking //RSSI Lower bound check if((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC) RSSI_Lower =(pDM_Odm->RSSI_Min-10); else RSSI_Lower =DM_DIG_MIN_NIC; //Upper and Lower Bound checking if(CurrentIGI > DM_DIG_MAX_NIC) CurrentIGI = DM_DIG_MAX_NIC; else if(CurrentIGI < RSSI_Lower) CurrentIGI = RSSI_Lower; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS(): pFalseAlmCnt->Cnt_all = %d\n",pFalseAlmCnt->Cnt_all)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS(): pDM_Odm->RSSI_Min = %d\n",pDM_Odm->RSSI_Min)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIGbyRSSI_LPS(): CurrentIGI = 0x%x\n",CurrentIGI)); ODM_Write_DIG(pDM_Odm, CurrentIGI);//ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); #endif } //3============================================================ //3 FASLE ALARM CHECK //3============================================================ VOID odm_FalseAlarmCounterStatistics( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); u4Byte ret_value; #if (DM_ODM_SUPPORT_TYPE == ODM_AP) //Mark there, and check this in odm_DMWatchDog #if 0 //(DM_ODM_SUPPORT_TYPE == ODM_AP) prtl8192cd_priv priv = pDM_Odm->priv; if( (priv->auto_channel != 0) && (priv->auto_channel != 2) ) return; #endif #endif if(!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) return; ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics()======>\n")); #if (ODM_IC_11N_SERIES_SUPPORT == 1) if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { //hold ofdm counter ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1); //hold page C counter ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1); //hold page D counter ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail + FalseAlmCnt->Cnt_Rate_Illegal + FalseAlmCnt->Cnt_Crc8_fail + FalseAlmCnt->Cnt_Mcs_fail + FalseAlmCnt->Cnt_Fast_Fsync + FalseAlmCnt->Cnt_SB_Search_fail; /* read CCK CRC32 counter */ FalseAlmCnt->cnt_cck_crc32_error = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, bMaskDWord); FalseAlmCnt->cnt_cck_crc32_ok= ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CRC32_OK_CNT_11N, bMaskDWord); /* read OFDM CRC32 counter */ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_CRC32_CNT_11N, bMaskDWord); FalseAlmCnt->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16; FalseAlmCnt->cnt_ofdm_crc32_ok= ret_value & 0xffff; /* read HT CRC32 counter */ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_HT_CRC32_CNT_11N, bMaskDWord); FalseAlmCnt->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16; FalseAlmCnt->cnt_ht_crc32_ok= ret_value & 0xffff; /* read VHT CRC32 counter */ FalseAlmCnt->cnt_vht_crc32_error = 0; FalseAlmCnt->cnt_vht_crc32_ok= 0; #if (RTL8188E_SUPPORT==1) if(pDM_Odm->SupportICType == ODM_RTL8188E) { ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_SC_CNT_11N, bMaskDWord); FalseAlmCnt->Cnt_BW_LSC = (ret_value&0xffff); FalseAlmCnt->Cnt_BW_USC = ((ret_value&0xffff0000)>>16); } #endif { //hold cck counter ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT12, 1); ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT14, 1); ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_LSB_11N, bMaskByte0); FalseAlmCnt->Cnt_Cck_fail = ret_value; ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); FalseAlmCnt->Cnt_Cck_fail += (ret_value& 0xff)<<8; ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord); FalseAlmCnt->Cnt_CCK_CCA = ((ret_value&0xFF)<<8) |((ret_value&0xFF00)>>8); } FalseAlmCnt->Cnt_all_pre = FalseAlmCnt->Cnt_all; FalseAlmCnt->Cnt_all = ( FalseAlmCnt->Cnt_Fast_Fsync + FalseAlmCnt->Cnt_SB_Search_fail + FalseAlmCnt->Cnt_Parity_Fail + FalseAlmCnt->Cnt_Rate_Illegal + FalseAlmCnt->Cnt_Crc8_fail + FalseAlmCnt->Cnt_Mcs_fail + FalseAlmCnt->Cnt_Cck_fail); FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; if (pDM_Odm->SupportICType >= ODM_RTL8188E) { /*reset false alarm counter registers*/ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT31, 1); ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT31, 0); ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT27, 1); ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT27, 0); /*update ofdm counter*/ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 0); /*update page C counter*/ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 0); /*update page D counter*/ /*reset CCK CCA counter*/ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT13|BIT12, 0); ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT13|BIT12, 2); /*reset CCK FA counter*/ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT15|BIT14, 0); ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT15|BIT14, 2); /*reset CRC32 counter*/ ODM_SetBBReg(pDM_Odm, ODM_REG_PAGE_F_RST_11N, BIT16, 1); ODM_SetBBReg(pDM_Odm, ODM_REG_PAGE_F_RST_11N, BIT16, 0); } /* Get debug port 0 */ ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x0); FalseAlmCnt->dbg_port0 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11N, bMaskDWord); /* Get EDCCA flag */ ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208); FalseAlmCnt->edcca_flag = (BOOLEAN)ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11N, BIT30); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Fast_Fsync=%d, Cnt_SB_Search_fail=%d\n", FalseAlmCnt->Cnt_Fast_Fsync, FalseAlmCnt->Cnt_SB_Search_fail)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Parity_Fail=%d, Cnt_Rate_Illegal=%d\n", FalseAlmCnt->Cnt_Parity_Fail, FalseAlmCnt->Cnt_Rate_Illegal)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Crc8_fail=%d, Cnt_Mcs_fail=%d\n", FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail)); } #endif #if (ODM_IC_11AC_SERIES_SUPPORT == 1) if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { u4Byte CCKenable; /* read OFDM FA counter */ FalseAlmCnt->Cnt_Ofdm_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_11AC, bMaskLWord); /* Read CCK FA counter */ FalseAlmCnt->Cnt_Cck_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_11AC, bMaskLWord); /* read CCK/OFDM CCA counter */ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11AC, bMaskDWord); FalseAlmCnt->Cnt_OFDM_CCA = (ret_value & 0xffff0000) >> 16; FalseAlmCnt->Cnt_CCK_CCA = ret_value & 0xffff; /* read CCK CRC32 counter */ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CRC32_CNT_11AC, bMaskDWord); FalseAlmCnt->cnt_cck_crc32_error = (ret_value & 0xffff0000) >> 16; FalseAlmCnt->cnt_cck_crc32_ok= ret_value & 0xffff; /* read OFDM CRC32 counter */ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_CRC32_CNT_11AC, bMaskDWord); FalseAlmCnt->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16; FalseAlmCnt->cnt_ofdm_crc32_ok= ret_value & 0xffff; /* read HT CRC32 counter */ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_HT_CRC32_CNT_11AC, bMaskDWord); FalseAlmCnt->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16; FalseAlmCnt->cnt_ht_crc32_ok= ret_value & 0xffff; /* read VHT CRC32 counter */ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_VHT_CRC32_CNT_11AC, bMaskDWord); FalseAlmCnt->cnt_vht_crc32_error = (ret_value & 0xffff0000) >> 16; FalseAlmCnt->cnt_vht_crc32_ok= ret_value & 0xffff; #if (RTL8881A_SUPPORT==1) /* For 8881A */ if(pDM_Odm->SupportICType == ODM_RTL8881A) { u4Byte Cnt_Ofdm_fail_temp = 0; if(FalseAlmCnt->Cnt_Ofdm_fail >= FalseAlmCnt->Cnt_Ofdm_fail_pre) { Cnt_Ofdm_fail_temp = FalseAlmCnt->Cnt_Ofdm_fail_pre; FalseAlmCnt->Cnt_Ofdm_fail_pre = FalseAlmCnt->Cnt_Ofdm_fail; FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Ofdm_fail - Cnt_Ofdm_fail_temp; } else FalseAlmCnt->Cnt_Ofdm_fail_pre = FalseAlmCnt->Cnt_Ofdm_fail; ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail_pre)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Ofdm_fail_pre=%d\n", Cnt_Ofdm_fail_temp)); /* Reset FA counter by enable/disable OFDM */ if(FalseAlmCnt->Cnt_Ofdm_fail_pre >= 0x7fff) { // reset OFDM ODM_SetBBReg(pDM_Odm, ODM_REG_BB_RX_PATH_11AC, BIT29,0); ODM_SetBBReg(pDM_Odm, ODM_REG_BB_RX_PATH_11AC, BIT29,1); FalseAlmCnt->Cnt_Ofdm_fail_pre = 0; ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Reset false alarm counter\n")); } } #endif /* reset OFDM FA coutner */ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT17, 1); ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT17, 0); /* reset CCK FA counter */ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT15, 0); ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT15, 1); /* reset CCA counter */ ODM_SetBBReg(pDM_Odm, ODM_REG_RST_RPT_11AC, BIT0, 1); ODM_SetBBReg(pDM_Odm, ODM_REG_RST_RPT_11AC, BIT0, 0); CCKenable = ODM_GetBBReg(pDM_Odm, ODM_REG_BB_RX_PATH_11AC, BIT28); if(CCKenable)//if(*pDM_Odm->pBandType == ODM_BAND_2_4G) { FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail + FalseAlmCnt->Cnt_Cck_fail; FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_CCK_CCA + FalseAlmCnt->Cnt_OFDM_CCA; } else { FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail; FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA; } /* Get debug port 0 */ ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC, bMaskDWord, 0x0); FalseAlmCnt->dbg_port0 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC, bMaskDWord); /* Get EDCCA flag */ ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC, bMaskDWord, 0x209); FalseAlmCnt->edcca_flag = (BOOLEAN)ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC, BIT30); } #endif FalseAlmCnt->cnt_crc32_error_all = FalseAlmCnt->cnt_vht_crc32_error + FalseAlmCnt->cnt_ht_crc32_error + FalseAlmCnt->cnt_ofdm_crc32_error + FalseAlmCnt->cnt_cck_crc32_error; FalseAlmCnt->cnt_crc32_ok_all = FalseAlmCnt->cnt_vht_crc32_ok + FalseAlmCnt->cnt_ht_crc32_ok + FalseAlmCnt->cnt_ofdm_crc32_ok + FalseAlmCnt->cnt_cck_crc32_ok; ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_OFDM_CCA=%d\n", FalseAlmCnt->Cnt_OFDM_CCA)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_CCK_CCA=%d\n", FalseAlmCnt->Cnt_CCK_CCA)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_CCA_all=%d\n", FalseAlmCnt->Cnt_CCA_all)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Cck_fail=%d\n", FalseAlmCnt->Cnt_Cck_fail)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Total False Alarm=%d\n", FalseAlmCnt->Cnt_all)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): CCK CRC32 fail: %d, ok: %d\n", FalseAlmCnt->cnt_cck_crc32_error, FalseAlmCnt->cnt_cck_crc32_ok)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): OFDM CRC32 fail: %d, ok: %d\n", FalseAlmCnt->cnt_ofdm_crc32_error, FalseAlmCnt->cnt_ofdm_crc32_ok)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): HT CRC32 fail: %d, ok: %d\n", FalseAlmCnt->cnt_ht_crc32_error, FalseAlmCnt->cnt_ht_crc32_ok)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): VHT CRC32 fail: %d, ok: %d\n", FalseAlmCnt->cnt_vht_crc32_error, FalseAlmCnt->cnt_vht_crc32_ok)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Total CRC32 fail: %d, ok: %d\n", FalseAlmCnt->cnt_crc32_error_all, FalseAlmCnt->cnt_crc32_ok_all)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): dbg port 0x0 = 0x%x, EDCCA = %d\n\n", FalseAlmCnt->dbg_port0, FalseAlmCnt->edcca_flag)); } //3============================================================ //3 CCK Packet Detect Threshold //3============================================================ VOID odm_PauseCCKPacketDetection( IN PVOID pDM_VOID, IN PHYDM_PAUSE_TYPE PauseType, IN PHYDM_PAUSE_LEVEL pause_level, IN u1Byte CCKPDThreshold ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection()=========> level = %d\n", pause_level)); if ((pDM_DigTable->pause_cckpd_level == 0) && (!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) || !(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Return: SupportAbility ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n")); return; } if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Return: Wrong pause level !!\n")); return; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_cckpd_level, CCKPDThreshold)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", pDM_DigTable->pause_cckpd_value[7], pDM_DigTable->pause_cckpd_value[6], pDM_DigTable->pause_cckpd_value[5], pDM_DigTable->pause_cckpd_value[4], pDM_DigTable->pause_cckpd_value[3], pDM_DigTable->pause_cckpd_value[2], pDM_DigTable->pause_cckpd_value[1], pDM_DigTable->pause_cckpd_value[0])); switch (PauseType) { /* Pause CCK Packet Detection Threshold */ case PHYDM_PAUSE: { /* Disable CCK PD */ ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility & (~ODM_BB_CCK_PD)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Pause CCK packet detection threshold !!\n")); /* Backup original CCK PD threshold decided by CCK PD mechanism */ if (pDM_DigTable->pause_cckpd_level == 0) { pDM_DigTable->CCKPDBackup = pDM_DigTable->CurCCK_CCAThres; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n", pDM_DigTable->CCKPDBackup, CCKPDThreshold)); } /* Update pause level */ pDM_DigTable->pause_cckpd_level = (pDM_DigTable->pause_cckpd_level | BIT(pause_level)); /* Record CCK PD threshold */ pDM_DigTable->pause_cckpd_value[pause_level] = CCKPDThreshold; /* Write new CCK PD threshold */ if (BIT(pause_level + 1) > pDM_DigTable->pause_cckpd_level) { ODM_Write_CCK_CCA_Thres(pDM_Odm, CCKPDThreshold); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): CCKPD of higher level = 0x%x\n", CCKPDThreshold)); } break; } /* Resume CCK Packet Detection Threshold */ case PHYDM_RESUME: { /* check if the level is illegal or not */ if ((pDM_DigTable->pause_cckpd_level & (BIT(pause_level))) != 0) { pDM_DigTable->pause_cckpd_level = pDM_DigTable->pause_cckpd_level & (~(BIT(pause_level))); pDM_DigTable->pause_cckpd_value[pause_level] = 0; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Resume CCK PD !!\n")); } else { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Wrong resume level !!\n")); break; } /* Resume DIG */ if (pDM_DigTable->pause_cckpd_level == 0) { /* Write backup IGI value */ ODM_Write_CCK_CCA_Thres(pDM_Odm, pDM_DigTable->CCKPDBackup); /* pDM_DigTable->bIgnoreDIG = TRUE; */ ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Write original CCKPD = 0x%x\n", pDM_DigTable->CCKPDBackup)); /* Enable DIG */ ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_CCK_PD); break; } if (BIT(pause_level) > pDM_DigTable->pause_cckpd_level) { s1Byte max_level; /* Calculate the maximum level now */ for (max_level = (pause_level - 1); max_level >= 0; max_level--) { if ((pDM_DigTable->pause_cckpd_level & BIT(max_level)) > 0) break; } /* write CCKPD of lower level */ ODM_Write_CCK_CCA_Thres(pDM_Odm, pDM_DigTable->pause_cckpd_value[max_level]); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Write CCKPD (0x%x) of level (%d)\n", pDM_DigTable->pause_cckpd_value[max_level], max_level)); break; } break; } default: ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Wrong type !!\n")); break; } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_cckpd_level, CCKPDThreshold)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", pDM_DigTable->pause_cckpd_value[7], pDM_DigTable->pause_cckpd_value[6], pDM_DigTable->pause_cckpd_value[5], pDM_DigTable->pause_cckpd_value[4], pDM_DigTable->pause_cckpd_value[3], pDM_DigTable->pause_cckpd_value[2], pDM_DigTable->pause_cckpd_value[1], pDM_DigTable->pause_cckpd_value[0])); } VOID odm_CCKPacketDetectionThresh( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); u1Byte CurCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres, RSSI_thd = 35; #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) //modify by Guo.Mingzhi 2011-12-29 if (pDM_Odm->bDualMacSmartConcurrent == TRUE) // if (pDM_Odm->bDualMacSmartConcurrent == FALSE) return; if(pDM_Odm->bBtHsOperation) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() write 0xcd for BT HS mode!!\n")); ODM_Write_CCK_CCA_Thres(pDM_Odm, 0xcd); return; } #endif if((!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD)) ||(!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) { ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() return==========\n")); #ifdef MCR_WIRELESS_EXTEND ODM_Write_CCK_CCA_Thres(pDM_Odm, 0x43); #endif return; } #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) if(pDM_Odm->ExtLNA) return; #endif ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() ==========>\n")); if (pDM_DigTable->cckFaMa == 0xffffffff) pDM_DigTable->cckFaMa = FalseAlmCnt->Cnt_Cck_fail; else pDM_DigTable->cckFaMa = ((pDM_DigTable->cckFaMa<<1) + pDM_DigTable->cckFaMa + FalseAlmCnt->Cnt_Cck_fail) >> 2; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh(): CCK FA moving average = %d\n", pDM_DigTable->cckFaMa)); if (pDM_Odm->bLinked) { #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) if (pDM_Odm->RSSI_Min > (RSSI_thd + 14)) CurCCK_CCAThres = 0xed; else if (pDM_Odm->RSSI_Min > (RSSI_thd + 6)) CurCCK_CCAThres = 0xdd; else if (pDM_Odm->RSSI_Min > RSSI_thd) CurCCK_CCAThres = 0xcd; else if (pDM_Odm->RSSI_Min > 20) { if (pDM_DigTable->cckFaMa > ((DM_DIG_FA_TH1>>1) + (DM_DIG_FA_TH1>>3))) CurCCK_CCAThres = 0xcd; else if (pDM_DigTable->cckFaMa < (DM_DIG_FA_TH0>>1)) CurCCK_CCAThres = 0x83; } else if (pDM_Odm->RSSI_Min > 7) CurCCK_CCAThres = 0x83; else CurCCK_CCAThres = 0x40; #else if (pDM_DigTable->CurIGValue > (0x24 + 14)) CurCCK_CCAThres = 0xed; else if (pDM_DigTable->CurIGValue > (0x24 + 6)) CurCCK_CCAThres = 0xdd; else if (pDM_DigTable->CurIGValue > 0x24) CurCCK_CCAThres = 0xcd; else { if (pDM_DigTable->cckFaMa > 0x400) CurCCK_CCAThres = 0x83; else if (pDM_DigTable->cckFaMa < 0x200) CurCCK_CCAThres = 0x40; } #endif } else { if (pDM_DigTable->cckFaMa > 0x400) CurCCK_CCAThres = 0x83; else if (pDM_DigTable->cckFaMa < 0x200) CurCCK_CCAThres = 0x40; } ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_CCKPacketDetectionThresh() CurCCK_CCAThres = 0x%x\n", CurCCK_CCAThres)); } VOID ODM_Write_CCK_CCA_Thres( IN PVOID pDM_VOID, IN u1Byte CurCCK_CCAThres ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; if(pDM_DigTable->CurCCK_CCAThres!=CurCCK_CCAThres) //modify by Guo.Mingzhi 2012-01-03 { ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA,pDM_Odm), CurCCK_CCAThres); pDM_DigTable->cckFaMa = 0xffffffff; } pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; } BOOLEAN phydm_DIG_GoUpCheck( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PCCX_INFO CCX_INFO = &pDM_Odm->DM_CCX_INFO; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; u1Byte CurIGValue = pDM_DigTable->CurIGValue; u1Byte max_DIG_cover_bond; u1Byte current_IGI_MaxUp_resolution; u1Byte rx_gain_range_max; u1Byte i = 0; u4Byte total_NHM_cnt; u4Byte DIG_cover_cnt; u4Byte over_DIG_cover_cnt; BOOLEAN ret = TRUE; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) prtl8192cd_priv priv = pDM_Odm->priv; max_DIG_cover_bond = DM_DIG_MAX_AP - priv->pshare->rf_ft_var.dig_upcheck_initial_value; current_IGI_MaxUp_resolution = CurIGValue + 6; rx_gain_range_max = pDM_DigTable->rx_gain_range_max; phydm_getNHMresult(pDM_Odm); total_NHM_cnt = CCX_INFO->NHM_result[0] + CCX_INFO->NHM_result[1]; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_DIG_GoUpCheck(): *****Get NHM results*****\n")); if (total_NHM_cnt != 0) { /* CurIGValue < max_DIG_cover_bond - 6 */ if (pDM_DigTable->DIG_GoUpCheck_Level == DIG_GOUPCHECK_LEVEL_0) { DIG_cover_cnt = CCX_INFO->NHM_result[1]; ret = ((priv->pshare->rf_ft_var.dig_level0_ratio_reciprocal * DIG_cover_cnt) >= total_NHM_cnt) ? TRUE : FALSE; } /* (max_DIG_cover_bond - 6) <= CurIGValue < DM_DIG_MAX_AP */ else if (pDM_DigTable->DIG_GoUpCheck_Level == DIG_GOUPCHECK_LEVEL_1) { over_DIG_cover_cnt = CCX_INFO->NHM_result[1]; ret = (priv->pshare->rf_ft_var.dig_level1_ratio_reciprocal * over_DIG_cover_cnt < total_NHM_cnt) ? TRUE : FALSE; if (!ret) { /* update pDM_DigTable->rx_gain_range_max */ pDM_DigTable->rx_gain_range_max = (rx_gain_range_max >= max_DIG_cover_bond - 6) ? (max_DIG_cover_bond - 6) : rx_gain_range_max; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_DIG_GoUpCheck(): Noise power is beyond DIG can filter, lock rx_gain_range_max to 0x%x\n", pDM_DigTable->rx_gain_range_max)); } } /* CurIGValue > DM_DIG_MAX_AP, foolproof */ else if (pDM_DigTable->DIG_GoUpCheck_Level == DIG_GOUPCHECK_LEVEL_2) { ret = TRUE; } ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_DIG_GoUpCheck(): DIG_GoUpCheck_level = %d\n, current_IGI_MaxUp_resolution = 0x%x\n, max_DIG_cover_bond = 0x%x\n, rx_gain_range_max = 0x%x, ret = %d\n", pDM_DigTable->DIG_GoUpCheck_Level, current_IGI_MaxUp_resolution, max_DIG_cover_bond, pDM_DigTable->rx_gain_range_max, ret)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_DIG_GoUpCheck(): NHM_result = %d, %d, %d, %d\n", CCX_INFO->NHM_result[0], CCX_INFO->NHM_result[1], CCX_INFO->NHM_result[2], CCX_INFO->NHM_result[3])); } else ret = TRUE; for (i = 0 ; i <= 10 ; i ++) { CCX_INFO->NHM_th[i] = 0xFF; } if (CurIGValue < max_DIG_cover_bond - 6){ CCX_INFO->NHM_th[0] = 2 * (CurIGValue - priv->pshare->rf_ft_var.dig_upcheck_initial_value); pDM_DigTable->DIG_GoUpCheck_Level = DIG_GOUPCHECK_LEVEL_0; } else if (CurIGValue <= DM_DIG_MAX_AP) { CCX_INFO->NHM_th[0] = 2 * max_DIG_cover_bond; pDM_DigTable->DIG_GoUpCheck_Level = DIG_GOUPCHECK_LEVEL_1; } /* CurIGValue > DM_DIG_MAX_AP, foolproof */ else { pDM_DigTable->DIG_GoUpCheck_Level = DIG_GOUPCHECK_LEVEL_2; ret = TRUE; } ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_DIG_GoUpCheck(): *****Set NHM settings*****\n")); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_DIG_GoUpCheck(): DIG_GoUpCheck_level = %d\n", pDM_DigTable->DIG_GoUpCheck_Level)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_DIG_GoUpCheck(): NHM_th = 0x%x, 0x%x, 0x%x\n", CCX_INFO->NHM_th[0], CCX_INFO->NHM_th[1], CCX_INFO->NHM_th[2])); CCX_INFO->NHM_inexclude_cca = NHM_EXCLUDE_CCA; CCX_INFO->NHM_inexclude_txon = NHM_EXCLUDE_TXON; CCX_INFO->NHM_period = 0xC350; phydm_NHMsetting(pDM_Odm, SET_NHM_SETTING); phydm_NHMtrigger(pDM_Odm); #endif return ret; } #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) // <20130108, Kordan> E.g., With LNA used, we make the Rx power smaller to have a better EVM. (Asked by Willis) VOID odm_RFEControl( IN PDM_ODM_T pDM_Odm, IN u8Byte RSSIVal ) { PADAPTER Adapter = (PADAPTER)pDM_Odm->Adapter; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); static u1Byte TRSW_HighPwr = 0; ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("===> odm_RFEControl, RSSI = %d, TRSW_HighPwr = 0x%X, pHalData->RFEType = %d\n", RSSIVal, TRSW_HighPwr, pHalData->RFEType )); if (pHalData->RFEType == 3) { pDM_Odm->RSSI_TRSW = RSSIVal; if (pDM_Odm->RSSI_TRSW >= pDM_Odm->RSSI_TRSW_H) { TRSW_HighPwr = 1; // Switch to PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT1|BIT0, 0x1); // Set ANTSW=1/ANTSWB=0 for SW control PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT9|BIT8, 0x3); // Set ANTSW=1/ANTSWB=0 for SW control } else if (pDM_Odm->RSSI_TRSW <= pDM_Odm->RSSI_TRSW_L) { TRSW_HighPwr = 0; // Switched back PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT1|BIT0, 0x1); // Set ANTSW=1/ANTSWB=0 for SW control PHY_SetBBReg(Adapter, r_ANTSEL_SW_Jaguar, BIT9|BIT8, 0x0); // Set ANTSW=1/ANTSWB=0 for SW control } } ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("(pDM_Odm->RSSI_TRSW_H, pDM_Odm->RSSI_TRSW_L) = (%d, %d)\n", pDM_Odm->RSSI_TRSW_H, pDM_Odm->RSSI_TRSW_L)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("(RSSIVal, RSSIVal, pDM_Odm->RSSI_TRSW_iso) = (%d, %d, %d)\n", RSSIVal, pDM_Odm->RSSI_TRSW_iso, pDM_Odm->RSSI_TRSW)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("<=== odm_RFEControl, RSSI = %d, TRSW_HighPwr = 0x%X\n", RSSIVal, TRSW_HighPwr)); } VOID odm_MPT_DIGWorkItemCallback( IN PVOID pContext ) { PADAPTER Adapter = (PADAPTER)pContext; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; ODM_MPT_DIG(pDM_Odm); } VOID odm_MPT_DIGCallback( PRT_TIMER pTimer ) { PADAPTER Adapter = (PADAPTER)pTimer->Adapter; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; #if DEV_BUS_TYPE==RT_PCI_INTERFACE #if USE_WORKITEM PlatformScheduleWorkItem(&pDM_Odm->MPT_DIGWorkitem); #else ODM_MPT_DIG(pDM_Odm); #endif #else PlatformScheduleWorkItem(&pDM_Odm->MPT_DIGWorkitem); #endif } #endif #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) VOID odm_MPT_DIGCallback( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; #if USE_WORKITEM PlatformScheduleWorkItem(&pDM_Odm->MPT_DIGWorkitem); #else ODM_MPT_DIG(pDM_Odm); #endif } #endif #if (DM_ODM_SUPPORT_TYPE != ODM_CE) VOID odm_MPT_Write_DIG( IN PVOID pDM_VOID, IN u1Byte CurIGValue ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_A,pDM_Odm), CurIGValue); #if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) /* Set IGI value of CCK for new CCK AGC */ if (pDM_Odm->cck_new_agc) { if (pDM_Odm->SupportICType & ODM_IC_PHY_STATUE_NEW_TYPE) ODM_SetBBReg(pDM_Odm, 0xa0c, 0x00003f00, (CurIGValue>>1)); } #endif if(pDM_Odm->RFType > ODM_1T1R) ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_B,pDM_Odm), CurIGValue); if((pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) && (pDM_Odm->RFType > ODM_2T2R)) { ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_C,pDM_Odm), CurIGValue); ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_D,pDM_Odm), CurIGValue); } pDM_DigTable->CurIGValue = CurIGValue; ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("CurIGValue = 0x%x\n", CurIGValue)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("pDM_Odm->RFType = 0x%x\n", pDM_Odm->RFType)); } VOID ODM_MPT_DIG( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; PFALSE_ALARM_STATISTICS pFalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); u1Byte CurrentIGI = pDM_DigTable->CurIGValue; u1Byte DIG_Upper = 0x40, DIG_Lower = 0x20; u4Byte RXOK_cal; u4Byte RxPWDBAve_final; u1Byte IGI_A = 0x20, IGI_B = 0x20; #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) #if ODM_FIX_2G_DIG IGI_A = 0x22; IGI_B = 0x24; #endif #else if (!(pDM_Odm->priv->pshare->rf_ft_var.mp_specific && pDM_Odm->priv->pshare->mp_dig_on)) return; if (*pDM_Odm->pBandType == ODM_BAND_5G) DIG_Lower = 0x22; #endif ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("===> ODM_MPT_DIG, pBandType = %d\n", *pDM_Odm->pBandType)); #if (ODM_FIX_2G_DIG || (DM_ODM_SUPPORT_TYPE & ODM_AP)) if (*pDM_Odm->pBandType == ODM_BAND_5G || (pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_RTL8822B))) // for 5G or 8814 #else if (1) // for both 2G/5G #endif { odm_FalseAlarmCounterStatistics(pDM_Odm); RXOK_cal = pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM; RxPWDBAve_final = (RXOK_cal != 0)?pDM_Odm->RxPWDBAve/RXOK_cal:0; pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK = 0; pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM = 0; pDM_Odm->RxPWDBAve = 0; pDM_Odm->MPDIG_2G = FALSE; #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) pDM_Odm->Times_2G = 0; #endif ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("RX OK = %d\n", RXOK_cal)); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("RSSI = %d\n", RxPWDBAve_final)); if (RXOK_cal >= 70 && RxPWDBAve_final <= 40) { if (CurrentIGI > 0x24) odm_MPT_Write_DIG(pDM_Odm, 0x24); } else { if(pFalseAlmCnt->Cnt_all > 1000){ CurrentIGI = CurrentIGI + 8; } else if(pFalseAlmCnt->Cnt_all > 200){ CurrentIGI = CurrentIGI + 4; } else if (pFalseAlmCnt->Cnt_all > 50){ CurrentIGI = CurrentIGI + 2; } else if (pFalseAlmCnt->Cnt_all < 2){ CurrentIGI = CurrentIGI - 2; } if (CurrentIGI < DIG_Lower ){ CurrentIGI = DIG_Lower; } if(CurrentIGI > DIG_Upper){ CurrentIGI = DIG_Upper; } odm_MPT_Write_DIG(pDM_Odm, CurrentIGI); ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG = 0x%x, Cnt_all = %d, Cnt_Ofdm_fail = %d, Cnt_Cck_fail = %d\n", CurrentIGI, pFalseAlmCnt->Cnt_all, pFalseAlmCnt->Cnt_Ofdm_fail, pFalseAlmCnt->Cnt_Cck_fail)); } } else { if(pDM_Odm->MPDIG_2G == FALSE) { if((pDM_Odm->SupportPlatform & ODM_WIN) && !(pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_RTL8822B))) { ODM_RT_TRACE(pDM_Odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("===> Fix IGI\n")); ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_A,pDM_Odm), IGI_A); ODM_Write1Byte( pDM_Odm, ODM_REG(IGI_B,pDM_Odm), IGI_B); pDM_DigTable->CurIGValue = IGI_B; } else odm_MPT_Write_DIG(pDM_Odm, IGI_A); } #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) pDM_Odm->Times_2G++; if (pDM_Odm->Times_2G == 3) #endif { pDM_Odm->MPDIG_2G = TRUE; } } #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) if (pDM_Odm->SupportICType == ODM_RTL8812) odm_RFEControl(pDM_Odm, RxPWDBAve_final); #endif ODM_SetTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer, 700); } #endif