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

📄 mlme.c

📁 D-link 无线usb网卡的Linux无线网卡驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	// A band - always set BBP_R62 to 0x04
	if ((pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) && (pAd->PortCfg.Channel <= 14))
	{
		if (pAd->PortCfg.LastRssi >= (-82 + pAd->BbpRssiToDbmDelta))
		{
			RTUSBWriteBBPRegister(pAd, BBP_R62, 0x04);
		}
		else
		{
			RTUSBWriteBBPRegister(pAd, BBP_R62, 0x02);
		}
		DBGPRINT(RT_DEBUG_INFO, "STAMlmePeriodicExec - LastRssi=%d, BbpRssiToDbmDelta=%d\n", pAd->PortCfg.LastRssi, pAd->BbpRssiToDbmDelta);
	}
	
	if (INFRA_ON(pAd))
	{
		// Is PSM bit consistent with user power management policy?
		// This is the only place that will set PSM bit ON.
		MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
	
#if 0
		// patch Gemtek Prism2.5 AP bug, which stop sending BEACON for no reason
		if (INFRA_ON(pAd) &&
			(pAd->PortCfg.LastBeaconRxTime + 2500 < pAd->Mlme.Now32))  // BEACON almost starving?
		{
			DBGPRINT(RT_DEBUG_TRACE, "!!! BEACON lost > 2.5 sec !!! Send ProbeRequest\n"); 
			EnqueueProbeRequest(pAd);
		}
#endif

		//
		// Lost Beacon for almost one sec && no data traffic then set R17 to lowbound.
		//
		if (INFRA_ON(pAd) &&
			(pAd->PortCfg.LastBeaconRxTime + 1 * HZ < pAd->Mlme.Now32) &&
			((pAd->BulkInDataOneSecCount + pAd->BulkOutDataOneSecCount) < 600))
		{
			if (pAd->PortCfg.Channel <= 14)
			{
				RTUSBWriteBBPRegister(pAd, BBP_R17, pAd->BbpTuning.R17LowerBoundG);
			}
			else
			{
				RTUSBWriteBBPRegister(pAd, BBP_R17, pAd->BbpTuning.R17LowerBoundA);
			}
		}

#if 0
		//Move the flowing code to RTUSBHardTransmit, after prepare EAPOL frame that idicated MIC error
		//To meet the WiFi Test Plan "The STAUT must deauthenticate itself from the AP".
		//Also need to bloc association frame.

		//The flowing code on here can't send disassociation frame to the AP, since AP may send deauthentication
		//	frame, on the meanwhile, station will call link down and then this code can't be performed.

		// Check for EAPOL frame sent after MIC countermeasures
		if (pAd->PortCfg.MicErrCnt >= 3)
		{
	
			MLME_DISASSOC_REQ_STRUCT	DisassocReq;

			// disassoc from current AP first
			DBGPRINT(RT_DEBUG_TRACE, ("MLME - disassociate with current AP after sending second continuous EAPOL frame\n"));
			DisassocParmFill(pAd, &DisassocReq, pAd->PortCfg.Bssid, REASON_MIC_FAILURE);
			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, 
						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);

			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
			pAd->PortCfg.bBlockAssoc = TRUE;
		}
#endif
			// send out a NULL frame every 10 sec. for what??? inform "PwrMgmt" bit?
			if ((pAd->Mlme.PeriodicRound % 10) == 8)
				RTMPSendNullFrame(pAd, pAd->PortCfg.TxRate);
		
			if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
			{
				DBGPRINT(RT_DEBUG_TRACE, "MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%d\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount);
	
				// Lost AP, send disconnect & link down event
				RTUSBEnqueueInternalCmd(pAd, RT_OID_LINK_DOWN);
	
				// RTMPPatchMacBbpBug(pAd);
				MlmeAutoReconnectLastSSID(pAd);
			}
			else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
			{
				pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
				DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Bad CQI. Auto Recovery attempt #%d\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount);
				MlmeAutoReconnectLastSSID(pAd);
			}
			else if (CQI_IS_POOR(pAd->Mlme.ChannelQuality))
			{
				// perform aggresive roaming only when SECURITY OFF or WEP64/128;
				// WPA and WPA-PSK has no aggresive roaming because re-negotiation 
				// between 802.1x supplicant and authenticator/AAA server is required
				// but can't be guaranteed.
				if (pAd->PortCfg.AuthMode < Ndis802_11AuthModeWPA)
					MlmeCheckForRoaming(pAd, pAd->Mlme.Now32);
			}
		}

	// !!! Regard the IBSS network as established one while both ADHOC_ON and fOP_STATUS_MEDIA_STATE_CONNECTED are TRUE !!!
#ifndef SINGLE_ADHOC_LINKUP 	   
	 else if (ADHOC_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))	
	 {	
		// If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
		// to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
		// join later.
		if ((pAd->PortCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32))
		{
			DBGPRINT(RT_DEBUG_TRACE, "MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"); 
	
			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
			// clean up previous SCAN result, add current BSS back to table if any
			BssTableDeleteEntry(&pAd->ScanTab, pAd->PortCfg.Bssid, pAd->PortCfg.Channel);
		
			pAd->PortCfg.LastScanTime = pAd->Mlme.Now32;
		}
	}	 
#endif
	else // no INFRA nor ADHOC connection
	{
		if (!ADHOC_ON(pAd) && !INFRA_ON(pAd)) 
		{
			DBGPRINT(RT_DEBUG_INFO, "MLME periodic exec, no association so far\n");
			
			if ((pAd->PortCfg.bAutoReconnect == TRUE) && 
			    (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
			{
				if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
				{
					MLME_SCAN_REQ_STRUCT	   ScanReq;
			  
					if ((pAd->PortCfg.LastScanTime + 10 * HZ) < pAd->Mlme.Now32)
					{
						DBGPRINT(RT_DEBUG_TRACE, "CNTL - No matching BSS, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid);
						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, FALSE);
						pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
						// Reset Missed scan number
						pAd->PortCfg.LastScanTime = pAd->Mlme.Now32;
					}
					else if (pAd->PortCfg.BssType == BSS_ADHOC)  // Quit the forever scan when in a very clean room
					{
						MlmeAutoReconnectLastSSID(pAd);
					}	 
				}
				else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
				{
					if ((pAd->Mlme.PeriodicRound % 20) == 8)
					{
						MlmeAutoScan(pAd);
						pAd->PortCfg.LastScanTime = pAd->Mlme.Now32;					
					}
					else if ((pAd->Mlme.PeriodicRound % 2) == 0)
					{
						MlmeAutoReconnectLastSSID(pAd);
					}
					DBGPRINT(RT_DEBUG_INFO, "pAd->PortCfg.bAutoReconnect is TRUE\n");
				}

				// after once scanning, set wpanone-psk key in the case of using configuration file
				if (pAd->Mlme.PeriodicRound >= 4)
				{
					if ((pAd->PortCfg.BssType == BSS_ADHOC) &&
						(pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)&&
						((pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
						(pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)) &&
						(pAd->PortCfg.WpaState == SS_START))
					{
						RTMPWPANoneAddKeyProc(pAd, pAd->PortCfg.PskKey.Key);
						// turn on the flag of PortCfg.WpaState as reading profile 
						// and reset after adding key
						pAd->PortCfg.WpaState = SS_NOTUSE;
					}	 
				}
			}
		}
	}

	// if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
	// restore outgoing BEACON to support B/G-mixed mode
	if (ADHOC_ON(pAd))
	{
		// 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
		// the "TX BEACON competition" for the entire past 1 sec.
		// So that even when ASIC's BEACONgen engine been blocked
		// by peer's BEACON due to slower system clock, this STA still can send out
		// minimum BEACON to tell the peer I'm alive.
		// drawback is that this BEACON won't be well aligned at TBTT boundary.
		EnqueueBeaconFrame(pAd);			  // software send BEACON

		if ((pAd->PortCfg.Channel <= 14)			 &&
			(pAd->PortCfg.MaxTxRate <= RATE_11) 	 &&
			(pAd->PortCfg.MaxDesiredRate > RATE_11)  &&
			((pAd->PortCfg.Last11bBeaconRxTime + 5 * HZ) < pAd->Mlme.Now32))
		{
			DBGPRINT(RT_DEBUG_TRACE, "MMCHK - last 11B peer left, update Tx rates\n"); 

			NdisMoveMemory(pAd->ActiveCfg.SupRate, pAd->PortCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
			pAd->ActiveCfg.SupRateLen = pAd->PortCfg.SupRateLen;

			RTUSBEnqueueInternalCmd(pAd, RT_OID_UPDATE_TX_RATE);	//MlmeUpdateTxRates(pAd, FALSE);
			AsicEnableIbssSync(pAd);	// copy to on-chip memory
		}
		

	}


	if (((pAd->Mlme.PeriodicRound % 2) == 0) &&
		(INFRA_ON(pAd) || ADHOC_ON(pAd)))
	{
		RTMPSetSignalLED(pAd, pAd->PortCfg.LastRssi - pAd->BbpRssiToDbmDelta);
	}

	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
	{
		//
		// Modify retry times (maximum 15) on low data traffic.
		// Should fix ping lost.
		//
		dbm = pAd->PortCfg.AvgRssi - pAd->BbpRssiToDbmDelta;
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED))
		{
			if (pAd->RalinkCounters.OneSecTxNoRetryOkCount > 15)
			{
				RTUSBReadMACRegister(pAd, TXRX_CSR4, &CurTxRxCsr4.word);
				CurTxRxCsr4.field.ShortRetryLimit = 0x07;
				CurTxRxCsr4.field.LongRetryLimit = 0x04;
				RTUSBWriteMACRegister(pAd, TXRX_CSR4, CurTxRxCsr4.word);
				OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED);
			}
		}
		else
		{
			if (pAd->RalinkCounters.OneSecTxNoRetryOkCount <= 15)
			{
				RTUSBReadMACRegister(pAd, TXRX_CSR4, &CurTxRxCsr4.word);
				CurTxRxCsr4.field.ShortRetryLimit = 0x0f;
				CurTxRxCsr4.field.LongRetryLimit = 0x0f;
				RTUSBWriteMACRegister(pAd, TXRX_CSR4, CurTxRxCsr4.word);
				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED);
			}
		}

		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RTS_PROTECTION_ENABLE))
		{
			if ((dbm > -60) || (pAd->RalinkCounters.OneSecTxNoRetryOkCount > 15))
				OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_RTS_PROTECTION_ENABLE);			
		}
		else
		{
			//
			// for long distance case, turn on RTS to protect data frame.
			//
			if ((dbm <= -60) && (pAd->RalinkCounters.OneSecTxNoRetryOkCount <= 15))
			{
				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RTS_PROTECTION_ENABLE);
            }
		}
	}

	//
	// Clear Tx/Rx Traffic one second count.
	//
	pAd->BulkLastOneSecCount = pAd->BulkOutDataOneSecCount + pAd->BulkInDataOneSecCount;
	pAd->BulkOutDataOneSecCount = 0;
	pAd->BulkInDataOneSecCount = 0;	

	// clear all OneSecxxx counters.
	pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
	pAd->RalinkCounters.OneSecFalseCCACnt = 0;
	pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
	pAd->RalinkCounters.OneSecRxOkCnt = 0;
	pAd->RalinkCounters.OneSecTxFailCount = 0;
	pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
	pAd->RalinkCounters.OneSecTxRetryOkCount = 0;

	// TODO: for debug only. to be removed
	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
	pAd->RalinkCounters.OneSecTxDoneCount = 0;
	pAd->RalinkCounters.OneSecTxAggregationCount = 0;
	pAd->RalinkCounters.OneSecRxAggregationCount = 0;	

	pAd->Mlme.PeriodicRound ++;
}

VOID LinkDownExec(
	IN	unsigned long data) 
{
	//RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
}

VOID MlmeAutoScan(
	IN PRTMP_ADAPTER pAd)
{
	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
	
	// tell CNTL state machine NOT to call NdisMSetInformationComplete() after completing
	// this request, because this request is initiated by driver itself.
	pAd->MlmeAux.CurrReqIsFromNdis = FALSE;

	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,
					FALSE);
		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);

		// tell CNTL state machine NOT to call NdisMSetInformationComplete() after completing
		// this request, because this request is initiated by driver itself.
		pAd->MlmeAux.CurrReqIsFromNdis = FALSE; 
					
		MlmeEnqueue(pAd, 
					MLME_CNTL_STATE_MACHINE, 
					OID_802_11_SSID, 
					sizeof(NDIS_802_11_SSID), 
					&OidSsid,
					FALSE);
	   RTUSBMlmeUp(pAd);
	}

}

VOID MlmeAutoReconnectLastSSID(
	IN PRTMP_ADAPTER pAd)
{
	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
	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);

⌨️ 快捷键说明

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