mlme.c
来自「ralink最新rt3070 usb wifi 无线网卡驱动程序」· C语言 代码 · 共 1,979 行 · 第 1/5 页
C
1,979 行
*pInitTxRateIdx = RateSwitchTable11G[1]; break; }#ifdef DOT11_N_SUPPORT#endif // DOT11_N_SUPPORT //#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) {#ifdef DOT11_N_SUPPORT //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))#endif // DOT11_N_SUPPORT // { // Legacy mode if (pAd->CommonCfg.MaxTxRate <= RATE_11) { *ppTable = RateSwitchTable11B; *pTableSize = RateSwitchTable11B[0]; *pInitTxRateIdx = RateSwitchTable11B[1]; } else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11)) { *ppTable = RateSwitchTable11G; *pTableSize = RateSwitchTable11G[0]; *pInitTxRateIdx = RateSwitchTable11G[1]; } else { *ppTable = RateSwitchTable11BG; *pTableSize = RateSwitchTable11BG[0]; *pInitTxRateIdx = RateSwitchTable11BG[1]; } break; }#ifdef DOT11_N_SUPPORT if (pAd->LatchRfRegs.Channel <= 14) { if (pAd->CommonCfg.TxStream == 1) { *ppTable = RateSwitchTable11N1S; *pTableSize = RateSwitchTable11N1S[0]; *pInitTxRateIdx = RateSwitchTable11N1S[1]; DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); } else { *ppTable = RateSwitchTable11N2S; *pTableSize = RateSwitchTable11N2S[0]; *pInitTxRateIdx = RateSwitchTable11N2S[1]; DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); } } else { if (pAd->CommonCfg.TxStream == 1) { *ppTable = RateSwitchTable11N1S; *pTableSize = RateSwitchTable11N1S[0]; *pInitTxRateIdx = RateSwitchTable11N1S[1]; DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); } else { *ppTable = RateSwitchTable11N2SForABand; *pTableSize = RateSwitchTable11N2SForABand[0]; *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); } }#endif // DOT11_N_SUPPORT // DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1])); }#endif // CONFIG_STA_SUPPORT // } while(FALSE);}#ifdef CONFIG_STA_SUPPORT/* ========================================================================== 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: ========================================================================== */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\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); RT28XX_MLME_HANDLER(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. IRQL = DISPATCH_LEVEL Output: ========================================================================== */VOID MlmeCheckForFastRoaming( IN PRTMP_ADAPTER pAd, IN ULONG Now){ USHORT i; BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; BSS_ENTRY *pBss; DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\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->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel)) continue; // RSSI too weak. forget it. if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) continue; // skip current AP if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)) continue; // skip different SSID if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA)) continue; // skip AP without better RSSI DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi)); // 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); RT28XX_MLME_HANDLER(pAd); } } // Maybe site survey required else { if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now) { // check CntlMachine.CurrState to avoid collision with NDIS SetOID request DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n")); pAd->StaCfg.ScanCnt = 2; pAd->StaCfg.LastScanTime = Now; MlmeAutoScan(pAd); } } DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));}/* ========================================================================== 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: StaCfg.ChannelQuality - 0..100 IRQL = DISPATCH_LEVEL 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; CHAR MaxRssi; ULONG BeaconLostTime = BEACON_LOST_TIME;#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier // longer beacon lost time when carrier detection enabled if (pAd->CommonCfg.CarrierDetect.Enable == TRUE) { BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2; }#endif // CARRIER_DETECTION_SUPPORT // MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2); // // 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) && (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32)) { DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt)); pAd->Mlme.ChannelQuality = 0; } else { // Normalize Rssi if (MaxRssi > -40) NorRssi = 100; else if (MaxRssi < -90) NorRssi = 0; else NorRssi = (MaxRssi + 90) * 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; } }VOID MlmeSetTxRate( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN PRTMP_TX_RATE_SWITCH pTxRate){ UCHAR MaxMode = MODE_OFDM; #ifdef DOT11_N_SUPPORT MaxMode = MODE_HTGREENFIELD; if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2)) pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE; else#endif // DOT11_N_SUPPORT // pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; if (pTxRate->CurrMCS < MCS_AUTO) pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS; if (pAd->StaCfg.HTPhyMode.field.MCS > 7) pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; if (ADHOC_ON(pAd)) { // If peer adhoc is b-only mode, we can't send 11g rate. pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; pEntry->HTPhyMode.field.STBC = STBC_NONE; // // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary // pEntry->HTPhyMode.field.MODE = pTxRate->Mode; pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; // Patch speed error in status page pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE; } else { if (pTxRate->Mode <= MaxMode) pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;#ifdef DOT11_N_SUPPORT if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI)) pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400; else#endif // DOT11_N_SUPPORT // pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;#ifdef DOT11_N_SUPPORT // Reexam each bandwidth's SGI support. if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) { if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE))) pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE))) pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; } // Turn RTS/CTS rate to 6Mbps. if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) { pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; if (pAd->MacTab.fAnyBASession) { AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); } else { AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); } } else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) { pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; if (pAd->MacTab.fAnyBASession) { AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); } else { AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); } } else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) { AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); } else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) { AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); }#endif // DOT11_N_SUPPORT // pEntry->HTPhyMode.field.STBC = pAd-
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?