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

📄 txproc.c

📁 marvell wifi driver CF-8385PN-NDIS-ARM4-WINCE50-5.24.17.p5-27.p11.src.zip
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************* ?Marvell Semiconductor, Inc., 2001-2004 *****************
 *
 *  Purpose:    This module has the implementation of TX functions
 *
 *	$Author: schiu $
 *
 *	$Date: 2004/11/03 $
 *
 *	$Revision: #7 $
 *
 *****************************************************************************/

#include "precomp.h"

// compilation error if this file is not included
#ifdef UNDER_CE
#include "pkfuncs.h"
#endif

/******************************************************************************
 *
 *  Name: MrvDrvSend()
 *
 *  Description: NDIS miniport serialized send packet routine
 *
 *  Conditions for Use: Protocol driver will call this routine to pass Tx NDIS_PACKET
 *
 *  Arguments:           
 *	    IN  NDIS_HANDLE   MiniportAdapterContext
 *	    IN  PPNDIS_PACKET Packet
 *	    IN  UINT          Flags
 *    
 *  Return Value: NDIS_STATUS_RESOURCES or NDIS_STATUS_PENDING
 * 
 *  Notes:               
 *
 *****************************************************************************/
NDIS_STATUS
MrvDrvSend(
    	IN NDIS_HANDLE MiniportAdapterContext,
    	IN PNDIS_PACKET Packet,
    	IN UINT Flags)
{
	PMRVDRV_ADAPTER Adapter;
       NDIS_STATUS Status;
	//Plus++
	PNDIS_PACKET pPacket;
	//Plus--

       UINT 		  BufferCount;
	UINT 		  TotalPacketLength = 0;	
	UINT 		  Length;
	PNDIS_BUFFER pBuffer;	
	PVOID 		  pVirtualAddr;
	PTxCtrlNode     pTxNode;
	PUCHAR           pHeader = NULL;

#ifdef TX_PERFORMANCE_MEASUREMENT
	static ULONG TxRdyEventCalled = 0;
	static ULONG TxTickCount = 0;
	ULONG	ulCurTickCount = GetTickCount();	
#endif 

//    return NDIS_STATUS_SUCCESS;

	Status = NDIS_STATUS_SUCCESS;  

	Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext;
	
///RETAILMSG(1, (TEXT("+MrvSend()  \r\n")));

	if (Adapter->bIsFreeNow == TRUE)
	{
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_FAILURE 0 \r\n")));       
		return NDIS_STATUS_FAILURE;
	}

       DBGPRINT(DBG_TXDATA, ("+MrvSend()\n"));

#ifdef DEEP_SLEEP 
       // In Deep Sleep Mode no packet can be sent out 
       if (Adapter->IsDeepSleepRequired ||  Adapter->IsDeepSleep)
       {
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_NO_CABLE  \r\n")));          
    		Status = NDIS_STATUS_NO_CABLE;
       }
#endif

       // Check device removal status
       if( Adapter->SurpriseRemoved == TRUE )    
       {
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_FAILURE 1 \r\n")));       
           	return NDIS_STATUS_FAILURE;
       }

	if ( Adapter->bIsPendingReset == TRUE )
	{
	    	//return NDIS_STATUS_RESET_IN_PROGRESS;
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_FAILURE 2 \r\n")));
           	return NDIS_STATUS_FAILURE;
	}

	if ( Adapter->MediaConnectStatus == NdisMediaStateDisconnected )
	{
           	DBGPRINT(DBG_WARNING, ("WARNING: OS attempted to send packet while disconnected!\n"));
	    	return NDIS_STATUS_FAILURE;
	}

#ifdef WPA
	pTxNode = &Adapter->TxNode;
		
	NdisQueryPacket( 
			Packet,
			NULL,
			&BufferCount,
			&pBuffer,
			&TotalPacketLength );

	if (!pBuffer || !BufferCount || !TotalPacketLength)
	{
		Status = NDIS_STATUS_FAILURE;
		return NDIS_STATUS_FAILURE;
		
	}

       NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length);
       pHeader = (PUCHAR)pVirtualAddr;

       if (( Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent ) || 
	    ( Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) )
       {

		// no key yet, only allow 802.1x packets
           	if ( TotalPacketLength < 14 )
           	{
               	DBGPRINT(DBG_TXDATA  | DBG_MACEVENT , ("Got packet with length less than 14, invalid!\n"));
///RETAILMSG(1, (TEXT("Got packet with length less than 14, invalid! \r\n")));	
               	Status =  NDIS_STATUS_FAILURE;
			
			return NDIS_STATUS_FAILURE;
            	}

            	if ( (pHeader[12] != 0x88) || (pHeader[13] != 0x8E) )
            	{
                	DBGPRINT(DBG_TXDATA  | DBG_MACEVENT , ("Still no key and packet type(0x%x 0x%x) is "
                                  "not 802.1x, drop!\n", 
                                  pHeader[12], pHeader[13]));

///RETAILMSG(1, (TEXT("Still no key and packet type \r\n")));		
                	Status = NDIS_STATUS_FAILURE;
			return NDIS_STATUS_FAILURE;		
			
            	}
       }
#endif
	
       EnterCriticalSection(&Adapter->TxCriticalSection);
       if (Adapter->TxPacketCount < MAX_TX_PACKETS )
       {   
            Adapter->SendPackets[Adapter->TxPacketPut] = Packet;
            Adapter->TxPacketCount++;
            Adapter->TxPacketPut++;
            Adapter->TxPacketPut %= MAX_TX_PACKETS;
            Adapter->TxPacketSend++;
       } 
       else
       {     
             DBGPRINT(DBG_DRALEE,("***TxPacketCount: %x \n\r",Adapter->TxPacketCount));     
             LeaveCriticalSection(&Adapter->TxCriticalSection); 
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_RESOURCES\r\n")));			 
	      return NDIS_STATUS_RESOURCES;
       }
       
       if ((Adapter->TxPacketGet != Adapter->TxPacketComplete) || (Adapter->CurCmd != NULL))
       {
             //NKDbgPrintfW( L"Get Complete count %d %d \r\n", Adapter->TxPacketGet, Adapter->TxPacketComplete );
             //DBGPRINT(1,("TxPacketCount: %x \n\r",Adapter->TxPacketCount));
             LeaveCriticalSection(&Adapter->TxCriticalSection);
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_PENDING 1 \r\n")));				 
             return NDIS_STATUS_PENDING;  
       }

       pPacket = Adapter->SendPackets[Adapter->TxPacketGet];
       Status = SendSinglePacket(Adapter,pPacket);
       if(Status == NDIS_STATUS_SUCCESS)
       {
           	//RETAILMSG(1,(TEXT("txproc: Packet is Sent \r\n")));

          	if (pPacket == Packet)
          	{ 
             		Adapter->SendPackets[Adapter->TxPacketGet] = NULL; 
             		Status = NDIS_STATUS_SUCCESS;
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_SUCCESS \r\n")));		
          	}   
          	else
             	{
             		Status = NDIS_STATUS_PENDING;
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_PENDING 2 \r\n")));					
          	}
          	//InterlockedIncrement(&Adapter->TxPacketGet);
          	Adapter->TxPacketGet++;
          	Adapter->TxPacketGet %= MAX_TX_PACKETS;
       }
       else
       {    
             	DBGPRINT(DBG_DRALEE,("###TxPacketCount: %x \n\r",Adapter->TxPacketCount));
             	LeaveCriticalSection(&Adapter->TxCriticalSection);
///RETAILMSG(1, (TEXT("+MrvSend()  NDIS_STATUS_PENDING 3 \r\n")));				
             	return NDIS_STATUS_PENDING;  
       }
       LeaveCriticalSection(&Adapter->TxCriticalSection);

       //DBGPRINT(DBG_ERROR,("Status %x TxSend %x \n", Status, Adapter->TxPacketSend));
		
#ifdef TX_PERFORMANCE_MEASUREMENT
	TxRdyEventCalled++;
	TxTickCount += GetTickCount() - ulCurTickCount;
	
	// average for 8000 pkts
	if ( TxRdyEventCalled == 8000 )
	{
		wchar_t buf[100];

		swprintf(buf, TEXT("time in ms per TX pkt: %d"), TxTickCount / TxRdyEventCalled);
		MessageBox(NULL, buf, TEXT("CF-25"), MB_OK);
		TxRdyEventCalled = 0;
		TxTickCount = 0;
	}
#endif 

       //DBGPRINT(DBG_TXDATA, ("-MrvSend()\n"));

      return Status;
	
}

/******************************************************************************
 *
 *  Name: SendSinglePacket()
 *
 *  Description: TX packet handler
 *
 *  Arguments:	PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value:
 * 
 *  Notes:               
 *
 *****************************************************************************/

NDIS_STATUS
SendSinglePacket(
	IN PMRVDRV_ADAPTER Adapter,
	IN PNDIS_PACKET Packet
)
{
        PCF_OBJECT 	    pCf = (PCF_OBJECT)Adapter->hwIface; // get cf interface object.
	 NDIS_STATUS   Status = NDIS_STATUS_SUCCESS;
	 IX_STATUS        ixStatus = IX_STATUS_SUCCESS;
	 UINT 		    BufferCount;
	 UINT 		    TotalPacketLength = 0;
	 UINT 		    BytesCopied = 0;
	 UINT 		    Length, AccumLength;
	 PNDIS_BUFFER  pBuffer, pNextBuffer;
	 ULONG  		    i;  
	 PVOID 		    pVirtualAddr;
	 PTxCtrlNode      pTxNode;
		
        UCHAR 		    Buffer[MRVDRV_ETH_TX_PACKET_BUFFER_SIZE];
	 PUCHAR            pDest = Buffer;
	 PUCHAR            pHeader = NULL;
        ULONG              coBufferLength = 0;
	 //USHORT            framlen;
	 UCHAR              llc_snap[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
	 
        //DBGPRINT(DBG_TXDATA ,("+SendSinglePacket()\n"));

	 NdisAcquireSpinLock(&Adapter->lCFInterfaceLock);
		
        if ((Adapter->psState != PS_STATE_FULL_POWER) &&
    	     (Adapter->psState != PS_STATE_WAKEUP))
	 {
		//DBGPRINT(DBG_TXDATA | DBG_MACEVENT |DBG_SP,("Tx can not send in the power state_1 \n"));
		NdisReleaseSpinLock(&Adapter->lCFInterfaceLock);
		return NDIS_STATUS_FAILURE;
	 }	
	
	 Adapter->bIsDoingTx = TRUE;
	
	 Status = NDIS_STATUS_SUCCESS; 
 
	 pTxNode = &Adapter->TxNode;
		
	 NdisQueryPacket( 
                        Packet,
			   NULL,
			   &BufferCount,
			   &pBuffer,
			   &TotalPacketLength );

	 if (!pBuffer || !BufferCount || !TotalPacketLength)
	 {
                DBGPRINT(DBG_TXDATA  | DBG_MACEVENT  ,("TX - NDIS buffer is not valid, return FAILURE \n"));
		  Status = NDIS_STATUS_FAILURE;
                goto end;
	 }

        NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length);
        pHeader = (PUCHAR)pVirtualAddr;

        /// RETAILMSG(1, (TEXT("First Ndis Buffer Length = %d  \r\n"), Length));

#ifdef WPA
        if ((Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent ) ||
	      (Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent )) 	
        {
                // no key yet, only allow 802.1x packets
           	  if ( TotalPacketLength < 14 )
           	  {
                        DBGPRINT(DBG_TXDATA  | DBG_MACEVENT , ("Got packet with length less than 14, invalid!\n"));
               	   Status =  NDIS_STATUS_FAILURE;
			   goto end;
            	  }

            	  if ( (pHeader[12] != 0x88) || (pHeader[13] != 0x8E) )
            	  {
                        DBGPRINT(DBG_TXDATA  | DBG_MACEVENT , ("Still no key and packet type(0x%x 0x%x) is "
                                  "not 802.1x, drop!\n", 
                                  pHeader[12], pHeader[13]));
                	   Status = NDIS_STATUS_FAILURE;
			   goto end;
            	  }
        }
#endif

        DBGPRINT(DBG_TXDATA  ,("SendSinglePacket: buffers %d, packet len %d\n",BufferCount, TotalPacketLength));
	 pTxNode->NPTxPacket = Packet;
	 NdisZeroMemory(pTxNode->LocalWCB, sizeof(WCB));
	 pTxNode->LocalWCB->Status = MRVDRV_WCB_STATUS_IDLE; 
	 
#ifdef INTERFACE20
	 DBGPRINT(DBG_DATARATE  | DBG_MACEVENT ,("DataRate = %x\n", (ULONG)Adapter->DataRate));
        // number of retry is 3
        // pTxNode->LocalWCB->TxControl = (( 3 << 12 ) | Adapter->DataRate);
        pTxNode->LocalWCB->TxControl = 0;
        pTxNode->LocalWCB->PktPtr = sizeof(WCB);
#endif

        // First buffer contains the MAC header
        // Call NdisMoveMemory() to copy DEST MAC address to WCB
	 NdisMoveMemory(
	    		(PVOID)pTxNode->LocalWCB->DestMACAdrHi,
	    		pVirtualAddr, 
	    		MRVDRV_ETH_ADDR_LEN);

	 if ((Adapter->psState != PS_STATE_FULL_POWER) &&
    	     (Adapter->psState != PS_STATE_WAKEUP))
	 {
                DBGPRINT(DBG_TXDATA ,("Tx can not send in the power state_2 \n"));
		  Status = NDIS_STATUS_FAILURE;
		  goto end;
	 }

//        DBGPRINT(DBG_TXDATA |DBG_SP,(" Realy start Tx \n"));


        // Query each buffer for the packet and move data to SQ
        AccumLength = sizeof(WCB);

        DBGPRINT(DBG_TXDATADUMP,("TX Buffer (Packet):\n"));
        for (i=0; i<BufferCount; i++)
        { 
                NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length);

                AccumLength += Length;
	         if ( AccumLength > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE )  // PJG: accum length already counts the header... need to compare to entire buffer size
	    	          break;
       
                if ( Length )
	         {                
                        NdisMoveMemory((PVOID)pDest, pVirtualAddr, Length);
                        pDest = (PUCHAR)(pDest + Length);
                        coBufferLength += Length;
                              
                        /// HexDump(DBG_TXDATADUMP, NULL, pVirtualAddr, Length);
                } 

                NdisGetNextBuffer(pBuffer, &pNextBuffer);
                if ( !pNextBuffer )
                        break;

	         pBuffer = pNextBuffer;
        }

/*
       // workarround -> add for two card test 
       framlen = (*((PUCHAR)Buffer+12) << 8) | (*((PUCHAR)Buffer+13));
	if (framlen <= 1500)
	{
        	NdisMoveMemory((PCHAR)Buffer+12, (PCHAR)Buffer+14, coBufferLength-14);
		coBufferLength -= 2;	
		AccumLength -=2;
	}
	 
        // workarround -> add for two card test 
	{
        	 if (NdisEqualMemory(llc_snap, (PCHAR)Buffer+12, 6) == 1) 
        	 {
			if( ((Buffer[18] == 0x80) && (Buffer[19] == 0xf3)) ||
			     ((Buffer[18] == 0x81) && (Buffer[19] == 0x37)) )
			{
                 		NdisMoveMemory((PCHAR)Buffer+12, (PCHAR)Buffer+18, coBufferLength-18);
				coBufferLength -= 6;	
				AccumLength -=6;
			}		
        	 }
	 }
*/		 
/*
	 {
        	 if (NdisEqualMemory(llc_snap, (PCHAR)Buffer+14, 6) == 1) 
        	 {
			if( ((Buffer[20] == 0x80) && (Buffer[21] == 0xf3)) ||
			     ((Buffer[20] == 0x81) && (Buffer[21] == 0x37)) )
			{
                 		NdisMoveMemory((PCHAR)Buffer+12, (PCHAR)Buffer+20, coBufferLength-20);
				coBufferLength -= 8;	
				AccumLength -=8;
			}		
        	 }
	 }
*/ 
        pTxNode->LocalWCB->PktLen = (USHORT)coBufferLength;
	 AccumLength	= sizeof(WCB) + coBufferLength;

        ///HexDump(DBG_TXDATA, "The Context of Tx data \n", Buffer, coBufferLength);

⌨️ 快捷键说明

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