mlme.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,669 行 · 第 1/5 页
C
1,669 行
/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-2005, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attempt
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
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
*/
#include "rt_config.h"
#include <stdarg.h>
// 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 100
CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
// 1 2 5.5 11
UCHAR 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 54
UCHAR Phy11BGNextRateDownward[]= {RATE_1, RATE_1, RATE_2, RATE_5_5,RATE_11, RATE_11, RATE_11, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48};
UCHAR Phy11BGNextRateUpward[] = {RATE_2, RATE_5_5, RATE_11, RATE_12, RATE_12, 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 54
UCHAR 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, 54
static USHORT RateUpPER[] = { 40, 40, 35, 20, 20, 20, 20, 16, 10, 16, 10, 6 }; // in percentage
static USHORT RateDownPER[] = { 50, 50, 45, 45, 35, 35, 35, 35, 25, 25, 25, 13 }; // in percentage
UCHAR 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 BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Reset the RFIC setting to new series
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},
// still lack of MMAC(Japan) ch 34,38,42,46
};
UCHAR NUM_OF_5225_CHNL = (sizeof(RF5225RegTable) / sizeof(RTMP_RF_REGS));
// Reset the RFIC setting to new series
RTMP_RF_REGS RF5225RegTable_1[] = {
// 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, 0x95002cd4, 0x9504481a, 0x95098455, 0x950c0a03},
{40, 0x95002cd0, 0x95044682, 0x95098455, 0x950c0a03},
{44, 0x95002cd0, 0x95044686, 0x95098455, 0x950c0a1b},
{48, 0x95002cd0, 0x9504468e, 0x95098655, 0x950c0a0b},
{52, 0x95002cd0, 0x95044692, 0x95098855, 0x950c0a23},
{56, 0x95002cd0, 0x9504469a, 0x95098c55, 0x950c0a13},
{60, 0x95002cd0, 0x950446a2, 0x95098e55, 0x950c0a03},
{64, 0x95002cd0, 0x950446a6, 0x95099255, 0x950c0a1b},
// 802.11 HyperLan 2
{100, 0x95002cd4, 0x9504489a, 0x950b9855, 0x950c0a03},
{104, 0x95002cd4, 0x950448a2, 0x950b9855, 0x950c0a03},
{108, 0x95002cd4, 0x950448aa, 0x950b9855, 0x950c0a03},
{112, 0x95002cd4, 0x950448b2, 0x950b9a55, 0x950c0a03},
{116, 0x95002cd4, 0x950448ba, 0x950b9a55, 0x950c0a03},
{120, 0x95002cd0, 0x95044702, 0x950b9a55, 0x950c0a03},
{124, 0x95002cd0, 0x95044706, 0x950b9a55, 0x950c0a1b},
{128, 0x95002cd0, 0x9504470e, 0x950b9c55, 0x950c0a0b},
{132, 0x95002cd0, 0x95044712, 0x950b9c55, 0x950c0a23},
{136, 0x95002cd0, 0x9504471a, 0x950b9e55, 0x950c0a13},
// 802.11 UNII
{140, 0x95002cd0, 0x95044722, 0x950b9e55, 0x950c0a03},
{149, 0x95002cd0, 0x9504472e, 0x950ba255, 0x950c0a1b},
{153, 0x95002cd0, 0x95044736, 0x950ba255, 0x950c0a0b},
{157, 0x95002cd4, 0x9504490a, 0x950ba255, 0x950c0a17},
{161, 0x95002cd4, 0x95044912, 0x950ba255, 0x950c0a17},
{165, 0x95002cd4, 0x9504491a, 0x950ba255, 0x950c0a17},
// still lack of MMAC(Japan) ch 34,38,42,46
};
UCHAR NUM_OF_5225_CHNL_1 = (sizeof(RF5225RegTable_1) / sizeof(RTMP_RF_REGS));
#ifdef RTL865X_SOC
static inline VOID RadarSMDetectPeriodic(
IN unsigned long data);
#endif
/*
==========================================================================
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, "--> MLME Initialize\n");
do
{
Status = MlmeQueueInit(&pAd->Mlme.Queue);
if(Status != NDIS_STATUS_SUCCESS)
break;
pAd->Mlme.bRunning = FALSE;
NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
NdisAllocateSpinLock(&pAd->Mlme.MemLock);
pAd->Mlme.DtimCount = 0;
pAd->Mlme.DtimPeriod = DEFAULT_DTIM_PERIOD;
// 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_FUNC_SIZE == MAX_WPA_MSG * MAX_WPA_PTK_STATE);
WpaStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
ASSERT(DLS_FUNC_SIZE == MAX_DLS_MSG * MAX_DLS_STATE);
DLSStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
#ifdef APCLI_SUPPORT
// init apcli state machines
ASSERT(STA_AUTH_FUNC_SIZE == STA_MAX_AUTH_MSG * STA_MAX_AUTH_STATE);
StaAuthStateMachineInit(pAd, &pAd->Mlme.ApCliAuthMachine, pAd->Mlme.ApCliAuthFunc);
ASSERT(STA_ASSOC_FUNC_SIZE == STA_MAX_ASSOC_MSG * STA_MAX_ASSOC_STATE);
StaAssocStateMachineInit(pAd, &pAd->Mlme.ApCliAssocMachine, pAd->Mlme.ApCliAssocFunc);
ASSERT(STA_SYNC_FUNC_SIZE == STA_MAX_SYNC_MSG * STA_MAX_SYNC_STATE);
StaSyncStateMachineInit(pAd, &pAd->Mlme.ApCliSyncMachine, pAd->Mlme.ApCliSyncFunc);
ASSERT(STA_CTRL_FUNC_SIZE == STA_MAX_CTRL_MSG * STA_MAX_CTRL_STATE);
StaCtrlStateMachineInit(pAd, &pAd->Mlme.ApCliCtrlMachine, pAd->Mlme.ApCliCtrlFunc);
ASSERT(STA_WPA_PSK_FUNC_SIZE == STA_MAX_WPA_PSK_MSG * STA_MAX_WPA_PSK_STATE);
StaWpaStateMachineInit(pAd, &pAd->Mlme.ApCliWpaPskMachine, pAd->Mlme.ApCliWpaPskFunc);
#endif
// Init mlme periodic timer
RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, (PVOID)&MlmePeriodicExec);
RTMPAddTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
// Init DFS periodic timer
RTMPInitTimer(pAd, &pAd->Mlme.DFSPeriodicTimer, (PVOID)&RadarSMDetectPeriodic);
RTMPAddTimer(&pAd->Mlme.DFSPeriodicTimer, HZ/10);
} while (FALSE);
DBGPRINT(RT_DEBUG_TRACE, "<-- MLME Initialize\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;
ULONG IrqFlags;
#ifdef APCLI_SUPPORT
SHORT apcliIfIndex;
#endif
// Only accept MLME and Frame from peer side, no other (control/data) frame should
// get into this state machine
RTMP_SEM_LOCK(&pAd->Mlme.TaskLock, IrqFlags);
if(pAd->Mlme.bRunning)
{
RTMP_SEM_UNLOCK(&pAd->Mlme.TaskLock, IrqFlags);
return;
}
else
{
pAd->Mlme.bRunning = TRUE;
}
RTMP_SEM_UNLOCK(&pAd->Mlme.TaskLock, IrqFlags);
while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
{
//From message type, determine which state machine I should drive
if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
{
// 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 WPA_STATE_MACHINE:
StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
break;
case DLS_STATE_MACHINE:
StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
break;
#ifdef APCLI_SUPPORT
case STA_AUTH_STATE_MACHINE:
apcliIfIndex = Elem->ifIndex;
if(isValidApCliIf(apcliIfIndex))
StaStateMachinePerformAction(pAd, &pAd->Mlme.ApCliAuthMachine, Elem,
apcliIfIndex, &(pAd->ApCliTab.ApCliEntry[apcliIfIndex].AuthCurrState));
break;
case STA_ASSOC_STATE_MACHINE:
apcliIfIndex = Elem->ifIndex;
if(isValidApCliIf(apcliIfIndex))
StaStateMachinePerformAction(pAd, &pAd->Mlme.ApCliAssocMachine, Elem,
apcliIfIndex, &(pAd->ApCliTab.ApCliEntry[apcliIfIndex].AssocCurrState));
break;
case STA_SYNC_STATE_MACHINE:
apcliIfIndex = Elem->ifIndex;
if(isValidApCliIf(apcliIfIndex))
StaStateMachinePerformAction(pAd, &pAd->Mlme.ApCliSyncMachine, Elem,
apcliIfIndex, &(pAd->ApCliTab.ApCliEntry[apcliIfIndex].SyncCurrState));
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?