📄 sync.c
字号:
/* ************************************************************************* * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* Module Name: sync.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- John Chang 2004-09-01 modified for rt2561/2661 Jan Lee 2006-08-01 modified for rt2860 for 802.11n*/#include "rt_config.h"/* ========================================================================== Description: The sync state machine, Parameters: Sm - pointer to the state machine Note: the state machine looks like the following ========================================================================== */VOID SyncStateMachineInit( IN PRTMP_ADAPTER pAd, IN STATE_MACHINE *Sm, OUT STATE_MACHINE_FUNC Trans[]) { StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE); // column 1 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction); StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon); StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction); //column 2 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction); StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction); // column 3 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction); StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction); // timer init RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE); RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);}/* ========================================================================== Description: Becaon timeout handler, executed in timer thread IRQL = DISPATCH_LEVEL ========================================================================== */VOID BeaconTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n")); // 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)) return; MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL); MlmeHandler(pAd);}/* ========================================================================== Description: Scan timeout handler, executed in timer thread IRQL = DISPATCH_LEVEL ========================================================================== */VOID ScanTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; DBGPRINT(RT_DEBUG_INFO,("SYNC - Scan Timeout \n")); // 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)) return; MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL); MlmeHandler(pAd);}/* ========================================================================== Description: MLME SCAN req state machine procedure ========================================================================== */VOID MlmeScanReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0; BOOLEAN TimerCancelled; ULONG Now; USHORT Status; PHEADER_802_11 pHdr80211; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; // Check the total scan tries for one single OID command // If this is the CCX 2.0 Case, skip that! if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n")); return; } // Increase the scan retry counters. pAd->StaCfg.ScanCnt++; // first check the parameter sanity if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, Ssid, &SsidLen, &ScanType)) { // Check for channel load and noise hist request // Suspend MSDU only at scan request, not the last two mentioned if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD)) { if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel) RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here } else { // Suspend MSDU transmission here RTMPSuspendMsduTransmission(pAd); } // // To prevent data lost. // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. // And should send an NULL data with turned PSM bit off to AP, when scan progress done // if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) { NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); if (NStatus == NDIS_STATUS_SUCCESS) { pHdr80211 = (PHEADER_802_11) pOutBuffer; MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid); pHdr80211->Duration = 0; pHdr80211->FC.Type = BTYPE_DATA; pHdr80211->FC.PwrMgmt = PWR_SAVE; // Send using priority queue MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11)); DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n")); MlmeFreeMemory(pAd, pOutBuffer); RTMPusecDelay(5000); } } NdisGetSystemUpTime(&Now); pAd->StaCfg.LastScanTime = Now; // reset all the timers RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); // record desired BSS parameters pAd->MlmeAux.BssType = BssType; pAd->MlmeAux.ScanType = ScanType; pAd->MlmeAux.SsidLen = SsidLen; NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); // start from the first channel pAd->MlmeAux.Channel = FirstChannel(pAd); // Change the scan channel when dealing with CCX beacon report if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE)) pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel; // Let BBP register at 20MHz to do scan RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_ERROR, ("SYNC - BBP R4 to 20MHz.l\n")); ScanNextChannel(pAd); } else { DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n")); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status); }}/* ========================================================================== Description: MLME JOIN req state machine procedure ========================================================================== */VOID MlmeJoinReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BSS_ENTRY *pBss; BOOLEAN TimerCancelled; HEADER_802_11 Hdr80211; NDIS_STATUS NStatus; ULONG FrameLen = 0; PUCHAR pOutBuffer = NULL; PUCHAR pSupRate = NULL; UCHAR SupRateLen; PUCHAR pExtRate = NULL; UCHAR ExtRateLen; UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C}; UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR); MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx)); // reset all the timers RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx]; // record the desired SSID & BSSID we're waiting for COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid); NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen); pAd->MlmeAux.SsidLen = pBss->SsidLen; pAd->MlmeAux.BssType = pBss->BssType; pAd->MlmeAux.Channel = pBss->Channel; pAd->MlmeAux.CentralChannel = pBss->CentralChannel; // switch channel and waiting for beacon timer AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); AsicLockChannel(pAd, pAd->MlmeAux.Channel); RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT); // // send probe request // NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus == NDIS_STATUS_SUCCESS) { if (pAd->MlmeAux.Channel <= 14) { pSupRate = pAd->CommonCfg.SupRate; SupRateLen = pAd->CommonCfg.SupRateLen; pExtRate = pAd->CommonCfg.ExtRate; ExtRateLen = pAd->CommonCfg.ExtRateLen; } else { // // Overwrite Support Rate, CCK rate are not allowed // pSupRate = ASupRate; SupRateLen = ASupRateLen; ExtRateLen = 0; } if (pAd->MlmeAux.BssType == BSS_INFRA) MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid); else MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR); MakeOutgoingFrame(pOutBuffer, &FrameLen,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -