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

📄 txproc.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/** @file txproc.c
 *  @This module has the implementation of TX functions
 *
 *  Copyright (c) Marvell Semiconductor, Inc. 
 */
 
#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;
	PTX_PKT_T                   pTxPkt;
       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;
	}


#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 )
	{
	    	return NDIS_STATUS_FAILURE;
	}

       if (Adapter->bIsScanInProgress == TRUE)
       {
	      Adapter->bTXRESOURCES=TRUE;
              return NDIS_STATUS_RESOURCES;  
       }		

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

	if (!pBuffer || !BufferCount || !TotalPacketLength)
	{
		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 )
           	{
			return NDIS_STATUS_FAILURE;
            	}

            	if ( (pHeader[12] != 0x88) || (pHeader[13] != 0x8E) )
            	{
			return NDIS_STATUS_FAILURE;		
            	}
       }
#endif

       EnterCriticalSection(&Adapter->TxCriticalSection);

       if (Adapter->TxPacketCount < MAX_TX_PACKETS )
       {   
              if (InsertNdisPacketToTXPkQ( Packet, &(Adapter->SendPackets[Adapter->TxPacketPut])))
              {
					 
      			Adapter->TxPacketCount++;
            		Adapter->TxPacketPut++;
            		Adapter->TxPacketPut %= MAX_TX_PACKETS;
            		Adapter->TxPacketSend++;

              }	
		else
		{
			LeaveCriticalSection(&Adapter->TxCriticalSection); 
		       return NDIS_STATUS_FAILURE;		
		}
       } 
       else
       {          
             	LeaveCriticalSection(&Adapter->TxCriticalSection); 		 
	      	return NDIS_STATUS_FAILURE;
       }
	   
       if ((Adapter->TxPacketGet != Adapter->TxPacketComplete) || (Adapter->CurCmd != NULL))
       {
             	LeaveCriticalSection(&Adapter->TxCriticalSection);			 
             	return NDIS_STATUS_SUCCESS;  
       }

       pTxPkt = &(Adapter->SendPackets[Adapter->TxPacketGet]);
       Status = SendSinglePacket(Adapter,pTxPkt);
	   
       if (Status == NDIS_STATUS_SUCCESS)
       {
         	Adapter->SendPackets[Adapter->TxPacketGet].PktLen = 0; 
         	Status = NDIS_STATUS_SUCCESS; 	
          	Adapter->TxPacketGet++;
          	Adapter->TxPacketGet %= MAX_TX_PACKETS;
       }
       
       LeaveCriticalSection(&Adapter->TxCriticalSection);
	
       //DBGPRINT(DBG_TXDATA, ("-MrvSend()\n"));

      return NDIS_STATUS_SUCCESS;
	
}


BOOLEAN
InsertNdisPacketToTXPkQ(
     	IN PNDIS_PACKET Packet,
     	IN PTX_PKT_T pSendPacket
     	
       )
{

	UINT 		    BufferCount;
	UINT 		    TotalPacketLength = 0;
	PNDIS_BUFFER   pBuffer, pNextBuffer;

	UINT 		    Length, AccumLength;
	ULONG              coBufferLength = 0;
	 
	ULONG  		    i;  
	PVOID 		    pVirtualAddr;
			
        
	 PUCHAR            pDest ;
	 PUCHAR            pHeader ;
	 

	 NdisQueryPacket( 
                        Packet,
			   NULL,
			   &BufferCount,
			   &pBuffer,
			   &TotalPacketLength );


	 if (!pBuffer || !BufferCount || !TotalPacketLength)
	 {
                goto end;
	 }

        NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length);
        pDest = (PUCHAR)(pSendPacket->PktBuf);
	 pHeader = pDest;


	 AccumLength =0;
        for (i=0; i<BufferCount; i++)
        { 
                NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length);
				

                AccumLength += Length;
	         if ( AccumLength > MAX_TX_PKT_LEN )  
	    	         goto end;
       
                if ( Length )
	         {                
                        NdisMoveMemory((PVOID)pDest, pVirtualAddr, Length);
                        pDest = (PUCHAR)(pDest + Length);
			   coBufferLength += Length;			
                } 

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

	         pBuffer = pNextBuffer;
        }

        pSendPacket->PktLen = (USHORT)coBufferLength;
		
		
        pSendPacket->Wcb.PktLen = (USHORT)coBufferLength;
        pSendPacket->Wcb.Status = MRVDRV_WCB_STATUS_IDLE; 
        pSendPacket->Wcb.TxControl = 0;
        pSendPacket->Wcb.PktPtr = sizeof(WCB);
        // First buffer contains the MAC header
        // Call NdisMoveMemory() to copy DEST MAC address to WCB
	 NdisMoveMemory(
	    		(PVOID)(pSendPacket->Wcb.DestMACAdrHi),
	    		pHeader, 
	    		MRVDRV_ETH_ADDR_LEN);

	return TRUE;

end:
	return FALSE;
	
}


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

NDIS_STATUS
SendSinglePacket(
	IN PMRVDRV_ADAPTER Adapter,
	IN PTX_PKT_T  Packet
)
{
        PCF_OBJECT 	    pCf = (PCF_OBJECT)Adapter->hwIface; // get cf interface object.
	 NDIS_STATUS   Status = NDIS_STATUS_SUCCESS;
	 IX_STATUS        ixStatus = IX_STATUS_SUCCESS;
	
	 
	 USHORT AccumLength;
	 
	 PTxCtrlNode      pTxNode;
		
       
	 

	 NdisAcquireSpinLock(&Adapter->lCFInterfaceLock);
		
        if ((Adapter->psState != PS_STATE_FULL_POWER) &&
    	     (Adapter->psState != PS_STATE_WAKEUP))
	 {
		NdisReleaseSpinLock(&Adapter->lCFInterfaceLock);
		return NDIS_STATUS_FAILURE;
	 }	
	
	 Adapter->bIsDoingTx = TRUE;
	
	 Status = NDIS_STATUS_SUCCESS; 
 
	 pTxNode = &Adapter->TxNode;
	 pTxNode->NPTxPacket = Packet; 

	 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;
	 }

	 AccumLength	= sizeof(WCB) + Packet->PktLen;

⌨️ 快捷键说明

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