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

📄 mlme.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	}	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:	========================================================================== */VOID MlmeCheckForFastRoaming(	IN	PRTMP_ADAPTER	pAd,	IN	ULONG			Now){	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;	}	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);			MlmeHandler(pAd);		}	}	// Maybe site survey required	else	{		if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)		{			// check CntlMachine.CurrState to avoid collision with NDIS SetOID request			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));			pAd->StaCfg.ScanCnt = 2;			pAd->StaCfg.LastScanTime = Now;			MlmeAutoScan(pAd);		}	}    DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));}/*	==========================================================================	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;	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 + BEACON_LOST_TIME < Now32))	{		DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %d msec with TxOkCnt=%ld -> CQI=0\n", BEACON_LOST_TIME, 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;	}	DBGPRINT(RT_DEBUG_INFO, ("MMCHK - CQI= %ld (Tx Fail=%u/Retry=%u/Total=%lu, Rx Fail=%u/Total=%lu, RSSI=%d dbm)\n", 		pAd->Mlme.ChannelQuality, 		pAd->RalinkCounters.OneSecTxFailCount, 		pAd->RalinkCounters.OneSecTxRetryOkCount, 		TxCnt, 		pAd->RalinkCounters.OneSecRxFcsErrCnt, 		RxCnt, MaxRssi));}VOID MlmeSetTxRate(	IN PRTMP_ADAPTER		pAd,	IN PMAC_TABLE_ENTRY		pEntry,	IN PRTMP_TX_RATE_SWITCH	pTxRate){	if (pTxRate->STBC && (pAd->CommonCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))		pAd->CommonCfg.HTPhyMode.field.STBC = STBC_USE;	else		pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;	if (pTxRate->ShortGI && (pAd->CommonCfg.MaxHTPhyMode.field.ShortGI))		pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_400;	else		pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;	if (pTxRate->CurrMCS < MCS_AUTO)		pAd->CommonCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;	if (pAd->CommonCfg.HTPhyMode.field.MCS > 7)		pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE; 		if (pTxRate->Mode <= MODE_HTGREENFIELD)		pAd->CommonCfg.HTPhyMode.field.MODE = pTxRate->Mode;	pEntry->HTPhyMode.field.STBC	= pAd->CommonCfg.HTPhyMode.field.STBC;	pEntry->HTPhyMode.field.ShortGI	= pAd->CommonCfg.HTPhyMode.field.ShortGI;	pEntry->HTPhyMode.field.MCS		= pAd->CommonCfg.HTPhyMode.field.MCS;	pEntry->HTPhyMode.field.MODE	= pAd->CommonCfg.HTPhyMode.field.MODE;    pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);	DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: MlmeSetTxRate - CurrTxRateIdx=%d, MCS=%d, STBC=%d, ShortGI=%d, Mode=%d, BW=%d \n", pAd->CommonCfg.TxRateIndex,		pAd->CommonCfg.HTPhyMode.field.MCS,	pAd->CommonCfg.HTPhyMode.field.STBC, pAd->CommonCfg.HTPhyMode.field.ShortGI,		pAd->CommonCfg.HTPhyMode.field.MODE, pAd->CommonCfg.HTPhyMode.field.BW));}VOID MlmeSelectTxRateTable(	IN PRTMP_ADAPTER		pAd,	IN PUCHAR				*ppTable,	IN PUCHAR				pTableSize,	IN PUCHAR				pInitTxRateIdx){	// decide the rate table for tuning	if (pAd->CommonCfg.TxRateTableSize > 0)	{		*ppTable = RateSwitchTable;		*pTableSize = RateSwitchTable[0];		*pInitTxRateIdx = RateSwitchTable[1];		DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: rate table is from rate.bin \n"));	}	else if (ADHOC_ON(pAd))	{		if (pAd->CommonCfg.PhyMode == PHY_11B)		{			*ppTable = RateSwitchTable11B;			*pTableSize = RateSwitchTable11B[0];			*pInitTxRateIdx = RateSwitchTable11B[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: B only Adhoc \n"));		}		else if (pAd->LatchRfRegs.Channel <= 14)		{			*ppTable = RateSwitchTable11BG;			*pTableSize = RateSwitchTable11BG[0];			*pInitTxRateIdx = RateSwitchTable11BG[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: B/G mixed Adhoc \n"));		}		else		{			*ppTable = RateSwitchTable11G;			*pTableSize = RateSwitchTable11G[0];			*pInitTxRateIdx = RateSwitchTable11G[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: A/G Adhoc \n"));		}	}	else	{		if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedHtPhy.MCSSet[0] == 0xff) &&			((pAd->StaActive.SupportedHtPhy.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))		{// 11BGN 1S AP			*ppTable = RateSwitchTable11BGN1S;			*pTableSize = RateSwitchTable11BGN1S[0];			*pInitTxRateIdx = RateSwitchTable11BGN1S[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: 11BGN 1S AP \n"));		}		else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedHtPhy.MCSSet[0] == 0xff) &&			(pAd->StaActive.SupportedHtPhy.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))		{// 11BGN 2S AP			*ppTable = RateSwitchTable11BGN2S;			*pTableSize = RateSwitchTable11BGN2S[0];			*pInitTxRateIdx = RateSwitchTable11BGN2S[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: 11BGN 2S AP \n"));		}		else if ((pAd->StaActive.SupportedHtPhy.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedHtPhy.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))		{// 11N 1S AP			*ppTable = RateSwitchTable11N1S;			*pTableSize = RateSwitchTable11N1S[0];			*pInitTxRateIdx = RateSwitchTable11N1S[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: 11N 1S AP \n"));		}		else if ((pAd->StaActive.SupportedHtPhy.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedHtPhy.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))		{// 11N 2S AP			*ppTable = RateSwitchTable11N2S;			*pTableSize = RateSwitchTable11N2S[0];			*pInitTxRateIdx = RateSwitchTable11N2S[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: 11N 2S AP \n"));		}		else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedHtPhy.MCSSet[0] == 0) && (pAd->StaActive.SupportedHtPhy.MCSSet[1] == 0))		{// B only AP			*ppTable = RateSwitchTable11B;			*pTableSize = RateSwitchTable11B[0];			*pInitTxRateIdx = RateSwitchTable11B[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: B only AP \n"));		}		else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedHtPhy.MCSSet[0] == 0) && (pAd->StaActive.SupportedHtPhy.MCSSet[1] == 0))		{// B/G  mixed AP			*ppTable = RateSwitchTable11BG;			*pTableSize = RateSwitchTable11BG[0];			*pInitTxRateIdx = RateSwitchTable11BG[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: B/G mixed AP \n"));		}		else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedHtPhy.MCSSet[0] == 0) && (pAd->StaActive.SupportedHtPhy.MCSSet[1] == 0))		{// G only AP			*ppTable = RateSwitchTable11G;			*pTableSize = RateSwitchTable11G[0];			*pInitTxRateIdx = RateSwitchTable11G[1];			DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: A/G AP \n"));		}		else		{			*ppTable = RateSwitchTable11N2S;			*pTableSize = RateSwitchTable11N2S[0];			*pInitTxRateIdx = RateSwitchTable11N2S[1];			DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode \n"));		}	}}/*	==========================================================================	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					TxTotalCnt;	ULONG					TxErrorRatio = 0;	BOOLEAN					bTxRateChanged = TRUE, bUpgradeQuality = FALSE;	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;	PUCHAR					pTable;	UCHAR					TableSize = 0;	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;	CHAR					Rssi;	CurrRateIdx = pAd->CommonCfg.TxRateIndex;//	Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);	if (pAd->Antenna.field.TxPath > 1)		Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;	else		Rssi = pAd->StaCfg.RssiSample.AvgRssi0;	MlmeSelectTxRateTable(pAd, &pTable, &TableSize, &InitTxRateIdx);	// decide the next upgrade rate and downgrade rate, if any	if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))	{		UpRateIdx = CurrRateIdx + 1;		DownRateIdx = CurrRateIdx -1;	}	else if (CurrRateIdx == 0)	{		UpRateIdx = CurrRateIdx + 1;		DownRateIdx = CurrRateIdx;	}	else if (CurrRateIdx == (TableSize - 1))	{		UpRateIdx = CurrRateIdx;		DownRateIdx = CurrRateIdx - 1;	}	pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];	if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))	{		TrainUp		= (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));		TrainDown	= (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));	}	else	{		TrainUp		= pCurrTxRate->TrainUp;		TrainDown	= pCurrTxRate->TrainDown;	}	// 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	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + 				 pAd->RalinkCounters.OneSecTxRetryOkCount + 				 pAd->RalinkCounters.OneSecTxFailCount;		if (TxTotalCnt)		TxErrorRatio = ((pAd->RalinkCounters.OneSecTxRetryOkCount + pAd->RalinkCounters.OneSecTxFailCount) * 100) / TxTotalCnt;	DBGPRINT_RAW(RT_DEBUG_INFO,("DRS: OneSecTxRetryOkCount=%d, OneSecTxFailCount=%d, OneSecTxNoRetryOkCount=%d \n",

⌨️ 快捷键说明

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