/* ======================================================================== Routine Description: Read statistical counters from hardware registers and record them in software variables for later on query Arguments: pAd Pointer to our adapter Return Value: None IRQL = DISPATCH_LEVEL ======================================================================== */ VOID NICUpdateRawCounters(RTMP_ADAPTER *pAd) { UINT32 OldValue;/*, Value2;*/ /*ULONG PageSum, OneSecTransmitCount;*/ /*ULONG TxErrorRatio, Retry, Fail;*/ RX_STA_CNT0_STRUC RxStaCnt0; RX_STA_CNT1_STRUC RxStaCnt1; RX_STA_CNT2_STRUC RxStaCnt2; TX_STA_CNT0_STRUC TxStaCnt0; TX_STA_CNT1_STRUC StaTx1; TX_STA_CNT2_STRUC StaTx2; #ifdef STATS_COUNT_SUPPORT TX_NAG_AGG_CNT_STRUC TxAggCnt; TX_AGG_CNT0_STRUC TxAggCnt0; TX_AGG_CNT1_STRUC TxAggCnt1; TX_AGG_CNT2_STRUC TxAggCnt2; TX_AGG_CNT3_STRUC TxAggCnt3; TX_AGG_CNT4_STRUC TxAggCnt4; TX_AGG_CNT5_STRUC TxAggCnt5; TX_AGG_CNT6_STRUC TxAggCnt6; TX_AGG_CNT7_STRUC TxAggCnt7; #endif /* STATS_COUNT_SUPPORT */ COUNTER_RALINK *pRalinkCounters; // TODO: shiang-7603 if (pAd->chipCap.hif_type == HIF_MT) { DBGPRINT(RT_DEBUG_OFF, ("%s(%d): Not support for HIF_MT yet!\n", __FUNCTION__, __LINE__)); return; } pRalinkCounters = &pAd->RalinkCounters; // TODO: shiang-7603, fix this! if (pAd->chipCap.hif_type != HIF_MT) { RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word); RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word); } pAd->RalinkCounters.PhyErrCnt += RxStaCnt0.field.PhyErr; #ifdef CONFIG_AP_SUPPORT #ifdef CARRIER_DETECTION_SUPPORT if ((pAd->CommonCfg.CarrierDetect.Enable == FALSE) || (pAd->OpMode == OPMODE_STA)) #endif /* CARRIER_DETECTION_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ { // TODO: shiang-7603, fix this! if (pAd->chipCap.hif_type != HIF_MT) { RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word); } /* Update RX PLCP error counter*/ pAd->RalinkCounters.PlcpErrCnt += RxStaCnt1.field.PlcpErr; /* Update False CCA counter*/ pAd->RalinkCounters.OneSecFalseCCACnt = RxStaCnt1.field.FalseCca; pAd->RalinkCounters.FalseCCACnt += RxStaCnt1.field.FalseCca; } #ifdef STATS_COUNT_SUPPORT /* Update FCS counters*/ OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart; pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); /* >> 7);*/ if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue) pAd->WlanCounters.FCSErrorCount.u.HighPart++; #endif /* STATS_COUNT_SUPPORT */ /* Add FCS error count to private counters*/ pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr; OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart; pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr; if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue) pRalinkCounters->RealFcsErrCount.u.HighPart++; /* Update Duplicate Rcv check*/ pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount; #ifdef STATS_COUNT_SUPPORT pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount; #endif /* STATS_COUNT_SUPPORT */ /* Update RX Overflow counter*/ pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount); /*pAd->RalinkCounters.RxCount = 0;*/ /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || */ /* (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))*/ if (!pAd->bUpdateBcnCntDone) { /* Update BEACON sent count*/ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1); // TODO: shiang-7603, fix this! if (pAd->chipCap.hif_type != HIF_MT) { RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word); } } /*if (pAd->bStaFifoTest == TRUE)*/ #ifdef STATS_COUNT_SUPPORT { // TODO: shiang-7603, fix this! if (pAd->chipCap.hif_type != HIF_MT) { RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word); RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word); RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word); RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word); RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word); RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word); RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word); RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word); RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word); } pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount; pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount; pRalinkCounters->TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count; pRalinkCounters->TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count; pRalinkCounters->TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count; pRalinkCounters->TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count; pRalinkCounters->TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count; pRalinkCounters->TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count; pRalinkCounters->TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count; pRalinkCounters->TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count; pRalinkCounters->TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count; pRalinkCounters->TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count; pRalinkCounters->TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count; pRalinkCounters->TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count; pRalinkCounters->TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count; pRalinkCounters->TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count; pRalinkCounters->TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count; pRalinkCounters->TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count; /* Calculate the transmitted A-MPDU count*/ pRalinkCounters->TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count; pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count >> 1); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count >> 2); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count >> 3); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15); pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count >> 4); } #endif /* STATS_COUNT_SUPPORT */ #ifdef DBG_DIAGNOSE { RtmpDiagStruct *pDiag; UCHAR ArrayCurIdx, i; struct dbg_diag_info *diag_info; pDiag = &pAd->DiagStruct; ArrayCurIdx = pDiag->ArrayCurIdx; if (pDiag->inited == 0) { NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_)); pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0; pDiag->inited = 1; } else { diag_info = &pDiag->diag_info[ArrayCurIdx]; /* Tx*/ diag_info->TxFailCnt = TxStaCnt0.field.TxFailCount; #ifdef DBG_TX_AGG_CNT diag_info->TxAggCnt = TxAggCnt.field.AggTxCount; diag_info->TxNonAggCnt = TxAggCnt.field.NonAggTxCount; diag_info->TxAMPDUCnt[0] = TxAggCnt0.field.AggSize1Count; diag_info->TxAMPDUCnt[1] = TxAggCnt0.field.AggSize2Count; diag_info->TxAMPDUCnt[2] = TxAggCnt1.field.AggSize3Count; diag_info->TxAMPDUCnt[3] = TxAggCnt1.field.AggSize4Count; diag_info->TxAMPDUCnt[4] = TxAggCnt2.field.AggSize5Count; diag_info->TxAMPDUCnt[5] = TxAggCnt2.field.AggSize6Count; diag_info->TxAMPDUCnt[6] = TxAggCnt3.field.AggSize7Count; diag_info->TxAMPDUCnt[7] = TxAggCnt3.field.AggSize8Count; diag_info->TxAMPDUCnt[8] = TxAggCnt4.field.AggSize9Count; diag_info->TxAMPDUCnt[9] = TxAggCnt4.field.AggSize10Count; diag_info->TxAMPDUCnt[10] = TxAggCnt5.field.AggSize11Count; diag_info->TxAMPDUCnt[11] = TxAggCnt5.field.AggSize12Count; diag_info->TxAMPDUCnt[12] = TxAggCnt6.field.AggSize13Count; diag_info->TxAMPDUCnt[13] = TxAggCnt6.field.AggSize14Count; diag_info->TxAMPDUCnt[14] = TxAggCnt7.field.AggSize15Count; diag_info->TxAMPDUCnt[15] = TxAggCnt7.field.AggSize16Count; #endif /* DBG_TX_AGG_CNT */ diag_info->RxCrcErrCnt = RxStaCnt0.field.CrcErr; INC_RING_INDEX(pDiag->ArrayCurIdx, DIAGNOSE_TIME); ArrayCurIdx = pDiag->ArrayCurIdx; NdisZeroMemory(&pDiag->diag_info[ArrayCurIdx], sizeof(pDiag->diag_info[ArrayCurIdx])); if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx) INC_RING_INDEX(pDiag->ArrayStartIdx, DIAGNOSE_TIME); } } #endif /* DBG_DIAGNOSE */ }
/* ========================================================================== Description: This routine calculates the acumulated TxPER of eaxh TxRate. And according to the calculation result, change CommonCfg.TxRate which is the stable TX Rate we expect the Radio situation could sustained. CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate} Output: CommonCfg.TxRate - IRQL = DISPATCH_LEVEL NOTE: call this routine every second ========================================================================== */ void MlmeDynamicTxRateSwitching( IN PRTMP_ADAPTER pAd) { unsigned char* pTable; unsigned char TableSize = 0; unsigned char UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx; unsigned long i, TxTotalCnt; unsigned long TxErrorRatio = 0; MAC_TABLE_ENTRY *pEntry; RTMP_RA_LEGACY_TB *pCurrTxRate, *pTmpTxRate = NULL; unsigned char InitTxRateIdx, TrainUp, TrainDown; TX_STA_CNT1_STRUC StaTx1; TX_STA_CNT0_STRUC TxStaCnt0; char Rssi, TmpIdx = 0; unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; RSSI_SAMPLE *pRssi = &pAd->StaCfg.RssiSample; #ifdef RT3290 unsigned long AccuTxTotalCnt = 0; #endif /* RT3290 */ #ifdef AGS_SUPPORT AGS_STATISTICS_INFO AGSStatisticsInfo = {0}; #endif /* AGS_SUPPORT */ #ifdef RALINK_ATE if (ATE_ON(pAd)) { return; } #endif /* RALINK_ATE */ /* Update statistic counter */ NicGetTxRawCounters(pAd, &TxStaCnt0, &StaTx1); TxRetransmit = StaTx1.field.TxRetransmit; TxSuccess = StaTx1.field.TxSuccess; TxFailCount = TxStaCnt0.field.TxFailCount; TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; /* walk through MAC table, see if need to change AP's TX rate toward each entry */ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { pEntry = &pAd->MacTab.Content[i]; if (IS_ENTRY_NONE(pEntry)) continue; /* check if this entry need to switch rate automatically */ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) continue; MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); pEntry->pTable = pTable; #ifdef NEW_RATE_ADAPT_SUPPORT if (ADAPT_RATE_TABLE(pTable)) { MlmeDynamicTxRateSwitchingAdapt(pAd, i, TxSuccess, TxRetransmit, TxFailCount); continue; } #endif /* NEW_RATE_ADAPT_SUPPORT */ if ((pAd->MacTab.Size == 1) || IS_ENTRY_DLS(pEntry)) { Rssi = RTMPAvgRssi(pAd, pRssi); if (TxTotalCnt) TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; #ifdef RT3290 /* If no traffic in the past 1-sec period, don't change TX rate, but clear all bad history. because the bad history may affect the next Chariot throughput test */ AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount + pAd->RalinkCounters.OneSecTxFailCount; if (IS_RT3290(pAd) && ((AccuTxTotalCnt > 150) || (pAd->AntennaDiversityState == 1)) && (pAd->CommonCfg.BBPCurrentBW == BW_40)) { WLAN_FUN_CTRL_STRUC WlanFunCtrl = {.word = 0}; RTMP_IO_READ32(pAd, WLAN_FUN_CTRL, &WlanFunCtrl.word); if ((WlanFunCtrl.field.WLAN_EN == TRUE) && (WlanFunCtrl.field.PCIE_APP0_CLK_REQ == FALSE)) { WlanFunCtrl.field.PCIE_APP0_CLK_REQ = TRUE; RTMP_IO_WRITE32(pAd, WLAN_FUN_CTRL, WlanFunCtrl.word); } // TODO: shiang, why RT3290 need to do AntSelection here?? MlmeAntSelection(pAd, AccuTxTotalCnt, TxErrorRatio, TxSuccess, pAd->StaCfg.RssiSample.AvgRssi0); } #endif /* RT3290 */ DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_RA, ("DRS:Aid=%d, TxSuccess=%ld, TxRetransmit=%ld, TxFailCount=%ld \n", pEntry->Aid, TxSuccess, TxRetransmit, TxFailCount)); #ifdef AGS_SUPPORT if (SUPPORT_AGS(pAd)) { /* Gather the statistics information*/ AGSStatisticsInfo.RSSI = Rssi; AGSStatisticsInfo.TxErrorRatio = TxErrorRatio; AGSStatisticsInfo.AccuTxTotalCnt = TxTotalCnt; AGSStatisticsInfo.TxTotalCnt = TxTotalCnt; AGSStatisticsInfo.TxSuccess = TxSuccess; AGSStatisticsInfo.TxRetransmit = TxRetransmit; AGSStatisticsInfo.TxFailCount = TxFailCount; } #endif /* AGS_SUPPORT */ } else { if (INFRA_ON(pAd) && (i == 1))