📄 mlme.c
字号:
pAd->RalinkCounters.OneSecTxRetryOkCount, pAd->RalinkCounters.OneSecTxFailCount, pAd->RalinkCounters.OneSecTxNoRetryOkCount)); if (pAd->CommonCfg.bAutoTxRateSwitch == FALSE) { DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: Fixed - CurrTxRateIdx=%d, MCS=%d, STBC=%d, ShortGI=%d, Mode=%d, BW=%d, PER=%ld%% \n\n", pAd->CommonCfg.TxRateIndex, pAd->CommonCfg.HTPhyMode.field.MCS, pAd->CommonCfg.HTPhyMode.field.STBC, pAd->CommonCfg.HTPhyMode.field.ShortGI, pAd->CommonCfg.HTPhyMode.field.MODE, pAd->CommonCfg.HTPhyMode.field.BW, TxErrorRatio)); return; } else { DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: Before- CurrTxRateIdx=%d, MCS=%d, STBC=%d, ShortGI=%d, Mode=%d, TrainUp=%d, TrainDown=%d, NextUp=%d, NextDown=%d, CurrMCS=%d, PER=%ld%%\n", CurrRateIdx, pCurrTxRate->CurrMCS, pCurrTxRate->STBC, pCurrTxRate->ShortGI, pCurrTxRate->Mode, TrainUp, TrainDown, UpRateIdx, DownRateIdx, pAd->CommonCfg.HTPhyMode.field.MCS, TxErrorRatio)); } if (! OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) return; // // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI // (criteria copied from RT2500 for Netopia case) // if (TxTotalCnt <= 15) { CHAR idx = 0; UCHAR TxRateIdx; //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0; UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; // check the existence and index of each needed MCS while (idx < pTable[0]) { pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5]; if (pCurrTxRate->CurrMCS == MCS_0) { MCS0 = idx; } else if (pCurrTxRate->CurrMCS == MCS_1) { MCS1 = idx; } else if (pCurrTxRate->CurrMCS == MCS_2) { MCS2 = idx; } else if (pCurrTxRate->CurrMCS == MCS_3) { MCS3 = idx; } else if (pCurrTxRate->CurrMCS == MCS_4) { MCS4 = idx; } else if (pCurrTxRate->CurrMCS == MCS_5) { MCS5 = idx; } else if (pCurrTxRate->CurrMCS == MCS_6) { MCS6 = idx; } else if (pCurrTxRate->CurrMCS == MCS_7) { MCS7 = idx; } else if (pCurrTxRate->CurrMCS == MCS_12) { MCS12 = idx; } else if (pCurrTxRate->CurrMCS == MCS_13) { MCS13 = idx; } else if (pCurrTxRate->CurrMCS == MCS_14) { MCS14 = idx; } else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate { MCS15 = idx; } idx ++; } /*if (MCS15)*/ if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable)) {// N mode with 2 stream if (MCS15 && (Rssi >= -70)) TxRateIdx = MCS15; else if (MCS14 && (Rssi >= -72)) TxRateIdx = MCS14; else if (MCS13 && (Rssi >= -76)) TxRateIdx = MCS13; else if (MCS12 && (Rssi >= -78)) TxRateIdx = MCS12; else if (MCS4 && (Rssi >= -82)) TxRateIdx = MCS4; else if (MCS3 && (Rssi >= -84)) TxRateIdx = MCS3; else if (MCS2 && (Rssi >= -86)) TxRateIdx = MCS2; else if (MCS1 && (Rssi >= -88)) TxRateIdx = MCS1; else TxRateIdx = MCS0; } else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) {// N mode with 1 stream if (MCS7 && (Rssi > -72)) TxRateIdx = MCS7; else if (MCS6 && (Rssi > -74)) TxRateIdx = MCS6; else if (MCS5 && (Rssi > -77)) TxRateIdx = MCS5; else if (MCS4 && (Rssi > -79)) TxRateIdx = MCS4; else if (MCS3 && (Rssi > -81)) TxRateIdx = MCS3; else if (MCS2 && (Rssi > -83)) TxRateIdx = MCS2; else if (MCS1 && (Rssi > -86)) TxRateIdx = MCS1; else TxRateIdx = MCS0; } else {// Legacy mode if (MCS7 && (Rssi > -70)) TxRateIdx = MCS7; else if (MCS6 && (Rssi > -74)) TxRateIdx = MCS6; else if (MCS5 && (Rssi > -78)) TxRateIdx = MCS5; else if (MCS4 && (Rssi > -82)) TxRateIdx = MCS4; else if (MCS4 == 0) // for B-only mode TxRateIdx = MCS3; else if (MCS3 && (Rssi > -85)) TxRateIdx = MCS3; else if (MCS2 && (Rssi > -87)) TxRateIdx = MCS2; else if (MCS1 && (Rssi > -90)) TxRateIdx = MCS1; else TxRateIdx = MCS0; }// if (TxRateIdx != pAd->CommonCfg.TxRateIndex) { pAd->CommonCfg.TxRateIndex = TxRateIdx; pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5]; MlmeSetTxRate(pAd, &pAd->MacTab.Content[BSSID_WCID], pNextTxRate); } NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); pAd->DrsCounters.fLastSecAccordingRSSI = TRUE; DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: TxTotalCnt <= 15, switch TxRateIndex as (%d) according to RSSI(%d)\n", pAd->CommonCfg.TxRateIndex, Rssi)); return; } if ((pAd->DrsCounters.fLastSecAccordingRSSI == TRUE) || (pAd->DrsCounters.LastSecTxRateChangeAction != 0)) { pAd->DrsCounters.fLastSecAccordingRSSI = FALSE; pAd->DrsCounters.LastSecTxRateChangeAction = 0; DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: MCS is according to RSSI or rate changed last sec, and ignore tuning this sec\n")); return; } do { BOOLEAN bTrainUpDown = FALSE; pAd->DrsCounters.CurrTxRateStableTime ++; // downgrade TX quality if PER >= Rate-Down threshold if (TxErrorRatio >= TrainDown) { bTrainUpDown = TRUE; pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; } // upgrade TX quality if PER <= Rate-Up threshold else if (TxErrorRatio <= TrainUp) { bTrainUpDown = TRUE; bUpgradeQuality = TRUE; if (pAd->DrsCounters.TxQuality[CurrRateIdx]) pAd->DrsCounters.TxQuality[CurrRateIdx] --; // quality very good in CurrRate if (pAd->DrsCounters.TxRateUpPenalty) pAd->DrsCounters.TxRateUpPenalty --; else if (pAd->DrsCounters.TxQuality[UpRateIdx]) pAd->DrsCounters.TxQuality[UpRateIdx] --; // may improve next UP rate's quality } pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio; if (bTrainUpDown) { // perform DRS - consider TxRate Down first, then rate up. if ((CurrRateIdx != DownRateIdx) && (pAd->DrsCounters.TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND)) { pAd->CommonCfg.TxRateIndex = DownRateIdx; } else if ((CurrRateIdx != UpRateIdx) && (pAd->DrsCounters.TxQuality[UpRateIdx] <= 0)) { pAd->CommonCfg.TxRateIndex = UpRateIdx; } } } while (FALSE); // if rate-up happen, clear all bad history of all TX rates if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) { DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: ++TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex)); pAd->DrsCounters.CurrTxRateStableTime = 0; pAd->DrsCounters.TxRateUpPenalty = 0; pAd->DrsCounters.LastSecTxRateChangeAction = 1; // rate UP NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); // // For TxRate fast train up // if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) { RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; } } // if rate-down happen, only clear DownRate's bad history else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) { DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex)); pAd->DrsCounters.CurrTxRateStableTime = 0; pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty pAd->DrsCounters.LastSecTxRateChangeAction = 2; // rate DOWN pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0; pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0; // // For TxRate fast train down // if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) { RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; } } else { pAd->DrsCounters.LastSecTxRateChangeAction = 0; // rate no change bTxRateChanged = FALSE; } pAd->DrsCounters.LastTxOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount; pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5]; if (bTxRateChanged && pNextTxRate) { MlmeSetTxRate(pAd, &pAd->MacTab.Content[BSSID_WCID], pNextTxRate); }}/* ======================================================================== Routine Description: Station side, Auto TxRate faster train up timer call back function. Arguments: SystemSpecific1 - Not used. FunctionContext - Pointer to our Adapter context. SystemSpecific2 - Not used. SystemSpecific3 - Not used. Return Value: None ========================================================================*/VOID StaQuickResponeForRateUpExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; ULONG TxTotalCnt; ULONG TxErrorRatio = 0; BOOLEAN bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE; PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; PUCHAR pTable; UCHAR TableSize = 0; UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; TX_STA_CNT1_STRUC StaTx1; TX_STA_CNT0_STRUC TxStaCnt0; CHAR Rssi, ratio; pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2); if (pAd->Antenna.field.TxPath > 1) Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1; else Rssi = pAd->StaCfg.RssiSample.AvgRssi0; CurrRateIdx = pAd->CommonCfg.TxRateIndex; MlmeSelectTxRateTable(pAd, &pTable, &TableSize, &InitTxRateIdx); // decide the next upgrade rate and downgrade rate, if any if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) { UpRateIdx = CurrRateIdx + 1; DownRateIdx = CurrRateIdx -1; } else if (CurrRateIdx == 0) { UpRateIdx = CurrRateIdx + 1; DownRateIdx = CurrRateIdx; } else if (CurrRateIdx == (TableSize - 1)) { UpRateIdx = CurrRateIdx; DownRateIdx = CurrRateIdx - 1; } pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) { TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); } else { TrainUp = pCurrTxRate->TrainUp; TrainDown = pCurrTxRate->TrainDown; } // Update statistic counter RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; pAd->WlanCounters.TransmittedFragmentCount.LowPart += StaTx1.field.TxSuccess; pAd->WlanCounters.RetryCount.LowPart += StaTx1.field.TxRetransmit; pAd->WlanCounters.FailedCount.LowPart += TxStaCnt0.field.TxFailCount; // 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 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount + pAd->RalinkCounters.OneSecTxFailCount; if (TxTotalCnt) TxErrorRatio = ((pAd->RalinkCounters.OneSecTxRetryOkCount + pAd->RalinkCounters.OneSecTxFailCount) * 100) / TxTotalCnt; DBGPRINT(RT_DEBUG_INFO, ("QuickDRS: OneSecTxNoRetryOkCount=%d, OneSecTxRetryOkCount=%d, OneSecTxFailCount=%d, TxErrorRatio=%ld \n", pAd->RalinkCounters.OneSecTxNoRetryOkCount, pAd->RalinkCounters.OneSecTxRetryOk
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -