📄 rxproc.c
字号:
/******************* ?Marvell Semiconductor, Inc., 2001-2004 ***************** * * Purpose: This module has the implementaion of RX routines * * $Author: * * $Date: * * $Revision: * *****************************************************************************/#include "precomp.h"// compilation error if this file is not included#ifdef UNDER_CE#include "pkfuncs.h"#endifVOIDReturnRxPacketDesc(PMRVDRV_ADAPTER Adapter, PNDIS_PACKET pPacket);/****************************************************************************** * * Name: MrvDrvReturnPacket() * * Description: the rx ndis return packet callback function (handler) * * Arguments: Packet : the packet Ndis return * * Notes: * *****************************************************************************/VOIDMrvDrvReturnPacket( 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);#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); // 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;#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: * * *****************************************************************************/VOIDResetRxPDQ( IN PMRVDRV_ADAPTER Adapter){#ifdef USE_RX_QUEUE 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);#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_STATUSGetRxPacketDesc(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; } // 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));#endif return GPS_SUCCESS;}/****************************************************************************** * * Name: ReturnRxPacketDesc() * * Description: Return a RX Packet descriptor * * Arguments: PMRVDRV_ADAPTER Adapter * * Return Value: NONE * * Notes: * *****************************************************************************/VOIDReturnRxPacketDesc(PMRVDRV_ADAPTER Adapter, PNDIS_PACKET pPacket){#ifdef USE_RX_QUEUE PPACKET_QUEUE_NODE pPacketNode = *((PACKET_QUEUE_NODE **)pPacket->MiniportReserved); NdisAcquireSpinLock(&Adapter->RxQueueSpinLock); if ( Adapter->sNumOutstandingRxPacket <= 0 ) { DBGPRINT(DBG_ERROR, ("ERROR: numOutstandingPacket already 0 before subtraction!!\n")); NdisReleaseSpinLock(&Adapter->RxQueueSpinLock); return; } InsertQNodeFromHead(&Adapter->RxPacketFreeQueue, pPacketNode); Adapter->sNumOutstandingRxPacket--; DBGPRINT(DBG_RXDATA, ("PacketNode(0x%x) with Packet(0x%x) returned, NumOutstandingRxPacket = %d\n", pPacketNode, pPacketNode->pPacket, Adapter->sNumOutstandingRxPacket)); NdisReleaseSpinLock(&Adapter->RxQueueSpinLock);#endif}/****************************************************************************** * * Name: HandleRxReadyEvent() * * Description: Rx ready event handler * * Arguments: PMRVDRV_ADAPTER Adapter * * Return Value: * * Notes: * *****************************************************************************/VOIDHandleRxReadyEvent( IN PMRVDRV_ADAPTER Adapter){ ULONG ulFramlen; int IsRxOK = 0; PRxPD pRxPDCurrent; PCF_OBJECT pCf = Adapter->hwIface; // MRVDRV_GET_PACKET_STATUS qStatus; // PNDIS_PACKET pPacket; // NDIS_STATUS pStatus; // PNDIS_BUFFER pBuffer; //UINT bufferLength; // PVOID pRxBufVM; ULONG ulLookAhead; DBGPRINT(DBG_RXDATA | DBG_CRLF,("+HandleRxReadyEvent()\n")); //NdisAcquireSpinLock(&Adapter->RxSpinLock); /// read a frame from FW IsRxOK = ReadRxFrame(Adapter, &ulFramlen); if (IsRxOK == 0) { DBGPRINT(DBG_RXDATA | DBG_CRLF,("Read rx frame error \n"));///RETAILMSG(1, (TEXT("Read rx frame error \r\n"))); //NdisReleaseSpinLock(&Adapter->RxSpinLock); return; } /// Check RxPD status and update 802.3 stat, we should have more bits to test pRxPDCurrent = (PRxPD)(&Adapter->RxPD); if (pRxPDCurrent->Status & MRVDRV_RXPD_STATUS_OK) { Adapter->RcvOK++; Adapter->DirectedFramesRcvOK++; ///RETAILMSG(1, (TEXT(" receive Date Rate = %x \r\n"), pRxPDCurrent->RxRate)); switch ( pRxPDCurrent->RxRate ) { case FRAME_STATUS_LINK_SPEED_1mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_1mbps; break; case FRAME_STATUS_LINK_SPEED_2mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_2mbps; break; case FRAME_STATUS_LINK_SPEED_5dot5mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_5dot5mbps; break; case FRAME_STATUS_LINK_SPEED_11mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_11mbps; break; case FRAME_STATUS_LINK_SPEED_6mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_6mbps; break; case FRAME_STATUS_LINK_SPEED_9mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_9mbps; break; case FRAME_STATUS_LINK_SPEED_12mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_12mbps; break; case FRAME_STATUS_LINK_SPEED_18mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_18mbps; break; case FRAME_STATUS_LINK_SPEED_24mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_24mbps; break; case FRAME_STATUS_LINK_SPEED_36mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_36mbps; break; case FRAME_STATUS_LINK_SPEED_48mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_48mbps; break; case FRAME_STATUS_LINK_SPEED_54mbps : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_54mbps; break; default : Adapter->LinkSpeed = MRVDRV_LINK_SPEED_11mbps; break; } DBGPRINT(DBG_RXDATA ,("RxPD: SNR = %d, NF = %d\n", pRxPDCurrent->SNR, pRxPDCurrent->NF)); DBGPRINT(DBG_RXDATA ,("Before computing SNR and NF\n")); DBGPRINT(DBG_RXDATA,("Adapter: SNR- avg = %d, NF-avg = %d\n", Adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, Adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE)); Adapter->SNR[TYPE_RXPD][TYPE_NOAVG] = pRxPDCurrent->SNR; Adapter->NF[TYPE_RXPD][TYPE_NOAVG] = pRxPDCurrent->NF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -