📄 mlme.c
字号:
DBGPRINT_RAW(RT_DEBUG_TRACE, "!!! reset MLME state machine !!!\n"); MlmeRestartStateMachine(pAd); MlmePostRestartStateMachine(pAd); Elem->Occupied = FALSE; Elem->MsgLen = 0; continue; } // if dequeue success switch (Elem->Machine) { case ASSOC_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem); break; case AUTH_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem); break; case AUTH_RSP_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem); break; case SYNC_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem); break; case MLME_CNTL_STATE_MACHINE: MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem); break; case WPA_PSK_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem); break; default: DBGPRINT(RT_DEBUG_TRACE, "ERROR: Illegal machine in MlmeHandler()\n"); break; } // end of switch // free MLME element Elem->Occupied = FALSE; Elem->MsgLen = 0; } else { DBGPRINT_ERR("MlmeHandler: MlmeQueue empty\n"); } } NdisAcquireSpinLock(&pAd->Mlme.TaskLock, IrqFlags); pAd->Mlme.bRunning = FALSE; NdisReleaseSpinLock(&pAd->Mlme.TaskLock, IrqFlags);}/* ========================================================================== 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) { BOOLEAN Cancelled; DBGPRINT(RT_DEBUG_TRACE, "==> MlmeHalt\n"); // Cancel pending timers RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled); RTMPusecDelay(500000); // 0.5 sec to guarantee timer canceled MlmeQueueDestroy(&pAd->Mlme.Queue); NdisFreeSpinLock(&pAd->Mlme.TaskLock); MlmeFreeMemoryHandler(pAd); //Free MLME memory handler DBGPRINT(RT_DEBUG_TRACE, "<== MlmeHalt\n");}VOID MlmeSuspend( IN PRTMP_ADAPTER pAd, IN BOOLEAN linkdown) { MLME_QUEUE_ELEM *Elem = NULL; unsigned long IrqFlags; BOOLEAN Cancelled; DBGPRINT(RT_DEBUG_TRACE, "==>MlmeSuspend\n"); // Cancel pending timers RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); while (TRUE) { NdisAcquireSpinLock(&pAd->Mlme.TaskLock, IrqFlags); if(pAd->Mlme.bRunning) { NdisReleaseSpinLock(&pAd->Mlme.TaskLock, IrqFlags); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) return; RTMPusecDelay(100); } else { pAd->Mlme.bRunning = TRUE; NdisReleaseSpinLock(&pAd->Mlme.TaskLock, IrqFlags); break; } } // Remove all Mlme queues elements while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) { //From message type, determine which state machine I should drive if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) { // free MLME element Elem->Occupied = FALSE; Elem->MsgLen = 0; } else { DBGPRINT(RT_DEBUG_ERROR, "ERROR: empty Elem in MlmeQueue\n"); } } // Remove running state NdisAcquireSpinLock(&pAd->Mlme.TaskLock, IrqFlags); pAd->Mlme.bRunning = FALSE; NdisReleaseSpinLock(&pAd->Mlme.TaskLock, IrqFlags); RTUSBCleanUpMLMEWaitQueue(pAd); RTUSBCleanUpMLMEBulkOutQueue(pAd); // 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 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);//steven:for test DBGPRINT(RT_DEBUG_TRACE, "<==MlmeSuspend\n");}VOID MlmeResume( IN PRTMP_ADAPTER pAd){ DBGPRINT(RT_DEBUG_TRACE, "==>MlmeResume\n"); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);//steven:for test // 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; 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 VOID MlmePeriodicExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3){ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; unsigned long IrqFlags; if(VIRTUAL_IF_NUM(pAd)==0) return;#ifdef RALINK_ATE if(pAd->ate.Mode != ATE_STASTART) { printk("RALINK_ATE\n"); //RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV); return; }#endif // RALINK_ATE // Timer need to reset every time, so using do-while loop do { 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))) break; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_PENDING)) { RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_PENDING); DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"); } // // hardware failure? // if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { printk("fRTMP_ADAPTER_NIC_NOT_EXIST\n"); RTUSBRejectPendingPackets(pAd); break; } pAd->Mlme.Now32 = 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) { PCmdQElmt cmdqelmt; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); NdisAcquireSpinLock(&pAd->CmdQLock, IrqFlags); while (pAd->CmdQ.size > 0) { RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt); if (cmdqelmt->CmdFromNdis == TRUE) { if ((cmdqelmt->command != RT_OID_MULTI_READ_MAC) && (cmdqelmt->command != RT_OID_VENDOR_READ_BBP) && (cmdqelmt->command != RT_OID_USB_VENDOR_EEPROM_READ)) { if (cmdqelmt->buffer != NULL) kfree(cmdqelmt->buffer); } kfree(cmdqelmt); } else cmdqelmt->InUse = FALSE; } NdisReleaseSpinLock(&pAd->CmdQLock, IrqFlags); RTUSBEnqueueInternalCmd(pAd, RT_OID_RESET_FROM_ERROR); DBGPRINT_RAW(RT_DEBUG_ERROR, "<---MlmePeriodicExec (Mgmt Ring Full)\n"); break; } pAd->RalinkCounters.MgmtRingFullCount = 0; RTUSBEnqueueInternalCmd(pAd, RT_OID_PERIODIC_EXECUT); //STAMlmePeriodicExec(pAd); RTUSBMlmeUp(pAd); } while (0); }VOID STAMlmePeriodicExec( IN PRTMP_ADAPTER pAd){ TXRX_CSR4_STRUC CurTxRxCsr4; SHORT dbm;#ifdef RALINK_WPA_SUPPLICANT_SUPPORT union iwreq_data wrqu;#endif // WPA MIC error should block association attempt for 60 seconds if (pAd->PortCfg.bBlockAssoc && (pAd->PortCfg.LastMicErrorTime + (60 * HZ) < pAd->Mlme.Now32)) pAd->PortCfg.bBlockAssoc = FALSE; DBGPRINT(RT_DEBUG_INFO,"MMCHK - PortCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n", pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid[0], pAd->PortCfg.Ssid[1], pAd->PortCfg.Ssid[2], pAd->PortCfg.Ssid[3], pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1], pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3]); // 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.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 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -