📄 rxproc.c
字号:
/******************* ?Marvell Semiconductor, Inc., 2001-2004 *****************
*
* Purpose: This module has the implementaion of RX routines
*
* $Author: schiu $
*
* $Date: 2004/10/29 $
*
* $Revision: #6 $
*
*****************************************************************************/
/*
===============================================================================
INCLUDE FILES
===============================================================================
*/
#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);
#ifdef NEW_RSSI
VOID
wlan_compute_rssi(PMRVDRV_ADAPTER Adapter, PRxPD pRxPDCurrent);
#endif
/******************************************************************************
*
* 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)
{
PMRVDRV_ADAPTER Adapter;
//RETAILMSG(1,(TEXT("[Marvell]+MrvDrvReturnPacket")));
Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext;
if (Adapter->sNumOutstandingRxPacket)
ReturnRxPacketDesc( MiniportAdapterContext, Packet);
//RETAILMSG(1,(TEXT("[Marvell]-MrvDrvReturnPacket")));
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
)
{
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);
//
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_LOAD | 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_LOAD | 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);
//to hide unused packet header ahead of pointer.
//(ULONG)Adapter->pRxBufVM[i] += (sizeof(RxPD)+sizeof(pkt.Len)+sizeof(pkt.Type));
(ULONG)Adapter->pRxBufVM[i] += MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE;
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-MRVDRV_ETH_RX_HIDDEN_HEADER_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;
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
)
{
ULONG i;
//RETAILMSG(1,(TEXT("Free Rx Q\r\n")));
for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
{
if ( Adapter->pRxBufVM[i] != NULL )
{
(ULONG)Adapter->pRxBufVM[i] -= MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE;
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;
}
return NDIS_STATUS_SUCCESS;
}
/******************************************************************************
*
* Name: ResetRxPDQ()
*
* Description: RxPDQ reset
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value:
*
*
*****************************************************************************/
VOID
ResetRxPDQ(
IN PMRVDRV_ADAPTER Adapter)
{
ULONG i;
NdisAcquireSpinLock(&Adapter->RxQueueSpinLock);
Adapter->sNumOutstandingRxPacket = 0;
InitializeQKeeper(&Adapter->RxPacketFreeQueue);
for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
InsertQNodeAtTail(&Adapter->RxPacketFreeQueue, &Adapter->RxPacketQueueNode[i]);
NdisReleaseSpinLock(&Adapter->RxQueueSpinLock);
return;
}
/******************************************************************************
*
* Name: GetRxPacketDesc()
*
* Description: Get a free RX Packet descriptor
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: MRVDRV_GET_PACKET_STATUS
*
* Notes:
*
*****************************************************************************/
__inline
extern MRVDRV_GET_PACKET_STATUS
GetRxPacketDesc(PMRVDRV_ADAPTER Adapter,
PNDIS_PACKET *p_PPacket)
{
PPACKET_QUEUE_NODE pPacketNode;
NdisAcquireSpinLock(&Adapter->RxQueueSpinLock);
if ( Adapter->sNumOutstandingRxPacket == MRVDRV_NUM_RX_PKT_IN_QUEUE )
{
NdisReleaseSpinLock(&Adapter->RxQueueSpinLock);
return GPS_FAILED;
}
// get a free packet
pPacketNode = (PPACKET_QUEUE_NODE)PopFirstQNode(&Adapter->RxPacketFreeQueue);
// return the pointer of the packet
*p_PPacket = pPacketNode->pPacket;
Adapter->sNumOutstandingRxPacket++;
NdisReleaseSpinLock(&Adapter->RxQueueSpinLock);
DBGPRINT(DBG_RXDATA, ("Packet 0x%x allocated, NumOutstandingRxPacket = %d\n",
pPacketNode->pPacket,
Adapter->sNumOutstandingRxPacket));
return GPS_SUCCESS;
}
/******************************************************************************
*
* Name: ReturnRxPacketDesc()
*
* Description: Return a RX Packet descriptor
*
* Arguments: PMRVDRV_ADAPTER Adapter
*
* Return Value: NONE
*
* Notes:
*
*****************************************************************************/
__inline
VOID
ReturnRxPacketDesc(PMRVDRV_ADAPTER Adapter,
PNDIS_PACKET pPacket)
{
PPACKET_QUEUE_NODE pPacketNode = *((PACKET_QUEUE_NODE **)pPacket->MiniportReserved);
// RETAILMSG(1,(TEXT("[Marvell]+ReturnRxPacketDesc")));
NdisAcquireSpinLock(&Adapter->RxQueueSpinLock);
InsertQNodeFromHead(&Adapter->RxPacketFreeQueue, pPacketNode);
if ( Adapter->sNumOutstandingRxPacket < 0 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -