mlme.c

来自「RT73无线网络芯片最新linux下驱动 支持到linux2.6.24 并向下兼」· C语言 代码 · 共 1,835 行 · 第 1/5 页

C
1,835
字号
VOID LinkDownExec(	IN PVOID SystemSpecific1,	IN PVOID FunctionContext,	IN PVOID SystemSpecific2,	IN PVOID SystemSpecific3){	//RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;}VOID MlmeAutoScan(	IN PRTMP_ADAPTER pAd){	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)	{		DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Driver auto scan\n");		MlmeEnqueue(pAd, 					MLME_CNTL_STATE_MACHINE, 					OID_802_11_BSSID_LIST_SCAN, 					0, 					NULL);		RTUSBMlmeUp(pAd);	}}	VOID MlmeAutoRecoverNetwork(	IN PRTMP_ADAPTER pAd){	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request	if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)	{		NDIS_802_11_SSID OidSsid;		OidSsid.SsidLength = pAd->PortCfg.SsidLen;		NdisMoveMemory(OidSsid.Ssid, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen);		DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Driver auto recovering network - %s\n", pAd->PortCfg.Ssid);		MlmeEnqueue(pAd, 					MLME_CNTL_STATE_MACHINE, 					OID_802_11_SSID, 					sizeof(NDIS_802_11_SSID), 					&OidSsid);	   RTUSBMlmeUp(pAd);	}}//2007/11/09:KH replace the original MlmeAutoReconnectLastSSIDVOID MlmeAutoReconnectLastSSID(	IN PRTMP_ADAPTER pAd){	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request	MLME_SCAN_REQ_STRUCT       ScanReq;	ULONG Now= pAd->Mlme.Now32;    if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && ((pAd->PortCfg.LastScanTime + (10*HZ)) >= Now))		// BUG (10 sec)    {	if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE &&		(MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))	{		NDIS_802_11_SSID OidSsid;		OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;		NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);		DBGPRINT(RT_DEBUG_TRACE, "Driver auto reconnect to last OID_802_11_SSID setting - %s\n", pAd->MlmeAux.AutoReconnectSsid);	     	/* carella modify: if no SSID, sta should not try to connect AP in scan table */			if(OidSsid.SsidLength)			{		MlmeEnqueue(pAd, 					MLME_CNTL_STATE_MACHINE, 					OID_802_11_SSID, 					sizeof(NDIS_802_11_SSID), 					&OidSsid);		RTUSBMlmeUp(pAd);	                 }            }      }      else if ((pAd->PortCfg.LastScanTime + (10*HZ)) < Now)								      {		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request		DBGPRINT(RT_DEBUG_TRACE, "MMCHK - FastRoaming, No eligable entry, try new scan!\n");		pAd->PortCfg.ScanCnt = 2;		pAd->PortCfg.LastScanTime = Now;		ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);				MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, 					sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);                RTUSBMlmeUp(pAd);		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;	}}/*	==========================================================================	Validate SSID for connection try and rescan purpose	Valid SSID will have visible chars only.	The valid length is from 0 to 32.	========================================================================== */BOOLEAN	MlmeValidateSSID(	IN PUCHAR	pSsid,	IN UCHAR	SsidLen){	int	index;	if (SsidLen > MAX_LEN_OF_SSID)		return (FALSE);	// Check each character value	for (index = 0; index < SsidLen; index++)	{		if (pSsid[index] < 0x20)			return (FALSE);	}	// All checked	return (TRUE);}/*	==========================================================================	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.			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::pAd->ScanTab.BssNr = %d\n", pAd->ScanTab.BssNr);	// 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];				DBGPRINT(RT_DEBUG_TRACE, "MlmeCheckForRoaming::pBss->LastBeaconRxTime = %d\n", pBss->LastBeaconRxTime);		if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)		{			DBGPRINT(RT_DEBUG_TRACE, "1: AP disappear::Now32 = %d\n", Now32);			continue;	 // AP disappear		}		if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)		{			DBGPRINT(RT_DEBUG_TRACE, "2: RSSI too weak::Rssi[%d] - RSSI_THRESHOLD_FOR_ROAMING[%d]\n", pBss->Rssi, RSSI_THRESHOLD_FOR_ROAMING);			continue;	 // RSSI too weak. forget it.		}		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->PortCfg.Bssid))		{			DBGPRINT(RT_DEBUG_TRACE, "3: skip current AP\n");			continue;	 // skip current AP		}		if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen))		{			DBGPRINT(RT_DEBUG_TRACE, "4: skip different SSID\n");			continue;	 // skip different SSID		}		if (pBss->Rssi < (pAd->PortCfg.LastRssi + RSSI_DELTA))		{			DBGPRINT(RT_DEBUG_TRACE, "5: only AP with stronger RSSI is eligible for roaming\n");			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 #%d\n", pAd->RalinkCounters.PoorCQIRoamingCount);			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);			RTUSBMlmeUp(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.	Output:	========================================================================== */VOID MlmeCheckForFastRoaming(	IN	PRTMP_ADAPTER	pAd,	IN	ULONG			Now){	USHORT     i;	BSS_TABLE  *pRoamTab = &pAd->MlmeAux.RoamTab;	BSS_ENTRY  *pBss;        MLME_SCAN_REQ_STRUCT       ScanReq;		DBGPRINT(RT_DEBUG_TRACE, "==> MlmeCheckForFastRoaming\n");	//        // If Scan talbe is fresh within 10 sec, then we can select the AP with the best RSSI        // Otherwise refresh this scan table.        //        //KH modified time-unit from jiffies to HZ        if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && ((pAd->PortCfg.LastScanTime + 10 * HZ) >= Now))        {           BssTableInit(pRoamTab);           // put all roaming candidates into RoamTab, and sort in RSSI order		for (i = 0; i < pAd->ScanTab.BssNr; i++)	{		pBss = &pAd->ScanTab.BssEntry[i];		/*2007/11/05:KH replace the line"if ((pBss->Rssi <= 45) && (pBss->Channel == pAd->PortCfg.Channel))" to enable the roaming between different channels.		*/			if(pBss->Rssi<=45)			continue;    // RSSI too weak. forget it.		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->PortCfg.Bssid))			continue;    // skip current AP                //2007/12/20:correct hidden bugs 		if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen) &&pBss->SsidLen>0&&pBss->Ssid[0]!=0 )			continue;    // skip different SSID		if (pBss->Rssi < (pAd->PortCfg.LastRssi + RSSI_DELTA)) 			continue;    // skip AP without better RSSI				DBGPRINT(RT_DEBUG_TRACE, "LastRssi = %d, pBss->Rssi = %d\n", pAd->PortCfg.LastRssi, pBss->Rssi);		// AP passing all above rules is put into roaming candidate table        		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));	                 //2007/12/06:KH add to fix roaming with hidden SSID		if(pBss->SsidLen==0||pBss->Ssid[0]==0)			{				DBGPRINT(RT_DEBUG_TRACE, "Roaming With NULL SSID and BSSID[#%d]=%s", pRoamTab->BssNr,pBss->Bssid);				pRoamTab->BssEntry[pRoamTab->BssNr].SsidLen=pAd->PortCfg.SsidLen;				NdisMoveMemory(pRoamTab->BssEntry[pRoamTab->BssNr].Ssid, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen);				DBGPRINT(RT_DEBUG_TRACE, "Roaming With NULL SSID after modified the BSSID[#%d]=%s with SSID[%d]=%s", pRoamTab->BssNr,pBss->Bssid,pRoamTab->BssEntry[pRoamTab->BssNr].SsidLen,pRoamTab->BssEntry[pRoamTab->BssNr].Ssid);			}		pRoamTab->BssNr += 1;	}	if (pRoamTab->BssNr > 0)	{					pAd->RalinkCounters.PoorCQIRoamingCount ++;			DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Roaming attempt #%d\n", pAd->RalinkCounters.PoorCQIRoamingCount);			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);			RTUSBMlmeUp(pAd);				}        }	// Maybe site survey required	else	{		if ((pAd->PortCfg.LastScanTime + 10*HZ) < Now)		{   		    			// check CntlMachine.CurrState to avoid collision with NDIS SetOID request			DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Roaming, No eligable entry, try a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid);                        pAd->PortCfg.ScanCnt = 2;			pAd->PortCfg.LastScanTime = Now;            ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, 						sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);			RTUSBMlmeUp(pAd);						pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;		}	}	DBGPRINT(RT_DEBUG_TRACE, "<== MlmeCheckForFastRoaming\n");	}/*	==========================================================================	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:		PortCfg.ChannelQuality - 0..100			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;	//	// 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) && 		(TxOkCnt < 2) && // no heavy traffic		(pAd->PortCfg.LastBeaconRxTime + BEACON_LOST_TIME < Now32))	{		DBGPRINT(RT_DEBUG_TRACE, "BEACON lost > %d msec with TxOkCnt=%d -> CQI=0\n", BEACON_LOST_TIME, TxOkCnt); 		pAd->Mlme.ChannelQuality = 0;	}	else	{		// Normalize Rssi		if (pAd->PortCfg.LastRssi > 0x50)			NorRssi = 100;		else if (pAd->PortCfg.LastRssi < 0x20)			NorRssi = 0;		else			NorRssi = (pAd->PortCfg.LastRssi - 0x20) * 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= %d (Tx Fail=%d/Retry=%d/Total=%d, Rx Fail=%d/Total=%d, RSSI=%d dbm)\n", 		pAd->Mlme.ChannelQuality, 		pAd->RalinkCounters.OneSecTxFailCount, 

⌨️ 快捷键说明

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