⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlme.c

📁 台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 ,支持linux2.4以上的 内河
💻 C
📖 第 1 页 / 共 5 页
字号:
    TxNoRetryCnt = pAd->MACCounters[6];
    TxOneRetryCnt = pAd->MACCounters[7];
    TxMRetryCnt = pAd->MACCounters[8];
	TxRetryOkCount = TxOneRetryCnt + TxMRetryCnt;
	TxOkCount = TxNoRetryCnt + TxRetryOkCount;
	TxTotalCnt = TxOkCount + TxFailCount;
	if (TxTotalCnt > 100)
	{
		pAd->ScanAllowed = FALSE;
	}
	else
	{
		pAd->ScanAllowed = TRUE;
	}
#if 1//steven:exclude CTS
	if ((pAd->PortCfg.TxRate >= RATE_FIRST_OFDM_RATE) && (pAd->PortCfg.BGProtectionInUsed))
		TxTotalCnt = TxTotalCnt / 2;
#endif
	if (TxTotalCnt > TxFailCount)
		TxRealOkCount = TxTotalCnt - TxFailCount;
	else
		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_RAW(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_RAW(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_RAW(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_RAW(RT_DEBUG_TRACE, ("TXRX_CSR18 = 0x%x\n", Csr18.value));
					
					pAd->BeaconIntervalChangeAllowed = FALSE;
				}
#endif
			}
#if 0
			else if (pAd->ReceivedBeaconsCount > 9 * pAd->SentBeaconsCount)
			{
				DBGPRINT_RAW(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_RAW(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
    NdisMoveMemory(&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;
            NdisZeroMemory(pAd->DrsCounters.TxQuality, MAX_LEN_OF_SUPPORTED_RATES);
            NdisZeroMemory(pAd->DrsCounters.PER, 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_RAW(RT_DEBUG_TRACE,"DRS(noisy):"); 
        }
        else
        {
            DBGPRINT_RAW(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)) && 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -