📄 recv.c
字号:
NDIS_STATUS OurPacketStatus;
UINT BytesTransferred;
LONGLONG TimeSent;
LONGLONG TimeReceived;
PUCHAR MediaArea;
UINT MediaSizeNeeded;
PULONG ErrorCounter;
IMStructAssert( Adapter );
//
// return this packet now if we're unable to deal with it right now
//
NdisAcquireSpinLock( &Adapter->Lock );
if ( Adapter->IMMPState & ADAPTER_STATE_RUNNING ) {
Status = NDIS_STATUS_SUCCESS;
++Adapter->RefCount;
ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("ClReceiveIndication (%08X) +Adapter:h %2d\n", Adapter, Adapter->RefCount));
} else {
Status = NDIS_STATUS_NOT_ACCEPTED;
ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("ClReceiveIndication: (%08X) +Adapter: Packet not accepted\n", Adapter));
}
NdisReleaseSpinLock( &Adapter->Lock );
if ( !NT_SUCCESS( Status )) {
return Status;
}
//
// get a packet
//
PacketEntry = NdisInterlockedPopEntrySList( &Adapter->PacketSList, &Adapter->PacketSListLock );
if ( PacketEntry == NULL ) {
//
// out of resources. indicate that we're not hanging onto the packet
//
ImDbgOut(DBG_FAILURE, DBG_RECEIVE, ("CLReceiveIndication: Out Of MP Packets!!!\n" ));
InterlockedIncrement( &Adapter->Stats.OutOfPackets );
DerefAdapter( Adapter );
return NDIS_STATUS_NOT_ACCEPTED;
}
OurPacket = CONTAINING_RECORD( PacketEntry, NDIS_PACKET, ProtocolReserved );
IMAssert( OurPacket->Private.Head == NULL );
//
// if this was the last packet on the list, then let NDIS know this so we'll get
// this one back pretty quick
//
if ( NdisQueryDepthSList( &Adapter->PacketSList ) == 0 ) {
OurPacketStatus = NDIS_STATUS_RESOURCES;
} else {
OurPacketStatus = NDIS_STATUS_SUCCESS;
}
NDIS_SET_PACKET_STATUS( OurPacket, OurPacketStatus );
//
// MPs might indicate more data in their lookahead buffers than what they
// reported in OID_GEN_MAXIMUM_LOOKAHEAD. If that is the case, then use
// a residual buffer which is the full frame size.
//
if (( HeaderBufferSize + LookaheadBufferSize ) > Adapter->LookaheadBufferSize ) {
SList = &Adapter->ResidualSList;
SListLock = &Adapter->ResidualSListLock;
ErrorCounter = &Adapter->Stats.OutOfResidualBuffers;
} else {
SList = &Adapter->LookaheadSList;
SListLock = &Adapter->LookaheadSListLock;
ErrorCounter = &Adapter->Stats.OutOfLookaheadBuffers;
}
LookaheadEntry = NdisInterlockedPopEntrySList( SList, SListLock );
if ( LookaheadEntry == NULL ) {
ImDbgOut(DBG_FAILURE, DBG_RECEIVE,
("CLReceiveIndication: Out Of Lookahead Buffers!!!\n" ));
NdisInterlockedPushEntrySList(&Adapter->PacketSList,
(PSINGLE_LIST_ENTRY)OurPacket->ProtocolReserved,
&Adapter->PacketSListLock);
InterlockedIncrement( ErrorCounter );
DerefAdapter( Adapter );
return NDIS_STATUS_NOT_ACCEPTED;
}
LookaheadNdisBuffer = ((PIM_BUFFER_CONTEXT)LookaheadEntry)->NdisBuffer;
//
// get a (or another) residual buffer if all the data is not available
//
if ( PacketSize != LookaheadBufferSize ) {
ResidualEntry = NdisInterlockedPopEntrySList(&Adapter->ResidualSList,
&Adapter->ResidualSListLock);
if ( ResidualEntry == NULL ) {
ImDbgOut(DBG_FAILURE, DBG_RECEIVE,
("CLReceiveIndication: Out Of Residual Buffers!!!\n" ));
NdisInterlockedPushEntrySList(SList,
&((PIM_BUFFER_CONTEXT)LookaheadEntry)->SListEntry,
SListLock);
NdisInterlockedPushEntrySList(&Adapter->PacketSList,
(PSINGLE_LIST_ENTRY)OurPacket->ProtocolReserved,
&Adapter->PacketSListLock);
InterlockedIncrement( &Adapter->Stats.OutOfResidualBuffers );
DerefAdapter( Adapter );
return NDIS_STATUS_NOT_ACCEPTED;
}
ResidualNdisBuffer = ((PIM_BUFFER_CONTEXT)ResidualEntry)->NdisBuffer;
}
//
// get a pointer to the start of the packet and our context area. Clear the
// original packet area. We'll key off of this when the packet is returned
// so we don't try and return it to the miniport
//
PktContext = IM_PACKET_CONTEXT_FROM_PACKET( Adapter, OurPacket );
IMStructAssert1( PktContext, PacketContext );
ImDbgOut(DBG_INFO, DBG_RECEIVE,
("(%08X) CLReceiveIndication: Packet %08X Packetsize %d %s\n",
Adapter, OurPacket, PacketSize,
(PacketSize != LookaheadBufferSize ? "(RD)" : "")));
PktContext->OriginalPacket = NULL;
//
// copy what we have into the lookahead buffer. set the lookahead buffer size
//
#if BINARY_COMPATIBLE
//
// TDI functions are not allowed
//
NdisMoveMemory( LookaheadEntry, HeaderBuffer, HeaderBufferSize );
NdisMoveMemory((CHAR *)LookaheadEntry + HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize);
#else // BINARY_COMPATIBLE
//
// for NT, we honor the copy lookahead flag
//
if ( Adapter->CopyLookaheadData ) {
NdisMoveMemory( LookaheadEntry, HeaderBuffer, HeaderBufferSize );
NdisMoveMemory((CHAR *)LookaheadEntry + HeaderBufferSize,
LookaheadBuffer,
LookaheadBufferSize);
} else {
TdiCopyLookaheadData( LookaheadEntry, HeaderBuffer, HeaderBufferSize, 0 );
TdiCopyLookaheadData((CHAR *)LookaheadEntry + HeaderBufferSize,
LookaheadBuffer,
LookaheadBufferSize,
0);
}
#endif // BINARY_COMPATIBLE
NdisAdjustBufferLength( LookaheadNdisBuffer, HeaderBufferSize + LookaheadBufferSize );
NDIS_SET_PACKET_HEADER_SIZE( OurPacket, HeaderBufferSize );
if ( ResidualEntry == NULL ) {
//
// we can indicate the packet now (or at least try to) since we have all of it.
// adjust the NDIS buffer to indicate the correct amount of data and chain the
// lookahead buffer onto the packet
//
NdisChainBufferAtFront( OurPacket, LookaheadNdisBuffer );
NdisMIndicateReceivePacket( Adapter->IMNdisHandle, &OurPacket, 1 );
//
// now check the packet's status to see if we can return it
//
if ( NDIS_GET_PACKET_STATUS( OurPacket ) != NDIS_STATUS_PENDING ) {
MPReturnPacket( (NDIS_HANDLE)Adapter, OurPacket );
}
} else {
//
// stuff a pointer to the lookahead NDIS buffer in the packet context area
// and chain the residual buffer at the front. The MP wants to copy data to
// beginning of the first buffer, so we'll chain the lookahead buffer when
// the transfer data stuff is complete.
//
NdisAdjustBufferLength( ResidualNdisBuffer, PacketSize - LookaheadBufferSize );
NdisChainBufferAtFront( OurPacket, ResidualNdisBuffer );
PktContext->LookaheadBuffer = LookaheadNdisBuffer;
NdisTransferData(&Status,
Adapter->LowerMPHandle,
MacReceiveContext,
LookaheadBufferSize,
PacketSize - LookaheadBufferSize,
OurPacket,
&BytesTransferred);
if ( Status != NDIS_STATUS_PENDING ) {
CLTransferDataComplete( (NDIS_HANDLE)Adapter, OurPacket, Status, BytesTransferred );
}
}
return NDIS_STATUS_SUCCESS;
} // CLReceiveIndication
VOID
CLReceiveComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
/*++
Routine Description:
Called by NIC via NdisIndicateReceiveComplete. Continue this indication
up to the higher layer
Arguments:
See the DDK...
Return Values:
None
--*/
{
PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
IMStructAssert( Adapter );
ImDbgOut(DBG_INFO, DBG_RECEIVE, ("(%08X) CLReceiveComplete:\n", Adapter));
if ( Adapter->IMMPState & ADAPTER_STATE_RUNNING ) {
switch( Adapter->MediaType ) {
case NdisMedium802_3:
NdisMEthIndicateReceiveComplete( Adapter->IMNdisHandle );
break;
case NdisMedium802_5:
NdisMTrIndicateReceiveComplete( Adapter->IMNdisHandle );
break;
case NdisMediumFddi:
NdisMFddiIndicateReceiveComplete( Adapter->IMNdisHandle );
break;
default:
IMAssert( FALSE );
}
}
} // CLReceiveComplete
NDIS_STATUS
MPTransferData(
OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE MiniportReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer
)
/*++
Routine Description:
Arguments:
See the DDK...
Return Values:
None
--*/
{
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
IMStructAssert( Adapter );
ImDbgOut(DBG_INFO, DBG_RECEIVE, ("(%08X) MPTransferData:\n", Adapter));
return NDIS_STATUS_FAILURE;
} // MPTransferData
VOID
CLTransferDataComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred
)
/*++
Routine Description:
Completion routine for NdisTransferData
Arguments:
See the DDK...
Return Values:
None
--*/
{
PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
PIM_PACKET_CONTEXT PktContext;
IMStructAssert( Adapter );
ImDbgOut(DBG_INFO, DBG_RECEIVE,
("(%08X) CLTransferDataComplete: Packet %08X Status %08X Bytes xfer'ed %d\n",
Adapter, Packet, Status, BytesTransferred));
//
// get the lookahead NDIS buffer pointer from the context area and chain it
// on the front
//
PktContext = IM_PACKET_CONTEXT_FROM_PACKET( Adapter, Packet );
IMStructAssert1( PktContext, PacketContext );
NdisChainBufferAtFront( Packet, PktContext->LookaheadBuffer );
//
// we can indicate the packet now (or at least try to) since we have all of it
//
NdisMIndicateReceivePacket( Adapter->IMNdisHandle, &Packet, 1 );
//
// now check the packet's status to see if we can return it
//
if ( NDIS_GET_PACKET_STATUS( Packet ) != NDIS_STATUS_PENDING ) {
MPReturnPacket( (NDIS_HANDLE)Adapter, Packet );
}
} // CLTransferDataComplete
/* end recv.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -