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

📄 mlme.c

📁 D-link 无线usb网卡的Linux无线网卡驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		//	 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 > 20%, 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] < 75) && 
			((pAd->DrsCounters.PER[CurrRate] > 20) || (pAd->DrsCounters.fNoisyEnvironment)) && 
			((pAd->DrsCounters.PER[CurrRate]+5) > pAd->DrsCounters.PER[UpRate]))
		{
			// we believe this is a noisy environment. better stay at UpRate
			DBGPRINT_RAW(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_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) &&
			(pAd->DrsCounters.PER[CurrRate] <= 12))
		{
			UCHAR JumpUpRate;

			pAd->DrsCounters.fNoisyEnvironment = FALSE;
			for (JumpUpRate = RATE_54; JumpUpRate > RATE_1; JumpUpRate--)
			{
				if (dbm > RssiSafeLevelForTxRate[JumpUpRate])
					break;
			}

			if (JumpUpRate > pAd->PortCfg.MaxTxRate)
				JumpUpRate = pAd->PortCfg.MaxTxRate;
			
			DBGPRINT_RAW(RT_DEBUG_TRACE,"DRS: #### leave Noisy environment ####, RSSI=%d, JumpUpRate=%d\n",
				dbm, RateIdToMbps[JumpUpRate]);
			
			if (JumpUpRate > CurrRate)
			{
				pAd->PortCfg.TxRate = JumpUpRate;
				break;
			}
		}
#endif
		// we're going to upgrade CurrRate to UpRate at next few seconds, 
		// but before that, we'd better try a NULL frame @ UpRate and 
		// see if UpRate is stable or not. If this NULL frame fails, it will
		// downgrade TxQuality[CurrRate], so that STA won't switch to
		// to UpRate in the next second
		// 2004-04-07 requested by David Tung - sent test frames only in OFDM rates
		if (fUpgradeQuality 	 && 
			INFRA_ON(pAd)		 && 
			(UpRate != CurrRate) && 
			(UpRate > RATE_11)	 &&
			(pAd->DrsCounters.TxQuality[CurrRate] <= 1) &&
			(pAd->DrsCounters.TxQuality[UpRate] <= 1))
		{
			DBGPRINT_RAW(RT_DEBUG_TRACE,"DRS: 2 NULL frames at UpRate = %d Mbps\n",RateIdToMbps[UpRate]);
			RTMPSendNullFrame(pAd, UpRate);
		}

		// 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))
		{
#if 1			 
			// guarantee a minimum TX rate for each RSSI segments
			if ((dbm >= -45) && (DownRate < RATE_48))
				pAd->PortCfg.TxRate = RATE_48;
			else if ((dbm >= -50) && (DownRate < RATE_36))
				pAd->PortCfg.TxRate = RATE_36;
			else if ((dbm >= -55) && (DownRate < RATE_24))
				pAd->PortCfg.TxRate = RATE_24;
			else if ((dbm >= -60) && (DownRate < RATE_18))
				pAd->PortCfg.TxRate = RATE_18;
			else if ((dbm >= -65) && (DownRate < RATE_12))
				pAd->PortCfg.TxRate = RATE_12;
			else if ((dbm >= -70) && (DownRate < RATE_9))
			{
				// in 11A or 11G-only mode, no CCK rates available
				if ((pAd->PortCfg.Channel > 14) || (pAd->PortCfg.PhyMode == PHY_11G))
					pAd->PortCfg.TxRate = RATE_9;
				else
					pAd->PortCfg.TxRate = RATE_11;
			}
			else
#endif
			{
				if ((dbm >= -75) && (DownRate < RATE_11))
					pAd->PortCfg.TxRate = RATE_11;
				else
				{
#ifdef WIFI_TEST
					if (DownRate <= RATE_2) break; // never goes lower than 5.5 Mbps TX rate
#endif
					// otherwise, if DownRate still better than the low bound that current RSSI can support,
					// go straight to DownRate
					pAd->PortCfg.TxRate = DownRate;
				}
			}
		}
		else if ((pAd->DrsCounters.TxQuality[CurrRate] <= 0) && 
			(pAd->DrsCounters.TxQuality[UpRate] <=0)		 &&
			(CurrRate != UpRate))
		{
			pAd->PortCfg.TxRate = UpRate;
		}

		//
		// To make sure TxRate didn't over MaxTxRate
		//
		if (pAd->PortCfg.TxRate > pAd->PortCfg.MaxTxRate)
			pAd->PortCfg.TxRate = pAd->PortCfg.MaxTxRate;

	}while (FALSE);


	// if rate-up happen, clear all bad history of all TX rates
	if (pAd->PortCfg.TxRate > CurrRate)
	{
		DBGPRINT(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 0
//This mechanism should be changed on USB device.
		//
		// For TxRate fast train up, issued by David 2005/05/12
		// 
		if (!pAd->PortCfg.QuickResponeForRateUpTimerRunning)
		{
			if (pAd->PortCfg.TxRate <= RATE_12)
				RTMPSetTimer(pAd, &pAd->PortCfg.QuickResponeForRateUpTimer, 200);	  
			else
			  RTMPSetTimer(pAd, &pAd->PortCfg.QuickResponeForRateUpTimer, 100); 		 
		
			pAd->PortCfg.QuickResponeForRateUpTimerRunning = TRUE;
		}
#endif		
	}
	// if rate-down happen, only clear DownRate's bad history
	else if (pAd->PortCfg.TxRate < CurrRate)
	{
		DBGPRINT(RT_DEBUG_TRACE,"DRS: --TX rate from %d to %d Mbps\n", RateIdToMbps[CurrRate],RateIdToMbps[pAd->PortCfg.TxRate]);
#if 0
//Remove this code for TxRate fast train up. issued by David 2005/05/12
		// 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
#endif
		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 link up in INFRA mode, Psm should not be switch to PWR_SAVE
		   if outgoing traffic available in TxRing or MgmtRing.
	Output:
		1. change pAd->PortCfg.Psm to PWR_SAVE or leave it untouched
		

	==========================================================================
 */
VOID MlmeCheckPsmChange(
	IN PRTMP_ADAPTER pAd,
	IN ULONG	Now32)
{
	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 1-sec period
		PowerMode = pAd->PortCfg.WindowsPowerMode;
	
	if (INFRA_ON(pAd) &&
		(PowerMode != Ndis802_11PowerModeCAM) &&
		(pAd->PortCfg.Psm == PWR_ACTIVE) &&
//		(! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
		(pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
		(pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
	{
		RTUSBEnqueueInternalCmd(pAd, RT_OID_SET_PSM_BIT_SAVE);
	}

}

VOID MlmeSetPsmBit(
	IN PRTMP_ADAPTER pAd, 
	IN USHORT psm)
{
	TXRX_CSR4_STRUC csr4;
	
	pAd->PortCfg.Psm = psm;    
	RTUSBReadMACRegister(pAd, TXRX_CSR4, &csr4.word);
	csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
	RTUSBWriteMACRegister(pAd, TXRX_CSR4, csr4.word);
	DBGPRINT(RT_DEBUG_TRACE, "MlmeSetPsmBit = %d\n", psm);
}

VOID MlmeSetTxPreamble(
	IN PRTMP_ADAPTER pAd, 
	IN USHORT TxPreamble)
{
	TXRX_CSR4_STRUC csr4;
	
	RTUSBReadMACRegister(pAd, TXRX_CSR4, &csr4.word);
	if (TxPreamble == Rt802_11PreambleShort)
	{
		// NOTE: 1Mbps should always use long preamble
		DBGPRINT(RT_DEBUG_TRACE, "MlmeSetTxPreamble (= SHORT PREAMBLE)\n");
		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
		csr4.field.AutoResponderPreamble = 0;
	}
	else
	{
		DBGPRINT(RT_DEBUG_TRACE, "MlmeSetTxPreamble (= LONG PREAMBLE)\n");
		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
		csr4.field.AutoResponderPreamble = 1;
	}
	RTUSBWriteMACRegister(pAd, TXRX_CSR4, csr4.word);
}

// 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 PRTMP_ADAPTER pAd,
	IN BOOLEAN		 bLinkUp)
{
	int i, num;
	UCHAR Rate, MaxDesire = RATE_1, MaxSupport = RATE_1;
	ULONG BasicRateBitmap = 0;
	UCHAR CurrBasicRate = RATE_1;
	UCHAR *pSupRate, *pExtRate, SupRateLen, ExtRateLen;

	// find max desired rate
	num = 0;
	for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
	{
		switch (pAd->PortCfg.DesireRate[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;
	}

	// 2003-12-10 802.11g WIFI spec disallow OFDM rates in 802.11g ADHOC mode
	if ((pAd->PortCfg.BssType == BSS_ADHOC) 	   &&
		(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)
		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
	else
		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); 

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

⌨️ 快捷键说明

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