📄 rxproc.c
字号:
//
// 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 + -