📄 mlme.c
字号:
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { // update channel quality for Roaming and UI LinkQuality display MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32); // perform dynamic tx rate switching based on past TX history MlmeDynamicTxRateSwitching(pAd); } // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if // Radio is currently in noisy environment AsicAdjustTxPower(pAd); 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); pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt; if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) && ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600))) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd)))); } // send out a NULL frame every 10 sec. for what??? inform "PwrMgmt" bit? if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) && (pAd->StaActive.SupportedHtPhy.bHtEnable == FALSE)) RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE); if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) { DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount)); pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE; pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime; // Lost AP, send disconnect & link down event LinkDown(pAd, FALSE); #ifdef WPA_SUPPLICANT_SUPPORT#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT if (pAd->StaCfg.WpaSupplicantUP) { union iwreq_data wrqu; //send disassociate 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 // NATIVE_WPA_SUPPLICANT_SUPPORT //#endif // WPA_SUPPLICANT_SUPPORT // #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT { union iwreq_data wrqu; memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); }#endif // NATIVE_WPA_SUPPLICANT_SUPPORT // // 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 #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount)); MlmeAutoReconnectLastSSID(pAd); } // Add auto seamless roaming if (pAd->StaCfg.bFastRoaming) { SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam; DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam)); if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam) { MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32); } } } else 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 all 11b peers leave this BSS more than 5 seconds, update Tx rate, // restore outgoing BEACON to support B/G-mixed mode if ((pAd->CommonCfg.Channel <= 14) && (pAd->CommonCfg.MaxTxRate <= RATE_11) && (pAd->CommonCfg.MaxDesiredRate > RATE_11) && ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32)) { DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n")); NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES); pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen; MlmeUpdateTxRates(pAd, FALSE); MakeIbssBeacon(pAd); // re-build BEACON frame AsicEnableIbssSync(pAd); // copy to on-chip memory } //radar detect if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { RadarDetectPeriodic(pAd); }#ifndef SINGLE_ADHOC_LINKUP // 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->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { UCHAR i; DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n")); NdisAcquireSpinLock(&pAd->MacTabLock); for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++) { if (pAd->MacTab.Size == 0) break; if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) { // free resources of BA BASessionTearDownALL(pAd, i); pAd->MacTab.Content[i].ValidAsCLI = FALSE; RTMPZeroMemory(pAd->MacTab.Content[i].Addr, MAC_ADDR_LEN); pAd->MacTab.Size --; AsicDelWcidTab(pAd, i); } pAd->MacTab.Content[i].ValidAsWDS = FALSE; } RTMPZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); NdisReleaseSpinLock(&pAd->MacTabLock); // Delete every BA session with BSSID before tear down INFRA. OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_IndicateMediaState(); // clean up previous SCAN result, add current BSS back to table if any BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel); pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; }#endif } else // no INFRA nor ADHOC connection { DBGPRINT(RT_DEBUG_INFO, ("STAMlmePeriodicExec, no association so far\n"));#ifdef WPA_SUPPLICANT_SUPPORT if (pAd->StaCfg.WpaSupplicantUP == 1) return;#endif // WPA_SUPPLICANT_SUPPORT // if ((pAd->StaCfg.bAutoReconnect == TRUE) && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP) && (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->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32) { DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, 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->StaCfg.LastScanTime = pAd->Mlme.Now32; } else if (pAd->StaCfg.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.OneSecPeriodicRound % 10) == 7) { if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32) { MlmeAutoScan(pAd); pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; } } else MlmeAutoReconnectLastSSID(pAd); DBGPRINT(RT_DEBUG_INFO, ("pAd->StaCfg.bAutoReconnect is TRUE\n")); } } } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { // // Only on infrastructure mode will change the RetryLimit & MPDU expiration time. // if (INFRA_ON(pAd)) { if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED)) { // // UPdate Retry & MPDU expiration time to normal // if (pAd->RalinkCounters.OneSecTxNoRetryOkCount > 15) { // // Update Retry for none Aggregate frame. // RTMP_IO_READ32(pAd, TX_RTY_CFG, &CurTxRryCfg.word); CurTxRryCfg.field.ShortRtyLimit = 0x07; CurTxRryCfg.field.LongRtyLimit = 0x04; CurTxRryCfg.field.AggRtyMode = 0x01; RTMP_IO_WRITE32(pAd, TX_RTY_CFG, CurTxRryCfg.word); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED); } } else { // // For low throughput or noise envirnment, update retry to 0xf and expiration time to 1sec. // if (pAd->RalinkCounters.OneSecTxNoRetryOkCount <= 15) { // // Update Retry for none Aggregate frame. // RTMP_IO_READ32(pAd, TX_RTY_CFG, &CurTxRryCfg.word); CurTxRryCfg.field.ShortRtyLimit = 0x0f; CurTxRryCfg.field.LongRtyLimit = 0x0f; CurTxRryCfg.field.AggRtyMode = 0x00; RTMP_IO_WRITE32(pAd, TX_RTY_CFG, CurTxRryCfg.word); OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED); } } } }}// Link down reportVOID LinkDownExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_IndicateMediaState();}// IRQL = DISPATCH_LEVELVOID 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); MlmeHandler(pAd); }} // IRQL = DISPATCH_LEVELVOID 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); DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen)); MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, sizeof(NDIS_802_11_SSID), &OidSsid); MlmeHandler(pAd); }}#endif // CONFIG_STA_SUPPORT ///* ========================================================================== Validate SSID for connection try and rescan purpose Valid SSID will have visible chars only. The valid length is from 0 to 32. IRQL = DISPATCH_LEVEL ========================================================================== */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. IRQL = DISPATCH_LEVEL Output: ========================================================================== */#ifdef CONFIG_STA_SUPPORTVOID 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); MlmeHandler(pAd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -