📄 mlme.c
字号:
}
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 + -