📄 receive.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
// Copyright 2001, Cisco Systems, Inc. All rights reserved.
// No part of this source, or the resulting binary files, may be reproduced,
// transmitted or redistributed in any form or by any means, electronic or
// mechanical, for any purpose, without the express written permission of Cisco.
//
// receive.cpp
//---------------------------------------------------------------------------
// Description:
//
// Revision History:
//
// Date
//---------------------------------------------------------------------------
// 05/30/01 spb007 Failed to Release Spin Lock which will cause
// lock ups.
//
//---------------------------------------------------------------------------
#pragma code_seg("LCODE")
#include "NDISVER.h"
extern "C"{
#include <ndis.h>
}
#if NDISVER == 5
#include "Cardx500.h"
#include "queue.h"
#include "receive.h"
void
RcvDpc(
PCARD card
)
{
NdisAcquireSpinLock(&card->m_lock);
PX500RFD SwRfd = (PX500RFD)QueueGetHead(&card->RfdList);
if (NULL == SwRfd ) {
NdisReleaseSpinLock(&card->m_lock);
return;
}
PUCHAR rcvbuf = (PUCHAR)&SwRfd->Rfd->RxMacHeader;
PNDIS_PACKET PacketArray = SwRfd->ReceivePacket;
card->m_PacketRxLen = GetRxHeader(card, rcvbuf );
if( 0 == card->m_PacketRxLen ){
AckRcvInterrupt(card);
NdisReleaseSpinLock(&card->m_lock); //spb007
return;
}
if ((card->m_PacketFilter == 0) ||
(!card->m_PromiscuousMode && !IsMyPacket(card, rcvbuf) && !CheckMulticast(card, rcvbuf))) {
AckRcvInterrupt(card);
NdisReleaseSpinLock(&card->m_lock);
return;
}
QueueRemoveHead(&card->RfdList);
SwRfd->FrameLength = card->m_PacketRxLen+AIRONET_HEADER_SIZE;
CopyUpPacketUShort( card, (PUCHAR)&SwRfd->Rfd->RxBufferData, card->m_PacketRxLen );
AckRcvInterrupt(card);
NdisAdjustBufferLength((PNDIS_BUFFER) SwRfd->ReceiveBuffer, (UINT) SwRfd->FrameLength);
NDIS_SET_PACKET_STATUS(PacketArray, NDIS_STATUS_SUCCESS );
NdisReleaseSpinLock(&card->m_lock);
NdisMIndicateReceivePacket(card->m_MAHandle, &PacketArray, 1 );
NdisAcquireSpinLock(&card->m_lock);
NDIS_STATUS ReturnStatus = NDIS_GET_PACKET_STATUS(PacketArray);
if (ReturnStatus != NDIS_STATUS_PENDING){
SwRfd = *(X500RFD **)(PacketArray->MiniportReserved);
QueuePutTail(&card->RfdList, &SwRfd->Link);
}
NdisReleaseSpinLock(&card->m_lock);
}
//-----------------------------------------------------------------------------
// cbReturnPacket
//
// PARAMETERS: IN NDIS_HANDLE MiniportcardContext
// - a context version of our card pointer
// IN NDIS_PACKET Packet
// - the packet that is being freed
//
// DESCRIPTION: This function attempts to return to the receive free list the
// packet passed to us by NDIS
//
// RETURNS: nothing
//
//-----------------------------------------------------------------------------
VOID
cbReturnPacket(
NDIS_HANDLE MiniportAdapterContext,
PNDIS_PACKET Packet
)
{
PCARD card = (PCARD)MiniportAdapterContext;
PX500RFD SwRfd;
NdisAcquireSpinLock(&card->m_lock);
SwRfd = *(X500RFD **)(Packet->MiniportReserved);
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_SUCCESS );
QueuePutTail(&card->RfdList, &SwRfd->Link);
--card->UsedRfdCount;
NdisReleaseSpinLock(&card->m_lock);
}
#define MAX_RX_DESCR 1024 // 0x400
#define NUM_BYT_PROT_RSRVD_SEC 16
BOOLEAN
SetupReceiveQueues(
IN PCARD card
)
{
// init the lists
QueueInitList(&card->RfdList);
NDIS_STATUS AllocStatus;
NdisAllocatePacketPool(&AllocStatus, &card->RxPktPool, MAX_RX_DESCR, NUM_BYT_PROT_RSRVD_SEC);
NdisAllocateBufferPool(&AllocStatus, &card->RxBufPool, MAX_RX_DESCR);
card->NumRfd = NUMRFD;
card->m_pSwRfd = NdisMalloc( sizeof(X500RFD) * card->NumRfd );
X500RFD *SwRfd = (X500RFD *)card->m_pSwRfd;
NdisZeroMemory( SwRfd, sizeof(X500RFD) * card->NumRfd );
for (UINT i = 0; i < card->NumRfd; i++, SwRfd++ ){
SwRfd->Rfd = (RFD_STRUC *)card->m_RcvBuf[i];
NdisAllocatePacket(&AllocStatus, &SwRfd->ReceivePacket, card->RxPktPool);
if( NDIS_STATUS_SUCCESS != AllocStatus){
SwRfd->ReceivePacket = NULL;
return FALSE;
}
NDIS_SET_PACKET_HEADER_SIZE(SwRfd->ReceivePacket, ETHERNET_HEADER_SIZE);
// point our buffer for receives at this Rfd
NdisAllocateBuffer(&AllocStatus,
&SwRfd->ReceiveBuffer,
card->RxBufPool,
&SwRfd->Rfd->RxMacHeader,
MAXIMUM_ETHERNET_PACKET_SIZE);
if( NDIS_STATUS_SUCCESS != AllocStatus){
SwRfd->ReceiveBuffer = NULL;
return FALSE;
}
// probably should do some error handling here
NdisChainBufferAtFront(SwRfd->ReceivePacket, SwRfd->ReceiveBuffer);
NDIS_SET_PACKET_STATUS(SwRfd->ReceivePacket, NDIS_STATUS_SUCCESS );
X500RFD **TempPtr = (PX500RFD *) &SwRfd->ReceivePacket->MiniportReserved;
*TempPtr = SwRfd;
QueuePutTail(&card->RfdList, &SwRfd->Link);
}
return TRUE;
}
VOID
FreeReceiveQueues(
IN PCARD card
)
{
X500RFD *SwRfd = (X500RFD *)card->m_pSwRfd;
for( UINT i=0; SwRfd && i<card->NumRfd; i++, SwRfd++ ){
if( SwRfd->ReceivePacket ){
if( SwRfd->ReceiveBuffer )
NdisFreeBuffer(SwRfd->ReceiveBuffer);
NdisFreePacket(SwRfd->ReceivePacket);
}
}
NdisAcquireSpinLock(&card->m_lock);
if( card->m_pSwRfd )
NdisFreeMemory(card->m_pSwRfd, sizeof(X500RFD)* card->NumRfd, 0 );
NdisReleaseSpinLock(&card->m_lock);
while(0!=NdisPacketPoolUsage(card->RxPktPool) )
NdisMSleep(10);
if( card->RxBufPool )
NdisFreeBufferPool(card->RxBufPool);
if( card->RxPktPool )
NdisFreePacketPool(card->RxPktPool);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -