From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/tdi/isnp/ipx/packet.c | 1560 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1560 insertions(+) create mode 100644 private/ntos/tdi/isnp/ipx/packet.c (limited to 'private/ntos/tdi/isnp/ipx/packet.c') diff --git a/private/ntos/tdi/isnp/ipx/packet.c b/private/ntos/tdi/isnp/ipx/packet.c new file mode 100644 index 000000000..f70154b03 --- /dev/null +++ b/private/ntos/tdi/isnp/ipx/packet.c @@ -0,0 +1,1560 @@ +/*++ +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + packet.c + +Abstract: + + This module contains code that implements the SEND_PACKET and + RECEIVE_PACKET objects, which describe NDIS packets used + by the transport. + +Environment: + + Kernel mode + +Revision History: + + Sanjay Anand (SanjayAn) - 22-Sept-1995 + BackFill optimization changes added under #if BACK_FILL + +--*/ + +#include "precomp.h" +#pragma hdrstop + + +NTSTATUS +IpxInitializeSendPacket( + IN PDEVICE Device, + IN PIPX_SEND_PACKET Packet, + IN PUCHAR Header + ) + +/*++ + +Routine Description: + + This routine initializes a send packet by chaining the + buffer for the header on it. + +Arguments: + + Device - The device. + + Packet - The packet to initialize. + + Header - Points to storage for the header. + +Return Value: + + None. + +--*/ + +{ + + NDIS_STATUS NdisStatus; + NTSTATUS Status; + PNDIS_BUFFER NdisMacBuffer; + PNDIS_BUFFER NdisIpxBuffer; + PIPX_SEND_RESERVED Reserved; + + IpxAllocateSendPacket (Device, Packet, &Status); + + if (Status != STATUS_SUCCESS) { + // ERROR LOG + return Status; + } + + NdisAllocateBuffer( + &NdisStatus, + &NdisMacBuffer, + Device->NdisBufferPoolHandle, + Header, + MAC_HEADER_SIZE); + + if (NdisStatus != NDIS_STATUS_SUCCESS) { + IpxFreeSendPacket (Device, Packet); + // ERROR LOG + return STATUS_INSUFFICIENT_RESOURCES; + } + + NdisAllocateBuffer( + &NdisStatus, + &NdisIpxBuffer, + Device->NdisBufferPoolHandle, + Header + MAC_HEADER_SIZE, + IPX_HEADER_SIZE + RIP_PACKET_SIZE); + + if (NdisStatus != NDIS_STATUS_SUCCESS) { + IpxFreeSendPacket (Device, Packet); + // ERROR LOG + return STATUS_INSUFFICIENT_RESOURCES; + } + + NdisChainBufferAtFront (PACKET(Packet), NdisMacBuffer); + NdisChainBufferAtBack (PACKET(Packet), NdisIpxBuffer); + + // + // This flag optimizes the virtual to physical address X-ln + // in the MAC drivers on x86 + // + NdisMacBuffer->MdlFlags|=MDL_NETWORK_HEADER; + NdisIpxBuffer->MdlFlags|=MDL_NETWORK_HEADER; + + Reserved = SEND_RESERVED(Packet); + Reserved->Identifier = IDENTIFIER_IPX; + Reserved->SendInProgress = FALSE; + Reserved->Header = Header; + Reserved->HeaderBuffer = NdisMacBuffer; + Reserved->PaddingBuffer = NULL; +#if BACK_FILL + Reserved->BackFill = FALSE; +#endif + + ExInterlockedInsertHeadList( + &Device->GlobalSendPacketList, + &Reserved->GlobalLinkage, + &Device->Lock); + + return STATUS_SUCCESS; + +} /* IpxInitializeSendPacket */ + +#if BACK_FILL +NTSTATUS +IpxInitializeBackFillPacket( + IN PDEVICE Device, + IN PIPX_SEND_PACKET Packet, + IN PUCHAR Header + ) + +/*++ + +Routine Description: + + This routine initializes a send packet by chaining the + buffer for the header on it. + +Arguments: + + Device - The device. + + Packet - The packet to initialize. + + Header - Points to storage for the header. + +Return Value: + + None. + +--*/ + +{ + + NDIS_STATUS NdisStatus; + NTSTATUS Status; + PNDIS_BUFFER NdisMacBuffer; + PNDIS_BUFFER NdisIpxBuffer; + PIPX_SEND_RESERVED Reserved; + + + IPX_DEBUG (PACKET, ("Initializing backfill packet\n")); + IpxAllocateSendPacket (Device, Packet, &Status); + + if (Status != STATUS_SUCCESS) { + // ERROR LOG + return Status; + } + + + Reserved = SEND_RESERVED(Packet); + Reserved->Identifier = IDENTIFIER_IPX; + Reserved->SendInProgress = FALSE; + Reserved->Header = NULL; + Reserved->HeaderBuffer = NULL; + Reserved->PaddingBuffer = NULL; + Reserved->BackFill = TRUE; + + ExInterlockedInsertHeadList( + &Device->GlobalBackFillPacketList, + &Reserved->GlobalLinkage, + &Device->Lock); + + IPX_DEBUG (PACKET, ("Initializing backfill packet Done\n")); + return STATUS_SUCCESS; + +} /* IpxInitializeBackFillPacket */ +#endif + + +NTSTATUS +IpxInitializeReceivePacket( + IN PDEVICE Device, + IN PIPX_RECEIVE_PACKET Packet + ) + +/*++ + +Routine Description: + + This routine initializes a receive packet. + +Arguments: + + Device - The device. + + Packet - The packet to initialize. + +Return Value: + + None. + +--*/ + +{ + + NTSTATUS Status; + PIPX_RECEIVE_RESERVED Reserved; + + IpxAllocateReceivePacket (Device, Packet, &Status); + + if (Status != STATUS_SUCCESS) { + // ERROR LOG + return Status; + } + + Reserved = RECEIVE_RESERVED(Packet); + Reserved->Identifier = IDENTIFIER_IPX; + Reserved->TransferInProgress = FALSE; + Reserved->SingleRequest = NULL; + Reserved->ReceiveBuffer = NULL; + InitializeListHead (&Reserved->Requests); + + ExInterlockedInsertHeadList( + &Device->GlobalReceivePacketList, + &Reserved->GlobalLinkage, + &Device->Lock); + + return STATUS_SUCCESS; + +} /* IpxInitializeReceivePacket */ + + +NTSTATUS +IpxInitializeReceiveBuffer( + IN PADAPTER Adapter, + IN PIPX_RECEIVE_BUFFER ReceiveBuffer, + IN PUCHAR DataBuffer, + IN ULONG DataBufferLength + ) + +/*++ + +Routine Description: + + This routine initializes a receive buffer by allocating + an NDIS_BUFFER to describe the data buffer. + +Arguments: + + Adapter - The adapter. + + ReceiveBuffer - The receive buffer to initialize. + + DataBuffer - The data buffer. + + DataBufferLength - The length of the data buffer. + +Return Value: + + None. + +--*/ + +{ + + NDIS_STATUS NdisStatus; + PNDIS_BUFFER NdisBuffer; + PDEVICE Device = Adapter->Device; + + + NdisAllocateBuffer( + &NdisStatus, + &NdisBuffer, + Device->NdisBufferPoolHandle, + DataBuffer, + DataBufferLength); + + if (NdisStatus != NDIS_STATUS_SUCCESS) { + // ERROR LOG + return STATUS_INSUFFICIENT_RESOURCES; + } + + ReceiveBuffer->NdisBuffer = NdisBuffer; + ReceiveBuffer->Data = DataBuffer; + ReceiveBuffer->DataLength = 0; + + ExInterlockedInsertHeadList( + &Device->GlobalReceiveBufferList, + &ReceiveBuffer->GlobalLinkage, + &Device->Lock); + + return STATUS_SUCCESS; + +} /* IpxInitializeReceiveBuffer */ + + +NTSTATUS +IpxInitializePaddingBuffer( + IN PDEVICE Device, + IN PIPX_PADDING_BUFFER PaddingBuffer, + IN ULONG DataBufferLength + ) + +/*++ + +Routine Description: + + This routine initializes a padding buffer by allocating + an NDIS_BUFFER to describe the data buffer. + +Arguments: + + Adapter - The adapter. + + PaddingBuffer - The receive buffer to initialize. + + DataBufferLength - The length of the data buffer. + +Return Value: + + None. + +--*/ + +{ + + NDIS_STATUS NdisStatus; + PNDIS_BUFFER NdisBuffer; + + NdisAllocateBuffer( + &NdisStatus, + &NdisBuffer, + Device->NdisBufferPoolHandle, + PaddingBuffer->Data, + DataBufferLength); + + if (NdisStatus != NDIS_STATUS_SUCCESS) { + // ERROR LOG + return STATUS_INSUFFICIENT_RESOURCES; + } + + NDIS_BUFFER_LINKAGE(NdisBuffer) = (PNDIS_BUFFER)NULL; + PaddingBuffer->NdisBuffer = NdisBuffer; + PaddingBuffer->DataLength = DataBufferLength; + RtlZeroMemory (PaddingBuffer->Data, DataBufferLength); + + return STATUS_SUCCESS; + +} /* IpxInitializePaddingBuffer */ + + +VOID +IpxDeinitializeSendPacket( + IN PDEVICE Device, + IN PIPX_SEND_PACKET Packet + ) + +/*++ + +Routine Description: + + This routine deinitializes a send packet. + +Arguments: + + Device - The device. + + Packet - The packet to deinitialize. + +Return Value: + + None. + +--*/ + +{ + + PNDIS_BUFFER NdisBuffer; + PNDIS_BUFFER NdisIpxBuffer; + PIPX_SEND_RESERVED Reserved; + CTELockHandle LockHandle; + + + Reserved = SEND_RESERVED(Packet); + + CTEGetLock (&Device->Lock, &LockHandle); + RemoveEntryList (&Reserved->GlobalLinkage); + CTEFreeLock (&Device->Lock, LockHandle); + + // + // Free the packet in a slightly unconventional way; this + // allows us to not have to NULL out HeaderBuffer's linkage + // field during normal operations when we put it back in + // the free pool. + // + + NdisBuffer = Reserved->HeaderBuffer; + NdisIpxBuffer = NDIS_BUFFER_LINKAGE(NdisBuffer); + NDIS_BUFFER_LINKAGE (NdisBuffer) = NULL; + NDIS_BUFFER_LINKAGE (NdisIpxBuffer) = NULL; + +#if 0 + NdisAdjustBufferLength (NdisBuffer, PACKET_HEADER_SIZE); +#endif + NdisAdjustBufferLength (NdisBuffer, MAC_HEADER_SIZE); + NdisAdjustBufferLength (NdisIpxBuffer, IPX_HEADER_SIZE + RIP_PACKET_SIZE); + + NdisFreeBuffer (NdisBuffer); + NdisFreeBuffer (NdisIpxBuffer); + + NdisReinitializePacket (PACKET(Packet)); + IpxFreeSendPacket (Device, Packet); + +} /* IpxDeinitializeSendPacket */ + +#if BACK_FILL +VOID +IpxDeinitializeBackFillPacket( + IN PDEVICE Device, + IN PIPX_SEND_PACKET Packet + ) + +/*++ + +Routine Description: + + This routine deinitializes a back fill packet. + +Arguments: + + Device - The device. + + Packet - The packet to deinitialize. + +Return Value: + + None. + +--*/ + +{ + + PNDIS_BUFFER NdisBuffer; + PNDIS_BUFFER NdisIpxBuffer; + PIPX_SEND_RESERVED Reserved; + CTELockHandle LockHandle; + + IPX_DEBUG (PACKET, ("DeInitializing backfill packet\n")); + + Reserved = SEND_RESERVED(Packet); + + CTEGetLock (&Device->Lock, &LockHandle); + RemoveEntryList (&Reserved->GlobalLinkage); + CTEFreeLock (&Device->Lock, LockHandle); + + + + NdisReinitializePacket (PACKET(Packet)); + IpxFreeSendPacket (Device, Packet); + IPX_DEBUG (PACKET, ("DeInitializing backfill packet Done\n")); + + +} /* IpxDeinitializeBackFillPacket */ +#endif + + +VOID +IpxDeinitializeReceivePacket( + IN PDEVICE Device, + IN PIPX_RECEIVE_PACKET Packet + ) + +/*++ + +Routine Description: + + This routine initializes a receive packet. + +Arguments: + + Device - The device. + + Packet - The packet to initialize. + +Return Value: + + None. + +--*/ + +{ + + PIPX_RECEIVE_RESERVED Reserved; + CTELockHandle LockHandle; + + Reserved = RECEIVE_RESERVED(Packet); + + CTEGetLock (&Device->Lock, &LockHandle); + RemoveEntryList (&Reserved->GlobalLinkage); + CTEFreeLock (&Device->Lock, LockHandle); + + IpxFreeReceivePacket (Device, Packet); + +} /* IpxDeinitializeReceivePacket */ + + +VOID +IpxDeinitializeReceiveBuffer( + IN PADAPTER Adapter, + IN PIPX_RECEIVE_BUFFER ReceiveBuffer, + IN ULONG DataBufferLength + ) + +/*++ + +Routine Description: + + This routine deinitializes a receive buffer. + +Arguments: + + Device - The device. + + ReceiveBuffer - The receive buffer. + + DataBufferLength - The allocated length of the receive buffer. + +Return Value: + + None. + +--*/ + +{ + CTELockHandle LockHandle; + PDEVICE Device = Adapter->Device; + + CTEGetLock (&Device->Lock, &LockHandle); + RemoveEntryList (&ReceiveBuffer->GlobalLinkage); + CTEFreeLock (&Device->Lock, LockHandle); + + NdisAdjustBufferLength (ReceiveBuffer->NdisBuffer, DataBufferLength); + NdisFreeBuffer (ReceiveBuffer->NdisBuffer); + +} /* IpxDeinitializeReceiveBuffer */ + + +VOID +IpxDeinitializePaddingBuffer( + IN PDEVICE Device, + IN PIPX_PADDING_BUFFER PaddingBuffer, + IN ULONG DataBufferLength + ) + +/*++ + +Routine Description: + + This routine deinitializes a padding buffer. + +Arguments: + + Device - The device. + + PaddingBuffer - The padding buffer. + + DataBufferLength - The allocated length of the padding buffer. + +Return Value: + + None. + +--*/ + +{ + + NdisAdjustBufferLength (PaddingBuffer->NdisBuffer, DataBufferLength); + NdisFreeBuffer (PaddingBuffer->NdisBuffer); + +} /* IpxDeinitializePaddingBuffer */ + + + +#ifdef IPX_OWN_PACKETS +VOID +IpxAllocateSendPool( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine adds 10 packets to the pool for this device. + +Arguments: + + Device - The device. + +Return Value: + + None. + +--*/ + +{ + PIPX_SEND_POOL SendPool; + UINT SendPoolSize; + UINT PacketNum; + PIPX_SEND_PACKET Packet; + PIPX_SEND_RESERVED Reserved; + PUCHAR Header; + CTELockHandle LockHandle; + + + SendPoolSize = FIELD_OFFSET (IPX_SEND_POOL, Packets[0]) + + (sizeof(IPX_SEND_PACKET) * Device->InitDatagrams) + + (PACKET_HEADER_SIZE * Device->InitDatagrams); + + + SendPool = (PIPX_SEND_POOL)IpxAllocateMemory (SendPoolSize, MEMORY_PACKET, "SendPool"); + if (SendPool == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate send pool memory\n")); + return; + } + + + IPX_DEBUG (PACKET, ("Initializing send pool %lx, %d packets\n", + SendPool, Device->InitDatagrams)); + + Header = (PUCHAR)(&SendPool->Packets[Device->InitDatagrams]); + + for (PacketNum = 0; PacketNum < Device->InitDatagrams; PacketNum++) { + + Packet = &SendPool->Packets[PacketNum]; + + if (IpxInitializeSendPacket (Device, Packet, Header) != STATUS_SUCCESS) { + IPX_DEBUG (PACKET, ("Could not initialize packet %lx\n", Packet)); + break; + } + + Reserved = SEND_RESERVED(Packet); + Reserved->Address = NULL; + Reserved->OwnedByAddress = FALSE; +#ifdef IPX_TRACK_POOL + Reserved->Pool = SendPool; +#endif + + Header += PACKET_HEADER_SIZE; + + } + + SendPool->PacketCount = PacketNum; + SendPool->PacketFree = PacketNum; + + + CTEGetLock (&Device->Lock, &LockHandle); + + for (PacketNum = 0; PacketNum < SendPool->PacketCount; PacketNum++) { + + Packet = &SendPool->Packets[PacketNum]; + Reserved = SEND_RESERVED(Packet); + IPX_PUSH_ENTRY_LIST (&Device->SendPacketList, &Reserved->PoolLinkage, &Device->SListsLock); + + } + + InsertTailList (&Device->SendPoolList, &SendPool->Linkage); + + Device->AllocatedDatagrams += SendPool->PacketCount; + + CTEFreeLock (&Device->Lock, LockHandle); + +} /* IpxAllocateSendPool */ + +#if BACK_FILL + +VOID +IpxAllocateBackFillPool( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine adds 10 packets to the pool for this device. + +Arguments: + + Device - The device. + +Return Value: + + None. + +--*/ + +{ + PIPX_SEND_POOL SendPool; + UINT SendPoolSize; + UINT PacketNum; + PIPX_SEND_PACKET Packet; + PIPX_SEND_RESERVED Reserved; + PUCHAR Header; + CTELockHandle LockHandle; + + PIPX_SEND_POOL BackFillPool; + UINT BackFillPoolSize; + + IPX_DEBUG (PACKET, ("Allocating backfill pool\n")); + + + BackFillPoolSize = FIELD_OFFSET (IPX_SEND_POOL, Packets[0]) + + (sizeof(IPX_SEND_PACKET) * Device->InitDatagrams); + + + // Allocate pool for back fillable packets + + BackFillPool = (PIPX_SEND_POOL)IpxAllocateMemory (BackFillPoolSize, MEMORY_PACKET, "BafiPool"); + + if (BackFillPool == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate BackFill pool memory\n")); + return; + } + + + + + + for (PacketNum = 0; PacketNum < Device->InitDatagrams; PacketNum++) { + + Packet = &BackFillPool->Packets[PacketNum]; + + if (IpxInitializeBackFillPacket (Device, Packet, NULL) != STATUS_SUCCESS) { + IPX_DEBUG (PACKET, ("Could not initialize packet %lx\n", Packet)); + break; + } + + Reserved = SEND_RESERVED(Packet); + Reserved->Address = NULL; + Reserved->OwnedByAddress = FALSE; +#ifdef IPX_TRACK_POOL + Reserved->Pool = BackFillPool; +#endif + + + } + + BackFillPool->PacketCount = PacketNum; + BackFillPool->PacketFree = PacketNum; + + + CTEGetLock (&Device->Lock, &LockHandle); + + for (PacketNum = 0; PacketNum < BackFillPool->PacketCount; PacketNum++) { + + Packet = &BackFillPool->Packets[PacketNum]; + Reserved = SEND_RESERVED(Packet); + IPX_PUSH_ENTRY_LIST (&Device->BackFillPacketList, &Reserved->PoolLinkage, &Device->SListsLock); + + } + + InsertTailList (&Device->BackFillPoolList, &BackFillPool->Linkage); + + + IPX_DEBUG (PACKET, ("Allocation of backfill pool done\n")); + + CTEFreeLock (&Device->Lock, LockHandle); + +} /* IpxAllocateBackFillPool */ + +#endif + + +VOID +IpxAllocateReceivePool( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine adds receive packets to the pool for this device. + +Arguments: + + Device - The device. + +Return Value: + + None. + +--*/ + +{ + PIPX_RECEIVE_POOL ReceivePool; + UINT ReceivePoolSize; + UINT PacketNum; + PIPX_RECEIVE_PACKET Packet; + PIPX_RECEIVE_RESERVED Reserved; + CTELockHandle LockHandle; + + ReceivePoolSize = FIELD_OFFSET (IPX_RECEIVE_POOL, Packets[0]) + + (sizeof(IPX_RECEIVE_PACKET) * Device->InitReceivePackets); + + ReceivePool = (PIPX_RECEIVE_POOL)IpxAllocateMemory (ReceivePoolSize, MEMORY_PACKET, "ReceivePool"); + if (ReceivePool == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate receive pool memory\n")); + return; + } + + IPX_DEBUG (PACKET, ("Initializing receive pool %lx, %d packets\n", + ReceivePool, Device->InitReceivePackets)); + + for (PacketNum = 0; PacketNum < Device->InitReceivePackets; PacketNum++) { + + Packet = &ReceivePool->Packets[PacketNum]; + + if (IpxInitializeReceivePacket (Device, Packet) != STATUS_SUCCESS) { + IPX_DEBUG (PACKET, ("Could not initialize packet %lx\n", Packet)); + break; + } + + Reserved = RECEIVE_RESERVED(Packet); + Reserved->Address = NULL; + Reserved->OwnedByAddress = FALSE; +#ifdef IPX_TRACK_POOL + Reserved->Pool = ReceivePool; +#endif + + } + + ReceivePool->PacketCount = PacketNum; + ReceivePool->PacketFree = PacketNum; + + CTEGetLock (&Device->Lock, &LockHandle); + + for (PacketNum = 0; PacketNum < ReceivePool->PacketCount; PacketNum++) { + + Packet = &ReceivePool->Packets[PacketNum]; + Reserved = RECEIVE_RESERVED(Packet); + IPX_PUSH_ENTRY_LIST (&Device->ReceivePacketList, &Reserved->PoolLinkage, &Device->SListsLock); + + } + + InsertTailList (&Device->ReceivePoolList, &ReceivePool->Linkage); + + Device->AllocatedReceivePackets += ReceivePool->PacketCount; + + CTEFreeLock (&Device->Lock, LockHandle); + +} /* IpxAllocateReceivePool */ + + +#else // IPX_OWN_PACKETS +VOID +IpxAllocateSendPool( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine adds 10 packets to the pool for this device. + +Arguments: + + Device - The device. + +Return Value: + + None. + +--*/ + +{ + PIPX_SEND_POOL SendPool; + UINT HeaderSize; + UINT PacketNum; + IPX_SEND_PACKET Packet; + PIPX_SEND_RESERVED Reserved; + PUCHAR Header; + NDIS_STATUS Status; + + CTELockHandle LockHandle; + + SendPool = (PIPX_SEND_POOL)IpxAllocateMemory (sizeof(IPX_SEND_POOL), MEMORY_PACKET, "SendPool"); + + if (SendPool == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate send pool memory\n")); + return; + } + + HeaderSize = PACKET_HEADER_SIZE * Device->InitDatagrams; + + Header = (PUCHAR)IpxAllocateMemory (HeaderSize, MEMORY_PACKET, "SendPool"); + + if (Header == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate header memory\n")); + return; + } + + NdisAllocatePacketPool(&Status, &SendPool->PoolHandle, Device->InitDatagrams, sizeof(IPX_SEND_RESERVED)); + + if (Status == NDIS_STATUS_RESOURCES) { + IPX_DEBUG (PACKET, ("Could not allocate Ndis pool memory\n")); + return; + } + + Device->MemoryUsage += (FIELD_OFFSET(NDIS_PACKET_POOL,Buffer[0]) + + Device->InitDatagrams * (FIELD_OFFSET(NDIS_PACKET,ProtocolReserved[0]) + sizeof(IPX_SEND_RESERVED))); + + IPX_DEBUG (PACKET, ("Initializing send pool %lx, %d packets\n", + SendPool, Device->InitDatagrams)); + + SendPool->Header = Header; + + for (PacketNum = 0; PacketNum < Device->InitDatagrams; PacketNum++) { + + NdisAllocatePacket(&Status, &PACKET(&Packet), SendPool->PoolHandle); + + if (IpxInitializeSendPacket (Device, &Packet, Header) != STATUS_SUCCESS) { + IPX_DEBUG (PACKET, ("Could not initialize packet %lx\n", Packet)); + break; + } + + Reserved = SEND_RESERVED(&Packet); + Reserved->Address = NULL; + Reserved->OwnedByAddress = FALSE; +#ifdef IPX_TRACK_POOL + Reserved->Pool = SendPool; +#endif + + IPX_PUSH_ENTRY_LIST (&Device->SendPacketList, &Reserved->PoolLinkage, &Device->SListsLock); + + Header += PACKET_HEADER_SIZE; + + } + + CTEGetLock (&Device->Lock, &LockHandle); + + Device->AllocatedDatagrams += PacketNum; + InsertTailList (&Device->SendPoolList, &SendPool->Linkage); + + CTEFreeLock (&Device->Lock, LockHandle); +} /* IpxAllocateSendPool */ + + +#if BACK_FILL + +VOID +IpxAllocateBackFillPool( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine adds 10 packets to the pool for this device. + +Arguments: + + Device - The device. + +Return Value: + + None. + +--*/ + +{ + UINT PacketNum; + IPX_SEND_PACKET Packet; + PIPX_SEND_RESERVED Reserved; + CTELockHandle LockHandle; + PIPX_SEND_POOL BackFillPool; + NDIS_STATUS Status; + + IPX_DEBUG (PACKET, ("Allocating backfill pool\n")); + + // Allocate pool for back fillable packets + + BackFillPool = (PIPX_SEND_POOL)IpxAllocateMemory (sizeof(IPX_SEND_POOL), MEMORY_PACKET, "BafiPool"); + + if (BackFillPool == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate backfill pool memory\n")); + return; + } + + NdisAllocatePacketPool(&Status, &BackFillPool->PoolHandle, Device->InitDatagrams, sizeof(IPX_SEND_RESERVED)); + + if (Status == NDIS_STATUS_RESOURCES) { + IPX_DEBUG (PACKET, ("Could not allocate Ndis pool memory\n")); + return; + } + + Device->MemoryUsage += (FIELD_OFFSET(NDIS_PACKET_POOL,Buffer[0]) + + Device->InitDatagrams * (FIELD_OFFSET(NDIS_PACKET,ProtocolReserved[0]) + sizeof(IPX_SEND_RESERVED))); + + for (PacketNum = 0; PacketNum < Device->InitDatagrams; PacketNum++) { + + NdisAllocatePacket(&Status, &PACKET(&Packet), BackFillPool->PoolHandle); + + if (IpxInitializeBackFillPacket (Device, &Packet, NULL) != STATUS_SUCCESS) { + IPX_DEBUG (PACKET, ("Could not initialize packet %lx\n", Packet)); + break; + } + + Reserved = SEND_RESERVED(&Packet); + Reserved->Address = NULL; + Reserved->OwnedByAddress = FALSE; +#ifdef IPX_TRACK_POOL + Reserved->Pool = BackFillPool; +#endif + + IPX_PUSH_ENTRY_LIST (&Device->BackFillPacketList, &Reserved->PoolLinkage, &Device->SListsLock); + } + + CTEGetLock (&Device->Lock, &LockHandle); + + InsertTailList (&Device->BackFillPoolList, &BackFillPool->Linkage); + + CTEFreeLock (&Device->Lock, LockHandle); +} /* IpxAllocateBackFillPool */ + +#endif + + +VOID +IpxAllocateReceivePool( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine adds receive packets to the pool for this device. + +Arguments: + + Device - The device. + +Return Value: + + None. + +--*/ + +{ + PIPX_RECEIVE_POOL ReceivePool; + UINT PacketNum; + IPX_RECEIVE_PACKET Packet; + PIPX_RECEIVE_RESERVED Reserved; + CTELockHandle LockHandle; + NDIS_STATUS Status; + + ReceivePool = (PIPX_SEND_POOL)IpxAllocateMemory (sizeof(IPX_RECEIVE_POOL), MEMORY_PACKET, "ReceivePool"); + + if (ReceivePool == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate receive pool memory\n")); + return; + } + + NdisAllocatePacketPool(&Status, &ReceivePool->PoolHandle, Device->InitDatagrams, sizeof(IPX_SEND_RESERVED)); + + if (Status == NDIS_STATUS_RESOURCES) { + IPX_DEBUG (PACKET, ("Could not allocate receive pool memory\n")); + return; + } + + IPX_DEBUG (PACKET, ("Initializing receive pool %lx, %d packets\n", + ReceivePool, Device->InitReceivePackets)); + + Device->MemoryUsage += (FIELD_OFFSET(NDIS_PACKET_POOL,Buffer[0]) + + Device->InitReceivePackets * (FIELD_OFFSET(NDIS_PACKET,ProtocolReserved[0]) + sizeof(IPX_RECEIVE_RESERVED))); + + for (PacketNum = 0; PacketNum < Device->InitReceivePackets; PacketNum++) { + + NdisAllocatePacket(&Status, &PACKET(&Packet), ReceivePool->PoolHandle); + + if (IpxInitializeReceivePacket (Device, &Packet) != STATUS_SUCCESS) { + IPX_DEBUG (PACKET, ("Could not initialize packet %lx\n", Packet)); + break; + } + + Reserved = RECEIVE_RESERVED(&Packet); + Reserved->Address = NULL; + Reserved->OwnedByAddress = FALSE; +#ifdef IPX_TRACK_POOL + Reserved->Pool = ReceivePool; +#endif + + IPX_PUSH_ENTRY_LIST (&Device->ReceivePacketList, &Reserved->PoolLinkage, &Device->SListsLock); + + } + + CTEGetLock (&Device->Lock, &LockHandle); + + Device->AllocatedReceivePackets += PacketNum; + + InsertTailList (&Device->ReceivePoolList, &ReceivePool->Linkage); + + CTEFreeLock (&Device->Lock, LockHandle); +} /* IpxAllocateReceivePool */ +#endif // IPX_OWN_PACKETS + +VOID +IpxAllocateReceiveBufferPool( + IN PADAPTER Adapter + ) + +/*++ + +Routine Description: + + This routine adds receive buffers to the pool for this adapter. + +Arguments: + + Adapter - The adapter. + +Return Value: + + None. + +--*/ + +{ + PIPX_RECEIVE_BUFFER ReceiveBuffer; + UINT ReceiveBufferPoolSize; + UINT BufferNum; + PIPX_RECEIVE_BUFFER_POOL ReceiveBufferPool; + PDEVICE Device = Adapter->Device; + UINT DataLength; + PUCHAR Data; + CTELockHandle LockHandle; + + DataLength = Adapter->MaxReceivePacketSize; + + ReceiveBufferPoolSize = FIELD_OFFSET (IPX_RECEIVE_BUFFER_POOL, Buffers[0]) + + (sizeof(IPX_RECEIVE_BUFFER) * Device->InitReceiveBuffers) + + (DataLength * Device->InitReceiveBuffers); + + ReceiveBufferPool = (PIPX_RECEIVE_BUFFER_POOL)IpxAllocateMemory (ReceiveBufferPoolSize, MEMORY_PACKET, "ReceiveBufferPool"); + if (ReceiveBufferPool == NULL) { + IPX_DEBUG (PACKET, ("Could not allocate receive buffer pool memory\n")); + return; + } + + IPX_DEBUG (PACKET, ("Init recv buffer pool %lx, %d buffers, data %d\n", + ReceiveBufferPool, Device->InitReceiveBuffers, DataLength)); + + Data = (PUCHAR)(&ReceiveBufferPool->Buffers[Device->InitReceiveBuffers]); + + + for (BufferNum = 0; BufferNum < Device->InitReceiveBuffers; BufferNum++) { + + ReceiveBuffer = &ReceiveBufferPool->Buffers[BufferNum]; + + if (IpxInitializeReceiveBuffer (Adapter, ReceiveBuffer, Data, DataLength) != STATUS_SUCCESS) { + IPX_DEBUG (PACKET, ("Could not initialize buffer %lx\n", ReceiveBuffer)); + break; + } + +#ifdef IPX_TRACK_POOL + ReceiveBuffer->Pool = ReceiveBufferPool; +#endif + + Data += DataLength; + + } + + ReceiveBufferPool->BufferCount = BufferNum; + ReceiveBufferPool->BufferFree = BufferNum; + + CTEGetLock (&Device->Lock, &LockHandle); + + for (BufferNum = 0; BufferNum < ReceiveBufferPool->BufferCount; BufferNum++) { + + ReceiveBuffer = &ReceiveBufferPool->Buffers[BufferNum]; + IPX_PUSH_ENTRY_LIST (&Adapter->ReceiveBufferList, &ReceiveBuffer->PoolLinkage, &Device->SListsLock); + + } + + InsertTailList (&Adapter->ReceiveBufferPoolList, &ReceiveBufferPool->Linkage); + + Adapter->AllocatedReceiveBuffers += ReceiveBufferPool->BufferCount; + + CTEFreeLock (&Device->Lock, LockHandle); + +} /* IpxAllocateReceiveBufferPool */ + + +PSINGLE_LIST_ENTRY +IpxPopSendPacket( + PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine allocates a packet from the device context's pool. + If there are no packets in the pool, it allocates one up to + the configured limit. + +Arguments: + + Device - Pointer to our device to charge the packet to. + +Return Value: + + The pointer to the Linkage field in the allocated packet. + +--*/ + +{ + PSINGLE_LIST_ENTRY s; + + s = IPX_POP_ENTRY_LIST( + &Device->SendPacketList, + &Device->SListsLock); + + if (s != NULL) { + return s; + } + + // + // No packets in the pool, see if we can allocate more. + // + + if (Device->AllocatedDatagrams < Device->MaxDatagrams) { + + // + // Allocate a pool and try again. + // + + IpxAllocateSendPool (Device); + s = IPX_POP_ENTRY_LIST( + &Device->SendPacketList, + &Device->SListsLock); + + return s; + + } else { + + return NULL; + + } + +} /* IpxPopSendPacket */ + +#if BACK_FILL + +PSINGLE_LIST_ENTRY +IpxPopBackFillPacket( + PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine allocates a packet from the device context's pool. + If there are no packets in the pool, it allocates one up to + the configured limit. + +Arguments: + + Device - Pointer to our device to charge the packet to. + +Return Value: + + The pointer to the Linkage field in the allocated packet. + +--*/ + +{ + PSINGLE_LIST_ENTRY s; + + IPX_DEBUG (PACKET, ("Popping backfill packet\n")); + + + s = IPX_POP_ENTRY_LIST( + &Device->BackFillPacketList, + &Device->SListsLock); + + if (s != NULL) { + return s; + } + + // + // No packets in the pool, see if we can allocate more. + // + + if (Device->AllocatedDatagrams < Device->MaxDatagrams) { + + // + // Allocate a pool and try again. + // + + IpxAllocateBackFillPool (Device); + s = IPX_POP_ENTRY_LIST( + &Device->BackFillPacketList, + &Device->SListsLock); + + + IPX_DEBUG (PACKET, ("Popping backfill packet done\n")); + return s; + + } else { + + return NULL; + + } + +} /* IpxPopBackFillPacket */ +#endif //BackFill + + +PSINGLE_LIST_ENTRY +IpxPopReceivePacket( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine allocates a packet from the device context's pool. + If there are no packets in the pool, it allocates one up to + the configured limit. + +Arguments: + + Device - Pointer to our device to charge the packet to. + +Return Value: + + The pointer to the Linkage field in the allocated packet. + +--*/ + +{ + PSINGLE_LIST_ENTRY s; + + s = IPX_POP_ENTRY_LIST( + &Device->ReceivePacketList, + &Device->SListsLock); + + if (s != NULL) { + return s; + } + + // + // No packets in the pool, see if we can allocate more. + // + + if (Device->AllocatedReceivePackets < Device->MaxReceivePackets) { + + // + // Allocate a pool and try again. + // + + IpxAllocateReceivePool (Device); + s = IPX_POP_ENTRY_LIST( + &Device->ReceivePacketList, + &Device->SListsLock); + + return s; + + } else { + + return NULL; + + } + +} /* IpxPopReceivePacket */ + + +PSINGLE_LIST_ENTRY +IpxPopReceiveBuffer( + IN PADAPTER Adapter + ) + +/*++ + +Routine Description: + + This routine allocates a receive buffer from the adapter's pool. + If there are no buffers in the pool, it allocates one up to + the configured limit. + +Arguments: + + Adapter - Pointer to our adapter to charge the buffer to. + +Return Value: + + The pointer to the Linkage field in the allocated receive buffer. + +--*/ + +{ + PSINGLE_LIST_ENTRY s; + PDEVICE Device = Adapter->Device; + + s = IPX_POP_ENTRY_LIST( + &Adapter->ReceiveBufferList, + &Device->SListsLock); + + if (s != NULL) { + return s; + } + + // + // No buffer in the pool, see if we can allocate more. + // + + if (Adapter->AllocatedReceiveBuffers < Device->MaxReceiveBuffers) { + + // + // Allocate a pool and try again. + // + + IpxAllocateReceiveBufferPool (Adapter); + s = IPX_POP_ENTRY_LIST( + &Adapter->ReceiveBufferList, + &Device->SListsLock); + + return s; + + } else { + + return NULL; + + } + +} /* IpxPopReceiveBuffer */ + + +PIPX_PADDING_BUFFER +IpxAllocatePaddingBuffer( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine allocates a padding buffer for use by all devices. + +Arguments: + + Device - Pointer to our device to charge the packet to. + +Return Value: + + The pointer to the allocated padding buffer. + +--*/ + +{ + PIPX_PADDING_BUFFER PaddingBuffer; + ULONG PaddingBufferSize; + + // + // We are assuming that we can use 1 global padding buffer for ALL + // transmits! We must therefore test to make sure that EthernetExtraPadding + // is not greater than 1. Otherwise, we must assume that the extra padding + // is being used for something and we therefore cannot share across all + // transmit requests. + // + + // + // We cannot support more than 1 byte padding space, since we allocate only + // one buffer for all transmit requests. + // + + if ( Device->EthernetExtraPadding > 1 ) { + IPX_DEBUG (PACKET, ("Padding buffer cannot be more than 1 byte\n")); + DbgBreakPoint(); + } + + // + // Allocate a padding buffer if possible. + // + + PaddingBufferSize = FIELD_OFFSET (IPX_PADDING_BUFFER, Data[0]) + Device->EthernetExtraPadding; + + PaddingBuffer = IpxAllocateMemory (PaddingBufferSize, MEMORY_PACKET, "PaddingBuffer"); + + if (PaddingBuffer != NULL) { + + if (IpxInitializePaddingBuffer (Device, PaddingBuffer, Device->EthernetExtraPadding) != + STATUS_SUCCESS) { + IpxFreeMemory (PaddingBuffer, PaddingBufferSize, MEMORY_PACKET, "Padding Buffer"); + } else { + IPX_DEBUG (PACKET, ("Allocate padding buffer %lx\n", PaddingBuffer)); + return PaddingBuffer; + } + } + + return NULL; + +} /* IpxAllocatePaddingBuffer */ + + +VOID +IpxFreePaddingBuffer( + IN PDEVICE Device + ) + +/*++ + +Routine Description: + + This routine deallocates the padding buffer. + +Arguments: + + Device - Pointer to our device to charge the packet to. + +Return Value: + + None + +--*/ + +{ + ULONG PaddingBufferSize; + + if ( IpxPaddingBuffer == (PIPX_PADDING_BUFFER)NULL ) { + return; + } + + PaddingBufferSize = FIELD_OFFSET (IPX_PADDING_BUFFER, Data[0]) + Device->EthernetExtraPadding; + IpxFreeMemory( IpxPaddingBuffer, PaddingBufferSize, MEMORY_PACKET, "Padding Buffer" ); + IpxPaddingBuffer = (PIPX_PADDING_BUFFER)NULL; + +} /* IpxFreePaddingBuffer */ + -- cgit v1.2.3