📄 mlme.c
字号:
/*************************************************************************** * RT2x00 SourceForge Project - http://rt2x00.serialmonkey.com * * * * 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. * * * * Licensed under the GNU GPL * * Original code supplied under license from RaLink Inc, 2004. * ***************************************************************************//*************************************************************************** * Module Name: mlme.c * * Abstract: * * Revision History: * Who When What * -------- ---------- ----------------------------- * John Chang 2004-08-25 Modify from RT2500 code base * John Chang 2004-09-06 modified for RT2600 * idamlaj 05-10-2006 Import rfmon implementation * ***************************************************************************/#include "rt_config.h"#include <stdarg.h>#include <net/iw_handler.h>// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rateULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */, 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */, 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than// this value, then it's quaranteed capable of operating in 36 mbps TX rate in// clean environment.// TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 }; // 1 2 5.5 11UCHAR Phy11BNextRateDownward[] = {RATE_1, RATE_1, RATE_2, RATE_5_5};UCHAR Phy11BNextRateUpward[] = {RATE_2, RATE_5_5, RATE_11, RATE_11}; // 1 2 5.5 11 6 9 12 18 24 36 48 54UCHAR Phy11BGNextRateDownward[]= {RATE_1, RATE_1, RATE_2, RATE_5_5,RATE_11, RATE_6, RATE_11, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48};UCHAR Phy11BGNextRateUpward[] = {RATE_2, RATE_5_5, RATE_11, RATE_12, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54, RATE_54}; // 1 2 5.5 11 6 9 12 18 24 36 48 54UCHAR Phy11ANextRateDownward[] = {RATE_6, RATE_6, RATE_6, RATE_6, RATE_6, RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48};UCHAR Phy11ANextRateUpward[] = {RATE_9, RATE_9, RATE_9, RATE_9, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54, RATE_54};// RATE_1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54static USHORT RateUpPER[] = { 40, 40, 35, 20, 20, 20, 20, 16, 10, 16, 10, 6 }; // in percentagestatic USHORT RateDownPER[] = { 50, 50, 45, 45, 35, 35, 35, 35, 25, 25, 25, 13 }; // in percentageUCHAR RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};UCHAR SsidIe = IE_SSID;UCHAR SupRateIe = IE_SUPP_RATES;UCHAR ExtRateIe = IE_EXT_SUPP_RATES;UCHAR ErpIe = IE_ERP;UCHAR DsIe = IE_DS_PARM;UCHAR TimIe = IE_TIM;UCHAR WpaIe = IE_WPA;UCHAR Wpa2Ie = IE_WPA2;UCHAR IbssIe = IE_IBSS_PARM;extern UCHAR WPA_OUI[];extern UCHAR RSN_OUI[];RTMP_RF_REGS RF2528RegTable[] = {// ch R1 R2 R3(TX0~4=0) R4 {1, 0x94002c0c, 0x94000786, 0x94068255, 0x940fea0b}, {2, 0x94002c0c, 0x94000786, 0x94068255, 0x940fea1f}, {3, 0x94002c0c, 0x9400078a, 0x94068255, 0x940fea0b}, {4, 0x94002c0c, 0x9400078a, 0x94068255, 0x940fea1f}, {5, 0x94002c0c, 0x9400078e, 0x94068255, 0x940fea0b}, {6, 0x94002c0c, 0x9400078e, 0x94068255, 0x940fea1f}, {7, 0x94002c0c, 0x94000792, 0x94068255, 0x940fea0b}, {8, 0x94002c0c, 0x94000792, 0x94068255, 0x940fea1f}, {9, 0x94002c0c, 0x94000796, 0x94068255, 0x940fea0b}, {10, 0x94002c0c, 0x94000796, 0x94068255, 0x940fea1f}, {11, 0x94002c0c, 0x9400079a, 0x94068255, 0x940fea0b}, {12, 0x94002c0c, 0x9400079a, 0x94068255, 0x940fea1f}, {13, 0x94002c0c, 0x9400079e, 0x94068255, 0x940fea0b}, {14, 0x94002c0c, 0x940007a2, 0x94068255, 0x940fea13}};UCHAR NUM_OF_2528_CHNL = (sizeof(RF2528RegTable) / sizeof(RTMP_RF_REGS));RTMP_RF_REGS RF5226RegTable[] = {// ch R1 R2 R3(TX0~4=0) R4 {1, 0x94002c0c, 0x94000786, 0x94068255, 0x940fea0b}, {2, 0x94002c0c, 0x94000786, 0x94068255, 0x940fea1f}, {3, 0x94002c0c, 0x9400078a, 0x94068255, 0x940fea0b}, {4, 0x94002c0c, 0x9400078a, 0x94068255, 0x940fea1f}, {5, 0x94002c0c, 0x9400078e, 0x94068255, 0x940fea0b}, {6, 0x94002c0c, 0x9400078e, 0x94068255, 0x940fea1f}, {7, 0x94002c0c, 0x94000792, 0x94068255, 0x940fea0b}, {8, 0x94002c0c, 0x94000792, 0x94068255, 0x940fea1f}, {9, 0x94002c0c, 0x94000796, 0x94068255, 0x940fea0b}, {10, 0x94002c0c, 0x94000796, 0x94068255, 0x940fea1f}, {11, 0x94002c0c, 0x9400079a, 0x94068255, 0x940fea0b}, {12, 0x94002c0c, 0x9400079a, 0x94068255, 0x940fea1f}, {13, 0x94002c0c, 0x9400079e, 0x94068255, 0x940fea0b}, {14, 0x94002c0c, 0x940007a2, 0x94068255, 0x940fea13}, {36, 0x94002c0c, 0x9400099a, 0x94098255, 0x940fea23}, {40, 0x94002c0c, 0x940009a2, 0x94098255, 0x940fea03}, {44, 0x94002c0c, 0x940009a6, 0x94098255, 0x940fea0b}, {48, 0x94002c0c, 0x940009aa, 0x94098255, 0x940fea13}, {52, 0x94002c0c, 0x940009ae, 0x94098255, 0x940fea1b}, {56, 0x94002c0c, 0x940009b2, 0x94098255, 0x940fea23}, {60, 0x94002c0c, 0x940009ba, 0x94098255, 0x940fea03}, {64, 0x94002c0c, 0x940009be, 0x94098255, 0x940fea0b}, {100, 0x94002c0c, 0x94000a2a, 0x940b8255, 0x940fea03}, {104, 0x94002c0c, 0x94000a2e, 0x940b8255, 0x940fea0b}, {108, 0x94002c0c, 0x94000a32, 0x940b8255, 0x940fea13}, {112, 0x94002c0c, 0x94000a36, 0x940b8255, 0x940fea1b}, {116, 0x94002c0c, 0x94000a3a, 0x940b8255, 0x940fea23}, {120, 0x94002c0c, 0x94000a82, 0x940b8255, 0x940fea03}, {124, 0x94002c0c, 0x94000a86, 0x940b8255, 0x940fea0b}, {128, 0x94002c0c, 0x94000a8a, 0x940b8255, 0x940fea13}, {132, 0x94002c0c, 0x94000a8e, 0x940b8255, 0x940fea1b}, {136, 0x94002c0c, 0x94000a92, 0x940b8255, 0x940fea23}, {140, 0x94002c0c, 0x94000a9a, 0x940b8255, 0x940fea03}, {149, 0x94002c0c, 0x94000aa2, 0x940b8255, 0x940fea1f}, {153, 0x94002c0c, 0x94000aa6, 0x940b8255, 0x940fea27}, {157, 0x94002c0c, 0x94000aae, 0x940b8255, 0x940fea07}, {161, 0x94002c0c, 0x94000ab2, 0x940b8255, 0x940fea0f}, {165, 0x94002c0c, 0x94000ab6, 0x940b8255, 0x940fea17}, //MMAC(Japan)J52 ch 34,38,42,46 {34, 0x94002c0c, 0x9408099a, 0x940da255, 0x940d3a0b}, {38, 0x94002c0c, 0x9408099e, 0x940da255, 0x940d3a13}, {42, 0x94002c0c, 0x940809a2, 0x940da255, 0x940d3a1b}, {46, 0x94002c0c, 0x940809a6, 0x940da255, 0x940d3a23},};UCHAR NUM_OF_5226_CHNL = (sizeof(RF5226RegTable) / sizeof(RTMP_RF_REGS));// Reset the RFIC setting to new seriesstatic RTMP_RF_REGS RF5225RegTable[] = {// ch R1 R2 R3(TX0~4=0) R4 {1, 0x95002ccc, 0x95004786, 0x95068455, 0x950ffa0b}, {2, 0x95002ccc, 0x95004786, 0x95068455, 0x950ffa1f}, {3, 0x95002ccc, 0x9500478a, 0x95068455, 0x950ffa0b}, {4, 0x95002ccc, 0x9500478a, 0x95068455, 0x950ffa1f}, {5, 0x95002ccc, 0x9500478e, 0x95068455, 0x950ffa0b}, {6, 0x95002ccc, 0x9500478e, 0x95068455, 0x950ffa1f}, {7, 0x95002ccc, 0x95004792, 0x95068455, 0x950ffa0b}, {8, 0x95002ccc, 0x95004792, 0x95068455, 0x950ffa1f}, {9, 0x95002ccc, 0x95004796, 0x95068455, 0x950ffa0b}, {10, 0x95002ccc, 0x95004796, 0x95068455, 0x950ffa1f}, {11, 0x95002ccc, 0x9500479a, 0x95068455, 0x950ffa0b}, {12, 0x95002ccc, 0x9500479a, 0x95068455, 0x950ffa1f}, {13, 0x95002ccc, 0x9500479e, 0x95068455, 0x950ffa0b}, {14, 0x95002ccc, 0x950047a2, 0x95068455, 0x950ffa13}, // 802.11 UNI / HyperLan 2 {36, 0x95002ccc, 0x9500499a, 0x9509be55, 0x950ffa23}, {40, 0x95002ccc, 0x950049a2, 0x9509be55, 0x950ffa03}, {44, 0x95002ccc, 0x950049a6, 0x9509be55, 0x950ffa0b}, {48, 0x95002ccc, 0x950049aa, 0x9509be55, 0x950ffa13}, {52, 0x95002ccc, 0x950049ae, 0x9509ae55, 0x950ffa1b}, {56, 0x95002ccc, 0x950049b2, 0x9509ae55, 0x950ffa23}, {60, 0x95002ccc, 0x950049ba, 0x9509ae55, 0x950ffa03}, {64, 0x95002ccc, 0x950049be, 0x9509ae55, 0x950ffa0b}, // 802.11 HyperLan 2 {100, 0x95002ccc, 0x95004a2a, 0x950bae55, 0x950ffa03}, {104, 0x95002ccc, 0x95004a2e, 0x950bae55, 0x950ffa0b}, {108, 0x95002ccc, 0x95004a32, 0x950bae55, 0x950ffa13}, {112, 0x95002ccc, 0x95004a36, 0x950bae55, 0x950ffa1b}, {116, 0x95002ccc, 0x95004a3a, 0x950bbe55, 0x950ffa23}, {120, 0x95002ccc, 0x95004a82, 0x950bbe55, 0x950ffa03}, {124, 0x95002ccc, 0x95004a86, 0x950bbe55, 0x950ffa0b}, {128, 0x95002ccc, 0x95004a8a, 0x950bbe55, 0x950ffa13}, {132, 0x95002ccc, 0x95004a8e, 0x950bbe55, 0x950ffa1b}, {136, 0x95002ccc, 0x95004a92, 0x950bbe55, 0x950ffa23}, // 802.11 UNII {140, 0x95002ccc, 0x95004a9a, 0x950bbe55, 0x950ffa03}, {149, 0x95002ccc, 0x95004aa2, 0x950bbe55, 0x950ffa1f}, {153, 0x95002ccc, 0x95004aa6, 0x950bbe55, 0x950ffa27}, {157, 0x95002ccc, 0x95004aae, 0x950bbe55, 0x950ffa07}, {161, 0x95002ccc, 0x95004ab2, 0x950bbe55, 0x950ffa0f}, {165, 0x95002ccc, 0x95004ab6, 0x950bbe55, 0x950ffa17}, //MMAC(Japan)J52 ch 34,38,42,46 {34, 0x95002ccc, 0x9500499a, 0x9509be55, 0x950ffa0b}, {38, 0x95002ccc, 0x9500499e, 0x9509be55, 0x950ffa13}, {42, 0x95002ccc, 0x950049a2, 0x9509be55, 0x950ffa1b}, {46, 0x95002ccc, 0x950049a6, 0x9509be55, 0x950ffa23},};UCHAR NUM_OF_5225_CHNL = (sizeof(RF5225RegTable) / sizeof(RTMP_RF_REGS));/* ========================================================================== Description: initialize the MLME task and its data structure (queue, spinlock, timer, state machines). Return: always return NDIS_STATUS_SUCCESS ==========================================================================*/NDIS_STATUS MlmeInit( IN PRTMP_ADAPTER pAd){ NDIS_STATUS Status = NDIS_STATUS_SUCCESS; DBGPRINT(RT_DEBUG_TRACE, "--> MlmeInit\n"); do { pAd->Mlme.Running = FALSE; NdisAllocateSpinLock(&pAd->Mlme.Queue.Lock); Status = MlmeQueueInit(&pAd->Mlme.Queue); if(Status != NDIS_STATUS_SUCCESS) break; // Initialize Mlme Memory Handler // Allocate 20 nonpaged memory pool which size are MAX_LEN_OF_MLME_BUFFER for use Status = MlmeInitMemoryHandler(pAd, 20, MAX_LEN_OF_MLME_BUFFER); if(Status != NDIS_STATUS_SUCCESS) { MlmeQueueDestroy(&pAd->Mlme.Queue); break; } // initialize table BssTableInit(&pAd->ScanTab); // init state machines ASSERT(ASSOC_FUNC_SIZE == MAX_ASSOC_MSG * MAX_ASSOC_STATE); AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc); ASSERT(AUTH_FUNC_SIZE == MAX_AUTH_MSG * MAX_AUTH_STATE); AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc); ASSERT(AUTH_RSP_FUNC_SIZE == MAX_AUTH_RSP_MSG * MAX_AUTH_RSP_STATE); AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc); ASSERT(SYNC_FUNC_SIZE == MAX_SYNC_MSG * MAX_SYNC_STATE); SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc); ASSERT(WPA_PSK_FUNC_SIZE == MAX_WPA_PSK_MSG * MAX_WPA_PSK_STATE); WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc); // Since we are using switch/case to implement it, the init is different from the above // state machine init MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL); // Init mlme periodic timer RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, &MlmePeriodicExecTimeout); // software-based RX Antenna diversity RTMPInitTimer(pAd, &pAd->RxAnt.RxAntDiversityTimer, &AsicRxAntEvalTimeout); // Init timer to report link down event RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, &LinkDownExec); } while (FALSE); DBGPRINT(RT_DEBUG_TRACE, "<-- MlmeInit\n"); return Status;}/* ========================================================================== Description: main loop of the MLME Pre: Mlme has to be initialized, and there are something inside the queue Note: This function is invoked from MPSetInformation and MPReceive; This task guarantee only one MlmeHandler will run. ========================================================================== */VOID MlmeHandler( IN PRTMP_ADAPTER pAd){ MLME_QUEUE_ELEM *Elem = NULL; unsigned long flags; // Only accept MLME and Frame from peer side, no other (control/data) // frame should get into this state machine // We fix the multiple context service drop problem identified by // Ben Hutchings in an SMP- safe way by combining TaskLock and Queue.Lock // per his suggestion. NdisAcquireSpinLock(&pAd->Mlme.Queue.Lock); if(pAd->Mlme.Running) { NdisReleaseSpinLock(&pAd->Mlme.Queue.Lock); return; } pAd->Mlme.Running = TRUE; // If there's a bubble, wait for it to collapse before proceeding. while (MlmeGetHead(&pAd->Mlme.Queue, &Elem)) { smp_read_barrier_depends(); if (!Elem->Occupied) break; NdisReleaseSpinLock(&pAd->Mlme.Queue.Lock); if (Elem->MsgType == RT_CMD_RESET_MLME) { DBGPRINT(RT_DEBUG_TRACE, "- %s: reset MLME state machine !!!\n", __FUNCTION__); MlmeRestartStateMachine(pAd); MlmePostRestartStateMachine(pAd); } //From message type, determine which state machine I should drive else if (pAd->PortCfg.BssType != BSS_MONITOR) 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_ERROR, "ERROR: Illegal machine in MlmeHandler()\n"); break; } // end of switch // free MLME element smp_mb(); Elem->Occupied = FALSE; // sic - bb NdisAcquireSpinLock(&pAd->Mlme.Queue.Lock); MlmeDequeue(&pAd->Mlme.Queue); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -