#include "odm_precomp.h"
void odm_NHMCounterStatisticsInit(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TIMER_11N+2, 0x2710);
rtw_write16(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff);
rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52);
rtw_write32(pDM_Odm->Adapter, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff);
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff);
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 0x7);
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1);
}
void odm_NHMCounterStatistics(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
odm_GetNHMCounterStatistics(pDM_Odm);
odm_NHMCounterStatisticsReset(pDM_Odm);
}
void odm_GetNHMCounterStatistics(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
u32 value32 = 0;
value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_NHM_CNT_11N, bMaskDWord);
pDM_Odm->NHM_cnt_0 = (u8)(value32 & bMaskByte0);
}
void odm_NHMCounterStatisticsReset(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 0);
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_NHM_TH9_TH10_11N, BIT1, 1);
}
void odm_NHMBBInit(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
pDM_Odm->adaptivity_flag = 0;
pDM_Odm->tolerance_cnt = 3;
pDM_Odm->NHMLastTxOkcnt = 0;
pDM_Odm->NHMLastRxOkcnt = 0;
pDM_Odm->NHMCurTxOkcnt = 0;
pDM_Odm->NHMCurRxOkcnt = 0;
}
void odm_NHMBB(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
pDM_Odm->NHMCurTxOkcnt =
*(pDM_Odm->pNumTxBytesUnicast)-pDM_Odm->NHMLastTxOkcnt;
pDM_Odm->NHMCurRxOkcnt =
*(pDM_Odm->pNumRxBytesUnicast)-pDM_Odm->NHMLastRxOkcnt;
pDM_Odm->NHMLastTxOkcnt =
*(pDM_Odm->pNumTxBytesUnicast);
pDM_Odm->NHMLastRxOkcnt =
*(pDM_Odm->pNumRxBytesUnicast);
if ((pDM_Odm->NHMCurTxOkcnt) + 1 > (u64)(pDM_Odm->NHMCurRxOkcnt<<2) + 1) {
if (pDM_Odm->NHM_cnt_0 >= 190 || pDM_Odm->adaptivity_flag == true) {
pDM_Odm->adaptivity_flag = true;
pDM_Odm->tolerance_cnt = 0;
} else {
if (pDM_Odm->tolerance_cnt < 3)
pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
else
pDM_Odm->tolerance_cnt = 4;
if (pDM_Odm->tolerance_cnt > 3) {
pDM_Odm->adaptivity_flag = false;
}
}
} else {
if (pDM_Odm->adaptivity_flag == true && pDM_Odm->NHM_cnt_0 <= 200) {
pDM_Odm->tolerance_cnt = 0;
} else {
if (pDM_Odm->tolerance_cnt < 3)
pDM_Odm->tolerance_cnt = pDM_Odm->tolerance_cnt + 1;
else
pDM_Odm->tolerance_cnt = 4;
if (pDM_Odm->tolerance_cnt > 3) {
pDM_Odm->adaptivity_flag = false;
}
}
}
}
void odm_SearchPwdBLowerBound(void *pDM_VOID, u8 IGI_target)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
u32 value32 = 0;
u8 cnt, IGI;
bool bAdjust = true;
s8 TH_L2H_dmc, TH_H2L_dmc;
s8 Diff;
IGI = 0x50;
ODM_Write_DIG(pDM_Odm, IGI);
Diff = IGI_target-(s8)IGI;
TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
if (TH_L2H_dmc > 10)
TH_L2H_dmc = 10;
TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
mdelay(5);
while (bAdjust) {
for (cnt = 0; cnt < 20; cnt++) {
value32 = PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG_RPT_11N, bMaskDWord);
if (value32 & BIT30)
pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
else if (value32 & BIT29)
pDM_Odm->txEdcca1 = pDM_Odm->txEdcca1 + 1;
else
pDM_Odm->txEdcca0 = pDM_Odm->txEdcca0 + 1;
}
if (pDM_Odm->txEdcca1 > 5) {
IGI = IGI-1;
TH_L2H_dmc = TH_L2H_dmc + 1;
if (TH_L2H_dmc > 10)
TH_L2H_dmc = 10;
TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
pDM_Odm->TxHangFlg = true;
pDM_Odm->txEdcca1 = 0;
pDM_Odm->txEdcca0 = 0;
if (TH_L2H_dmc == 10) {
bAdjust = false;
pDM_Odm->TxHangFlg = false;
pDM_Odm->txEdcca1 = 0;
pDM_Odm->txEdcca0 = 0;
pDM_Odm->H2L_lb = TH_H2L_dmc;
pDM_Odm->L2H_lb = TH_L2H_dmc;
pDM_Odm->Adaptivity_IGI_upper = IGI;
}
} else {
bAdjust = false;
pDM_Odm->TxHangFlg = false;
pDM_Odm->txEdcca1 = 0;
pDM_Odm->txEdcca0 = 0;
pDM_Odm->H2L_lb = TH_H2L_dmc;
pDM_Odm->L2H_lb = TH_L2H_dmc;
pDM_Odm->Adaptivity_IGI_upper = IGI;
}
}
}
void odm_AdaptivityInit(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
if (pDM_Odm->Carrier_Sense_enable == false)
pDM_Odm->TH_L2H_ini = 0xf7;
else
pDM_Odm->TH_L2H_ini = 0xa;
pDM_Odm->AdapEn_RSSI = 20;
pDM_Odm->TH_EDCCA_HL_diff = 7;
pDM_Odm->IGI_Base = 0x32;
pDM_Odm->IGI_target = 0x1c;
pDM_Odm->ForceEDCCA = 0;
pDM_Odm->NHM_disable = false;
pDM_Odm->TxHangFlg = true;
pDM_Odm->txEdcca0 = 0;
pDM_Odm->txEdcca1 = 0;
pDM_Odm->H2L_lb = 0;
pDM_Odm->L2H_lb = 0;
pDM_Odm->Adaptivity_IGI_upper = 0;
odm_NHMBBInit(pDM_Odm);
PHY_SetBBReg(pDM_Odm->Adapter, REG_RD_CTRL, BIT11, 1);
}
void odm_Adaptivity(void *pDM_VOID, u8 IGI)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
s8 TH_L2H_dmc, TH_H2L_dmc;
s8 Diff, IGI_target;
bool EDCCA_State = false;
if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) {
return;
}
if (*pDM_Odm->pBandWidth == ODM_BW20M)
IGI_target = pDM_Odm->IGI_Base;
else if (*pDM_Odm->pBandWidth == ODM_BW40M)
IGI_target = pDM_Odm->IGI_Base + 2;
else
IGI_target = pDM_Odm->IGI_Base;
pDM_Odm->IGI_target = (u8) IGI_target;
if (pDM_Odm->TxHangFlg == true) {
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208);
odm_SearchPwdBLowerBound(pDM_Odm, pDM_Odm->IGI_target);
}
if ((!pDM_Odm->bLinked) || (*pDM_Odm->pChannel > 149)) {
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, 0x7f);
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, 0x7f);
return;
}
if (!pDM_Odm->ForceEDCCA) {
if (pDM_Odm->RSSI_Min > pDM_Odm->AdapEn_RSSI)
EDCCA_State = true;
else if (pDM_Odm->RSSI_Min < (pDM_Odm->AdapEn_RSSI - 5))
EDCCA_State = false;
} else
EDCCA_State = true;
if (
pDM_Odm->bLinked &&
pDM_Odm->Carrier_Sense_enable == false &&
pDM_Odm->NHM_disable == false &&
pDM_Odm->TxHangFlg == false
)
odm_NHMBB(pDM_Odm);
if (EDCCA_State) {
Diff = IGI_target-(s8)IGI;
TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff;
if (TH_L2H_dmc > 10)
TH_L2H_dmc = 10;
TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff;
if (TH_H2L_dmc < pDM_Odm->H2L_lb)
TH_H2L_dmc = pDM_Odm->H2L_lb;
if (TH_L2H_dmc < pDM_Odm->L2H_lb)
TH_L2H_dmc = pDM_Odm->L2H_lb;
} else {
TH_L2H_dmc = 0x7f;
TH_H2L_dmc = 0x7f;
}
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc);
PHY_SetBBReg(pDM_Odm->Adapter, rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc);
}
void ODM_Write_DIG(void *pDM_VOID, u8 CurrentIGI)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
if (pDM_DigTable->bStopDIG) {
return;
}
if (pDM_DigTable->CurIGValue != CurrentIGI) {
if (!pDM_DigTable->bPSDInProgress) {
if (CurrentIGI > pDM_DigTable->rx_gain_range_max) {
CurrentIGI = pDM_DigTable->rx_gain_range_max;
}
}
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI);
pDM_DigTable->CurIGValue = CurrentIGI;
}
}
bool odm_DigAbort(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) {
return true;
}
if (!(pDM_Odm->SupportAbility & ODM_BB_DIG)) {
return true;
}
if (*(pDM_Odm->pbScanInProcess)) {
return true;
}
if (pDM_Odm->bDMInitialGainEnable == false) {
return true;
}
return false;
}
void odm_DIGInit(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
pDM_DigTable->bStopDIG = false;
pDM_DigTable->bPSDInProgress = false;
pDM_DigTable->CurIGValue = (u8) PHY_QueryBBReg(pDM_Odm->Adapter, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm));
pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW;
pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH;
pDM_DigTable->FALowThresh = DMfalseALARM_THRESH_LOW;
pDM_DigTable->FAHighThresh = DMfalseALARM_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->Recover_cnt = 0;
pDM_DigTable->bMediaConnect_0 = false;
pDM_DigTable->bMediaConnect_1 = false;
pDM_Odm->bDMInitialGainEnable = true;
pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
pDM_DigTable->BT30_CurIGI = 0x32;
pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
}
void odm_DIG(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
bool FirstConnect, FirstDisConnect;
u8 DIG_MaxOfMin, DIG_Dynamic_MIN;
u8 dm_dig_max, dm_dig_min;
u8 CurrentIGI = pDM_DigTable->CurIGValue;
u8 offset;
u32 dm_FA_thres[3];
u8 Adap_IGI_Upper = 0;
u32 TxTp = 0, RxTp = 0;
bool bDFSBand = false;
bool bPerformance = true, bFirstTpTarget = false, bFirstCoverage = false;
if (odm_DigAbort(pDM_Odm))
return;
if (pDM_Odm->adaptivity_flag == true)
Adap_IGI_Upper = pDM_Odm->Adaptivity_IGI_upper;
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);
dm_dig_max = 0x5A;
dm_dig_min = DM_DIG_MIN_NIC;
DIG_MaxOfMin = DM_DIG_MAX_AP;
if (pDM_Odm->bLinked && bPerformance) {
if (pDM_Odm->bBtLimitedDig == 1) {
offset = 10;
} else
offset = 15;
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 (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;
}
} else {
pDM_DigTable->rx_gain_range_max = dm_dig_max;
DIG_Dynamic_MIN = dm_dig_min;
}
if (pDM_Odm->bLinked && !pDM_Odm->bOneEntryOnly) {
if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
if (
pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV ||
pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV ||
pDM_Odm->AntDivType == S0S1_SW_ANTDIV
) {
if (pDM_DigTable->AntDiv_RSSI_max > DIG_MaxOfMin)
DIG_Dynamic_MIN = DIG_MaxOfMin;
else
DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max;
}
}
}
if (FirstDisConnect) {
pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN;
pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
} else
pDM_DigTable->rx_gain_range_min =
odm_ForbiddenIGICheck(pDM_Odm, DIG_Dynamic_MIN, CurrentIGI);
if (pDM_Odm->bLinked && !FirstConnect) {
if (
(pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
pDM_Odm->bsta_state
) {
pDM_DigTable->rx_gain_range_min = dm_dig_min;
}
}
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_FAThresholdCheck(pDM_Odm, bDFSBand, bPerformance, RxTp, TxTp, dm_FA_thres);
if (pDM_Odm->bLinked && bPerformance) {
if (bFirstTpTarget || FirstConnect) {
pDM_DigTable->LargeFAHit = 0;
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;
}
} else {
if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
CurrentIGI = CurrentIGI + 4;
else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
CurrentIGI = CurrentIGI + 2;
else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
CurrentIGI = CurrentIGI - 2;
if (
(pDM_Odm->PhyDbgInfo.NumQryBeaconPkt < 5) &&
(pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) &&
(pDM_Odm->bsta_state)
) {
CurrentIGI = pDM_DigTable->rx_gain_range_min;
}
}
} else {
if (FirstDisConnect || bFirstCoverage) {
CurrentIGI = dm_dig_min;
} else {
if (pFalseAlmCnt->Cnt_all > dm_FA_thres[2])
CurrentIGI = CurrentIGI + 4;
else if (pFalseAlmCnt->Cnt_all > dm_FA_thres[1])
CurrentIGI = CurrentIGI + 2;
else if (pFalseAlmCnt->Cnt_all < dm_FA_thres[0])
CurrentIGI = CurrentIGI - 2;
}
}
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;
if (
pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY &&
pDM_Odm->adaptivity_flag == true
) {
if (CurrentIGI > Adap_IGI_Upper)
CurrentIGI = Adap_IGI_Upper;
if (pDM_Odm->IGI_LowerBound != 0) {
if (CurrentIGI < pDM_Odm->IGI_LowerBound)
CurrentIGI = pDM_Odm->IGI_LowerBound;
}
}
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);
}
} else {
ODM_Write_DIG(pDM_Odm, CurrentIGI);
pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
}
}
void odm_DIGbyRSSI_LPS(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
u8 RSSI_Lower = DM_DIG_MIN_NIC;
u8 CurrentIGI = pDM_Odm->RSSI_Min;
CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
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;
RSSI_Lower = max(pDM_Odm->RSSI_Min - 10, DM_DIG_MIN_NIC);
if (CurrentIGI > DM_DIG_MAX_NIC)
CurrentIGI = DM_DIG_MAX_NIC;
else if (CurrentIGI < RSSI_Lower)
CurrentIGI = RSSI_Lower;
ODM_Write_DIG(pDM_Odm, CurrentIGI);
}
void odm_FalseAlarmCounterStatistics(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
u32 ret_value;
if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
return;
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1);
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1);
ret_value = PHY_QueryBBReg(
pDM_Odm->Adapter, 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 = PHY_QueryBBReg(
pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord
);
FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
ret_value = PHY_QueryBBReg(
pDM_Odm->Adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord
);
FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
ret_value = PHY_QueryBBReg(
pDM_Odm->Adapter, 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;
{
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT12, 1);
PHY_SetBBReg(pDM_Odm->Adapter, ODM_REG_CCK_FA_RST_11N, BIT14, 1);
ret_value = PHY_QueryBBReg(
pDM_Odm->Adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0
);
FalseAlmCnt->Cnt_Cck_fail = ret_value;
ret_value = PHY_QueryBBReg(
pDM_Odm->Adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3
);
FalseAlmCnt->Cnt_Cck_fail += (ret_value&0xff)<<8;
ret_value = PHY_QueryBBReg(
pDM_Odm->Adapter, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord
);
FalseAlmCnt->Cnt_CCK_CCA =
((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
}
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;
}
void odm_FAThresholdCheck(
void *pDM_VOID,
bool bDFSBand,
bool bPerformance,
u32 RxTp,
u32 TxTp,
u32 *dm_FA_thres
)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
if (pDM_Odm->bLinked && (bPerformance || bDFSBand)) {
dm_FA_thres[0] = DM_DIG_FA_TH0;
dm_FA_thres[1] = DM_DIG_FA_TH1;
dm_FA_thres[2] = DM_DIG_FA_TH2;
} else {
dm_FA_thres[0] = 2000;
dm_FA_thres[1] = 4000;
dm_FA_thres[2] = 5000;
}
}
u8 odm_ForbiddenIGICheck(void *pDM_VOID, u8 DIG_Dynamic_MIN, u8 CurrentIGI)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
struct false_ALARM_STATISTICS *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
u8 rx_gain_range_min = pDM_DigTable->rx_gain_range_min;
if (pFalseAlmCnt->Cnt_all > 10000) {
if (pDM_DigTable->LargeFAHit != 3)
pDM_DigTable->LargeFAHit++;
if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
pDM_DigTable->ForbiddenIGI = CurrentIGI;
pDM_DigTable->LargeFAHit = 1;
}
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;
}
} else {
if (pDM_DigTable->Recover_cnt != 0) {
pDM_DigTable->Recover_cnt--;
} else {
if (pDM_DigTable->LargeFAHit < 3) {
if ((pDM_DigTable->ForbiddenIGI - 2) < DIG_Dynamic_MIN) {
pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN;
rx_gain_range_min = DIG_Dynamic_MIN;
} else {
pDM_DigTable->ForbiddenIGI -= 2;
rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 2);
}
} else
pDM_DigTable->LargeFAHit = 0;
}
}
return rx_gain_range_min;
}
void odm_CCKPacketDetectionThresh(void *pDM_VOID)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct false_ALARM_STATISTICS *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
u8 CurCCK_CCAThres;
if (
!(pDM_Odm->SupportAbility & ODM_BB_CCK_PD) ||
!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)
) {
return;
}
if (pDM_Odm->ExtLNA)
return;
if (pDM_Odm->bLinked) {
if (pDM_Odm->RSSI_Min > 25)
CurCCK_CCAThres = 0xcd;
else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10))
CurCCK_CCAThres = 0x83;
else {
if (FalseAlmCnt->Cnt_Cck_fail > 1000)
CurCCK_CCAThres = 0x83;
else
CurCCK_CCAThres = 0x40;
}
} else {
if (FalseAlmCnt->Cnt_Cck_fail > 1000)
CurCCK_CCAThres = 0x83;
else
CurCCK_CCAThres = 0x40;
}
ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres);
}
void ODM_Write_CCK_CCA_Thres(void *pDM_VOID, u8 CurCCK_CCAThres)
{
struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID;
struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
rtw_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres);
pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
}