mlme.c

来自「ralink最新rt3070 usb wifi 无线网卡驱动程序」· C语言 代码 · 共 1,979 行 · 第 1/5 页

C
1,979
字号
			*pInitTxRateIdx = RateSwitchTable11G[1];						break;		}#ifdef DOT11_N_SUPPORT#endif // DOT11_N_SUPPORT //#ifdef CONFIG_STA_SUPPORT		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)		{#ifdef DOT11_N_SUPPORT			//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))			if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))#endif // DOT11_N_SUPPORT //			{	// Legacy mode				if (pAd->CommonCfg.MaxTxRate <= RATE_11)				{					*ppTable = RateSwitchTable11B;					*pTableSize = RateSwitchTable11B[0];					*pInitTxRateIdx = RateSwitchTable11B[1];				}				else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))				{					*ppTable = RateSwitchTable11G;					*pTableSize = RateSwitchTable11G[0];					*pInitTxRateIdx = RateSwitchTable11G[1];									}				else						{					*ppTable = RateSwitchTable11BG;					*pTableSize = RateSwitchTable11BG[0];					*pInitTxRateIdx = RateSwitchTable11BG[1];				}				break;			}#ifdef DOT11_N_SUPPORT			if (pAd->LatchRfRegs.Channel <= 14)			{				if (pAd->CommonCfg.TxStream == 1)				{					*ppTable = RateSwitchTable11N1S;					*pTableSize = RateSwitchTable11N1S[0];					*pInitTxRateIdx = RateSwitchTable11N1S[1];					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));				}				else				{					*ppTable = RateSwitchTable11N2S;					*pTableSize = RateSwitchTable11N2S[0];					*pInitTxRateIdx = RateSwitchTable11N2S[1];					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));									}			}			else			{				if (pAd->CommonCfg.TxStream == 1)				{					*ppTable = RateSwitchTable11N1S;					*pTableSize = RateSwitchTable11N1S[0];					*pInitTxRateIdx = RateSwitchTable11N1S[1];					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));				}				else				{					*ppTable = RateSwitchTable11N2SForABand;					*pTableSize = RateSwitchTable11N2SForABand[0];					*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));									}			}#endif // DOT11_N_SUPPORT //			DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",				pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));		}#endif // CONFIG_STA_SUPPORT //	} while(FALSE);}#ifdef CONFIG_STA_SUPPORT/*	==========================================================================	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 + BEACON_LOST_TIME) < 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);			RT28XX_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:	========================================================================== */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);			RT28XX_MLME_HANDLER(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;	ULONG BeaconLostTime = BEACON_LOST_TIME;#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier	// longer beacon lost time when carrier detection enabled	if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)	{		BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/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-

⌨️ 快捷键说明

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