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

📄 mlme.c

📁 ralink 2870 usb无线网卡 最新驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*	==========================================================================	Description:		This routine checks if there're other APs out there capable for		roaming. Caller should call this routine only when Link up in INFRA mode		and channel quality is below CQI_GOOD_THRESHOLD.	IRQL = DISPATCH_LEVEL	Output:	========================================================================== */VOID MlmeCheckForRoaming(	IN PRTMP_ADAPTER pAd,	IN ULONG	Now32){	USHORT	   i;	BSS_TABLE  *pRoamTab = &pAd->MlmeAux.RoamTab;	BSS_ENTRY  *pBss;	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));	// put all roaming candidates into RoamTab, and sort in RSSI order	BssTableInit(pRoamTab);	for (i = 0; i < pAd->ScanTab.BssNr; i++)	{		pBss = &pAd->ScanTab.BssEntry[i];		if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) < Now32) 			continue;	 // AP disappear		if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)			continue;	 // RSSI too weak. forget it.		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))			continue;	 // skip current AP		if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))			continue;	 // only AP with stronger RSSI is eligible for roaming		// AP passing all above rules is put into roaming candidate table		 		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));		pRoamTab->BssNr += 1;	}	if (pRoamTab->BssNr > 0)	{		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)		{			pAd->RalinkCounters.PoorCQIRoamingCount ++;			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);			RTMP_MLME_HANDLER(pAd);		}	}	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));   }/*	==========================================================================	Description:		This routine checks if there're other APs out there capable for		roaming. Caller should call this routine only when link up in INFRA mode		and channel quality is below CQI_GOOD_THRESHOLD.	IRQL = DISPATCH_LEVEL	Output:	========================================================================== */BOOLEAN MlmeCheckForFastRoaming(	IN	PRTMP_ADAPTER	pAd){	USHORT		i;	BSS_TABLE	*pRoamTab = &pAd->MlmeAux.RoamTab;	BSS_ENTRY	*pBss;	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));	// put all roaming candidates into RoamTab, and sort in RSSI order	BssTableInit(pRoamTab);	for (i = 0; i < pAd->ScanTab.BssNr; i++)	{		pBss = &pAd->ScanTab.BssEntry[i];        if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))			continue;	 // RSSI too weak. forget it.		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))			continue;	 // skip current AP		if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))			continue;	 // skip different SSID        if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA)) 			continue;	 // skip AP without better RSSI		        DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));		// AP passing all above rules is put into roaming candidate table		 		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));		pRoamTab->BssNr += 1;	}	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));	if (pRoamTab->BssNr > 0)	{		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)		{			pAd->RalinkCounters.PoorCQIRoamingCount ++;			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);			RTMP_MLME_HANDLER(pAd);			return TRUE;		}	}	return FALSE;}/*	==========================================================================	Description:		This routine calculates TxPER, RxPER of the past N-sec period. And 		according to the calculation result, ChannelQuality is calculated here 		to decide if current AP is still doing the job. 		If ChannelQuality is not good, a ROAMing attempt may be tried later.	Output:		StaCfg.ChannelQuality - 0..100	IRQL = DISPATCH_LEVEL	NOTE: This routine decide channle quality based on RX CRC error ratio.		Caller should make sure a function call to NICUpdateRawCounters(pAd)		is performed right before this routine, so that this routine can decide		channel quality based on the most up-to-date information	========================================================================== */VOID MlmeCalculateChannelQuality(	IN PRTMP_ADAPTER pAd,	IN ULONG Now32){	ULONG TxOkCnt, TxCnt, TxPER, TxPRR;	ULONG RxCnt, RxPER;	UCHAR NorRssi;	CHAR  MaxRssi;	ULONG BeaconLostTime = pAd->StaCfg.BeaconLostTime;#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier	// longer beacon lost time when carrier detection enabled	if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)	{		BeaconLostTime = pAd->StaCfg.BeaconLostTime + (pAd->StaCfg.BeaconLostTime/2);	}#endif // CARRIER_DETECTION_SUPPORT //	MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);	//	// calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics	//	TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;	TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;	if (TxCnt < 5) 	{		TxPER = 0;		TxPRR = 0;	}	else 	{		TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt; 		TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;	}	//	// calculate RX PER - don't take RxPER into consideration if too few sample	//	RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;	if (RxCnt < 5)		RxPER = 0;		else		RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;	//	// decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER	//	if (INFRA_ON(pAd) && 		(pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic		((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32))	{		DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt)); 		pAd->Mlme.ChannelQuality = 0;	}	else	{		// Normalize Rssi		if (MaxRssi > -40)			NorRssi = 100;		else if (MaxRssi < -90)			NorRssi = 0;		else			NorRssi = (MaxRssi + 90) * 2;				// ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER	 (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)		pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi + 								   TX_WEIGHTING * (100 - TxPRR) + 								   RX_WEIGHTING* (100 - RxPER)) / 100;		if (pAd->Mlme.ChannelQuality >= 100)			pAd->Mlme.ChannelQuality = 100;	}	}VOID MlmeSetTxRate(	IN PRTMP_ADAPTER		pAd,	IN PMAC_TABLE_ENTRY		pEntry,	IN PRTMP_TX_RATE_SWITCH	pTxRate){	UCHAR	MaxMode = MODE_OFDM;	#ifdef DOT11_N_SUPPORT	MaxMode = MODE_HTGREENFIELD;	if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))		pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;	else#endif // DOT11_N_SUPPORT //		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;	if (pTxRate->CurrMCS < MCS_AUTO)		pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;	if (pAd->StaCfg.HTPhyMode.field.MCS > 7)		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; 	   	if (ADHOC_ON(pAd))	{		// If peer adhoc is b-only mode, we can't send 11g rate.		pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;		pEntry->HTPhyMode.field.STBC	= STBC_NONE;		//		// For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary		//		pEntry->HTPhyMode.field.MODE	= pTxRate->Mode;		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;		// Patch speed error in status page		pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;	}	else    {		if (pTxRate->Mode <= MaxMode)		pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;#ifdef DOT11_N_SUPPORT        if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;		else#endif // DOT11_N_SUPPORT //			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;#ifdef DOT11_N_SUPPORT		// Reexam each bandwidth's SGI support.		if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)		{			if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;			if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;		}        // Turn RTS/CTS rate to 6Mbps.		if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))		{			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;			if (pAd->MacTab.fAnyBASession)			{				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);			}			else			{				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);			}		}		else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))		{			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;			if (pAd->MacTab.fAnyBASession)			{				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);			}			else			{				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);			}		}		else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))		{			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);		}		else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))		{			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);		}#endif // DOT11_N_SUPPORT //        		pEntry->HTPhyMode.field.STBC	= pAd->StaCfg.HTPhyMode.field.STBC;		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;		pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;#ifdef DOT11_N_SUPPORT        if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&            pAd->WIFItestbed.bGreenField)            pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;#endif // DOT11_N_SUPPORT //    }	    pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);}/*	==========================================================================	Description:		This routine calculates the acumulated TxPER of eaxh TxRate. And 		according to the calculation result, change CommonCfg.TxRate which 		is the stable TX Rate we expect the Radio situation could sustained. 		CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate} 	Output:		CommonCfg.TxRate - 	IRQL = DISPATCH_LEVEL	NOTE:		call this routine every second	========================================================================== */VOID MlmeDynamicTxRateSwitching(	IN PRTMP_ADAPTER pAd){	UCHAR					UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;	ULONG					i, AccuTxTotalCnt = 0, TxTotalCnt;	ULONG					TxErrorRatio = 0;	BOOLEAN					bTxRateChanged = FALSE, bUpgradeQuality = FALSE;	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;	PUCHAR					pTable;	UCHAR					TableSize = 0;	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;	CHAR					Rssi, RssiOffset = 0;	TX_STA_CNT1_STRUC		StaTx1;	TX_STA_CNT0_STRUC		TxStaCnt0;	ULONG					TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;	MAC_TABLE_ENTRY			*pEntry;#ifdef RALINK_ATE	if (ATE_ON(pAd))	{		return;	}#endif // RALINK_ATE //	//	// walk through MAC table, see if need to change AP's TX rate toward each entry	//   	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) 	{		pEntry = &pAd->MacTab.Content[i];			// check if this entry need to switch rate automatically		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)			continue;		if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))		{			Rssi = RTMPMaxRssi(pAd, 							   pAd->StaCfg.RssiSample.AvgRssi0, 							   pAd->StaCfg.RssiSample.AvgRssi1, 							   pAd->StaCfg.RssiSample.AvgRssi2);						// Update statistic counter			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);			pAd->bUpdateBcnCntDone = TRUE;			TxRetransmit = StaTx1.field.TxRetransmit;			TxSuccess = StaTx1.field.TxSuccess;			TxFailCount = TxStaCnt0.field.TxFailCount;			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;			pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;			pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;			pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;			pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;			pAd->WlanCounters.FailedCount.u.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			AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + 						 pAd->RalinkCounter

⌨️ 快捷键说明

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