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 + -
显示快捷键?