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

📄 mlme.c

📁 台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 ,支持linux2.4以上的 内河
💻 C
📖 第 1 页 / 共 5 页
字号:
			(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;

            pAd->DrsCounters.fNoisyEnvironment = FALSE;
            for (JumpUpRate = RATE_54; JumpUpRate > RATE_1; JumpUpRate--)
            {
                if (pAd->PortCfg.AvgRssi > (RssiSafeLevelForTxRate[JumpUpRate] + pAd->BBPTuningParameters.RSSIToDbmOffset))
                    break;
            }

            if (JumpUpRate > pAd->PortCfg.MaxTxRate)
                JumpUpRate = pAd->PortCfg.MaxTxRate;
            
            DBGPRINT(RT_DEBUG_TRACE,"DRS: #### leave Noisy environment ####, RSSI=%d, JumpUpRate=%d\n",
                pAd->PortCfg.AvgRssi - pAd->BBPTuningParameters.RSSIToDbmOffset, RateIdToMbps[JumpUpRate]);
            
            if (JumpUpRate > CurrRate)
            {
                pAd->PortCfg.TxRate = JumpUpRate;
               	break;
            }
        }
        
        // perform DRS - consider TxRate Down first, then rate up.
        //     1. rate down, if current TX rate's quality is not good
        //     2. rate up, if UPRate's quality is very good
        if ((pAd->DrsCounters.TxQuality[CurrRate] >= DRS_TX_QUALITY_WORST_BOUND) &&
            (CurrRate != DownRate))
        {

			pAd->PortCfg.TxRate = DownRate;
        }
        else if ((pAd->DrsCounters.TxQuality[CurrRate] <= 0) && 
            (pAd->DrsCounters.TxQuality[UpRate] <=0)         &&
            (CurrRate != UpRate))
        {
            pAd->PortCfg.TxRate = UpRate;
        }
    }while (FALSE);

    // if rate-up happen, clear all bad history of all TX rates
    if (pAd->PortCfg.TxRate > CurrRate)
    {
       	DBGPRINT_RAW(RT_DEBUG_TRACE,"DRS: ++TX rate from %d to %d Mbps\n", RateIdToMbps[CurrRate],RateIdToMbps[pAd->PortCfg.TxRate]);
        pAd->DrsCounters.CurrTxRateStableTime = 0;
        pAd->DrsCounters.TxRateUpPenalty = 0;
        pAd->DrsCounters.LastSecTxRateChangeAction = 1; // rate UP
        NdisZeroMemory(pAd->DrsCounters.TxQuality, MAX_LEN_OF_SUPPORTED_RATES);
        NdisZeroMemory(pAd->DrsCounters.PER, MAX_LEN_OF_SUPPORTED_RATES);
    }
    // if rate-down happen, only clear DownRate's bad history
    else if (pAd->PortCfg.TxRate < CurrRate)
    {
       	DBGPRINT_RAW(RT_DEBUG_TRACE,"DRS: --TX rate from %d to %d Mbps\n", RateIdToMbps[CurrRate],RateIdToMbps[pAd->PortCfg.TxRate]);
	    // shorter stable time require more penalty in next rate UP criteria
       	if (pAd->DrsCounters.CurrTxRateStableTime < 4)      // less then 4 sec
       	    pAd->DrsCounters.TxRateUpPenalty = DRS_PENALTY; // add 8 sec penalty
       	else if (pAd->DrsCounters.CurrTxRateStableTime < 8) // less then 8 sec
       	    pAd->DrsCounters.TxRateUpPenalty = 2;           // add 2 sec penalty
       	else                                                // >= 8 sec
       	    pAd->DrsCounters.TxRateUpPenalty = 0;           // no penalty
       	    
        pAd->DrsCounters.CurrTxRateStableTime = 0;
        pAd->DrsCounters.LastSecTxRateChangeAction = 2; // rate DOWN
       	pAd->DrsCounters.TxQuality[pAd->PortCfg.TxRate] = 0;
       	pAd->DrsCounters.PER[pAd->PortCfg.TxRate] = 0;
    }
    else
        pAd->DrsCounters.LastSecTxRateChangeAction = 0; // rate no change
	}


}

/*
    ==========================================================================
    Description:
        This routine is executed periodically inside MlmePeriodicExec() after 
        association with an AP.
        It checks if PortCfg.Psm is consistent with user policy (recorded in
        PortCfg.WindowsPowerMode). If not, enforce user policy. However, 
        there're some conditions to consider:
        1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
           the time when Mibss==TRUE
        2. When Massoc==TRUE (INFRA mode), Psm should not be switch to PWR_SAVE
           if outgoing traffic available in TxRing or PrioRing.
    Output:
        1. change pAd->PortCfg.Psm to PWR_SAVE or leave it untouched
        
	IRQL = DISPATCH_LEVEL

    ==========================================================================
 */
VOID MlmeCheckForPsmChange(
    IN PRT2570ADAPTER pAd)
{
	ULONG	PowerMode;
    // condition -
    // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
    // 2. user wants either MAX_PSP or FAST_PSP
    // 3. but current psm is not in PWR_SAVE
    // 4. CNTL state machine is not doing SCANning
    // 5. no TX SUCCESS event for the past period
    	PowerMode = pAd->PortCfg.WindowsPowerMode;
    
    if (INFRA_ON(pAd) &&
        (PowerMode != Ndis802_11PowerModeCAM) &&
		(pAd->BulkOutPending == FALSE) &&
		(LOCAL_TX_RING_EMPTY(pAd)) &&
		(pAd->SendTxWaitQueue.Number == 0) &&
        (pAd->PortCfg.Psm == PWR_ACTIVE) &&
        (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
        (pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart == pAd->Mlme.PrevTxCnt))
    {
		RTUSBEnqueueInternalCmd(pAd, RT_OID_SET_PSM_BIT_SAVE);
    }
    
    // latch current count for next-time comparison
    pAd->Mlme.PrevTxCnt = pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart;

}

// IRQL = PASSIVE_LEVEL
// IRQL = DISPATCH_LEVEL
VOID MlmeSetPsmBit(
    IN PRT2570ADAPTER pAd, 
    IN USHORT psm)
{
    pAd->PortCfg.Psm = psm;    
    
    DBGPRINT(RT_DEBUG_TEMP, "MMCHK - change PSM bit to %d <<<\n", psm);
}

// IRQL = DISPATCH_LEVEL
// IRQL = DISPATCH_LEVEL
VOID MlmeSetTxPreamble(
    IN PRT2570ADAPTER pAd, 
    IN USHORT TxPreamble)
{
	USHORT	value;

    RTUSBReadMACRegister(pAd, TXRX_CSR10, &value);
    if (TxPreamble == Rt802_11PreambleShort)
    {
        DBGPRINT(RT_DEBUG_TRACE, "MlmeSetTxPreamble (= SHORT PREAMBLE)\n");
		value |= 0x0004;
        pAd->PortCfg.TxPreambleInUsed = Rt802_11PreambleShort;
    }
    else
    {
        DBGPRINT(RT_DEBUG_TRACE, "MlmeSetTxPreamble (= LONG PREAMBLE)\n");
		value &= 0xFFFB;
        pAd->PortCfg.TxPreambleInUsed = Rt802_11PreambleLong;
    }

    RTUSBWriteMACRegister(pAd, TXRX_CSR10, value);
}
    
// IRQL = PASSIVE_LEVEL
// IRQL = DISPATCH_LEVEL
// bLinkUp is to identify the inital link speed.
// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
VOID MlmeUpdateTxRates(
    IN PRT2570ADAPTER pAd,
    IN BOOLEAN		 bLinkUp)
{
    int i, num;
    UCHAR Rate, MaxDesire = RATE_1, MaxSupport = RATE_1;
    USHORT BasicRateBitmap = 0;
    UCHAR CurrBasicRate = RATE_1;

    // find max desired rate
    num = 0;
    for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
    {
        switch (pAd->PortCfg.DesiredRates[i] & 0x7f)
        {
            case 2:  Rate = RATE_1;   num++;   break;
            case 4:  Rate = RATE_2;   num++;   break;
            case 11: Rate = RATE_5_5; num++;   break;
            case 22: Rate = RATE_11;  num++;   break;
            case 12: Rate = RATE_6;   num++;   break;
            case 18: Rate = RATE_9;   num++;   break;
            case 24: Rate = RATE_12;  num++;   break;
            case 36: Rate = RATE_18;  num++;   break;
            case 48: Rate = RATE_24;  num++;   break;
            case 72: Rate = RATE_36;  num++;   break;
            case 96: Rate = RATE_48;  num++;   break;
            case 108: Rate = RATE_54; num++;   break;
            default: Rate = RATE_1;   break;
        }
        if (MaxDesire < Rate)  MaxDesire = Rate;

		// Fixed the Maximum rate of 2426 to b only
		if (pAd->PortCfg.RfType == RFIC_2426)
			if (MaxDesire > RATE_11)
				MaxDesire = RATE_11;
    }

    // 2003-12-10 802.11g WIFI spec disallow OFDM rates in 802.11g ADHOC mode
    if ((pAd->PortCfg.BssType == BSS_INDEP)        &&
        (pAd->PortCfg.PhyMode == PHY_11BG_MIXED)   && 
        (pAd->PortCfg.AdhocMode == 0) &&
        (MaxDesire > RATE_11))
        MaxDesire = RATE_11;
    
    pAd->PortCfg.MaxDesiredRate = MaxDesire;
    
    // Auto rate switching is enabled only if more than one DESIRED RATES are 
    // specified; otherwise disabled
    if (num <= 1)
        pAd->PortCfg.EnableAutoRateSwitching = FALSE;
    else
        pAd->PortCfg.EnableAutoRateSwitching = TRUE;

    // find max supported rate
    for (i=0; i<pAd->PortCfg.SupportedRatesLen; i++)
    {
        switch (pAd->PortCfg.SupportedRates[i] & 0x7f)
        {
            case 2: Rate = RATE_1;   
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0001;  
                    break;
            case 4: Rate = RATE_2;   
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0002;  
                    break;
            case 11: 
                    Rate = RATE_5_5; 
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0004;  
                    break;
            case 22: 
                    Rate = RATE_11;  
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0008;  
                    break;
            case 12: 
                    Rate = RATE_6;   
//                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0010;  
                    break;
            case 18: 
                    Rate = RATE_9;   
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0020;  
                    break;
            case 24: 
                    Rate = RATE_12;  
//                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0040;  
                    break;
            case 36: 
                    Rate = RATE_18;  
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0080;  
                    break;
            case 48: 
                    Rate = RATE_24;  
//                  if (pAd->PortCfg.SupportedRates[i] & 0x80) 
						BasicRateBitmap |= 0x0100;  
                    break;
            case 72: 
                    Rate = RATE_36;  
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0200;  
                    break;
            case 96: 
                    Rate = RATE_48;  
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0400;  
                    break;
            case 108: 
                    Rate = RATE_54; 
                    if (pAd->PortCfg.SupportedRates[i] & 0x80) 
                        BasicRateBitmap |= 0x0800;  
                    break;
            default:  
                    Rate = RATE_1;   
                    break;
        }
        if (MaxSupport < Rate)  MaxSupport = Rate;
    }

	// Limit the max support rate and basic rate map to 11b only
	if (pAd->PortCfg.RfType == RFIC_2426)
	{
		if (MaxSupport > RATE_11)
		{
			MaxSupport = RATE_11;
			BasicRateBitmap &= 0x000f;
		}
	}
	
	RTUSBWriteMACRegister(pAd, TXRX_CSR11, BasicRateBitmap);

    // calculate the exptected ACK rate for each TX rate. This info is used to caculate
    // the DURATION field of outgoing uniicast DATA/MGMT frame
    for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
    {
        if (BasicRateBitmap & (0x01 << i))
            CurrBasicRate = (UCHAR)i;
        pAd->PortCfg.ExpectedACKRate[i] = CurrBasicRate;
        DBGPRINT(RT_DEBUG_INFO,"Exptected ACK rate[%d] = %d Mbps\n", RateIdToMbps[i], RateIdToMbps[CurrBasicRate]);
    }

    // max tx rate

⌨️ 快捷键说明

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