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

📄 soft_ap.c

📁 Ralink RT61 SoftAP Driver source code. RT61:MiniPCI
💻 C
📖 第 1 页 / 共 4 页
字号:
}

VOID SendSingalToDaemon(
	IN PRTMP_ADAPTER	pAd,
	IN INT				sig)
{
	DBGPRINT(RT_DEBUG_TRACE, "SendSingalToDaemon - ApdPid=%d\n", pAd->ApdPid);

	if (pAd->ApdPid != 0)
	{
		kill_proc(pAd->ApdPid, sig, 0);
	}
}

VOID ApStop(
    IN PRTMP_ADAPTER	pAd,
    IN BOOLEAN			bDFSRestart) 
{
	DBGPRINT(RT_DEBUG_TRACE, "!!! ApStop !!!\n");

	if (bDFSRestart == TRUE)
	{
		RadarDetectionStop(pAd);
		AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00);   // send stop-RD command to MCU
              //delay to get H2M_MAILBOX ownership again before next RTMPSetLED().
	       mdelay(1000);
	}
    AsicDisableSync(pAd);
	RTMPSetLED(pAd, LED_RADIO_OFF);
    //delay to get H2M_MAILBOX ownership again before next RTMPSetLED().
    mdelay(1000);
    RTMPSetLED(pAd, LED_LINK_DOWN);

    if(pAd->PortCfg.REKEYTimerRunning==TRUE)
    {
        RTMPCancelTimer(&pAd->PortCfg.REKEYTimer);
        pAd->PortCfg.REKEYTimerRunning=FALSE;
    }

    if(pAd->PortCfg.CMTimerRunning==TRUE)
    {
        RTMPCancelTimer(&pAd->PortCfg.CounterMeasureTimer);
    	pAd->PortCfg.CMTimerRunning = FALSE;
    }

    MacTableReset(pAd, bDFSRestart);
}

/*
    ==========================================================================
    Description:
        This routine is used to clean up a specified power-saving queue. It's
        used whenever a wireless client is deleted.
    ==========================================================================
 */
VOID CleanupPsQueue(
    IN  PRTMP_ADAPTER   pAd,
    IN  PQUEUE_HEADER   pQueue)
{
    struct sk_buff	*pSkb;
    
    while (pQueue->Head)
    {
        pSkb = (struct sk_buff *)RemoveHeadQueue(pQueue);
        if(pSkb)		
#ifdef RTL865X_FAST_PATH
	  	 	rtl865x_extDev_kfree_skb(pSkb, FALSE);
#else
        	RELEASE_NDIS_PACKET(pAd, pSkb);
#endif
    }
}

/*
    ==========================================================================
    Description:
        This routine reset the entire MAC table. All packets pending in
        the power-saving queues are freed here.
    ==========================================================================
 */
VOID MacTableReset(
    IN  PRTMP_ADAPTER  pAd,
    IN	BOOLEAN		bDFSRestart)
{
    INT				i;
    ULONG			IrqFlags;
    PCHAR        	pOutBuffer = NULL;
    ULONG       	FrameLen = 0;
    HEADER_802_11	DisassocHdr;
    USHORT      	Reason;

#ifndef THREAD_ISR
    RTMP_SEM_LOCK(&pAd->MacTabLock, IrqFlags);
#endif
    
    for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
    {
        if (pAd->MacTab.Content[i].Valid)
       {
            if (pAd->MacTab.Content[i].RetryTimerRunning == TRUE)
            {
                DBGPRINT(RT_DEBUG_TRACE, "pAd->MacTab.Content[%d]  Cancel Retry Timer !\n",i);
                del_timer_sync(&pAd->MacTab.Content[i].RetryTimer);
                pAd->MacTab.Content[i].RetryTimerRunning = FALSE;             
            }

#ifdef THREAD_ISR
			RTMP_IRQ_LOCK(IrqFlags);
#endif    
            CleanupPsQueue(pAd, &pAd->MacTab.Content[i].PsQueue);
#ifdef THREAD_ISR
			RTMP_IRQ_UNLOCK(IrqFlags);
#endif    


            // Before reset MacTable, send disassociation packet to client.
            if ((!bDFSRestart) && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
            {
                //  send out a DISASSOC request frame
                pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG);
                if(pOutBuffer == NULL) {
#ifndef THREAD_ISR
				    RTMP_SEM_UNLOCK(&pAd->MacTabLock, IrqFlags);
#endif
                	return;
                }
                	


                Reason = REASON_DISASSOC_INACTIVE;
                DBGPRINT(RT_DEBUG_ERROR, "ASSOC - Send DISASSOC  Reason = %d frame  TO %x %x %x %x %x %x \n",Reason,pAd->MacTab.Content[i].Addr[0],
                    pAd->MacTab.Content[i].Addr[1],pAd->MacTab.Content[i].Addr[2],pAd->MacTab.Content[i].Addr[3],pAd->MacTab.Content[i].Addr[4],pAd->MacTab.Content[i].Addr[5]);
                MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAd->MacTab.Content[i].Addr, pAd->PortCfg.MBSSID[pAd->MacTab.Content[i].ApIdx].Bssid);
                MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), (CHAR *)&DisassocHdr, 2, (char*)&Reason, END_OF_ARGS);
                MiniportMMRequest(pAd, pOutBuffer, FrameLen);
                kfree(pOutBuffer);

                RTMPusecDelay(2000);
            }
        }
    }
    
#ifdef THREAD_ISR
	RTMP_IRQ_LOCK(IrqFlags);
#endif    
    CleanupPsQueue(pAd, &pAd->MacTab.McastPsQueue);
    NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
    InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
#ifdef THREAD_ISR
	RTMP_IRQ_UNLOCK(IrqFlags);
#endif	

#ifndef THREAD_ISR
    RTMP_SEM_UNLOCK(&pAd->MacTabLock, IrqFlags);
#endif

}


/*
    ==========================================================================
    Description:
        Add and new entry into MAC table
    ==========================================================================
 */
MAC_TABLE_ENTRY *MacTableInsertEntry(
    IN	PRTMP_ADAPTER	pAd, 
    IN  PUCHAR        pAddr,
    IN  UCHAR           apidx) 
{
    UCHAR HashIdx;
    int i;
    MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
    ULONG	IrqFlags;

    // if FULL, return
    if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) 
        return NULL;

    // allocate one MAC entry
    RTMP_SEM_LOCK(&pAd->MacTabLock, IrqFlags);
    for (i = 1; i< MAX_LEN_OF_MAC_TABLE; i++)		// skip entry#0 so that "entry index == AID" for fast lookup
    {
        // pick up the first available vacancy
        if (pAd->MacTab.Content[i].Valid == FALSE)
        {
            pEntry = &pAd->MacTab.Content[i];
            NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
            pEntry->Valid = TRUE;

            // Move init entry retry timer to where it first created
            init_timer(&pEntry->RetryTimer);
            
            pEntry->bDot1xDynamicWep = FALSE;
            pEntry->RetryTimerRunning = FALSE;
            pEntry->CMTimerRunning = FALSE;
            pEntry->RSNIE_Len = 0;
            NdisMoveMemory(pEntry->R_Counter, pAd->PortCfg.R_Counter, sizeof(pEntry->R_Counter));
            pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
            pEntry->AuthMode = pAd->PortCfg.MBSSID[apidx].AuthMode;
            pEntry->WepStatus = pAd->PortCfg.MBSSID[apidx].WepStatus;
            pEntry->pAd = (unsigned long)pAd;
            pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;

            if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
                pEntry->WpaState = AS_NOTUSE;
            else
                pEntry->WpaState = AS_INITIALIZE;
            pEntry->GTKState = REKEY_NEGOTIATING;
            pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;        
            pEntry->PairwiseKey.KeyLen = 0;
            pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
            AsicRemovePairwiseKeyEntry(pAd, (UCHAR)i);
            COPY_MAC_ADDR(pEntry->Addr, pAddr);
            pEntry->Sst = SST_NOT_AUTH;
            pEntry->AuthState = AS_NOT_AUTH;
            pEntry->Aid = 0;
            pEntry->CapabilityInfo = 0;
            pEntry->PsMode = PWR_ACTIVE;
            pEntry->MaxSupportedRate = RATE_11;
            pEntry->CurrTxRate = RATE_11;
            pEntry->LastTxRate = pEntry->CurrTxRate;//for initial value
            pEntry->PsQIdleCount = 0;
            pEntry->NoDataIdleCount = 0;
            InitializeQueueHeader(&pEntry->PsQueue);

            pEntry->MaxSPLength = 0;
            pEntry->bDlsInit = FALSE;

            pEntry->ApIdx = apidx;
            
            pAd->MacTab.Size ++;

            DBGPRINT(RT_DEBUG_TRACE, "MacTableInsertEntry -IF(ra%d) allocate entry #%d, Total= %d\n",apidx, i, pAd->MacTab.Size);
            break;
        }
    }

    // add this MAC entry into HASH table
    if (pEntry)
    {
        HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
        if (pAd->MacTab.Hash[HashIdx] == NULL)
        {
            pAd->MacTab.Hash[HashIdx] = pEntry;
        }
        else
        {
            pCurrEntry = pAd->MacTab.Hash[HashIdx];
            while (pCurrEntry->pNext != NULL)
                pCurrEntry = pCurrEntry->pNext;
            pCurrEntry->pNext = pEntry;
        }
    }
    
    RTMP_SEM_UNLOCK(&pAd->MacTabLock, IrqFlags);
    return pEntry;
}

/*
    ==========================================================================
    Description:
        Delete a specified client from MAC table
    ==========================================================================
 */
BOOLEAN MacTableDeleteEntry(
    IN PRTMP_ADAPTER pAd, 
    IN PUCHAR pAddr) 
{
    USHORT HashIdx;
    MAC_TABLE_ENTRY *pEntry, *pPrevEntry;
    ULONG	IrqFlags;

    RTMP_SEM_LOCK(&pAd->MacTabLock, IrqFlags);
    HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
    pEntry = pAd->MacTab.Hash[HashIdx];
    if (pEntry)
    {
        if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
        {
        	if(pEntry->RetryTimerRunning==TRUE)
	        {
	            DBGPRINT(RT_DEBUG_TRACE, "MacTableDeleteEntry : Cancel Retry Timer !\n");
	            del_timer_sync(&pEntry->RetryTimer);
	            pEntry->RetryTimerRunning=FALSE;                
	        }

            pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
            CleanupPsQueue(pAd, &pEntry->PsQueue); // return all skb buffer in PSQ
            AsicRemovePairwiseKeyEntry(pAd, (UCHAR)(((ULONG)pEntry - (ULONG)&pAd->MacTab.Content[0])/sizeof(MAC_TABLE_ENTRY)));
            NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
            pAd->MacTab.Size --;
            DBGPRINT(RT_DEBUG_TRACE, "MacTableDeleteEntry 1 - Total= %d\n", pAd->MacTab.Size);
        }
        else
        {
            while (pEntry->pNext)
            {
                pPrevEntry = pEntry;
                pEntry = pEntry->pNext;
                if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
                {
                	if(pEntry->RetryTimerRunning==TRUE)
			        {
			            DBGPRINT(RT_DEBUG_TRACE, "MacTableDeleteEntry : Cancel Retry Timer !\n");
			            del_timer_sync(&pEntry->RetryTimer);
			            pEntry->RetryTimerRunning=FALSE;                
			        }

               	
                    pPrevEntry->pNext = pEntry->pNext;
                    CleanupPsQueue(pAd, &pEntry->PsQueue); // return all skb buffer in PSQ
                    AsicRemovePairwiseKeyEntry(pAd, (UCHAR)(((ULONG)pEntry - (ULONG)&pAd->MacTab.Content[0])/sizeof(MAC_TABLE_ENTRY)));
                    NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
                    pAd->MacTab.Size --;
                    DBGPRINT(RT_DEBUG_TRACE, "MacTableDeleteEntry 2 - Total= %d\n", pAd->MacTab.Size);
                    break;
                }
            }
        }
    }

    RTMP_SEM_UNLOCK(&pAd->MacTabLock, IrqFlags);
    ApUpdateCapabilityAndErpIe(pAd);
    
    return TRUE;
}

/*
    ==========================================================================
    Description:
        Look up the MAC address in the MAC table. Return NULL if not found.
    Return:
        pEntry - pointer to the MAC entry; NULL is not found
    ==========================================================================
*/
MAC_TABLE_ENTRY *MacTableLookup(
    IN PRTMP_ADAPTER pAd, 
    IN PUCHAR pAddr) 
{
    ULONG HashIdx;
    MAC_TABLE_ENTRY *pEntry = NULL;

    HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
    pEntry = pAd->MacTab.Hash[HashIdx];

    while (pEntry && pEntry->Valid)
    {
        if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) 
        {
            break;
        }
        else
            pEntry = pEntry->pNext;
    }

    return pEntry;
}

/*
    ==========================================================================
    Description:
        This routine is called by MlmePeriodicExec() every second to check if
        1. any associated client in PSM. If yes, then TX MCAST/BCAST should be
           out in DTIM only
        2. any client being idle for too long and should be aged-out from MAC table
        3. garbage collect PSQ
    ==========================================================================
*/
VOID MacTableMaintenance(
    IN PRTMP_ADAPTER pAd)
{
    INT     i;
    ULONG	IrqFlags;

    pAd->MacTab.fAnyStationInPsm = FALSE;
    for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) 
    {
        MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];

        if (pEntry->Valid == FALSE)
            continue;
        
        pEntry->NoDataIdleCount ++;

        DBGPRINT(RT_DEBUG_INFO, "(ra%d)%02x:%02x:%02x:%02x:%02x:%02x,TxByte=%d,RxByte=%d,LastDataTime=%d\n", pEntry->ApIdx,
            pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
            pEntry->Addr[4],pEntry->Addr[5],pEntry->HSCounter.TotalTxByteCount,
            pEntry->HSCounter.TotalRxByteCount,pEntry->HSCounter.LastDataPacketTime);

        // 0. STA failed to complete association should be removed to save MAC table space.

⌨️ 快捷键说明

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