📄 mlme.c
字号:
pAd->Mlme.Running = FALSE; NdisReleaseSpinLock(&pAd->Mlme.Queue.Lock);}static void cancelSMTimers( IN PRTMP_ADAPTER pAd){ RTMPCancelTimer(&pAd->Mlme.PeriodicTimer); RTMPCancelTimer(&pAd->Mlme.LinkDownTimer); RTMPCancelTimer(&pAd->MlmeAux.AssocTimer); RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer); RTMPCancelTimer(&pAd->MlmeAux.AuthTimer); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer); RTMPCancelTimer(&pAd->MlmeAux.ScanTimer); RTMPCancelTimer(&pAd->PortCfg.QuickResponeForRateUpTimer); RTMPCancelTimer(&pAd->RxAnt.RxAntDiversityTimer);} /* End cancelSMTimers () */VOID MlmeStart( IN PRTMP_ADAPTER pAd){ // Set mlme periodic timer RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);}/* ========================================================================== Description: Destructor of MLME (Destroy queue, state machine, spin lock and timer) Parameters: Adapter - NIC Adapter pointer Post: The MLME task will no longer work properly ========================================================================== */VOID MlmeHalt( IN PRTMP_ADAPTER pAd){ DBGPRINT(RT_DEBUG_TRACE, "==> MlmeHalt\n"); MlmeRestartStateMachine(pAd); // Cancel pending timers cancelSMTimers(pAd); msleep(500); //RTMPusecDelay(500000); // 0.5 sec to guarantee timer canceled RTUSBwaitTxDone(pAd); // We want to wait until all pending receives and sends to the // device object. We cancel any // irps. Wait until sends and receives have stopped. // RTUSBCancelPendingIRPs(pAd); RTUSBCleanUpMLMEWaitQueue(pAd); RTUSBCleanUpMLMEBulkOutQueue(pAd); RTUSBfreeCmdQ(pAd, &pAd->CmdQ); MlmeQueueInit(&pAd->Mlme.Queue); BssTableInit(&pAd->ScanTab); // no scan resuls when closed - bb DBGPRINT(RT_DEBUG_TRACE, "<== MlmeHalt\n");}VOID MlmeSuspend( IN PRTMP_ADAPTER pAd, IN BOOLEAN linkdown){ MLME_QUEUE_ELEM *Elem = NULL; unsigned long flags; DBGPRINT(RT_DEBUG_TRACE, "==>MlmeSuspend\n"); // Cancel pending timers cancelSMTimers(pAd); while (TRUE) { NdisAcquireSpinLock(&pAd->Mlme.Queue.Lock); if(pAd->Mlme.Running) { NdisReleaseSpinLock(&pAd->Mlme.Queue.Lock); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) return; RTMPusecDelay(100); } else { pAd->Mlme.Running = TRUE; NdisReleaseSpinLock(&pAd->Mlme.Queue.Lock); break; } } // Remove all Mlme queues elements NdisAcquireSpinLock(&pAd->Mlme.Queue.Lock); while (MlmeGetHead(&pAd->Mlme.Queue, &Elem)) { // free MLME element MlmeDequeue(&pAd->Mlme.Queue); Elem->Occupied = FALSE; } NdisReleaseSpinLock(&pAd->Mlme.Queue.Lock); RTUSBwaitTxDone(pAd); RTUSBCancelPendingIRPs(pAd); RTUSBCleanUpDataBulkInQueue(pAd); RTUSBCleanUpDataBulkOutQueue(pAd); RTUSBCleanUpMLMEBulkOutQueue(pAd); RTUSBCleanUpMLMEWaitQueue(pAd); RTUSBfreeCmdQ(pAd, &pAd->CmdQ); // Set all state machines back IDLE pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; // Remove running state NdisAcquireSpinLock(&pAd->Mlme.Queue.Lock); pAd->Mlme.Running = FALSE; NdisReleaseSpinLock(&pAd->Mlme.Queue.Lock); DBGPRINT(RT_DEBUG_TRACE, "<==MlmeSuspend\n");}VOID MlmeResume( IN PRTMP_ADAPTER pAd){ DBGPRINT(RT_DEBUG_TRACE, "==>MlmeResume\n"); // Set all state machines back IDLE pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; // If previously associated, reassociate on resume - bb. if (pAd->MlmeAux.SsidLen > 0) { memcpy(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen; } MlmePeriodicExec(pAd); DBGPRINT(RT_DEBUG_TRACE, "<==MlmeResume\n");}/* ========================================================================== Description: This routine is executed periodically to - 1. Decide if it's a right time to turn on PwrMgmt bit of all outgoiing frames 2. Calculate ChannelQuality based on statistics of the last period, so that TX rate won't toggling very frequently between a successful TX and a failed TX. 3. If the calculated ChannelQuality indicated current connection not healthy, then a ROAMing attempt is tried here. ========================================================================== */#define ADHOC_BEACON_LOST_TIME (10*HZ) // 4 sec// interrupt context (timer handler)VOID MlmePeriodicExecTimeout( IN unsigned long data){ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data; RTUSBEnqueueInternalCmd(pAd, RT_OID_PERIODIC_EXECUT);}// process contextVOID MlmePeriodicExec( IN PRTMP_ADAPTER pAd){ // Timer need to reset every time, so using do-while loop do { if (pAd->PortCfg.BssType == BSS_MONITOR) { DBGPRINT(RT_DEBUG_TRACE, "==> MlmePeriodicExec Monitor Mode\n"); break; } DBGPRINT(RT_DEBUG_TRACE, "==> MlmePeriodicExec\n"); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { DBGPRINT(RT_DEBUG_INFO, "- MlmePeriodicExec scan active\n"); break; } if ((pAd->PortCfg.bHardwareRadio == TRUE) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { RTUSBEnqueueInternalCmd(pAd, RT_OID_CHECK_GPIO); } // Do nothing if the driver is starting halt state. // This might happen when timer already been fired before cancel timer with mlmehalt if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) { DBGPRINT(RT_DEBUG_INFO, "- MlmePeriodicExec Hlt or Radio Off\n"); break; } if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_PENDING)) { RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_PENDING); DBGPRINT(RT_DEBUG_INFO, "NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"); } // // hardware failure? // if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { DBGPRINT(RT_DEBUG_INFO, "- MlmePeriodicExec NIC not exist\n"); RTUSBRejectPendingPackets(pAd); break; } pAd->Mlme.Now = jiffies; // if MGMT RING is full more than twice within 1 second, we consider there's // a hardware problem stucking the TX path. In this case, try a hardware reset // to recover the system if (pAd->RalinkCounters.MgmtRingFullCount >= 2) { RTUSBfreeCmdQ(pAd, &pAd->CmdQ); RTUSBEnqueueInternalCmd(pAd, RT_OID_RESET_FROM_ERROR); DBGPRINT(RT_DEBUG_ERROR, "<---MlmePeriodicExec (Mgmt Ring Full)\n"); break; } pAd->RalinkCounters.MgmtRingFullCount = 0; DBGPRINT(RT_DEBUG_INFO, "- MlmePeriodicExec call STAExec\n"); STAMlmePeriodicExec(pAd); } while (0); if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { /* Only start the next period if we haven't been told to close while * waiting for register I/O to complete. Otherwise, we can get into * trouble when we (redundantly) start the timer on the next open. * - bb */ if (netif_running(pAd->net_dev)) { RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV); } } DBGPRINT(RT_DEBUG_TRACE, "<== MlmePeriodicExec\n");}// process contextVOID STAMlmePeriodicExec( IN PRTMP_ADAPTER pAd){ TXRX_CSR4_STRUC CurTxRxCsr4; SHORT dbm;#if WPA_SUPPLICANT_SUPPORT union iwreq_data wrqu;#endif // WPA MIC error should block association attempt for 60 seconds if (pAd->PortCfg.bBlockAssoc && (time_after(pAd->Mlme.Now, pAd->PortCfg.LastMicErrorTime + (60*HZ)))) { pAd->PortCfg.bBlockAssoc = FALSE; } DBGPRINT(RT_DEBUG_INFO, "MMCHK - PortCfg.Ssid=%s ... MlmeAux.Ssid=%s\n", pAd->PortCfg.Ssid, pAd->MlmeAux.Ssid); // add the most up-to-date h/w raw counters into software variable, so that // the dynamic tuning mechanism below are based on most up-to-date information NICUpdateRawCounters(pAd); // danamic tune BBP R17 to find a balance between sensibility and noise isolation AsicBbpTuning(pAd); if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { // update channel quality for Roaming and UI LinkQuality display MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now); // 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 Rx Antenna is DIVERSITY ON, then perform Software-based diversity evaluation if (((pAd->Antenna.field.NumOfAntenna == 2) && (pAd->Antenna.field.TxDefaultAntenna == 0) && (pAd->Antenna.field.RxDefaultAntenna == 0)) && (pAd->Mlme.PeriodicRound % 2 == 1)) { // check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a // valid indication of the distance between this AP and its clients. if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { SHORT realavgrssi1; BOOLEAN evaluate = FALSE; if (pAd->PortCfg.NumOfAvgRssiSample < 5) { pAd->RxAnt.Pair1LastAvgRssi = (-115); pAd->RxAnt.Pair2LastAvgRssi = (-115); DBGPRINT(RT_DEBUG_TRACE, "MlmePeriodicExec: no traffic/beacon, reset RSSI\n"); } else pAd->PortCfg.NumOfAvgRssiSample = 0; realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3); DBGPRINT(RT_DEBUG_INFO,"Ant-realrssi0(%d),Lastrssi0(%d)\n",realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi); if ((realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5))) { evaluate = TRUE; pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1; } if (evaluate == TRUE) { AsicEvaluateSecondaryRxAnt(pAd); } } 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.Now); // // Lost Beacon for almost one sec && no data traffic then set R17 to lowbound.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -