📄 mlme.c
字号:
TxRealOkCount = 0; OldValue = pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart; pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart += TxRealOkCount; if (pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart < OldValue) { pAd->WlanCounters.TransmittedFragmentCount.vv.HighPart++; } AsicBbpTuning(pAd); if (pAd->MediaState == NdisMediaStateConnected) { if (TxTotalCnt < 5) // if too few TX samples, skip TX related statistics { TxPER = 0; // don't take TxPER into CQI consideration if too few sample TxPRR = 0; } else { if (TxFailCount < TxTotalCnt) { USHORT temp = TxOneRetryCnt + TxMRetryCnt + TxFailCount; TxPER = (TxFailCount * 100) / TxTotalCnt; if (temp < TxTotalCnt) TxPRR = (temp * 100) / TxTotalCnt; else TxPRR = 100; } else TxPER = 100; } // // calculate RX PER // RxFailCnt = pAd->MACCounters[0]; RxOkCnt = pAd->WlanCounters.ReceivedFragmentCount.vv.LowPart - pAd->Mlme.PrevWlanCounters.ReceivedFragmentCount.vv.LowPart; RxCnt = RxOkCnt + RxFailCnt; if (RxCnt < 5) RxPER = 0; // don't take RxPER into ChannelQuality consideration if too few sample else RxPER = (RxFailCnt * 100) / RxCnt; if ((ADHOC_ON(pAd)) && (pAd->MediaState == NdisMediaStateConnected)) { pAd->SentBeaconsCount += pAd->MACCounters[5]; pAd->ReceivedBeaconsCount += pAd->MACCounters[10]; if ((pAd->Mlme.PeriodicRound % 2) == 1) { TXRX_CSR18_STRUC Csr18; USHORT temp; DBGPRINT(RT_DEBUG_INFO, "SentBeaconsCount = %d ReceivedBeaconsCount = %d\n", pAd->SentBeaconsCount, pAd->ReceivedBeaconsCount); if (pAd->BeaconIntervalChangeAllowed == TRUE) { if (2 * pAd->SentBeaconsCount > pAd->ReceivedBeaconsCount) { temp = (pAd->PortCfg.BeaconPeriod << 8) + 1; Csr18.field.Offset = (temp & 0x000F); Csr18.field.Interval = (temp >> 6); RTUSBWriteMACRegister(pAd, TXRX_CSR18, Csr18.value); DBGPRINT(RT_DEBUG_INFO, "TXRX_CSR18 = 0x%x\n", Csr18.value); pAd->BeaconIntervalChangeAllowed = FALSE; } else if (pAd->ReceivedBeaconsCount > 9 * pAd->SentBeaconsCount) { temp = (pAd->PortCfg.BeaconPeriod << 8) - 5; Csr18.field.Offset = (temp & 0x000F); Csr18.field.Interval = (temp >> 6); RTUSBWriteMACRegister(pAd, TXRX_CSR18, Csr18.value); DBGPRINT(RT_DEBUG_INFO, "TXRX_CSR18 = 0x%x\n", Csr18.value); pAd->BeaconIntervalChangeAllowed = FALSE; } else if (pAd->ReceivedBeaconsCount > 3 * pAd->SentBeaconsCount) { temp = (pAd->PortCfg.BeaconPeriod << 8) - 1; Csr18.field.Offset = (temp & 0x000F); Csr18.field.Interval = (temp >> 6); RTUSBWriteMACRegister(pAd, TXRX_CSR18, Csr18.value); DBGPRINT(RT_DEBUG_INFO, "TXRX_CSR18 = 0x%x\n", Csr18.value); pAd->BeaconIntervalChangeAllowed = FALSE; }#if 0 else if (pAd->ReceivedBeaconsCount > 2 * pAd->SentBeaconsCount) { temp = (pAd->PortCfg.BeaconPeriod << 8) - 1; Csr18.field.Offset = (temp & 0x000F); Csr18.field.Interval = (temp >> 6); RTUSBWriteMACRegister(pAd, TXRX_CSR18, Csr18.value); DBGPRINT(RT_DEBUG_TRACE, ("TXRX_CSR18 = 0x%x\n", Csr18.value)); pAd->BeaconIntervalChangeAllowed = FALSE; }#endif }#if 0 else if (pAd->ReceivedBeaconsCount > 9 * pAd->SentBeaconsCount) { DBGPRINT(RT_DEBUG_TRACE, ("Do Nothing\n")); }#endif else { temp = (pAd->PortCfg.BeaconPeriod << 8); Csr18.field.Offset = (temp & 0x000F); Csr18.field.Interval = (temp >> 6); RTUSBWriteMACRegister(pAd, TXRX_CSR18, Csr18.value); DBGPRINT(RT_DEBUG_INFO, "TXRX_CSR18 = 0x%x\n", Csr18.value); pAd->BeaconIntervalChangeAllowed = TRUE; } pAd->SentBeaconsCount = 0; pAd->ReceivedBeaconsCount = 0; } } Now32 = jiffies; { // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * pAd->PortCfg.LastRssi + TX_WEIGHTING * (100 - TxPRR) + RX_WEIGHTING* (100 - RxPER)) / 100; if (pAd->Mlme.ChannelQuality >= 100) pAd->Mlme.ChannelQuality = 100; } DBGPRINT(RT_DEBUG_INFO, "MMCHK - CQI= %d, (Tx Fail=%d/Retry=%d/Total=%d, Rx Fail=%d/Total=%d, RSSI=%d dbm)\n", pAd->Mlme.ChannelQuality, TxFailCount, TxRetryOkCount, TxTotalCnt, RxFailCnt, RxCnt, pAd->PortCfg.LastRssi - pAd->BBPTuningParameters.RSSIToDbmOffset); // latch current WLAN counters for next check-for-roaming usage memcpy(&pAd->Mlme.PrevWlanCounters, &pAd->WlanCounters, sizeof(COUNTER_802_11));#if 1//steven:move this from MlmePeriodicExec if (INFRA_ON(pAd)) { if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) { pAd->RalinkCounters.BadCQIAutoRecoveryCount ++; DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Bad CQI. Auto Recovery attempt #%d\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount); MlmeAutoRecoverNetwork(pAd); } else if (CQI_IS_FAIR(pAd->Mlme.ChannelQuality) || CQI_IS_POOR(pAd->Mlme.ChannelQuality)) { // perform aggresive roaming only when SECURITY OFF or WEP64/128; // WPA and WPA-PSK has no aggresive roaming because re-negotiation // between 802.1x supplicant and authenticator/AAA server is required // but can't be guaranteed. if (pAd->PortCfg.AuthMode < Ndis802_11AuthModeWPA) MlmeCheckForRoaming(pAd, Now32); } }#endif pAd->PortCfg.CurrTxRateStableTime++; CurrRate = pAd->PortCfg.TxRate; do { USHORT TxErrorRatio; BOOLEAN fUpgradeQuality = FALSE; USHORT *pRateUpPER, *pRateDownPER; if (pAd->PortCfg.EnableAutoRateSwitching == FALSE) break; // do nothing if no traffic in the past period if (TxTotalCnt == 0) { // TxRateUpPenalty maybe too large, we don't want this penalty to affect // next Chariot throughput test too much therefore zero it here. pAd->PortCfg.TxRateUpPenalty = 0; memset(pAd->DrsCounters.TxQuality, 0, MAX_LEN_OF_SUPPORTED_RATES); memset(pAd->DrsCounters.PER, 0, MAX_LEN_OF_SUPPORTED_RATES); break; } // decide the next upgrade rate and downgrade rate, if any if (pAd->PortCfg.PhyMode == PHY_11BG_MIXED) { UpRate = Phy11BGNextRateUpward[CurrRate]; DownRate = Phy11BGNextRateDownward[CurrRate]; } else if (pAd->PortCfg.PhyMode == PHY_11B) { UpRate = Phy11BNextRateUpward[CurrRate]; DownRate = Phy11BNextRateDownward[CurrRate]; } else if (pAd->PortCfg.PhyMode == PHY_11A) { UpRate = Phy11ANextRateUpward[CurrRate]; DownRate = Phy11ANextRateDownward[CurrRate]; } else // PHY_11ABG_MIXED { if (pAd->PortCfg.Channel > 14) { UpRate = Phy11ANextRateUpward[CurrRate]; DownRate = Phy11ANextRateDownward[CurrRate]; } else { UpRate = Phy11BGNextRateUpward[CurrRate]; DownRate = Phy11BGNextRateDownward[CurrRate]; } } if (UpRate > pAd->PortCfg.MaxTxRate) UpRate = pAd->PortCfg.MaxTxRate; // decide TX quality based on Tx retry ratio when enough samples are available if (TxTotalCnt > 15) { USHORT temp = TxRetryOkCount + TxFailCount; if (temp < TxTotalCnt) TxErrorRatio = (temp *100) / TxTotalCnt; else TxErrorRatio = 100; pRateUpPER = &NewRateUpPER[0]; pRateDownPER = &NewRateDownPER[0]; // downgrade TX quality if retry+error ratio reached if (TxErrorRatio >= pRateDownPER[CurrRate]) { pAd->DrsCounters.TxQuality[CurrRate] = DRS_TX_QUALITY_WORST_BOUND; } // upgrade TX quality if retry+error ratio reached else if (TxErrorRatio <= pRateUpPER[CurrRate]) { fUpgradeQuality = TRUE; if (pAd->DrsCounters.TxQuality[CurrRate]) pAd->DrsCounters.TxQuality[CurrRate] --; // quality very good in CurrRate if (pAd->PortCfg.TxRateUpPenalty) pAd->PortCfg.TxRateUpPenalty --; else if (pAd->DrsCounters.TxQuality[UpRate]) pAd->DrsCounters.TxQuality[UpRate] --; // may improve next UP rate's quality } } // if not enough TX samples, decide by heuristic rules else { TxErrorRatio = 0; // Downgrade TX quality upon - // 1. any TX failure in the past second // 2. TX retry ratio too high when enough TX samples are available if (TxFailCount) { if ((TxFailCount <= 1) && (TxRealOkCount + TxRetryOkCount)) { pAd->DrsCounters.TxQuality[CurrRate] += 2; // degrade quality if (pAd->DrsCounters.TxQuality[CurrRate] > DRS_TX_QUALITY_WORST_BOUND) pAd->DrsCounters.TxQuality[CurrRate] = DRS_TX_QUALITY_WORST_BOUND; } else // more than 2 failure, or no TX ok cases { pAd->DrsCounters.TxQuality[CurrRate] = DRS_TX_QUALITY_WORST_BOUND; // quality bad } } // upgrade TX quality if - // 1. no TX failure but do have TX ok case, and // 2. there's more one-time-ok cases than retry-ok cases in the past second // 3. current rate's Tx retry ratio <= 10% else if ((TxRealOkCount > TxRetryOkCount)) { fUpgradeQuality = TRUE; if (pAd->DrsCounters.TxQuality[CurrRate]) pAd->DrsCounters.TxQuality[CurrRate] --; // quality very good in CurrRate if (pAd->PortCfg.TxRateUpPenalty) pAd->PortCfg.TxRateUpPenalty --; else if (pAd->DrsCounters.TxQuality[UpRate]) pAd->DrsCounters.TxQuality[UpRate] --; // may improve next UP rate's quality } } pAd->DrsCounters.PER[CurrRate] = (UCHAR)TxErrorRatio; if (pAd->DrsCounters.fNoisyEnvironment) { DBGPRINT(RT_DEBUG_TRACE,"DRS(noisy): "); } else { DBGPRINT(RT_DEBUG_TRACE,"DRS: "); } DBGPRINT_RAW(RT_DEBUG_TRACE,"Qty[%d]=%d PER=%d%% %d-sec, Qty[%d]=%d, Pty=%d\n", RateIdToMbps[CurrRate], pAd->DrsCounters.TxQuality[CurrRate], TxErrorRatio, pAd->DrsCounters.CurrTxRateStableTime, RateIdToMbps[UpRate], pAd->DrsCounters.TxQuality[UpRate], pAd->DrsCounters.TxRateUpPenalty); // 2004-3-13 special case: Claim noisy environment // decide if there was a false "rate down" in the past 2 sec due to noisy // environment. if so, we would rather switch back to the higher TX rate. // criteria - // 1. there's a higher rate available, AND // 2. there was a rate-down happened, AND // 3. current rate has 75% > PER > 25%, AND // 4. comparing to UpRate, current rate didn't improve PER more than 5 % if ((UpRate != CurrRate) && (pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (((pAd->DrsCounters.PER[CurrRate] > 20) || (pAd->DrsCounters.fNoisyEnvironment)) && (pAd->DrsCounters.PER[CurrRate] < 75)) && ((pAd->DrsCounters.PER[CurrRate]+5) > pAd->DrsCounters.PER[UpRate])) { // we believe this is a noisy environment. better stay at UpRate DBGPRINT(RT_DEBUG_TRACE,"DRS: #### enter Noisy environment ####\n"); pAd->DrsCounters.fNoisyEnvironment = TRUE; // 2004-3-14 when claiming noisy environment, we're not only switch back // to UpRate, but can be more aggressive to use one more rate up UpRate++;// if (UpRate>RATE_54) UpRate=RATE_54; if ((UpRate==RATE_6) || (UpRate==RATE_9)) UpRate=RATE_12; if (UpRate > pAd->PortCfg.MaxTxRate) UpRate = pAd->PortCfg.MaxTxRate; pAd->PortCfg.TxRate = UpRate; break; } // 2004-3-12 special case: Leave noisy environment // The interference has gone suddenly. reset TX rate to // the theoritical value according to RSSI. Criteria - // 1. it's currently in noisy environment // 2. PER drops to be below 12% if ((pAd->DrsCounters.fNoisyEnvironment == TRUE) && (TxTotalCnt > 15) && (pAd->DrsCounters.PER[CurrRate] <= 12)) { UCHAR JumpUpRate;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -