You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
769 lines
21 KiB
769 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
recv.c
|
|
|
|
Abstract:
|
|
|
|
routines to handle receiving data
|
|
|
|
Author:
|
|
|
|
Charlie Wickham (charlwi) 08-May-1996
|
|
Rajesh Sundaram (rajeshsu) 01-Aug-1998.
|
|
|
|
Environment:
|
|
|
|
Kernel Mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "psched.h"
|
|
#pragma hdrstop
|
|
|
|
/* External */
|
|
|
|
/* Static */
|
|
|
|
/* Forward */ /* Generated by Emacs 19.17.0 on Thu May 09 10:34:39 1996 */
|
|
|
|
INT
|
|
ClReceivePacket(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN PNDIS_PACKET Packet
|
|
);
|
|
|
|
VOID
|
|
MpReturnPacket(
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN PNDIS_PACKET Packet
|
|
);
|
|
|
|
VOID
|
|
ClReceiveComplete(
|
|
IN NDIS_HANDLE ProtocolBindingContext
|
|
);
|
|
|
|
NDIS_STATUS
|
|
MpTransferData(
|
|
OUT PNDIS_PACKET Packet,
|
|
OUT PUINT BytesTransferred,
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN NDIS_HANDLE MiniportReceiveContext,
|
|
IN UINT ByteOffset,
|
|
IN UINT BytesToTransfer
|
|
);
|
|
|
|
VOID
|
|
ClTransferDataComplete(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN PNDIS_PACKET pNdisPacket,
|
|
IN NDIS_STATUS Status,
|
|
IN UINT BytesTransferred
|
|
);
|
|
|
|
/* End Forward */
|
|
|
|
VOID
|
|
PsAllocateRecvPacket(PNDIS_STATUS Status,
|
|
PPNDIS_PACKET Packet,
|
|
PADAPTER Adapter)
|
|
{
|
|
|
|
if(!Adapter->RecvPacketPool)
|
|
{
|
|
PS_LOCK_DPC(&Adapter->Lock);
|
|
|
|
if(!Adapter->RecvPacketPool)
|
|
{
|
|
NDIS_HANDLE PoolHandle = (void *) NDIS_PACKET_POOL_TAG_FOR_PSCHED;
|
|
|
|
NdisAllocatePacketPoolEx(Status,
|
|
&PoolHandle,
|
|
MIN_PACKET_POOL_SIZE,
|
|
MAX_PACKET_POOL_SIZE,
|
|
sizeof(PS_RECV_PACKET_CONTEXT));
|
|
|
|
if(*Status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
Adapter->Stats.OutOfPackets ++;
|
|
PS_UNLOCK_DPC(&Adapter->Lock);
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// We successfully allocated a packet pool. We can now free the Fixed Size Block pool for the packet-stack API
|
|
//
|
|
Adapter->RecvPacketPool = PoolHandle;
|
|
|
|
}
|
|
|
|
PS_UNLOCK_DPC(&Adapter->Lock);
|
|
}
|
|
|
|
NdisDprAllocatePacket(Status,
|
|
Packet,
|
|
Adapter->RecvPacketPool);
|
|
|
|
}
|
|
|
|
|
|
INT
|
|
ClReceivePacket(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN PNDIS_PACKET MpPacket
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Called by the NIC to indicate a data as an NDIS_PACKET. Make a copy of the
|
|
packet struct, switch to miniport mode and continue the packet along its way
|
|
|
|
Arguments:
|
|
|
|
See the DDK...
|
|
|
|
Return Values:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
|
|
NDIS_STATUS Status;
|
|
PPS_RECV_PACKET_CONTEXT ContextArea;
|
|
PNDIS_PACKET OurPacket;
|
|
BOOLEAN Remaining;
|
|
|
|
PsStructAssert( Adapter );
|
|
|
|
if(!Adapter->PsNdisHandle)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if(Adapter->MediaType == NdisMediumWan &&
|
|
Adapter->ProtocolType == ARP_ETYPE_IP)
|
|
{
|
|
//
|
|
// Munge s-mac and d-mac so that wanarp is happy.
|
|
//
|
|
PNDIS_BUFFER pNdisBuf;
|
|
UINT Len;
|
|
PETH_HEADER pAddr;
|
|
PUSHORT id;
|
|
PPS_WAN_LINK WanLink;
|
|
|
|
pNdisBuf = MpPacket->Private.Head;
|
|
NdisQueryBuffer(pNdisBuf, &pAddr, &Len);
|
|
|
|
if(Len < sizeof(ETH_HEADER))
|
|
{
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
id = (PUSHORT)&pAddr->DestAddr[0];
|
|
|
|
PS_LOCK(&Adapter->Lock);
|
|
|
|
if((WanLink = (PPS_WAN_LINK)g_WanLinkTable[*id]) == 0)
|
|
{
|
|
PS_UNLOCK(&Adapter->Lock);
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
if(WanLink->State != WanStateOpen)
|
|
{
|
|
PS_UNLOCK(&Adapter->Lock);
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
NdisMoveMemory(pAddr,
|
|
&WanLink->RecvHeader,
|
|
FIELD_OFFSET(ETH_HEADER, Type));
|
|
|
|
PS_UNLOCK(&Adapter->Lock);
|
|
}
|
|
|
|
NdisIMGetCurrentPacketStack(MpPacket, &Remaining);
|
|
|
|
if(Remaining != 0)
|
|
{
|
|
Status = NDIS_GET_PACKET_STATUS(MpPacket);
|
|
|
|
if (TimeStmpRecvPacket) {
|
|
|
|
if (!(TimeStmpRecvPacket)(
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
MpPacket,
|
|
Adapter->MediaType
|
|
)) {
|
|
|
|
PsDbgRecv(DBG_FAILURE, DBG_RECEIVE, CL_RECV_PACKET, OURS, Adapter, MpPacket, 0);
|
|
}
|
|
|
|
}
|
|
|
|
NdisMIndicateReceivePacket(Adapter->PsNdisHandle, &MpPacket, 1);
|
|
|
|
return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
|
|
}
|
|
else
|
|
{
|
|
|
|
PsAllocateRecvPacket(&Status, &OurPacket, Adapter);
|
|
|
|
if(Status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
PsDbgRecv(DBG_INFO, DBG_RECEIVE, CL_RECV_PACKET, ENTER, Adapter, OurPacket, MpPacket);
|
|
|
|
//
|
|
// Save Original Packet
|
|
//
|
|
ContextArea = PS_RECV_PACKET_CONTEXT_FROM_PACKET(OurPacket);
|
|
ContextArea->OriginalPacket = MpPacket;
|
|
|
|
|
|
OurPacket->Private.Head = MpPacket->Private.Head;
|
|
OurPacket->Private.Tail = MpPacket->Private.Tail;
|
|
|
|
//
|
|
// Get the original packet (it could be the same packet as one received or a different one
|
|
// based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible
|
|
// correctly at the top.
|
|
//
|
|
NDIS_SET_ORIGINAL_PACKET(OurPacket, NDIS_GET_ORIGINAL_PACKET(MpPacket));
|
|
|
|
NDIS_SET_PACKET_HEADER_SIZE(OurPacket, NDIS_GET_PACKET_HEADER_SIZE(MpPacket));
|
|
|
|
//
|
|
// Set Packet Flags
|
|
//
|
|
NdisGetPacketFlags(OurPacket) = NdisGetPacketFlags(MpPacket);
|
|
|
|
Status = NDIS_GET_PACKET_STATUS(MpPacket);
|
|
|
|
NDIS_SET_PACKET_STATUS(OurPacket, Status);
|
|
|
|
if (TimeStmpRecvPacket) {
|
|
|
|
if (!(TimeStmpRecvPacket)(
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
OurPacket,
|
|
Adapter->MediaType
|
|
)) {
|
|
|
|
PsDbgRecv(DBG_FAILURE, DBG_RECEIVE, CL_RECV_PACKET, OURS, Adapter, OurPacket, OurPacket);
|
|
}
|
|
|
|
}
|
|
|
|
NdisMIndicateReceivePacket(Adapter->PsNdisHandle, &OurPacket, 1);
|
|
|
|
if (Status == NDIS_STATUS_RESOURCES)
|
|
{
|
|
NdisDprFreePacket(OurPacket);
|
|
}
|
|
|
|
return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
|
|
}
|
|
else
|
|
{
|
|
|
|
//
|
|
// out of resources. indicate that we're not hanging onto the packet
|
|
//
|
|
PsDbgRecv(DBG_FAILURE, DBG_RECEIVE, CL_RECV_PACKET, NO_RESOURCES,
|
|
Adapter, 0, MpPacket);
|
|
|
|
Adapter->Stats.OutOfPackets ++;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
} // ClReceivePacket
|
|
|
|
|
|
VOID
|
|
MpReturnPacket(
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN PNDIS_PACKET Packet
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Potentially return a packet we indicated previously to the
|
|
underlying miniport. It might be one of ours from a ProtocolReceive
|
|
indication, so we disassemble it and return the packet and its
|
|
buffers to their respective S Lists
|
|
|
|
Arguments:
|
|
|
|
See the DDK...
|
|
|
|
Return Values:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
|
|
PPS_RECV_PACKET_CONTEXT PktContext;
|
|
PNDIS_PACKET MyPacket;
|
|
BOOLEAN Remaining;
|
|
|
|
PsStructAssert(Adapter);
|
|
|
|
NdisIMGetCurrentPacketStack(Packet, &Remaining);
|
|
|
|
if(Remaining != 0)
|
|
{
|
|
NdisReturnPackets(&Packet, 1);
|
|
}
|
|
else
|
|
{
|
|
|
|
//
|
|
// see if the OriginalPacket field indicates that this belongs
|
|
// to someone below us and return it now
|
|
//
|
|
|
|
PktContext = PS_RECV_PACKET_CONTEXT_FROM_PACKET(Packet);
|
|
|
|
MyPacket = PktContext->OriginalPacket;
|
|
|
|
PsDbgRecv(DBG_INFO, DBG_RECEIVE, MP_RETURN_PACKET, RETURNING, Adapter, Packet, MyPacket);
|
|
|
|
NdisDprFreePacket(Packet);
|
|
|
|
NdisReturnPackets(&MyPacket, 1);
|
|
}
|
|
|
|
|
|
} // MpReturnPacket
|
|
|
|
|
|
NDIS_STATUS
|
|
ClReceiveIndication(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN NDIS_HANDLE MacReceiveContext,
|
|
IN PVOID HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PVOID LookAheadBuffer,
|
|
IN UINT LookAheadBufferSize,
|
|
IN UINT PacketSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Called by NIC to notify protocol of incoming data. Copy the data
|
|
into a cached packet we set up during initialization and indicate
|
|
that packet to the higher layer.
|
|
|
|
Arguments:
|
|
|
|
See the DDK...
|
|
|
|
Return Values:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
|
|
PNDIS_PACKET MyPacket, Packet;
|
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
|
|
|
PsStructAssert(Adapter);
|
|
|
|
if(!Adapter->PsNdisHandle)
|
|
{
|
|
Status = NDIS_STATUS_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
do
|
|
{
|
|
//
|
|
// If this was indicated by the miniport below as a packet, then get that packet
|
|
// pointer and indicate it as a packet as well (with appropriate status).
|
|
// This way the OOB stuff is accessible to the transport above us.
|
|
//
|
|
|
|
Packet = NdisGetReceivedPacket(Adapter->LowerMpHandle, MacReceiveContext);
|
|
|
|
if (Packet != NULL)
|
|
{
|
|
BOOLEAN Remaining;
|
|
|
|
//
|
|
// Check if there are any more packet stacks left. If there is need to keep per packet information,
|
|
// then the packet stack (which is returned by the api) can be used to store that
|
|
//
|
|
NdisIMGetCurrentPacketStack(Packet, &Remaining);
|
|
if (Remaining != 0)
|
|
{
|
|
NDIS_STATUS OldPacketStatus;
|
|
|
|
if (TimeStmpRecvPacket) {
|
|
|
|
if (!(TimeStmpRecvPacket)(
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
Packet,
|
|
Adapter->MediaType
|
|
)) {
|
|
|
|
PsDbgRecv(DBG_FAILURE, DBG_RECEIVE, CL_RECV_IND, OURS, Adapter, Packet, Packet);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Save the old status, and set packet status to NDIS_STATUS_RESOURCES
|
|
// because we can't have the protocol above us retain the packet -- it
|
|
// can go away as soon as we return from this function.
|
|
//
|
|
|
|
OldPacketStatus = NDIS_GET_PACKET_STATUS(Packet);
|
|
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_RESOURCES);
|
|
|
|
NdisMIndicateReceivePacket(Adapter->PsNdisHandle, &Packet, 1);
|
|
|
|
//
|
|
// Restore the old Status
|
|
//
|
|
NDIS_SET_PACKET_STATUS(Packet, OldPacketStatus);
|
|
|
|
// Since we had set the packet status to NDIS_STATUS_RESOURCES, our
|
|
// ReturnPacket handler won't be called for this packet.
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get a packet off the pool and indicate that up
|
|
//
|
|
PsAllocateRecvPacket(&Status,
|
|
&MyPacket,
|
|
Adapter);
|
|
|
|
if (Status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
MyPacket->Private.Head = Packet->Private.Head;
|
|
MyPacket->Private.Tail = Packet->Private.Tail;
|
|
|
|
//
|
|
// Get the original packet (it could be the same packet as one received or
|
|
// a different one based on # of layered MPs) and set it on the indicated
|
|
// packet so the OOB stuff is visible correctly at the top.
|
|
//
|
|
NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
|
|
|
|
NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);
|
|
|
|
//
|
|
// Set Packet Flags
|
|
//
|
|
NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);
|
|
|
|
//
|
|
// Make sure the status is set to NDIS_STATUS_RESOURCES.
|
|
//
|
|
NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);
|
|
|
|
if (TimeStmpRecvPacket) {
|
|
|
|
if (!(TimeStmpRecvPacket)(
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
MyPacket,
|
|
Adapter->MediaType
|
|
)) {
|
|
|
|
PsDbgRecv(DBG_FAILURE, DBG_RECEIVE, CL_RECV_IND, OURS, Adapter, MyPacket, MyPacket);
|
|
}
|
|
|
|
}
|
|
|
|
NdisMIndicateReceivePacket(Adapter->PsNdisHandle, &MyPacket, 1);
|
|
|
|
PsAssert (NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES);
|
|
|
|
NdisDprFreePacket(MyPacket);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fall through if the miniport below us has either not indicated a packet or we
|
|
// could not allocate one
|
|
//
|
|
Adapter->IndicateRcvComplete = TRUE;
|
|
|
|
//
|
|
// If the timestamp driver is present.
|
|
//
|
|
//
|
|
if (TimeStmpRecvIndication) {
|
|
|
|
if (!(TimeStmpRecvIndication)(
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
HeaderBuffer,
|
|
HeaderBufferSize,
|
|
LookAheadBuffer,
|
|
LookAheadBufferSize,
|
|
PacketSize,
|
|
Adapter->IPHeaderOffset
|
|
)) {
|
|
|
|
PsDbgRecv(DBG_FAILURE, DBG_RECEIVE, CL_RECV_IND, OURS, Adapter, (PNDIS_PACKET) LookAheadBuffer, NULL);
|
|
}
|
|
|
|
}
|
|
|
|
switch (Adapter->MediaType)
|
|
{
|
|
case NdisMedium802_3:
|
|
case NdisMediumWan:
|
|
|
|
|
|
NdisMEthIndicateReceive(Adapter->PsNdisHandle,
|
|
MacReceiveContext,
|
|
HeaderBuffer,
|
|
HeaderBufferSize,
|
|
LookAheadBuffer,
|
|
LookAheadBufferSize,
|
|
PacketSize);
|
|
break;
|
|
|
|
case NdisMedium802_5:
|
|
NdisMTrIndicateReceive(Adapter->PsNdisHandle,
|
|
MacReceiveContext,
|
|
HeaderBuffer,
|
|
HeaderBufferSize,
|
|
LookAheadBuffer,
|
|
LookAheadBufferSize,
|
|
PacketSize);
|
|
break;
|
|
|
|
case NdisMediumFddi:
|
|
NdisMFddiIndicateReceive(Adapter->PsNdisHandle,
|
|
MacReceiveContext,
|
|
HeaderBuffer,
|
|
HeaderBufferSize,
|
|
LookAheadBuffer,
|
|
LookAheadBufferSize,
|
|
PacketSize);
|
|
break;
|
|
|
|
default:
|
|
PsAssert (0);
|
|
Status = NDIS_STATUS_FAILURE;
|
|
break;
|
|
}
|
|
|
|
} while (FALSE);
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // 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;
|
|
|
|
PsStructAssert(Adapter);
|
|
|
|
PsDbgRecv(DBG_INFO, DBG_RECEIVE, CL_RECV_COMPL, ENTER, Adapter, 0, 0);
|
|
|
|
if((Adapter->PsNdisHandle != NULL) && Adapter->IndicateRcvComplete) {
|
|
|
|
switch(Adapter->MediaType){
|
|
|
|
case NdisMediumWan:
|
|
case NdisMedium802_3:
|
|
|
|
NdisMEthIndicateReceiveComplete(Adapter->PsNdisHandle);
|
|
break;
|
|
|
|
case NdisMedium802_5:
|
|
|
|
NdisMTrIndicateReceiveComplete(Adapter->PsNdisHandle);
|
|
break;
|
|
|
|
case NdisMediumFddi:
|
|
|
|
NdisMFddiIndicateReceiveComplete(Adapter->PsNdisHandle);
|
|
break;
|
|
|
|
default:
|
|
|
|
PsAssert(FALSE);
|
|
}
|
|
}
|
|
Adapter->IndicateRcvComplete = 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;
|
|
NDIS_STATUS Status;
|
|
|
|
PsStructAssert(Adapter);
|
|
|
|
PsDbgRecv(DBG_INFO, DBG_RECEIVE, MP_XFER_DATA, ENTER, Adapter, 0, 0);
|
|
|
|
if(IsDeviceStateOn(Adapter) == FALSE)
|
|
{
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
NdisTransferData(
|
|
&Status,
|
|
Adapter->LowerMpHandle,
|
|
MiniportReceiveContext,
|
|
ByteOffset,
|
|
BytesToTransfer,
|
|
Packet,
|
|
BytesTransferred);
|
|
|
|
return Status;
|
|
|
|
} // 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;
|
|
PPS_RECV_PACKET_CONTEXT PktContext;
|
|
|
|
PsStructAssert(Adapter);
|
|
|
|
PsDbgRecv(DBG_INFO, DBG_RECEIVE, CL_XFER_COMPL, ENTER, Adapter, Packet, 0);
|
|
|
|
if(Adapter->PsNdisHandle)
|
|
{
|
|
NdisMTransferDataComplete(
|
|
Adapter->PsNdisHandle,
|
|
Packet,
|
|
Status,
|
|
BytesTransferred);
|
|
}
|
|
|
|
} // ClTransferDataComplete
|
|
|
|
UINT
|
|
ClCoReceivePacket(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN NDIS_HANDLE ProtocolVcContext,
|
|
IN PNDIS_PACKET Packet
|
|
)
|
|
{
|
|
//
|
|
// We don't do anything special in the coreceive path. Just call ClReceivePacket.
|
|
//
|
|
|
|
return ClReceivePacket(ProtocolBindingContext, Packet);
|
|
|
|
} // ClCoReceivePacket
|
|
|
|
/* end recv.c */
|
|
|