rtmp_data.c

来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,485 行 · 第 1/5 页

C
1,485
字号
#define REPORT_MGMT_FRAME_TO_MLME(_pAd, _pFrame, _FrameSize, _Rssi, _Offset)                     \
{                                                                                       \
    ULONG High32TSF, Low32TSF;                                                          \
	RTMP_IO_READ32(_pAd, TXRX_CSR13, &High32TSF);                                       \
	RTMP_IO_READ32(_pAd, TXRX_CSR12, &Low32TSF);                                        \
	MlmeEnqueueForRecv(_pAd, High32TSF,	Low32TSF, (UCHAR)_Rssi, _FrameSize, _pFrame, _Offset);   \
}

/*
	========================================================================

	Routine	Description:
		Process	RxDone interrupt, running in DPC level

	Arguments:
		pAdapter	Pointer	to our adapter

	Return Value:
		None

	Note:
		This routine has to	maintain Rx	ring read pointer.
		Need to consider QOS DATA format when converting to 802.3
	========================================================================
*/
VOID	RTMPHandleRxDoneInterrupt(
	IN	PRTMP_ADAPTER	pAd)
{
    PRXD_STRUC					pRxD;
#ifdef BIG_ENDIAN
    PRXD_STRUC      			pDestRxD;
    RXD_STRUC       			RxD;
#endif
	PHEADER_802_11				pHeader;
	PUCHAR						pData;
	USHORT						DataSize, Msdu2Size;
	PUCHAR						pDA, pSA;
	UCHAR						Header802_3[14];
	INT							Count, apidx = MAIN_MBSSID, i;
	MAC_TABLE_ENTRY				*pEntry = NULL;
    NDIS_802_11_PRIVACY_FILTER	Privacy;
    WPA_STATE					WpaState;
    struct net_device			*net_dev = pAd->net_dev;
    BOOLEAN         			bWdsPacket = FALSE;
    UCHAR                       Offset = 0;
    ULONG						IrqFlags;
	BOOLEAN						bQoS;
	UCHAR						OldPwrMgmt = PWR_ACTIVE;
#ifdef APCLI_SUPPORT
	INT 						ApCliIdx = MAIN_MBSSID;
	BOOLEAN         			bApCliPacket = FALSE;	
#endif

    // Make sure Rx ring resource won't be used by other threads
    RTMP_SEM_LOCK(&pAd->RxRingLock, IrqFlags);

    DBGPRINT(RT_DEBUG_INFO, "RTMPHandleRxDoneInterrupt --->\n");

    for (Count=0; Count<MAX_RX_PROCESS; Count++)
    {
#ifndef BIG_ENDIAN
        // Point to Rx indexed rx ring descriptor
        pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
#else
        pDestRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
        RxD = *pDestRxD;
        pRxD = &RxD;
        RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
#endif

		        
        // In case of false alarm or processed at last instance
        if (pRxD->Owner != DESC_OWN_HOST)
            break;

        // beak out this "do {...} while FALSE" loop whenever RX frame error without indicating 
        // to upper layer
        do
        {
        	pci_unmap_single(pAd->pPci_Dev, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
            pData   = (PUCHAR) (pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa);
            pHeader = (PHEADER_802_11) pData;

#ifdef BIG_ENDIAN
	        RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, FALSE);
#endif
            // Increase Total receive byte counter after real data received no mater any error or not
            pAd->RalinkCounters.ReceivedByteCount +=  pRxD->DataByteCnt;
            pAd->RalinkCounters.RxCount ++;
            
            // Check for all RxD errors
            if (RTMPCheckRxError(pRxD) != NDIS_STATUS_SUCCESS)
            {
                if (pRxD->U2M && pRxD->CipherErr)
                {
                	if ((pRxD->CipherAlg == CIPHER_TKIP) && (pRxD->CipherErr == 2))	//MIC error
                	{
                		pEntry = PACInquiry(pAd, pHeader->Addr2, &Privacy, &WpaState);

                		if (pEntry)
                		{
                			HandleCounterMeasure(pAd, pEntry);
                		}
                	}
                    DBGPRINT(RT_DEBUG_ERROR, "Rx u2me DATA Cipger Err(len=%d,Alg=%d,keyidx=%d,ciphererr=%d)\n", 
                    	pRxD->DataByteCnt, pRxD->CipherAlg, pRxD->KeyIndex, pRxD->CipherErr);
                }
                
                pAd->Counters8023.RxErrors++;
                break;  // give up this frame
            }			  

            pAd->WlanCounters.ReceivedFragmentCount++;
            
#ifdef RALINK_ATE
            pAd->ate.RxCntPerSec++;
#endif

            // All frames to AP are directed except probe_req. IEEE 802.11/1999 - p.463
            // Do this before checking "duplicate frame".
            // 2003-08-20 accept BEACON to decide if OLBC (Overlapping Legacy BSS Condition) happens
            // TODO: consider move this code to be inside "APCheckRxError()"
            if (pRxD->U2M)
            {
                if (pHeader->FC.Type == BTYPE_DATA)
                {
                    CHAR RealRssi;
                    
                    RealRssi = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpRssi, RSSI_NO_1);
                    pAd->PortCfg.LastRssi  = RealRssi + pAd->BbpRssiToDbmDelta;
                    pAd->PortCfg.AvgRssiX8  = (pAd->PortCfg.AvgRssiX8 - pAd->PortCfg.AvgRssi) + pAd->PortCfg.LastRssi;
                    pAd->PortCfg.AvgRssi = pAd->PortCfg.AvgRssiX8 >> 3;
                    pAd->PortCfg.NumOfAvgRssiSample ++;
                    
                    if ((pAd->RfIcType == RFIC_5325) || (pAd->RfIcType == RFIC_2529))
                    {
                    	pAd->PortCfg.LastRssi2  = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpSignal, RSSI_NO_2) + pAd->BbpRssiToDbmDelta;
                    	pAd->PortCfg.AvgRssi2X8  = (pAd->PortCfg.AvgRssi2X8 - pAd->PortCfg.AvgRssi2) + pAd->PortCfg.LastRssi2;
	                    pAd->PortCfg.AvgRssi2 = pAd->PortCfg.AvgRssi2X8 >> 3;
                    }
                    
                    // Gather PowerSave information from all valid DATA frames. IEEE 802.11/1999 p.461
                    if (pHeader->FC.PwrMgmt)
                        OldPwrMgmt = PsIndicate(pAd, pHeader->Addr2, pAd->PortCfg.LastRssi, PWR_SAVE);
                    else
                        OldPwrMgmt = PsIndicate(pAd, pHeader->Addr2, pAd->PortCfg.LastRssi, PWR_ACTIVE);
            
#ifdef APCLI_SUPPORT               
                	// gather U2M data frame from ApCli interface to update AvgRSSI 
                	if (pHeader->FC.FrDs == 1 && pHeader->FC.ToDs == 0)
                	{
                		for (i = 0; i < MAX_APCLI_ENTRY; i++)
						{
							//BSSID match the ApCliBssid ?(from a valid AP)
							if ((pAd->ApCliTab.ApCliEntry[i].Valid== TRUE)
									&& (MAC_ADDR_EQUAL(&pAd->ApCliTab.ApCliEntry[i].ApCliBssid, &pHeader->Addr2)))
							{
								pAd->ApCliTab.ApCliEntry[i].NumOfAvgRssiSample ++;
								break;
							}
						}
                	}
#endif                		
                }
                // ignore all CNTL frames except PS-POLL
                else if ((pHeader->FC.Type == BTYPE_CNTL) && (pHeader->FC.SubType != SUBTYPE_PS_POLL))
                    break;
            }
            else // B/M-cast frame
            { 
#ifdef RALINK_ATE
				if(pAd->ate.Mode != ATE_APSTART)
				{
	            	CHAR RealRssi;
	                    
	                RealRssi = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpRssi, RSSI_NO_1);
	                pAd->PortCfg.LastRssi  = RealRssi + pAd->BbpRssiToDbmDelta;
	                pAd->PortCfg.AvgRssiX8  = (pAd->PortCfg.AvgRssiX8 - pAd->PortCfg.AvgRssi) + pAd->PortCfg.LastRssi;
	                pAd->PortCfg.AvgRssi = pAd->PortCfg.AvgRssiX8 >> 3;

	                if ((pAd->RfIcType == RFIC_5325) || (pAd->RfIcType == RFIC_2529))
                    {
                    	pAd->PortCfg.LastRssi2  = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpSignal, RSSI_NO_2) + pAd->BbpRssiToDbmDelta;
                    	pAd->PortCfg.AvgRssi2X8  = (pAd->PortCfg.AvgRssi2X8 - pAd->PortCfg.AvgRssi2) + pAd->PortCfg.LastRssi2;
	                	pAd->PortCfg.AvgRssi2 = pAd->PortCfg.AvgRssi2X8 >> 3;
                    }
				}
#endif	// RALINK_ATE
                    
                if ((pHeader->FC.Type == BTYPE_MGMT) && 
                    ((pHeader->FC.SubType == SUBTYPE_BEACON) || (pHeader->FC.SubType == SUBTYPE_PROBE_REQ)))
                {    
#ifdef APCLI_SUPPORT
					// gather beacon from ApCli interface to update AvgRSSI 
					if (pHeader->FC.SubType == SUBTYPE_BEACON)
					{
						for (i = 0; i < MAX_APCLI_ENTRY; i++)
						{
							//BSSID match the ApCliBssid ?(from a valid AP)
							if ((pAd->ApCliTab.ApCliEntry[i].Valid== TRUE)
								&& (MAC_ADDR_EQUAL(&pAd->ApCliTab.ApCliEntry[i].ApCliBssid, &pHeader->Addr2)))
							{
								pAd->ApCliTab.ApCliEntry[i].NumOfAvgRssiSample ++;
								break;
							}
						}	
					}	
#endif
                }
                else
				{
#ifndef APCLI_SUPPORT
                    break; // give up this frame
#else 
					// It is possible to receive the multicast packet when in AP Client mode
					// Such as a broadcast from AP2 to AP1, address1 is ffffff, address2 is AP2 bssid, addr3 is sta4 mac address
					PUCHAR pRemovedLLCSNAP;

					for(i = 0; i < MAX_APCLI_ENTRY; i++)
					{
						//BSSID match the ApCliBssid ?(from a valid AP)
						if((pAd->ApCliTab.ApCliEntry[i].Valid == TRUE)
							&& (pAd->ApCliTab.ApCliEntry[i].Enable == TRUE)
							&& (MAC_ADDR_EQUAL(&pAd->ApCliTab.ApCliEntry[i].ApCliBssid, &pHeader->Addr2)))
						{
							net_dev = pAd->ApCliTab.ApCliEntry[i].dev;
							DBGPRINT(RT_DEBUG_INFO, "APCLI Multicast packet from (apcli%d)!!!\n", i);
							break;
						}
					}   

					if (i == MAX_APCLI_ENTRY)
					{
						DBGPRINT(RT_DEBUG_INFO, "APCLI packet, but not our APCLI group, give it up!!!\n");
						break;// give up this frame
					}

 					// Filter out Bcast frame which AP relayed for us
					// Multicast packet send from AP1 , received by AP2 and send back to AP1, drop this frame   					
					if (MAC_ADDR_EQUAL(pHeader->Addr3, pAd->ApCliTab.ApCliEntry[i].CurrentAddress))
							break;// give up this frame
					
					// This frame must be from DS when in AP Client mode
					if (pHeader->FC.FrDs == 0)
						break;// give up this frame
					
					// Use software to decrypt the encrypted frame
					// Because this received frame isn't my BSS frame, Asic passed to driver without decrypting it.
					// Then its "CipherAlg" in RxD would be marked as "NONE".
            		if ((pRxD->MyBss == 0) && (pRxD->CipherAlg == CIPHER_NONE) && (pHeader->FC.Wep == 1)) 
            		{
            			// handle WEP decryption
            			if(pAd->PortCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11WEPEnabled)
            			{
            				UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
            	
            				if (RTMPDecryptData(pAd, pPayload, pRxD->DataByteCnt - LENGTH_802_11) == FALSE)
   							{
								printk("ERROR : Software decrypt WEP data fails.\n");	
								break;// give up this frame
							}
                			else 
								pRxD->DataByteCnt -= 8;  //Minus IV[4] & ICV[4]
#ifdef RTL865X_SOC
							//printk("RTMPDecryptData WEP data Complete \n");	
#else							
							DBGPRINT(RT_DEBUG_INFO, "RTMPDecryptData WEP data Complete \n");	
#endif							
						}
						// handle TKIP decryption
						else if(pAd->PortCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11Encryption2Enabled)
						{	
							if (RTMPSoftDecryptTKIP(pAd, pData, pRxD->DataByteCnt, 0, pAd->ApCliTab.ApCliEntry[i].SharedKey))
							{
#ifdef RTL865X_SOC
								//printk("RTMPSoftDecryptTKIP Complete \n");
#else								
								DBGPRINT(RT_DEBUG_INFO, "RTMPSoftDecryptTKIP Complete \n");
#endif								
								pRxD->DataByteCnt -= 20;  //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
							}
                			else
							{
								printk("ERROR : RTMPSoftDecryptTKIP Failed\n");
                    			break; // give up this frame
            				}
						}
						// handle AES decryption
						else if(pAd->PortCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11Encryption3Enabled)
						{
							if (RTMPSoftDecryptAES(pAd, pData, pRxD->DataByteCnt , pAd->ApCliTab.ApCliEntry[i].SharedKey))
							{
#ifdef RTL865X_SOC
								//printk("RTMPSoftDecryptAES Complete \n");
#else								
								DBGPRINT(RT_DEBUG_INFO, "RTMPSoftDecryptAES Complete \n");
#endif								

⌨️ 快捷键说明

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