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

📄 rxproc.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// 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 rxproc.c
 *   @This module has the implementaion of RX routines
 *
 *  Copyright (c) Marvell Semiconductor, Inc. 
 */
#include "precomp.h"

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

VOID
ReturnRxPacketDesc(PMRVDRV_ADAPTER Adapter,
                   PNDIS_PACKET    pPacket);

/******************************************************************************
 *
 *  Name: MrvDrvReturnPacket()
 *
 *  Description: the rx ndis return packet callback function (handler) 
 *
 *  Arguments:  Packet : the packet Ndis return
 *    
 *  Notes:        
 *
 *****************************************************************************/

VOID
MrvDrvReturnPacket(
    	IN NDIS_HANDLE  MiniportAdapterContext,
    	IN PNDIS_PACKET Packet)
{

#ifdef USE_RX_QUEUE	

	PMRVDRV_ADAPTER Adapter;
 
	Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext;

	if (Adapter->sNumOutstandingRxPacket)
    		ReturnRxPacketDesc( MiniportAdapterContext, Packet);

	
	{
		PPACKET_QUEUE_NODE  	pPacketNode;
		PNDIS_PACKET 			pPacket;
		NDIS_STATUS                 	pStatus;

    		while (1)
    		{
    			pPacketNode = (PPACKET_QUEUE_NODE)PopFirstQNode(&Adapter->RxPacketWaitQueue);

			if ( pPacketNode == NULL)
				break;

			pPacket = pPacketNode->pPacket;
				
			NdisMIndicateReceivePacket(Adapter->MrvDrvAdapterHdl, &pPacket, 1);
			
        		pStatus = NDIS_GET_PACKET_STATUS(pPacket);
        
        		if ((pStatus == NDIS_STATUS_RESOURCES) || (pStatus == NDIS_STATUS_SUCCESS))
        		{
            			// return packet
           	 		DBGPRINT(DBG_RXDATA, ("Packet returned success or resources...\n"));
            			ReturnRxPacketDesc(Adapter,pPacket);   
        		}
        		else
        		{
            			DBGPRINT(DBG_RXDATA, ("Packet returned pending...\n"));
				Adapter->bIsRxIndicatePacket = TRUE;
				return;
        		}

    		}
			
		Adapter->bIsRxIndicatePacket = FALSE;
			
	}
#endif

	return;
}

/******************************************************************************
 *
 *  Name: AllocateRxQ()
 *
 *  Description: Allocate Rx Buffer
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
 * 
 *  Notes:        
 *
 *****************************************************************************/
NDIS_STATUS AllocateRxQ(
	IN PMRVDRV_ADAPTER Adapter
	)
{

#ifdef USE_RX_QUEUE

	ULONG 					i;
    	NDIS_STATUS 			tStatus;
    	BOOLEAN                 		bSuccess = TRUE;
    	PACKET_QUEUE_NODE        	**pNode;
    	PNDIS_PACKET_OOB_DATA  pOOB;
   
    	/// Initialize rx-related variables 
    	Adapter->RxBufferPoolHandle = 
    	Adapter->RxPacketPoolHandle = NULL;
    	//
    	InitializeQKeeper(&Adapter->RxPacketFreeQueue);
	InitializeQKeeper(&Adapter->RxPacketWaitQueue);	
    	// 
    	for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
    	{
       	Adapter->pRxBufVM[i] = NULL;
        	Adapter->pRxBuffer[i] = NULL;
        	Adapter->pRxPacket[i] = NULL;
    	}

    	/// Allocate all needed memory space 
    	do
    	{
		// packet pool 
		NdisAllocatePacketPoolEx(
						&tStatus, 
                                		&Adapter->RxPacketPoolHandle,
                                		MRVDRV_NUM_RX_PKT_IN_QUEUE,
                   				MRVDRV_NUM_RX_PKT_IN_QUEUE, 
                                		PROTOCOL_RESERVED_SIZE_IN_PACKET);

        	if ( tStatus != NDIS_STATUS_SUCCESS )
        	{
            		DBGPRINT( DBG_ERROR,
                    			("Unable to allocate packet pool!\n"));
            		return tStatus;
        	}

        	// buffer pool 
        	NdisAllocateBufferPool(
						&tStatus,
                               		&Adapter->RxBufferPoolHandle,
                               		MRVDRV_NUM_RX_PKT_IN_QUEUE);
        
        	if ( tStatus != NDIS_STATUS_SUCCESS )
        	{
            		DBGPRINT( DBG_ERROR,
                    			("Unable to allocate buffer pool!\n"));
            		bSuccess = FALSE;
            		break;
        	}

		// assign space to used three array 
        	for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
        	{
			// data payload space array 
			tStatus = 
			NdisAllocateMemoryWithTag(
							&Adapter->pRxBufVM[i], 
                                      		MRVDRV_ETH_RX_PACKET_BUFFER_SIZE,
                                      		MRVDRV_MEMORY_TAG);

            		if ( tStatus != NDIS_STATUS_SUCCESS )
            		{
                		bSuccess = FALSE;
                		break;
            		}

            		// buffer array 
            		NdisAllocateBuffer(
            					&tStatus,
                                		&Adapter->pRxBuffer[i],
                                		Adapter->RxBufferPoolHandle,
                                		Adapter->pRxBufVM[i],
                                		MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);

            		if ( tStatus != NDIS_STATUS_SUCCESS )
            		{
                		bSuccess = FALSE;
                		break;
            		}

			// packet array 	
            		NdisAllocatePacket(
							&tStatus, 
                               			&Adapter->pRxPacket[i],
                               			Adapter->RxPacketPoolHandle);

            		if ( tStatus != NDIS_STATUS_SUCCESS )
            		{
                		bSuccess = FALSE;
                		break;
            		}

            		// init OBB space
            		pOOB = NDIS_OOB_DATA_FROM_PACKET(Adapter->pRxPacket[i]);
            		NdisZeroMemory(pOOB, sizeof(NDIS_PACKET_OOB_DATA));
            		NDIS_SET_PACKET_HEADER_SIZE(Adapter->pRxPacket[i], MRVDRV_ETH_HEADER_SIZE);

            		// chain the packet and buffer 
            		NdisChainBufferAtFront(Adapter->pRxPacket[i],
                     			              Adapter->pRxBuffer[i]);

            		// fill packet node 
           	 	Adapter->RxPacketQueueNode[i].pPacket = Adapter->pRxPacket[i];
		
            		pNode = (PACKET_QUEUE_NODE **)Adapter->pRxPacket[i]->MiniportReserved;
            		*pNode = &Adapter->RxPacketQueueNode[i];
            
			// insert to free queue
            		InsertQNodeAtTail(&Adapter->RxPacketFreeQueue, &Adapter->RxPacketQueueNode[i]);

		}   // end of for(;;)

    	} while (0);

    	if ( ! bSuccess )
    	{
       	// clean up all
        	FreeRxQ(Adapter);
        	return NDIS_STATUS_FAILURE;
    	}

    	Adapter->sNumOutstandingRxPacket = 0;
	Adapter->bIsRxIndicatePacket = FALSE;

#endif

    	return NDIS_STATUS_SUCCESS;
}

/******************************************************************************
 *
 *  Name: FreeRxQ()
 *
 *  Description: Free Rx buffer
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
 * 
 *  Notes:        
 *
 *****************************************************************************/
NDIS_STATUS FreeRxQ(
	IN PMRVDRV_ADAPTER Adapter
	)
{

#ifdef USE_RX_QUEUE

    	ULONG i;

    	for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
    	{
       	if ( Adapter->pRxBufVM[i] != NULL )
        	{
            		NdisFreeMemory(Adapter->pRxBufVM[i],
                     		      MRVDRV_ETH_RX_PACKET_BUFFER_SIZE,
                           			0);            
            		Adapter->pRxBufVM[i] = NULL;
        	}

        	if ( Adapter->pRxBuffer[i] != NULL )
        	{
            		NdisFreeBuffer(Adapter->pRxBuffer[i]);
            		Adapter->pRxBuffer[i] = NULL;
        	}

        	if ( Adapter->pRxPacket[i] != NULL )
        	{
            		NdisFreePacket(Adapter->pRxPacket[i]);
            		Adapter->pRxPacket[i] = NULL;
        	}
    	} 
    
    	if ( Adapter->RxBufferPoolHandle != NULL )
    	{
       	NdisFreeBufferPool(Adapter->RxBufferPoolHandle);
       	Adapter->RxBufferPoolHandle = NULL;
    	}

    	if ( Adapter->RxPacketPoolHandle != NULL )
    	{
       	NdisFreePacketPool(Adapter->RxPacketPoolHandle);
       	Adapter->RxPacketPoolHandle = NULL;
    	}
    	
#endif

    	return NDIS_STATUS_SUCCESS;
}

/******************************************************************************
 *
 *  Name: ResetRxPDQ()
 *
 *  Description: RxPDQ reset
 *
 *  Arguments:	PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value:        
 * 
 *
 *****************************************************************************/
VOID
ResetRxPDQ(
	IN PMRVDRV_ADAPTER Adapter)
{

#ifdef USE_RX_QUEUE

	ULONG i;
	
    	NdisAcquireSpinLock(&Adapter->RxQueueSpinLock);

	Adapter->sNumOutstandingRxPacket = 0;
	InitializeQKeeper(&Adapter->RxPacketFreeQueue);
	InitializeQKeeper(&Adapter->RxPacketWaitQueue);
	
    	for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
		InsertQNodeAtTail(&Adapter->RxPacketFreeQueue, &Adapter->RxPacketQueueNode[i]);

    	NdisReleaseSpinLock(&Adapter->RxQueueSpinLock);

	Adapter->sNumOutstandingRxPacket = 0;
	Adapter->bIsRxIndicatePacket = FALSE;

#endif 

	return;
}

/******************************************************************************
 *
 *  Name: GetRxPacketDesc()
 *
 *  Description: Get a free RX Packet descriptor
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value: MRVDRV_GET_PACKET_STATUS
 * 
 *  Notes:        
 *
 *****************************************************************************/
MRVDRV_GET_PACKET_STATUS
GetRxPacketDesc(PMRVDRV_ADAPTER Adapter,
                PNDIS_PACKET    *p_PPacket)
{

#ifdef USE_RX_QUEUE

    	PPACKET_QUEUE_NODE  pPacketNode;

    	NdisAcquireSpinLock(&Adapter->RxQueueSpinLock);

    	if ( Adapter->sNumOutstandingRxPacket == MRVDRV_NUM_RX_PKT_IN_QUEUE )
    	{
       	NdisReleaseSpinLock(&Adapter->RxQueueSpinLock);
        	return GPS_FAILED;
    	}

⌨️ 快捷键说明

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