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

📄 mlme.c

📁 RT73_Linux_STA_Drv1.0.3.6 linux系统下
💻 C
📖 第 1 页 / 共 5 页
字号:
		}
		else
		{
			UCHAR	temp;

			temp = pAd->RxAnt.Pair1PrimaryRxAnt;
			pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
			pAd->RxAnt.Pair1SecondaryRxAnt = temp;
			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt, 0xFF);	//0xFF means not used.
		}
	}

	// G band - set BBP_R62 to 0x02 when site survey or rssi<-82
	// 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);

#if WPA_SUPPLICANT_SUPPORT
            if (pAd->PortCfg.WPA_Supplicant == TRUE) {
                // send disassoc event to wpa_supplicant 
               memset(&wrqu, 0, sizeof(wrqu));
               wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
               wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
            }
#endif
	
            // 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);
        }
// TODO: temp removed
#if 0
        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);
        }
#endif
        // fast roaming
        if (pAd->PortCfg.bFastRoaming)
        {
            // Check the RSSI value, we should begin the roaming attempt
            INT RxSignal = pAd->PortCfg.LastRssi - pAd->BbpRssiToDbmDelta;

            DBGPRINT(RT_DEBUG_TRACE, "RxSignal %d\n", RxSignal);
            // Only perform action when signal is less than or equal to setting from the UI or registry
            if (pAd->PortCfg.LastRssi <= (pAd->BbpRssiToDbmDelta - pAd->PortCfg.dBmToRoam))
            {
                MlmeCheckForFastRoaming(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);
						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))
	{
		// 1.	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.
		// 2.	avoid mlme-queue full while doing radar detection
		if ((pAd->PortCfg.bIEEE80211H == 0) || (pAd->PortCfg.RadarDetect.RDMode == RD_NORMAL_MODE))
			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
		}
		

		//radar detect
		if (((pAd->PortCfg.PhyMode == PHY_11A) || (pAd->PortCfg.PhyMode == PHY_11ABG_MIXED)) && (pAd->PortCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->PortCfg.Channel))
		{
			// need to check channel availability, after switch channel
			if (pAd->PortCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
			{
				pAd->PortCfg.RadarDetect.RDCount++;
				
				// channel availability check time is 60sec
				if (pAd->PortCfg.RadarDetect.RDCount > 65)
				{
					if (RadarDetectionStop(pAd))
					{
						pAd->ExtraInfo = DETECT_RADAR_SIGNAL;
						pAd->PortCfg.RadarDetect.RDCount = 0;		// stat at silence mode and detect radar signal
						DBGPRINT(RT_DEBUG_TRACE, "Found radar signal!!!\n\n");
					}
					else
					{
						DBGPRINT(RT_DEBUG_TRACE, "Not found radar signal, start send beacon\n");
						AsicEnableIbssSync(pAd);
						pAd->PortCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
					}
				}
			}
		}

	}


	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;

		//
		// Only on infrastructure mode will change the RetryLimit.
		//
		if (INFRA_ON(pAd))
		{
			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;

⌨️ 快捷键说明

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