mirror of https://github.com/lianthony/NT4.0
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.
1624 lines
33 KiB
1624 lines
33 KiB
/*++
|
|
|
|
Copyright (c) 1990-1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Ndiswan.c
|
|
|
|
Abstract:
|
|
|
|
This is the initialization file for the NdisWan driver. This driver
|
|
is a shim between the protocols, where it conforms to the NDIS 3.1
|
|
Miniport interface spec, and the WAN Miniport drivers, where it exports
|
|
the WAN Extensions for Miniports (it looks like a protocol to the WAN
|
|
Miniport drivers).
|
|
|
|
Author:
|
|
|
|
Tony Bell (TonyBe) June 06, 1995
|
|
|
|
Environment:
|
|
|
|
Kernel Mode
|
|
|
|
Revision History:
|
|
|
|
TonyBe 06/06/95 Created
|
|
|
|
--*/
|
|
|
|
#include "wan.h"
|
|
#include "tcpip.h"
|
|
#include "vjslip.h"
|
|
|
|
|
|
//
|
|
// Local function prototypes
|
|
//
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateLinkCB(
|
|
OUT PLINKCB *LinkCB
|
|
);
|
|
|
|
VOID
|
|
NdisWanInitLinkCB(
|
|
IN PLINKCB *LinkCB,
|
|
IN PWAN_ADAPTERCB WanAdapterCB,
|
|
IN ULONG SendWindow
|
|
);
|
|
|
|
VOID
|
|
NdisWanDestroyLinkCB(
|
|
IN PLINKCB LinkCB
|
|
);
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateBundleCB(
|
|
OUT PBUNDLECB *BundleCB
|
|
);
|
|
|
|
VOID
|
|
NdisWanInitBundleCB(
|
|
IN PBUNDLECB BundleCB
|
|
);
|
|
|
|
VOID
|
|
NdisWanDestroyBundleCB(
|
|
IN PBUNDLECB BundleCB
|
|
);
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateProtocolCB(
|
|
OUT PPROTOCOLCB *ProtocolCB,
|
|
IN USHORT usProtocolType,
|
|
IN USHORT usBindingNameLength,
|
|
IN PWSTR BindingName,
|
|
IN ULONG ulBufferLength,
|
|
IN PUCHAR Buffer
|
|
);
|
|
|
|
//VOID
|
|
//NdisWanInitProtocolCB(
|
|
// IN PPROTOCOLCB ProtocolCB,
|
|
// IN ULONG ulBufferLength,
|
|
// IN PUCHAR Buffer,
|
|
// IN USHORT usProtocolType
|
|
// );
|
|
|
|
VOID
|
|
NdisWanDestroyProtocolCB(
|
|
IN PPROTOCOLCB ProtocolCB
|
|
);
|
|
|
|
|
|
NDIS_STATUS
|
|
NdisWanAllocateSendResources(
|
|
IN PLINKCB LinkCB,
|
|
IN ULONG SendWindow
|
|
);
|
|
|
|
VOID
|
|
NdisWanFreeSendResources(
|
|
IN PLINKCB LinkCB
|
|
);
|
|
|
|
//
|
|
// End local function prototypes
|
|
//
|
|
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateAdapterCB(
|
|
OUT PADAPTERCB *pAdapterCB,
|
|
IN PNDIS_STRING AdapterName
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
NdisWanCreateAdapterCB
|
|
|
|
Routine Description:
|
|
|
|
This routine creates and initializes an AdapterCB
|
|
|
|
Arguments:
|
|
|
|
pAdapterCB - Pointer to a pointer to the AdapterCB that was created
|
|
|
|
Return Values:
|
|
|
|
NDIS_STATUS_SUCCESS
|
|
NDIS_STATUS_RESOURCES
|
|
|
|
--*/
|
|
{
|
|
PADAPTERCB LocalAdapterCB;
|
|
ULONG ulAllocationSize, i;
|
|
PDEFERRED_DESC FreeDesc;
|
|
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateAdapterCB: Enter"));
|
|
|
|
//
|
|
// Allocate and zero out the memory block
|
|
//
|
|
ulAllocationSize = sizeof(ADAPTERCB) + 20*sizeof(DEFERRED_DESC);
|
|
NdisWanAllocateMemory(&LocalAdapterCB, ulAllocationSize);
|
|
|
|
if (LocalAdapterCB == NULL) {
|
|
|
|
return (NDIS_STATUS_RESOURCES);
|
|
}
|
|
|
|
//
|
|
// setup the new control block
|
|
//
|
|
LocalAdapterCB->ulAllocationSize = ulAllocationSize;
|
|
|
|
NdisAllocateSpinLock(&LocalAdapterCB->Lock);
|
|
|
|
#ifdef MINIPORT_NAME
|
|
// NdisWanStringToNdisString(&LocalAdapterCB->AdapterName, AdapterName->Buffer);
|
|
NdisWanAllocateAdapterName(&LocalAdapterCB->AdapterName, AdapterName);
|
|
#endif
|
|
|
|
//
|
|
// Setup free deferred desc list
|
|
//
|
|
FreeDesc = (PDEFERRED_DESC)((PUCHAR)LocalAdapterCB + sizeof(ADAPTERCB));
|
|
|
|
for (i = 0; i < 20; i++) {
|
|
InsertHeadDeferredQueue(&LocalAdapterCB->FreeDeferredQueue, FreeDesc);
|
|
(PUCHAR)FreeDesc += sizeof(DEFERRED_DESC);
|
|
}
|
|
|
|
#if DBG
|
|
InitializeListHead(&LocalAdapterCB->DbgNdisPacketList);
|
|
#endif
|
|
|
|
//
|
|
// Add to global list
|
|
//
|
|
InsertTailGlobalList(AdapterCBList, &(LocalAdapterCB->Linkage));
|
|
|
|
*pAdapterCB = LocalAdapterCB;
|
|
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("%ls AdapterCB: 0x%x, Number: %d",
|
|
LocalAdapterCB->AdapterName.Buffer, *pAdapterCB, AdapterCBList.ulCount));
|
|
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateAdapterCB: Exit"));
|
|
|
|
return (NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
VOID
|
|
NdisWanDestroyAdapterCB(
|
|
IN PADAPTERCB pAdapterCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
NdisWanDestroyAdapterCB
|
|
|
|
Routine Description:
|
|
|
|
This destroys an AdapterCB
|
|
|
|
Arguments:
|
|
|
|
pAdapterCB - Pointer to to the AdapterCB that is being destroyed
|
|
|
|
Return Values:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyAdapterCB: Enter"));
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("AdapterCB: 0x%x", pAdapterCB));
|
|
|
|
#ifdef MINIPORT_NAME
|
|
NdisWanFreeNdisString(&pAdapterCB->AdapterName);
|
|
#endif
|
|
|
|
NdisFreeSpinLock(&pAdapterCB->Lock);
|
|
|
|
NdisWanFreeMemory(pAdapterCB);
|
|
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyAdapterCB: Exit"));
|
|
}
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateWanAdapterCB(
|
|
IN PWSTR BindName
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
NdisWanCreateWanAdapterCB
|
|
|
|
Routine Description:
|
|
|
|
This routine creates and initializes a WanAdapterCB
|
|
|
|
Arguments:
|
|
|
|
BindName - Pointer to an NDIS_STRING that has the name of the WAN Miniport
|
|
that will be used in the NdisOpenAdapter call when we bind to
|
|
the WAN Miniport.
|
|
|
|
Return Values:
|
|
|
|
NDIS_STATUS_SUCCESS
|
|
NDIS_STATUS_RESOURCES
|
|
|
|
--*/
|
|
{
|
|
PWAN_ADAPTERCB pWanAdapterCB;
|
|
ULONG ulAllocationSize;
|
|
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateWanAdapterCB: Enter"));
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("BindName: %ls", BindName));
|
|
|
|
//
|
|
// Allocate memory for WanAdapterCB
|
|
//
|
|
ulAllocationSize = sizeof(WAN_ADAPTERCB);
|
|
|
|
NdisWanAllocateMemory(&pWanAdapterCB, ulAllocationSize);
|
|
|
|
if (pWanAdapterCB == NULL) {
|
|
|
|
return (NDIS_STATUS_RESOURCES);
|
|
}
|
|
|
|
//
|
|
// Init WanAdapterCB
|
|
//
|
|
|
|
//
|
|
// Setup new control block
|
|
//
|
|
pWanAdapterCB->ulAllocationSize = ulAllocationSize;
|
|
|
|
NdisWanStringToNdisString(&(pWanAdapterCB->MiniportName), BindName);
|
|
|
|
NdisAllocateSpinLock(&pWanAdapterCB->Lock);
|
|
InitializeListHead(&pWanAdapterCB->FreeLinkCBList);
|
|
|
|
#if DBG
|
|
InitializeListHead(&pWanAdapterCB->DbgWanPacketList);
|
|
#endif
|
|
|
|
//
|
|
// Put WanAdapterCB on global list
|
|
//
|
|
InsertTailGlobalList(WanAdapterCBList, &(pWanAdapterCB->Linkage));
|
|
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("WanMiniport %ls WanAdapterCB: 0x%x",
|
|
pWanAdapterCB->MiniportName.Buffer, pWanAdapterCB));
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateWanAdapterCB: Exit"));
|
|
|
|
return(NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
VOID
|
|
NdisWanDestroyWanAdapterCB(
|
|
IN PWAN_ADAPTERCB pWanAdapterCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
NdisWanDestroyWanAdapterCB
|
|
|
|
Routine Description:
|
|
|
|
This routine destroys a WanAdapterCB
|
|
|
|
Arguments:
|
|
|
|
pWanAdapterCB - Pointer to the WanAdapterCB that is being destroyed
|
|
|
|
Return Values:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyWanAdapterCB: Enter - WanAdapterCB: 0x%4.4x", pWanAdapterCB));
|
|
|
|
//
|
|
// Free the memory allocated for the NDIS_STRING
|
|
//
|
|
NdisWanFreeNdisString(&pWanAdapterCB->MiniportName);
|
|
|
|
NdisFreeSpinLock(&pWanAdapter->Lock);
|
|
|
|
//
|
|
// Free the memory allocated for the control block
|
|
//
|
|
NdisWanFreeMemory(pWanAdapterCB);
|
|
|
|
NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyWanAdapterCB: Exit"));
|
|
}
|
|
|
|
VOID
|
|
NdisWanGetProtocolCB(
|
|
OUT PPROTOCOLCB *ProtocolCB,
|
|
IN USHORT usProtocolType,
|
|
IN USHORT usBindingNameLength,
|
|
IN PWSTR BindingName,
|
|
IN ULONG ulBufferLength,
|
|
IN PUCHAR Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
*ProtocolCB = NULL;
|
|
|
|
// NdisAcquireSpinLock(&(FreeProtocolCBList.Lock));
|
|
|
|
//
|
|
// See if there are any ProtocolCB's available on the free list.
|
|
// If there are not we will need to allocate one.
|
|
//
|
|
// if (FreeProtocolCBList.ulCount == 0) {
|
|
|
|
//
|
|
// Create ProtocolCB
|
|
//
|
|
NdisWanCreateProtocolCB(ProtocolCB,
|
|
usProtocolType,
|
|
usBindingNameLength,
|
|
BindingName,
|
|
ulBufferLength,
|
|
Buffer);
|
|
|
|
// } else {
|
|
|
|
//
|
|
// Get the ProtocolCB from the free list
|
|
//
|
|
// *ProtocolCB = (PPROTOCOLCB)RemoveHeadList(&(FreeProtocolCBList.List));
|
|
|
|
// FreeProtocolCBList.ulCount--;
|
|
|
|
// }
|
|
|
|
// NdisReleaseSpinLock(&(FreeProtocolCBList.Lock));
|
|
|
|
// if (*ProtocolCB != NULL) {
|
|
// NdisWanInitProtocolCB(*ProtocolCB,
|
|
// ulBufferLength,
|
|
// Buffer,
|
|
// usProtocolType);
|
|
// }
|
|
|
|
}
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateProtocolCB(
|
|
OUT PPROTOCOLCB *ProtocolCB,
|
|
IN USHORT usProtocolType,
|
|
IN USHORT usBindingNameLength,
|
|
IN PWSTR BindingName,
|
|
IN ULONG ulBufferLength,
|
|
IN PUCHAR Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
NDIS_STATUS_SUCCESS - ProtocolCB was allocated and initialized
|
|
NDIS_STATUS_RESOURCES - Error allocating memory for ProtocolCB
|
|
|
|
--*/
|
|
{
|
|
PPROTOCOLCB LocalProtocolCB = NULL;
|
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
|
ULONG ulAllocationSize = sizeof(PROTOCOLCB) + ulBufferLength;
|
|
PUCHAR AllocatedMemory;
|
|
ULONG i;
|
|
|
|
NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
|
|
|
|
if (AllocatedMemory != NULL) {
|
|
|
|
LocalProtocolCB = (PPROTOCOLCB)AllocatedMemory;
|
|
LocalProtocolCB->ulAllocationSize = ulAllocationSize;
|
|
AllocatedMemory += sizeof(PROTOCOLCB);
|
|
LocalProtocolCB->LineUpInfo = AllocatedMemory;
|
|
|
|
#ifdef BANDWIDTH_ON_DEMAND
|
|
//
|
|
// Initialize the sample table
|
|
//
|
|
LocalProtocolCB->SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
|
|
NdisWanInitWanTime(&LocalProtocolCB->SampleTable.SampleRate, ONE_HUNDRED_MILS);
|
|
NdisWanInitWanTime(&LocalProtocolCB->SampleTable.SamplePeriod, ONE_SECOND);
|
|
#endif
|
|
|
|
//
|
|
// Copy the bindingname
|
|
//
|
|
NdisWanStringToNdisString(&LocalProtocolCB->BindingName, BindingName);
|
|
|
|
//
|
|
// Copy over the protocol info
|
|
//
|
|
LocalProtocolCB->ulLineUpInfoLength = ulBufferLength;
|
|
NdisMoveMemory(LocalProtocolCB->LineUpInfo,
|
|
Buffer,
|
|
ulBufferLength);
|
|
|
|
//
|
|
// Setup the protocol type
|
|
//
|
|
LocalProtocolCB->usProtocolType = usProtocolType;
|
|
|
|
//
|
|
// Get the PPP protocol value for this protocol type
|
|
//
|
|
LocalProtocolCB->usPPPProtocolID = GetPPP_ProtocolID(usProtocolType, PROTOCOL_TYPE);
|
|
|
|
switch (usProtocolType) {
|
|
case PROTOCOL_IP:
|
|
LocalProtocolCB->NonIdleDetectFunc = IpIsDataFrame;
|
|
break;
|
|
case PROTOCOL_IPX:
|
|
LocalProtocolCB->NonIdleDetectFunc = IpxIsDataFrame;
|
|
break;
|
|
case PROTOCOL_NBF:
|
|
LocalProtocolCB->NonIdleDetectFunc = NbfIsDataFrame;
|
|
break;
|
|
default:
|
|
LocalProtocolCB->NonIdleDetectFunc = NULL;
|
|
break;
|
|
}
|
|
|
|
NdisWanGetSystemTime(&LocalProtocolCB->LastRecvNonIdleData);
|
|
|
|
#ifdef BANDWIDTH_ON_DEMAND
|
|
|
|
LocalProtocolCB->SampleTable.ulFirstIndex =
|
|
LocalProtocolCB->SampleTable.ulCurrentIndex = 0;
|
|
NdisZeroMemory(&LocalProtocolCB->SampleTable.SampleArray[0],
|
|
sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
|
|
|
|
#endif // end BANDWIDTH_ON_DEMAND
|
|
|
|
} else {
|
|
|
|
Status = NDIS_STATUS_RESOURCES;
|
|
NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for ProtocolCB, ulAllocationSize: %d",
|
|
ulAllocationSize));
|
|
}
|
|
|
|
*ProtocolCB = LocalProtocolCB;
|
|
|
|
return (Status);
|
|
}
|
|
|
|
//VOID
|
|
//NdisWanInitProtocolCB(
|
|
// IN PPROTOCOLCB ProtocolCB,
|
|
// IN ULONG ulBufferLength,
|
|
// IN PUCHAR Buffer,
|
|
// IN USHORT usProtocolType
|
|
// )
|
|
///*++
|
|
//
|
|
//Routine Name:
|
|
//
|
|
//Routine Description:
|
|
//
|
|
//Arguments:
|
|
//
|
|
//Return Values:
|
|
//
|
|
//--*/
|
|
//{
|
|
// //
|
|
// // Copy over the protocol info
|
|
// //
|
|
// ProtocolCB->ulLineUpInfoLength = ulBufferLength;
|
|
// NdisMoveMemory(ProtocolCB->LineUpInfo,
|
|
// Buffer,
|
|
// ulBufferLength);
|
|
//
|
|
// //
|
|
// // Setup the protocol type
|
|
// //
|
|
// ProtocolCB->usProtocolType = usProtocolType;
|
|
//
|
|
// //
|
|
// // Get the PPP protocol value for this protocol type
|
|
// //
|
|
// ProtocolCB->usPPPProtocolID = GetPPP_ProtocolID(usProtocolType, PROTOCOL_TYPE);
|
|
//
|
|
// ProtocolCB->SampleTable.ulFirstIndex =
|
|
// ProtocolCB->SampleTable.ulCurrentIndex = 0;
|
|
// NdisZeroMemory(&ProtocolCB->SampleTable.SampleArray[0],
|
|
// sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
|
|
//
|
|
//}
|
|
|
|
VOID
|
|
NdisWanReturnProtocolCB(
|
|
IN PPROTOCOLCB ProtocolCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
// NdisAcquireSpinLock(&(FreeProtocolCBList.Lock));
|
|
//
|
|
// if (FreeProtocolCBList.ulCount > FreeProtocolCBList.ulMaxCount) {
|
|
|
|
NdisWanDestroyProtocolCB(ProtocolCB);
|
|
|
|
// } else {
|
|
//
|
|
// InsertTailGlobalList(FreeProtocolCBList, &(ProtocolCB->Linkage));
|
|
//
|
|
// FreeProtocolCBList.ulCount++;
|
|
//
|
|
// }
|
|
//
|
|
// NdisReleaseSpinLock(&(FreeProtocolCBList.Lock));
|
|
}
|
|
|
|
VOID
|
|
NdisWanDestroyProtocolCB(
|
|
IN PPROTOCOLCB ProtocolCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
ASSERT(ProtocolCB->HeadNdisPacketQueue == NULL);
|
|
ASSERT(ProtocolCB->TailNdisPacketQueue == NULL);
|
|
|
|
if (ProtocolCB->DeviceName.Length != 0) {
|
|
NdisWanFreeNdisString(&ProtocolCB->DeviceName);
|
|
}
|
|
|
|
if (ProtocolCB->BindingName.Length != 0) {
|
|
NdisWanFreeNdisString(&ProtocolCB->BindingName);
|
|
}
|
|
|
|
NdisWanFreeMemory(ProtocolCB);
|
|
}
|
|
|
|
VOID
|
|
NdisWanGetLinkCB(
|
|
OUT PLINKCB *LinkCB,
|
|
IN PWAN_ADAPTERCB WanAdapterCB,
|
|
IN ULONG SendWindow
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
NdisWanGetLinkCB
|
|
|
|
Routine Description:
|
|
|
|
This function returns a pointer to a LinkCB. The LinkCB is either retrieved
|
|
from the WanAdapters free list or, if this list is empty, it is allocated.
|
|
|
|
Arguments:
|
|
|
|
*LinkCB - Pointer to the location to store the pointer to the LinkCB
|
|
|
|
WanAdapterCB - Pointer to the WanAdapter control block that this Link is
|
|
associated with
|
|
|
|
Return Values:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// See if we have any free LinkCB's hanging around
|
|
// if not we will allocate one
|
|
//
|
|
NdisAcquireSpinLock(&(WanAdapterCB->Lock));
|
|
|
|
if (IsListEmpty(&(WanAdapterCB->FreeLinkCBList))) {
|
|
|
|
//
|
|
// Create LinkCB
|
|
//
|
|
NdisWanCreateLinkCB(LinkCB);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Get the LinkCB from the free list
|
|
//
|
|
*LinkCB = (PLINKCB)RemoveHeadList(&(WanAdapterCB->FreeLinkCBList));
|
|
}
|
|
|
|
NdisReleaseSpinLock(&(WanAdapterCB->Lock));
|
|
|
|
//
|
|
// Set the new link state
|
|
//
|
|
NdisWanInitLinkCB(LinkCB, WanAdapterCB, SendWindow);
|
|
}
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateLinkCB(
|
|
OUT PLINKCB *LinkCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
|
PLINKCB LocalLinkCB = NULL;
|
|
ULONG ulAllocationSize, n;
|
|
PUCHAR AllocatedMemory = NULL;
|
|
|
|
//
|
|
// Figure out how much we need to allocate
|
|
//
|
|
ulAllocationSize = sizeof(LINKCB);
|
|
|
|
//
|
|
// Allocate the memory for the LinkCB and it's WAN PACKETS
|
|
//
|
|
NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
|
|
|
|
|
|
if (AllocatedMemory != NULL) {
|
|
|
|
//
|
|
// Initialize the control block
|
|
//
|
|
LocalLinkCB = (PLINKCB)AllocatedMemory;
|
|
LocalLinkCB->ulAllocationSize = ulAllocationSize;
|
|
|
|
InitializeListHead(&LocalLinkCB->WanPacketPool);
|
|
NdisWanInitializeSyncEvent(&LocalLinkCB->OutstandingFramesEvent);
|
|
|
|
} else {
|
|
Status = NDIS_STATUS_RESOURCES;
|
|
|
|
NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for LinkCB, AllocationSize: %d",
|
|
ulAllocationSize));
|
|
}
|
|
|
|
*LinkCB = LocalLinkCB;
|
|
|
|
return (Status);
|
|
}
|
|
|
|
VOID
|
|
NdisWanInitLinkCB(
|
|
IN PLINKCB *LinkCB,
|
|
IN PWAN_ADAPTERCB WanAdapterCB,
|
|
IN ULONG SendWindow
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
PLINKCB LocalLinkCB = *LinkCB;
|
|
|
|
if (LocalLinkCB == NULL) {
|
|
return;
|
|
}
|
|
|
|
LocalLinkCB->hLinkContext = NULL;
|
|
LocalLinkCB->ulReferenceCount = 0;
|
|
LocalLinkCB->State = LINK_UP;
|
|
LocalLinkCB->WanAdapterCB = WanAdapterCB;
|
|
LocalLinkCB->OutstandingFrames = 0;
|
|
LocalLinkCB->LastRecvSeqNumber = 0;
|
|
LocalLinkCB->ulBandwidth = 100;
|
|
LocalLinkCB->PacketMemory = NULL;
|
|
LocalLinkCB->PacketMemorySize = 0;
|
|
LocalLinkCB->RecvFragmentsLost = 0;
|
|
|
|
NdisZeroMemory(&LocalLinkCB->LinkInfo, sizeof(WAN_LINK_INFO));
|
|
|
|
LocalLinkCB->LinkInfo.HeaderPadding = WanAdapterCB->WanInfo.HeaderPadding;
|
|
LocalLinkCB->LinkInfo.TailPadding = WanAdapterCB->WanInfo.TailPadding;
|
|
LocalLinkCB->LinkInfo.SendACCM =
|
|
LocalLinkCB->LinkInfo.RecvACCM = WanAdapterCB->WanInfo.DesiredACCM;
|
|
|
|
NdisZeroMemory(&LocalLinkCB->LinkStats, sizeof(WAN_STATS));
|
|
|
|
if (NdisWanAllocateSendResources(LocalLinkCB, SendWindow) != NDIS_STATUS_SUCCESS) {
|
|
//
|
|
// return the linkcb
|
|
//
|
|
NdisWanReturnLinkCB(LocalLinkCB);
|
|
*LinkCB = NULL;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
NdisWanReturnLinkCB(
|
|
PLINKCB LinkCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
PWAN_ADAPTERCB WanAdapterCB = LinkCB->WanAdapterCB;
|
|
|
|
NdisAcquireSpinLock(&(WanAdapterCB->Lock));
|
|
|
|
//
|
|
// Free the wanpacket pool
|
|
//
|
|
NdisWanFreeSendResources(LinkCB);
|
|
|
|
InsertTailList(&WanAdapterCB->FreeLinkCBList, &LinkCB->Linkage);
|
|
|
|
NdisReleaseSpinLock(&(WanAdapterCB->Lock));
|
|
}
|
|
|
|
VOID
|
|
NdisWanDestroyLinkCB(
|
|
IN PLINKCB LinkCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
PWAN_ADAPTERCB WanAdapterCB = LinkCB->WanAdapterCB;
|
|
|
|
//
|
|
// Free the memory allocated for the control block
|
|
//
|
|
NdisWanFreeMemory(LinkCB);
|
|
}
|
|
|
|
NDIS_STATUS
|
|
NdisWanAllocateSendResources(
|
|
IN PLINKCB LinkCB,
|
|
IN ULONG SendWindow
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
NdisWanAllocateSendResources
|
|
|
|
Routine Description:
|
|
|
|
Allocates all resources (SendDescriptors, WanPackets, ...)
|
|
required for sending data. Should be called at line up time.
|
|
|
|
Arguments:
|
|
|
|
LinkCB - Pointer to the linkcb that the send resources will be attached to.
|
|
SendWindow - Maximum number of sends that this link can handle
|
|
|
|
Return Values:
|
|
|
|
NDIS_STATUS_SUCCESS
|
|
NDIS_STATUS_RESOURCES
|
|
|
|
--*/
|
|
{
|
|
PWAN_ADAPTERCB WanAdapterCB = LinkCB->WanAdapterCB;
|
|
ULONG BufferSize, PacketMemorySize, NumberOfPackets, n;
|
|
PUCHAR PacketMemory = NULL;
|
|
PNDIS_WAN_PACKET WanPacket;
|
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
|
|
|
SendWindow = (SendWindow == 0) ?
|
|
WanAdapterCB->WanInfo.MaxTransmit : SendWindow;
|
|
|
|
SendWindow = (SendWindow == 0) ? 1 : SendWindow;
|
|
|
|
//
|
|
// The number of packets that we will create is the send
|
|
// window of this WAN Miniport + 1
|
|
//
|
|
NumberOfPackets = SendWindow + 1;
|
|
|
|
//
|
|
// The size of the buffer that we create is
|
|
//
|
|
BufferSize = WanAdapterCB->WanInfo.MaxFrameSize +
|
|
WanAdapterCB->WanInfo.HeaderPadding +
|
|
WanAdapterCB->WanInfo.TailPadding +
|
|
40 + sizeof(PVOID);
|
|
|
|
//
|
|
// We assume compression is always on so we pad out 12%
|
|
// incase the compressor expands. I don't know where the
|
|
// 12% figure comes from.
|
|
//
|
|
BufferSize += (WanAdapterCB->WanInfo.MaxFrameSize + 7) / 8;
|
|
|
|
//
|
|
// Make sure that the buffer is dword aligned.
|
|
//
|
|
BufferSize &= ~(sizeof(PVOID) - 1);
|
|
|
|
PacketMemorySize = (BufferSize + sizeof(NDIS_WAN_PACKET)) * NumberOfPackets;
|
|
|
|
//
|
|
// Allocate the memory for the wan packet buffer pool
|
|
//
|
|
NdisAllocateMemory(&PacketMemory,
|
|
PacketMemorySize,
|
|
WanAdapterCB->WanInfo.MemoryFlags,
|
|
WanAdapterCB->WanInfo.HighestAcceptableAddress);
|
|
|
|
if (PacketMemory != NULL) {
|
|
|
|
LinkCB->PacketMemory = PacketMemory;
|
|
LinkCB->PacketMemorySize = PacketMemorySize;
|
|
LinkCB->BufferSize = BufferSize;
|
|
|
|
for (n = 0; n < NumberOfPackets; n++) {
|
|
|
|
WanPacket = (PNDIS_WAN_PACKET)PacketMemory;
|
|
PacketMemory += sizeof(NDIS_WAN_PACKET);
|
|
|
|
InsertTailList(&LinkCB->WanPacketPool, &WanPacket->WanPacketQueue);
|
|
LinkCB->ulWanPacketCount++;
|
|
}
|
|
|
|
//
|
|
// Walk the list of newly created packets and fix up startbuffer and
|
|
// endbuffer pointers.
|
|
//
|
|
for (WanPacket = (PNDIS_WAN_PACKET)LinkCB->WanPacketPool.Flink;
|
|
(PVOID)WanPacket != (PVOID)&LinkCB->WanPacketPool;
|
|
WanPacket = (PNDIS_WAN_PACKET)WanPacket->WanPacketQueue.Flink) {
|
|
|
|
//
|
|
// Point to the begining of the data.
|
|
//
|
|
WanPacket->StartBuffer = PacketMemory;
|
|
PacketMemory += BufferSize;
|
|
|
|
//
|
|
// The 5 bytes give us a short buffer at the end and will
|
|
// keep a WAN Miniport from alignment checking if it uses
|
|
// this pointer to 'back copy'
|
|
//
|
|
WanPacket->EndBuffer = PacketMemory - 5;
|
|
}
|
|
|
|
} else {
|
|
Status = NDIS_STATUS_RESOURCES;
|
|
|
|
NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for BufferPool, AllocationSize: %d",
|
|
PacketMemorySize));
|
|
}
|
|
|
|
return (Status);
|
|
}
|
|
|
|
VOID
|
|
NdisWanFreeSendResources(
|
|
IN PLINKCB LinkCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
NdisWanFreeSendResources
|
|
|
|
Routine Description:
|
|
|
|
This routine removes the WanPackets from this linkcb's send list
|
|
and free's the memory allocated for these packets. Should be called
|
|
at linedown time after all outstanding sends have been accounted for.
|
|
|
|
Arguments:
|
|
|
|
LinkCB - Pointer to the linkcb that the resources are being freed from.
|
|
|
|
Return Values:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PNDIS_WAN_PACKET WanPacket;
|
|
PUCHAR PacketMemory;
|
|
ULONG PacketMemorySize, Flags;
|
|
|
|
PacketMemory = LinkCB->PacketMemory;
|
|
PacketMemorySize = LinkCB->PacketMemorySize;
|
|
Flags = LinkCB->WanAdapterCB->WanInfo.MemoryFlags;
|
|
|
|
//
|
|
// Remove the packets from the wan packet pool
|
|
//
|
|
while (!IsListEmpty(&LinkCB->WanPacketPool)) {
|
|
RemoveHeadList(&LinkCB->WanPacketPool);
|
|
LinkCB->ulWanPacketCount--;
|
|
}
|
|
|
|
//
|
|
// Free the block of memory allocated for this send
|
|
//
|
|
if (PacketMemory != NULL) {
|
|
NdisFreeMemory(PacketMemory, PacketMemorySize, Flags);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
NdisWanGetBundleCB(
|
|
OUT PBUNDLECB *BundleCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
NdisAcquireSpinLock(&(FreeBundleCBList.Lock));
|
|
|
|
//
|
|
// See if there are any BundleCB's available on the free list.
|
|
// If there are not we will need to allocate one.
|
|
//
|
|
if (FreeBundleCBList.ulCount == 0) {
|
|
|
|
//
|
|
// Create BundleCB
|
|
//
|
|
NdisWanCreateBundleCB(BundleCB);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Get the BundleCB from the free list
|
|
//
|
|
*BundleCB = (PBUNDLECB)RemoveHeadList(&(FreeBundleCBList.List));
|
|
|
|
FreeBundleCBList.ulCount--;
|
|
|
|
}
|
|
|
|
NdisReleaseSpinLock(&(FreeBundleCBList.Lock));
|
|
|
|
if (*BundleCB != NULL) {
|
|
NdisWanInitBundleCB(*BundleCB);
|
|
}
|
|
}
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateBundleCB(
|
|
OUT PBUNDLECB *BundleCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
|
PBUNDLECB LocalBundleCB = NULL;
|
|
ULONG ulAllocationSize;
|
|
PUCHAR AllocatedMemory = NULL;
|
|
|
|
//
|
|
// Allocation size is the size of the control block plus the size
|
|
// of a table of pointers to protocolcb's that might be routed to
|
|
// this bundle.
|
|
//
|
|
ulAllocationSize = sizeof(BUNDLECB) +
|
|
sizeof(PROTOCOLCB) +
|
|
(sizeof(PPROTOCOLCB) * MAX_PROTOCOLS);
|
|
|
|
NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
|
|
|
|
if (AllocatedMemory != NULL) {
|
|
PWSTR IOName = L"I/O ProtocolCB";
|
|
PPROTOCOLCB ProtocolCB;
|
|
|
|
//
|
|
// This is the bundlecb
|
|
//
|
|
LocalBundleCB = (PBUNDLECB)AllocatedMemory;
|
|
LocalBundleCB->ulAllocationSize = ulAllocationSize;
|
|
AllocatedMemory += sizeof(BUNDLECB);
|
|
|
|
//
|
|
// This is the memory used for the I/O protocolcb
|
|
//
|
|
ProtocolCB = (PPROTOCOLCB)AllocatedMemory;
|
|
AllocatedMemory += sizeof(PROTOCOLCB);
|
|
|
|
//
|
|
// This is the protocolcb table
|
|
//
|
|
(PUCHAR)LocalBundleCB->ProtocolCBTable = (PUCHAR)AllocatedMemory;
|
|
|
|
//
|
|
// Initialize the BundleCB
|
|
//
|
|
|
|
NdisAllocateSpinLock(&LocalBundleCB->Lock);
|
|
InitializeListHead(&LocalBundleCB->LinkCBList);
|
|
InitializeListHead(&LocalBundleCB->SendPacketQueue);
|
|
InitializeListHead(&LocalBundleCB->RecvDescPool);
|
|
InitializeListHead(&LocalBundleCB->RecvDescAssemblyList);
|
|
InitializeListHead(&LocalBundleCB->ProtocolCBList);
|
|
NdisWanInitializeSyncEvent(&LocalBundleCB->OutstandingFramesEvent);
|
|
NdisWanInitializeSyncEvent(&LocalBundleCB->IndicationEvent);
|
|
|
|
#ifdef BANDWIDTH_ON_DEMAND
|
|
LocalBundleCB->UpperBonDInfo.SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
|
|
LocalBundleCB->LowerBonDInfo.SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
|
|
#endif // end of BANDWIDTH_ON_DEMAND
|
|
|
|
//
|
|
// Add the protocolcb to the bundle's table and list
|
|
//
|
|
ProtocolCB->hProtocolHandle = 0;
|
|
ProtocolCB->BundleCB = LocalBundleCB;
|
|
ProtocolCB->HeadNdisPacketQueue =
|
|
ProtocolCB->TailNdisPacketQueue = NULL;
|
|
NdisWanStringToNdisString(&ProtocolCB->DeviceName, IOName);
|
|
|
|
#ifdef BANDWIDTH_ON_DEMAND
|
|
ProtocolCB->SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
|
|
NdisWanInitWanTime(&ProtocolCB->SampleTable.SampleRate, ONE_HUNDRED_MILS);
|
|
NdisWanInitWanTime(&ProtocolCB->SampleTable.SamplePeriod, ONE_SECOND);
|
|
#endif
|
|
|
|
LocalBundleCB->ProtocolCBTable[0] = ProtocolCB;
|
|
InsertHeadList(&LocalBundleCB->ProtocolCBList, &ProtocolCB->Linkage);
|
|
LocalBundleCB->ulNumberOfRoutes = 1;
|
|
|
|
} else {
|
|
|
|
Status = NDIS_STATUS_RESOURCES;
|
|
NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for BundleCB, AllocationSize: %d",
|
|
ulAllocationSize));
|
|
}
|
|
|
|
*BundleCB = LocalBundleCB;
|
|
|
|
return (Status);
|
|
}
|
|
|
|
VOID
|
|
NdisWanInitBundleCB(
|
|
PBUNDLECB BundleCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
PPROTOCOLCB ProtocolCB = BundleCB->ProtocolCBTable[0];
|
|
PRECV_DESC RecvDescHole;
|
|
|
|
#ifdef BANDWIDTH_ON_DEMAND
|
|
PSAMPLE_TABLE SampleTable;
|
|
PBOND_INFO BonDInfo;
|
|
#endif // end of BANDWIDTH_ON_DEMAND
|
|
|
|
BundleCB->State = BUNDLE_UP;
|
|
NdisZeroMemory(&BundleCB->FramingInfo, sizeof(BUNDLE_FRAME_INFO));
|
|
BundleCB->NextLinkToXmit = NULL;
|
|
BundleCB->SendingLinks = 0;
|
|
BundleCB->SendSeqNumber = 0;
|
|
BundleCB->SendSeqMask = 0;
|
|
BundleCB->SendSeqTest = 0;
|
|
BundleCB->Flags = 0;
|
|
NdisZeroMemory(&BundleCB->LineUpInfo, sizeof(BUNDLE_LINE_UP));
|
|
BundleCB->LineUpInfo.ulMaximumTotalSize = MAX_TOTAL_SIZE;
|
|
|
|
//
|
|
// Init the recv hole desc
|
|
//
|
|
BundleCB->RecvSeqMask = 0;
|
|
BundleCB->RecvSeqTest = 0;
|
|
BundleCB->RecvFragmentsLost = 0;
|
|
BundleCB->MinReceivedSeqNumber = 0;
|
|
ASSERT(BundleCB->RecvDescAssemblyList.Flink == BundleCB->RecvDescAssemblyList.Blink);
|
|
NdisWanGetRecvDesc(BundleCB, &RecvDescHole);
|
|
RecvDescHole->SequenceNumber = 0;
|
|
RecvDescHole->Flags = 1;
|
|
BundleCB->RecvDescHole = RecvDescHole;
|
|
InsertHeadList(&BundleCB->RecvDescAssemblyList, &RecvDescHole->Linkage);
|
|
NdisWanGetSystemTime(&BundleCB->LastRecvNonIdleData);
|
|
|
|
ProtocolCB->SendMaskBit = IO_SEND_MASK_BIT;
|
|
|
|
NdisZeroMemory(&BundleCB->SendVJInfo, sizeof(VJ_INFO));
|
|
NdisZeroMemory(&BundleCB->RecvVJInfo, sizeof(VJ_INFO));
|
|
NdisZeroMemory(&BundleCB->SendCompInfo, sizeof(COMPRESS_INFO));
|
|
NdisZeroMemory(&BundleCB->RecvCompInfo, sizeof(COMPRESS_INFO));
|
|
NdisZeroMemory(&BundleCB->SendEncryptInfo,sizeof(ENCRYPTION_INFO));
|
|
NdisZeroMemory(&BundleCB->RecvEncryptInfo,sizeof(ENCRYPTION_INFO));
|
|
|
|
/*
|
|
#ifdef ENCRYPT_128BIT
|
|
BundleCB->SendEncryptInfo.SessionKeyLength =
|
|
BundleCB->RecvEncryptInfo.SessionKeyLength = 16;
|
|
BundleCB->SendCompInfo.MSCompType =
|
|
BundleCB->RecvCompInfo.MSCompType = NDISWAN_ENCRYPTION |
|
|
NDISWAN_40_ENCRYPTION |
|
|
NDISWAN_128_ENCRYPTION |
|
|
NDISWAN_COMPRESSION;
|
|
#else
|
|
BundleCB->SendEncryptInfo.SessionKeyLength =
|
|
BundleCB->RecvEncryptInfo.SessionKeyLength = 8;
|
|
BundleCB->SendCompInfo.MSCompType =
|
|
BundleCB->RecvCompInfo.MSCompType = NDISWAN_ENCRYPTION |
|
|
NDISWAN_40_ENCRYPTION |
|
|
NDISWAN_COMPRESSION;
|
|
#endif
|
|
*/
|
|
BundleCB->SendCompInfo.CompType =
|
|
BundleCB->RecvCompInfo.CompType = COMPTYPE_NONE;
|
|
|
|
ProtocolCB->usProtocolType = PROTOCOL_PRIVATE_IO;
|
|
ProtocolCB->usPPPProtocolID = PPP_PROTOCOL_PRIVATE_IO;
|
|
|
|
BundleCB->SendMask = IO_SEND_MASK_BIT;
|
|
|
|
#ifdef BANDWIDTH_ON_DEMAND
|
|
|
|
ProtocolCB->usPriority = 100;
|
|
ProtocolCB->ulByteQuota = 0xFFFFFFFF;
|
|
ProtocolCB->SampleTable.ulFirstIndex =
|
|
ProtocolCB->SampleTable.ulCurrentIndex = 0;
|
|
NdisZeroMemory(&ProtocolCB->SampleTable.SampleArray[0],
|
|
sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
|
|
|
|
|
|
BonDInfo = &BundleCB->UpperBonDInfo;
|
|
BonDInfo->ulBytesThreshold = 0;
|
|
BonDInfo->State = BonDIdle;
|
|
BonDInfo->usPercentBandwidth = 0xFFFF;
|
|
BonDInfo->ulSecondsInSamplePeriod = 0;
|
|
NdisWanInitWanTime(&BonDInfo->StartTime, 0);
|
|
|
|
SampleTable = &BonDInfo->SampleTable;
|
|
NdisWanInitWanTime(&SampleTable->SampleRate, 0);
|
|
NdisWanInitWanTime(&SampleTable->SamplePeriod, 0);
|
|
SampleTable->ulFirstIndex =
|
|
SampleTable->ulCurrentIndex =
|
|
SampleTable->ulCurrentSampleByteCount = 0;
|
|
|
|
NdisZeroMemory(&SampleTable->SampleArray[0],
|
|
sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
|
|
|
|
BonDInfo = &BundleCB->LowerBonDInfo;
|
|
BonDInfo->ulBytesThreshold = 0;
|
|
BonDInfo->State = BonDIdle;
|
|
BonDInfo->usPercentBandwidth = 0xFFFF;
|
|
BonDInfo->ulSecondsInSamplePeriod = 0;
|
|
NdisWanInitWanTime(&BonDInfo->StartTime, 0);
|
|
SampleTable = &BonDInfo->SampleTable;
|
|
NdisWanInitWanTime(&SampleTable->SampleRate, 0);
|
|
NdisWanInitWanTime(&SampleTable->SamplePeriod, 0);
|
|
SampleTable->ulFirstIndex =
|
|
SampleTable->ulCurrentIndex =
|
|
SampleTable->ulCurrentSampleByteCount = 0;
|
|
|
|
NdisZeroMemory(&SampleTable->SampleArray[0],
|
|
sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
|
|
|
|
#endif // end of BANDWIDTH_ON_DEMAND
|
|
|
|
BundleCB->ulNameLength = 0;
|
|
NdisZeroMemory(&BundleCB->Name, MAX_NAME_LENGTH);
|
|
|
|
NdisZeroMemory(&BundleCB->BundleStats, sizeof(WAN_STATS));
|
|
}
|
|
|
|
VOID
|
|
NdisWanReturnBundleCB(
|
|
IN PBUNDLECB BundleCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
|
|
sl_compress_terminate(&BundleCB->VJCompress);
|
|
|
|
WanDeallocateCCP(BundleCB);
|
|
|
|
FlushRecvDescAssemblyList(BundleCB);
|
|
|
|
FreeRecvDescFreeList(BundleCB);
|
|
|
|
NdisAcquireSpinLock(&(FreeBundleCBList.Lock));
|
|
|
|
if (FreeBundleCBList.ulCount >= FreeBundleCBList.ulMaxCount) {
|
|
|
|
NdisWanDestroyBundleCB(BundleCB);
|
|
|
|
} else {
|
|
InsertTailList(&FreeBundleCBList.List, &(BundleCB->Linkage));
|
|
|
|
FreeBundleCBList.ulCount++;
|
|
}
|
|
|
|
NdisReleaseSpinLock(&(FreeBundleCBList.Lock));
|
|
}
|
|
|
|
VOID
|
|
NdisWanDestroyBundleCB(
|
|
IN PBUNDLECB BundleCB
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
PPROTOCOLCB ProtocolCB = BundleCB->ProtocolCBTable[0];
|
|
|
|
NdisFreeSpinLock(&BundleCB->Lock);
|
|
|
|
NdisWanFreeNdisString(&ProtocolCB->DeviceName);
|
|
|
|
NdisWanFreeMemory(BundleCB);
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreatePPPProtocolTable(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
|
ULONG ulAllocationSize = 0;
|
|
PUCHAR AllocatedMemory;
|
|
|
|
|
|
//
|
|
// Allocate ProtocolLookupTable. This table is used to match protocol values
|
|
// with their corresponding PPP Protocol values. The table size is set to
|
|
// MAX_PROTOCOLS.
|
|
//
|
|
ulAllocationSize = sizeof(PPP_PROTOCOL_TABLE) +
|
|
(sizeof(USHORT) * MAX_PROTOCOLS) +
|
|
(sizeof(USHORT) * MAX_PROTOCOLS);
|
|
|
|
NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
|
|
|
|
if (AllocatedMemory == NULL) {
|
|
NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
|
|
("Failed allocating memory for ProtocolLookupTable! TableSize: %d",
|
|
ulAllocationSize));
|
|
|
|
return (NDIS_STATUS_RESOURCES);
|
|
}
|
|
|
|
PPP_ProtocolTable = (PPPP_PROTOCOL_TABLE)AllocatedMemory;
|
|
|
|
//
|
|
// Save the allocation size
|
|
//
|
|
PPP_ProtocolTable->ulAllocationSize = ulAllocationSize;
|
|
|
|
//
|
|
// Store the array size. This should be read from the registry
|
|
//
|
|
PPP_ProtocolTable->ulArraySize = MAX_PROTOCOLS;
|
|
|
|
NdisAllocateSpinLock(&PPP_ProtocolTable->Lock);
|
|
|
|
//
|
|
// Setup the pointer to the ProtocolValue array
|
|
//
|
|
AllocatedMemory += sizeof(PPP_PROTOCOL_TABLE);
|
|
PPP_ProtocolTable->ProtocolID = (PUSHORT)(AllocatedMemory);
|
|
|
|
//
|
|
// Setup the pointer to the PPPProtocolValue array
|
|
//
|
|
AllocatedMemory += (sizeof(USHORT) * MAX_PROTOCOLS);
|
|
PPP_ProtocolTable->PPPProtocolID = (PUSHORT)(AllocatedMemory);
|
|
|
|
//
|
|
// Insert default values for Netbuei, IP, IPX
|
|
//
|
|
InsertPPP_ProtocolID(PROTOCOL_PRIVATE_IO, PROTOCOL_TYPE);
|
|
InsertPPP_ProtocolID(PPP_PROTOCOL_PRIVATE_IO, PPP_TYPE);
|
|
|
|
InsertPPP_ProtocolID(PROTOCOL_IP, PROTOCOL_TYPE);
|
|
InsertPPP_ProtocolID(PPP_PROTOCOL_IP, PPP_TYPE);
|
|
|
|
InsertPPP_ProtocolID(PROTOCOL_IPX, PROTOCOL_TYPE);
|
|
InsertPPP_ProtocolID(PPP_PROTOCOL_IPX, PPP_TYPE);
|
|
|
|
InsertPPP_ProtocolID(PROTOCOL_NBF, PROTOCOL_TYPE);
|
|
InsertPPP_ProtocolID(PPP_PROTOCOL_NBF, PPP_TYPE);
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
VOID
|
|
NdisWanDestroyPPPProtocolTable(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
NdisFreeSpinLock(&PPP_ProtocolTable->Lock);
|
|
|
|
NdisWanFreeMemory(PPP_ProtocolTable);
|
|
}
|
|
|
|
NDIS_STATUS
|
|
NdisWanCreateConnectionTable(
|
|
ULONG TableSize
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
|
ULONG ulAllocationSize = 0;
|
|
PUCHAR AllocatedMemory;
|
|
PCONNECTION_TABLE NewTable;
|
|
|
|
//
|
|
// Since we skip the first place in the tables we increase the
|
|
// size by one.
|
|
//
|
|
TableSize += 1;
|
|
|
|
//
|
|
// Allocate the Bundle and Link Arrays based on the number of possible connections
|
|
// that we have in the system. This should be grown if we get called
|
|
// to reinitialize and gain new ports.
|
|
//
|
|
ulAllocationSize = sizeof(CONNECTION_TABLE) +
|
|
(sizeof(PBUNDLECB) * TableSize) +
|
|
(sizeof(PLINKCB) * TableSize);
|
|
|
|
NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
|
|
|
|
if (AllocatedMemory == NULL) {
|
|
|
|
NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
|
|
("Failed allocating memory for ConnectionTable! Size: %d, Links: %d",
|
|
ulAllocationSize, TableSize));
|
|
|
|
return (NDIS_STATUS_RESOURCES);
|
|
}
|
|
|
|
NewTable = (PCONNECTION_TABLE)AllocatedMemory;
|
|
|
|
NdisAllocateSpinLock(&NewTable->Lock);
|
|
|
|
//
|
|
// This is the amount of memory we allocated
|
|
//
|
|
NewTable->ulAllocationSize = ulAllocationSize;
|
|
NewTable->ulArraySize = TableSize;
|
|
InitializeListHead(&NewTable->BundleList);
|
|
|
|
//
|
|
// Setup pointer to the linkcb array
|
|
//
|
|
AllocatedMemory += sizeof(CONNECTION_TABLE);
|
|
NewTable->LinkArray = (PLINKCB*)(AllocatedMemory);
|
|
|
|
//
|
|
// Setup the pointer to the bundlecb array
|
|
//
|
|
AllocatedMemory += (sizeof(PLINKCB) * TableSize);
|
|
NewTable->BundleArray = (PBUNDLECB*)(AllocatedMemory);
|
|
|
|
if (ConnectionTable != NULL) {
|
|
//
|
|
// We must be growing the table
|
|
//
|
|
NewTable->ulNumActiveLinks = ConnectionTable->ulNumActiveLinks;
|
|
NewTable->ulNumActiveBundles = ConnectionTable->ulNumActiveBundles;
|
|
|
|
NdisMoveMemory((PUCHAR)NewTable->LinkArray,
|
|
(PUCHAR)ConnectionTable->LinkArray,
|
|
ConnectionTable->ulArraySize * sizeof(PLINKCB));
|
|
|
|
NdisMoveMemory((PUCHAR)NewTable->BundleArray,
|
|
(PUCHAR)ConnectionTable->BundleArray,
|
|
ConnectionTable->ulArraySize * sizeof(PBUNDLECB));
|
|
|
|
while (!IsListEmpty(&ConnectionTable->BundleList)) {
|
|
PBUNDLECB BundleCB;
|
|
|
|
BundleCB = (PBUNDLECB)RemoveHeadList(&ConnectionTable->BundleList);
|
|
InsertTailList(&NewTable->BundleList, &BundleCB->Linkage);
|
|
}
|
|
|
|
NdisWanDestroyConnectionTable();
|
|
}
|
|
|
|
ConnectionTable = NewTable;
|
|
|
|
return (Status);
|
|
}
|
|
|
|
VOID
|
|
NdisWanDestroyConnectionTable(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Values:
|
|
|
|
--*/
|
|
{
|
|
NdisFreeSpinLock(&ConnectionTable->Lock);
|
|
|
|
NdisWanFreeMemory(ConnectionTable);
|
|
}
|
|
|
|
VOID
|
|
NdisWanGetDeferredDesc(
|
|
PADAPTERCB AdapterCB,
|
|
PDEFERRED_DESC *RetDesc
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
if (IsDeferredQueueEmpty(&AdapterCB->FreeDeferredQueue)) {
|
|
PDEFERRED_DESC DeferredDesc;
|
|
NdisWanAllocateMemory(&DeferredDesc, sizeof(DEFERRED_DESC) * 20);
|
|
|
|
if (DeferredDesc != NULL) {
|
|
for (i = 0; i < 20; i++) {
|
|
InsertHeadDeferredQueue(&AdapterCB->FreeDeferredQueue, DeferredDesc);
|
|
(PUCHAR)DeferredDesc += sizeof(DEFERRED_DESC);
|
|
}
|
|
}
|
|
}
|
|
|
|
*RetDesc = RemoveHeadDeferredQueue(&AdapterCB->FreeDeferredQueue);
|
|
|
|
ASSERT(*RetDesc != NULL);
|
|
}
|