⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soft_ap.c

📁 Ralink RT61 SoftAP Driver source code. RT61:MiniPCI
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 ***************************************************************************
 * 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:
	soft_ap.c

	Abstract:

	Revision History:
	Who			When			What
	--------	----------		----------------------------------------------
	John		2004-08-08		Major modification from RT2560
*/
#include "rt_config.h"

char const *pEventText[EVENT_MAX_EVENT_TYPE] = {
    "restart access point",
    "successfully associated",
    "has disassociated",
    "has been aged-out and disassociated" ,    
    "active countermeasures",
    "has disassociated with invalid PSK password"};
    
/*
    ==========================================================================
    Description:
        Initialize AP specific data
    ==========================================================================
 */
NDIS_STATUS ApInitialize(
	IN	PRTMP_ADAPTER	pAd)
{
    UCHAR       apidx;

    DBGPRINT(RT_DEBUG_TRACE, "---> ApInitialize\n");

    // Initialize MAC table and allocate spin lock
    NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
    NdisAllocateSpinLock(&pAd->MacTabLock);

    for (apidx = 0; apidx < pAd->PortCfg.BssidNum; apidx++)
    {
        // Init TKIP Group-Key-related variables
        GenRandom(pAd,pAd->PortCfg.MBSSID[apidx].GMK, apidx);
        GenRandom(pAd,pAd->PortCfg.MBSSID[apidx].GNonce, apidx);

        pAd->PortCfg.MBSSID[apidx].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
    }

    // Init Group key update timer, and countermeasures timer
	RTMPInitTimer(pAd, &pAd->PortCfg.REKEYTimer, (PVOID)&GREKEYPeriodicExec);
	RTMPInitTimer(pAd, &pAd->PortCfg.CounterMeasureTimer, (PVOID)&CMTimerExec);
	RTMPInitTimer(pAd, &pAd->QuickResponeForRateUpTimer, (PVOID)&QuickResponeForRateUp);

    DBGPRINT(RT_DEBUG_TRACE, "<--- ApInitialize\n");
    
	return NDIS_STATUS_SUCCESS;
}

/*
    ==========================================================================
    Description:
        Shutdown AP and free AP specific resources
    ==========================================================================
 */
VOID ApShutdown(
    IN PRTMP_ADAPTER pAd)
{
    DBGPRINT(RT_DEBUG_TRACE, "---> ApShutdown\n");
    ApStop(pAd, TRUE);
    DBGPRINT(RT_DEBUG_TRACE, "<--- ApShutdown\n");
}

VOID ApStartUp(
    IN PRTMP_ADAPTER	pAd,
    IN BOOLEAN			bDFSRestart)
{
	UCHAR       apidx, i;
	ULONG       sec_csr4 = 0, MacCsr0 = 0;
	BOOLEAN		bWmmCapable = FALSE;
#ifdef APCLI_SUPPORT
	UCHAR		apcliidx;
#endif

    DBGPRINT(RT_DEBUG_TRACE, "---> ApStartUp\n");

    for (apidx = 0; apidx < pAd->PortCfg.BssidNum; apidx++)
    {
        if ((pAd->PortCfg.MBSSID[apidx].SsidLen <= 0) || (pAd->PortCfg.MBSSID[apidx].SsidLen > MAX_LEN_OF_SSID))
            return;
        
        // when B-only mode, beacon will not report using short slot time
        if (pAd->PortCfg.PhyMode == PHY_11B)
        {
        	pAd->PortCfg.UseShortSlotTime = FALSE;
        }
        
        // Decide the Capability information field
        // In IEEE Std 802.1h-2003, the spectrum management bit is enabled in the 5 GHz band 
        if (pAd->PortCfg.PhyMode == PHY_11A && pAd->PortCfg.RadarDetect.IEEE80211H == TRUE)
        	pAd->PortCfg.MBSSID[apidx].CapabilityInfo = CAP_GENERATE((pAd->PortCfg.MBSSID[apidx].WepStatus != Ndis802_11EncryptionDisabled), (pAd->PortCfg.TxPreamble == Rt802_11PreambleShort), pAd->PortCfg.UseShortSlotTime, TRUE);
        else
        	pAd->PortCfg.MBSSID[apidx].CapabilityInfo = CAP_GENERATE((pAd->PortCfg.MBSSID[apidx].WepStatus != Ndis802_11EncryptionDisabled), (pAd->PortCfg.TxPreamble == Rt802_11PreambleShort), pAd->PortCfg.UseShortSlotTime, FALSE);

		// if one bssid turn on the WMM, the parameter will set to ASIC once.
        if (pAd->PortCfg.MBSSID[apidx].bWmmCapable)
        	bWmmCapable = TRUE;

        DBGPRINT(RT_DEBUG_TRACE, "IF(ra%d) CapabilityInfo=%x, WepStatus=%d\n", apidx,
            pAd->PortCfg.MBSSID[apidx].CapabilityInfo,pAd->PortCfg.MBSSID[apidx].WepStatus);

        // if AuthMode >= WPA and IEEE802.1x is enabled, then pairwise key table must be used; 
	    // if legacy WEP inused, then only shared key table is used
	    if ((pAd->PortCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA) ||(pAd->PortCfg.MBSSID[apidx].IEEE8021X == TRUE))
	    {
	    	sec_csr4 |= BIT32[apidx];
	        DBGPRINT(RT_DEBUG_TRACE, "IF(ra%d)-AP AuthMode=%d, IEEE802.1x is %d, Pairwise Key Table in-used\n", apidx, 
	        																		pAd->PortCfg.MBSSID[apidx].AuthMode, 
	        																		pAd->PortCfg.MBSSID[apidx].IEEE8021X);
	    }
	    else
	    {
	        DBGPRINT(RT_DEBUG_TRACE, "IF(ra%d)-AP AuthMode=%d, disable Pairwise Key Table\n", apidx, pAd->PortCfg.MBSSID[apidx].AuthMode);
	    }
	    RTMP_IO_WRITE32(pAd, SEC_CSR4, sec_csr4);

	    // remove group key table
    	for (i=0; i<SHARE_KEY_NUM; i++)
    	{
			AsicRemoveSharedKeyEntry(pAd, apidx, i);
    	}

    	// remove pairwise key table
    	for (i=0; i<PAIRWISE_KEY_NO; i++)
    	{
			AsicRemovePairwiseKeyEntry(pAd, i);
    	}

		// Set shared key to ASIC :
		// SHARED-WEP, Auto-WEP, OPEN-WEP(no matter 802.1x is enabled or disabled) need to set key
    	if ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeShared) ||
    		(((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeAutoSwitch) || (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeOpen)) && (pAd->PortCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption1Enabled)))
    	{
    		for (i=0; i<SHARE_KEY_NUM; i++)
	    	{
	    		if (pAd->PortCfg.MBSSID[apidx].SharedKey[i].KeyLen != 0)
	    		{
                    AsicAddSharedKeyEntry(pAd, apidx, i, pAd->PortCfg.MBSSID[apidx].SharedKey[i].CipherAlg, pAd->PortCfg.MBSSID[apidx].SharedKey[i].Key, NULL, NULL);
	    		}
	    	}
    	}

        // Add wds key to pairwise key table when TKIP/AES
    	if (((pAd->WdsTab.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->WdsTab.WepStatus == Ndis802_11Encryption3Enabled)) && (pAd->WdsTab.Wpa_key.KeyLen > 0))
    	{
			AsicAddPairwiseKeyEntry(pAd, pAd->WdsTab.WdsEntry[0].WdsAddr, WDS_PAIRWISE_KEY_OFFSET, pAd->WdsTab.Wpa_key.CipherAlg, 
				pAd->WdsTab.Wpa_key.Key, pAd->WdsTab.Wpa_key.TxMic, pAd->WdsTab.Wpa_key.RxMic);
			AsicAddPairwiseKeyEntry(pAd, pAd->WdsTab.WdsEntry[1].WdsAddr, WDS_PAIRWISE_KEY_OFFSET + 1, pAd->WdsTab.Wpa_key.CipherAlg,	
				pAd->WdsTab.Wpa_key.Key, pAd->WdsTab.Wpa_key.TxMic, pAd->WdsTab.Wpa_key.RxMic);
			AsicAddPairwiseKeyEntry(pAd, pAd->WdsTab.WdsEntry[2].WdsAddr, WDS_PAIRWISE_KEY_OFFSET + 2, pAd->WdsTab.Wpa_key.CipherAlg,	
				pAd->WdsTab.Wpa_key.Key, pAd->WdsTab.Wpa_key.TxMic, pAd->WdsTab.Wpa_key.RxMic);
			AsicAddPairwiseKeyEntry(pAd, pAd->WdsTab.WdsEntry[3].WdsAddr, WDS_PAIRWISE_KEY_OFFSET + 3, pAd->WdsTab.Wpa_key.CipherAlg,	
				pAd->WdsTab.Wpa_key.Key, pAd->WdsTab.Wpa_key.TxMic, pAd->WdsTab.Wpa_key.RxMic);
    	}

		// Send singal to daemon to indicate driver had restarted
	    if ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) || (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2)
        	|| (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->PortCfg.MBSSID[apidx].IEEE8021X == TRUE))
        {
        	SendSingalToDaemon(pAd, SIGUSR1);
    	}
    }

#ifdef WMM_SUPPORT
    if (bWmmCapable)
    {
        // EDCA parameters used for AP's own transmission
        if (pAd->PortCfg.APEdcaParm.bValid == FALSE)
        {
            pAd->PortCfg.APEdcaParm.bValid = TRUE;
            pAd->PortCfg.APEdcaParm.Aifsn[0] = 3;
            pAd->PortCfg.APEdcaParm.Aifsn[1] = 7;
            pAd->PortCfg.APEdcaParm.Aifsn[2] = 1;
            pAd->PortCfg.APEdcaParm.Aifsn[3] = 1;
                              
            pAd->PortCfg.APEdcaParm.Cwmin[0] = 4;
            pAd->PortCfg.APEdcaParm.Cwmin[1] = 4;
            pAd->PortCfg.APEdcaParm.Cwmin[2] = 3;
            pAd->PortCfg.APEdcaParm.Cwmin[3] = 2;
                                    
            pAd->PortCfg.APEdcaParm.Cwmax[0] = 10;
            pAd->PortCfg.APEdcaParm.Cwmax[1] = 6;
            pAd->PortCfg.APEdcaParm.Cwmax[2] = 4;
            pAd->PortCfg.APEdcaParm.Cwmax[3] = 3;
        
            pAd->PortCfg.APEdcaParm.Txop[0]  = 0;
            pAd->PortCfg.APEdcaParm.Txop[1]  = 0;
            pAd->PortCfg.APEdcaParm.Txop[2]  = 94;
            pAd->PortCfg.APEdcaParm.Txop[3]  = 47;
        }
        AsicSetEdcaParm(pAd, &pAd->PortCfg.APEdcaParm);

        // EDCA parameters to be annouced in outgoing BEACON, used by WMM STA
        if (pAd->PortCfg.BssEdcaParm.bValid == FALSE)
        {
            pAd->PortCfg.BssEdcaParm.bValid = TRUE;
            pAd->PortCfg.BssEdcaParm.Aifsn[0] = 3;
            pAd->PortCfg.BssEdcaParm.Aifsn[1] = 7;
            pAd->PortCfg.BssEdcaParm.Aifsn[2] = 2;
            pAd->PortCfg.BssEdcaParm.Aifsn[3] = 2;
                              
            pAd->PortCfg.BssEdcaParm.Cwmin[0] = 4;
            pAd->PortCfg.BssEdcaParm.Cwmin[1] = 4;
            pAd->PortCfg.BssEdcaParm.Cwmin[2] = 3;
            pAd->PortCfg.BssEdcaParm.Cwmin[3] = 2;
                                    
            pAd->PortCfg.BssEdcaParm.Cwmax[0] = 10;
            pAd->PortCfg.BssEdcaParm.Cwmax[1] = 10;
            pAd->PortCfg.BssEdcaParm.Cwmax[2] = 4;
            pAd->PortCfg.BssEdcaParm.Cwmax[3] = 3;
        
            pAd->PortCfg.BssEdcaParm.Txop[0]  = 0;
            pAd->PortCfg.BssEdcaParm.Txop[1]  = 0;
            pAd->PortCfg.BssEdcaParm.Txop[2]  = 94;
            pAd->PortCfg.BssEdcaParm.Txop[3]  = 47;
        }
        DBGPRINT(RT_DEBUG_TRACE,"STA        : AIFSN CWmin CWmax TXOP(us)  ACM\n");
        DBGPRINT(RT_DEBUG_TRACE,"    AC_BE     %d     %d   %d    %4d     %d\n",
            pAd->PortCfg.BssEdcaParm.Aifsn[0], pAd->PortCfg.BssEdcaParm.Cwmin[0], pAd->PortCfg.BssEdcaParm.Cwmax[0],
            pAd->PortCfg.BssEdcaParm.Txop[0]<<5, pAd->PortCfg.BssEdcaParm.bACM[0]);
        DBGPRINT(RT_DEBUG_TRACE,"    AC_BK     %d     %d   %d    %4d     %d\n",
            pAd->PortCfg.BssEdcaParm.Aifsn[1], pAd->PortCfg.BssEdcaParm.Cwmin[1], pAd->PortCfg.BssEdcaParm.Cwmax[1],
            pAd->PortCfg.BssEdcaParm.Txop[1]<<5, pAd->PortCfg.BssEdcaParm.bACM[1]);
        DBGPRINT(RT_DEBUG_TRACE,"    AC_VI     %d     %d     %d    %4d     %d\n",
            pAd->PortCfg.BssEdcaParm.Aifsn[2], pAd->PortCfg.BssEdcaParm.Cwmin[2], pAd->PortCfg.BssEdcaParm.Cwmax[2],
            pAd->PortCfg.BssEdcaParm.Txop[2]<<5, pAd->PortCfg.BssEdcaParm.bACM[2]);
        DBGPRINT(RT_DEBUG_TRACE,"    AC_VO     %d     %d     %d     %4d     %d\n",
            pAd->PortCfg.BssEdcaParm.Aifsn[3], pAd->PortCfg.BssEdcaParm.Cwmin[3], pAd->PortCfg.BssEdcaParm.Cwmax[3],
            pAd->PortCfg.BssEdcaParm.Txop[3]<<5, pAd->PortCfg.BssEdcaParm.bACM[3]);
    }
#endif /* WMM_SUPPORT */

	AsicSetBssid(pAd, pAd->CurrentAddress); 
    AsicSwitchChannel(pAd, pAd->PortCfg.Channel);
    AsicLockChannel(pAd, pAd->PortCfg.Channel);
    MlmeUpdateTxRates(pAd);
	AsicSetSlotTime(pAd, (BOOLEAN)pAd->PortCfg.UseShortSlotTime);
    
//	if (pAd->PortCfg.RadarDetect.IEEE80211H == TRUE)
	{
		RTMPPrepareRadarDetectParams(pAd);
	}
    
	RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
   
	MakeAllBssBeacon(pAd);
	UpdateAllBeaconFrame(pAd);

	// This part needs to take care of following situation.
	// 1. NO DFS, 2. DFS in silence mode, 3. DFS in normal mode 4. DFS in switching mode
	if ((pAd->PortCfg.PhyMode == PHY_11A) && (pAd->PortCfg.RadarDetect.IEEE80211H == TRUE) && RadarChannelCheck(pAd, pAd->PortCfg.Channel) && (bDFSRestart == TRUE))
	{
		AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00);   // send stop-RD command to MCU
		RTMPusecDelay(500000);

		pAd->PortCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
		pAd->PortCfg.RadarDetect.RDCount = 0;
		pAd->PortCfg.RadarDetect.InServiceMonitorCount = 0;
		RadarDetectionStart(pAd);
	}
	else if ((pAd->PortCfg.PhyMode == PHY_11A) && (pAd->PortCfg.RadarDetect.IEEE80211H == TRUE) && RadarChannelCheck(pAd, pAd->PortCfg.Channel))
	{
	}
	else
	{
		AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00);   // send stop-RD command to MCU
		RTMPusecDelay(500000);
		
		pAd->PortCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
		RadarDetectionStop(pAd);
        AsicEnableBssSync(pAd);
	}
	
    // Set LED
	RTMPSetLED(pAd, LED_RADIO_ON);
	//delay to get H2M_MAILBOX ownership again before next RTMPSetLED().
	mdelay(1000);
	RTMPSetLED(pAd, LED_LINK_UP);

    // Group rekey related
    if ((pAd->PortCfg.WPAREKEY.ReKeyInterval != 0) && ((pAd->PortCfg.WPAREKEY.ReKeyMethod == TIME_REKEY) || (pAd->PortCfg.WPAREKEY.ReKeyMethod == PKT_REKEY))) 
    {
        // Regularly check the timer
        if (pAd->PortCfg.REKEYTimerRunning == FALSE)
        {
			RTMPAddTimer(&pAd->PortCfg.REKEYTimer, GUPDATE_EXEC_INTV);
            pAd->PortCfg.REKEYTimerRunning = TRUE;
            pAd->PortCfg.REKEYCOUNTER = 0;
        }
    }
    else
    	pAd->PortCfg.REKEYTimerRunning = FALSE;

	pAd->Mlme.PeriodicRound = 0;

    ApLogEvent(pAd, pAd->CurrentAddress, EVENT_RESET_ACCESS_POINT, MAIN_MBSSID);

#ifdef APCLI_SUPPORT
	for (apcliidx = 0; apcliidx < MAX_APCLI_ENTRY; apcliidx++)
	{
		// Pairwise or Shared key table lookup enable for ApCli interface
		if (pAd->ApCliTab.ApCliEntry[apcliidx].Enable)
		{
			// remove group key table for ApCli IF
    		for (i = 0; i < SHARE_KEY_NUM; i++)
    		{
				AsicRemoveSharedKeyEntry(pAd, pAd->PortCfg.BssidNum, i);
    		}
			
			// When OPEN-WEP, Shared-WEP, Auto-WEP, open shared key table security
			if (pAd->PortCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11WEPEnabled)
    		{
    			for (i = 0; i < SHARE_KEY_NUM; i++)
	    		{
	    			if (pAd->PortCfg.MBSSID[MAIN_MBSSID].SharedKey[i].KeyLen != 0)
	    			{
                    	AsicAddSharedKeyEntry(pAd, pAd->PortCfg.BssidNum, i, pAd->PortCfg.MBSSID[MAIN_MBSSID].SharedKey[i].CipherAlg, pAd->PortCfg.MBSSID[MAIN_MBSSID].SharedKey[i].Key, NULL, NULL);
	    			}
	    		}
	    		
	    		// Stop STA supplicant WPA state machine
                pAd->ApCliTab.ApCliEntry[apcliidx].WpaState = SS_NOTUSE;
#ifdef RTL865X_SOC
				printk("IF(apcli%d) AP-Client AuthMode=%d, Shared Key Table in-used\n", apcliidx, pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode);
#else                
                DBGPRINT(RT_DEBUG_TRACE, "IF(apcli%d) AP-Client AuthMode=%d, Shared Key Table in-used\n", apcliidx, pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode);
#endif                
    		}
    		// When WPA, open pairwise key table security
			else if (pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode >= Ndis802_11AuthModeWPA)
	    	{
	    		sec_csr4 |= BIT32[pAd->PortCfg.BssidNum];
	        	
	        	// Start STA supplicant WPA state machine
                pAd->ApCliTab.ApCliEntry[apcliidx].WpaState = SS_START;

#ifdef RTL865X_SOC
				printk("IF(apcli%d) AP-Client AuthMode=%d, Pairwise Key Table in-used\n", apcliidx, pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode);
#else
	        	DBGPRINT(RT_DEBUG_TRACE, "IF(apcli%d) AP-Client AuthMode=%d, Pairwise Key Table in-used\n", apcliidx, pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode);
#endif	        	

	    		RTMP_IO_WRITE32(pAd, SEC_CSR4, sec_csr4);	
	    	}
	    	else
	    	{
	        	// Stop STA supplicant WPA state machine
                pAd->ApCliTab.ApCliEntry[apcliidx].WpaState = SS_NOTUSE;
#ifdef RTL865X_SOC
				printk("IF(apcli%d) AP-Client AuthMode=%d, disable Pairwise or Shared Key Table\n", apcliidx, pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode);
#else                
	        	DBGPRINT(RT_DEBUG_TRACE, "IF(apcli%d) AP-Client AuthMode=%d, disable Pairwise or Shared Key Table\n", apcliidx, pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode);
#endif	        	
	    	}
		}
		
		// firstly, disassociate this connection,
		// Then re-connect that previous AP. 
		if (pAd->ApCliTab.ApCliEntry[apcliidx].Enable && pAd->ApCliTab.ApCliEntry[apcliidx].Valid)
		{
			DBGPRINT(RT_DEBUG_TRACE, "Restart ApCli link - IF(apcli%d).\n", apcliidx);
			StaMlmeEnqueue(pAd, STA_CTRL_STATE_MACHINE, STA_CTRL_DISCONNECT_REQ, 0, NULL, apcliidx);
		}		
	}
#endif

    DBGPRINT(RT_DEBUG_TRACE, "<--- ApStartUp (sec_csr4=0x%x)\n", sec_csr4);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -