summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/odimac
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/odimac
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/odimac')
-rw-r--r--private/ntos/ndis/odimac/keywords.h54
-rw-r--r--private/ntos/ndis/odimac/mlid.c4413
-rw-r--r--private/ntos/ndis/odimac/mlidsft.h814
-rw-r--r--private/ntos/ndis/odimac/odihsm.h418
-rw-r--r--private/ntos/ndis/odimac/umi.c336
5 files changed, 6035 insertions, 0 deletions
diff --git a/private/ntos/ndis/odimac/keywords.h b/private/ntos/ndis/odimac/keywords.h
new file mode 100644
index 000000000..35896713e
--- /dev/null
+++ b/private/ntos/ndis/odimac/keywords.h
@@ -0,0 +1,54 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ keywords.h
+
+Abstract:
+
+ Contains all Ndis2 and Ndis3 mac-specific keywords.
+
+Author:
+
+ Bob Noradki
+
+Environment:
+
+ This driver is expected to work in DOS, OS2 and NT at the equivalent
+ of kernal mode.
+
+ Architecturally, there is an assumption in this driver that we are
+ on a little endian machine.
+
+Notes:
+
+ optional-notes
+
+Revision History:
+
+
+
+--*/
+#ifndef NDIS2
+#define NDIS2 0
+#endif
+
+#if NDIS2
+
+#define IOBASE NDIS_STRING_CONST("IOBASE")
+#define MAXMULTICASTLIST NDIS_STRING_CONST("MAXMULTICAST")
+#define NETADDRESS NDIS_STRING_CONST("NETADDRESS")
+#define INTERRUPT NDIS_STRING_CONST("IRQ")
+#define MEMMAPPEDBASEADDRESS NDIS_STRING_CONST("RAMADDRESS")
+
+#else // NDIS3
+
+#define IOBASE NDIS_STRING_CONST("IoBaseAddress")
+#define MAXMULTICASTLIST NDIS_STRING_CONST("MaximumMulticastList")
+#define NETADDRESS NDIS_STRING_CONST("NetworkAddress")
+#define INTERRUPT NDIS_STRING_CONST("InterruptNumber")
+#define MEMMAPPEDBASEADDRESS NDIS_STRING_CONST("MemoryMappedBaseAddress")
+
+#endif
diff --git a/private/ntos/ndis/odimac/mlid.c b/private/ntos/ndis/odimac/mlid.c
new file mode 100644
index 000000000..67826a8f1
--- /dev/null
+++ b/private/ntos/ndis/odimac/mlid.c
@@ -0,0 +1,4413 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ Mlid.c
+
+Abstract:
+
+ This is the main file for the Western Digital
+ Ethernet controller. This driver conforms to the NDIS 3.1 interface.
+
+Author:
+
+ Sean Selitrennikoff (SeanSe) 15-Jan-1992
+
+Environment:
+
+ Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
+
+Revision History:
+
+
+--*/
+
+#include <ndis.h>
+#include <efilter.h>
+#include <odihsm.h>
+#include <mlidsft.h>
+#include "keywords.h"
+
+#if DBG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+#if DBG
+
+
+#define LOGSIZE 512
+
+extern UCHAR MlidDebugLog[LOGSIZE] = {0};
+extern UINT MlidDebugLogPlace = 0;
+
+
+extern
+VOID
+LOG (UCHAR A) {
+ MlidDebugLog[MlidDebugLogPlace++] = A;
+ MlidDebugLog[(MlidDebugLogPlace + 4) % LOGSIZE] = '\0';
+ if (MlidDebugLogPlace >= LOGSIZE) MlidDebugLogPlace = 0;
+}
+
+
+ULONG MlidDebugFlag= MLID_DEBUG_LOG; // MLID_DEBUG_LOG | MLID_DEBUG_LOUD | MLID_DEBUG_VERY_LOUD;
+
+#define IF_LOG(A) A
+
+#else
+
+#define IF_LOG(A)
+
+#endif
+
+
+//
+// This constant is used for places where NdisAllocateMemory
+// needs to be called and the HighestAcceptableAddress does
+// not matter.
+//
+
+NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
+ NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
+
+
+
+//
+// The global MAC block.
+//
+
+extern MAC_BLOCK MlidMacBlock={0};
+
+
+
+//
+// If you add to this, make sure to add the
+// a case in MlidFillInGlobalData() and in
+// MlidQueryGlobalStatistics() if global
+// information only or
+// MlidQueryProtocolStatistics() if it is
+// protocol queriable information.
+//
+UINT MlidGlobalSupportedOids[] = {
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MAXIMUM_LOOKAHEAD,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_MAC_OPTIONS,
+ OID_GEN_PROTOCOL_OPTIONS,
+ OID_GEN_LINK_SPEED,
+
+/*++
+ These are not available
+
+ OID_GEN_TRANSMIT_BUFFER_SPACE,
+ OID_GEN_RECEIVE_BUFFER_SPACE,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+
+--*/
+
+ OID_GEN_DRIVER_VERSION,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_CURRENT_LOOKAHEAD,
+
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+
+ OID_802_5_PERMANENT_ADDRESS,
+ OID_802_5_CURRENT_ADDRESS,
+ OID_802_5_CURRENT_FUNCTIONAL,
+ OID_802_5_CURRENT_GROUP,
+ OID_802_5_LAST_OPEN_STATUS,
+ OID_802_5_CURRENT_RING_STATUS,
+ OID_802_5_CURRENT_RING_STATE,
+ OID_802_5_LINE_ERRORS,
+ OID_802_5_LOST_FRAMES
+ };
+
+//
+// If you add to this, make sure to add the
+// a case in MlidQueryGlobalStatistics() and in
+// MlidQueryProtocolInformation()
+//
+UINT MlidProtocolSupportedOids[] = {
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MAXIMUM_LOOKAHEAD,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_MAC_OPTIONS,
+ OID_GEN_PROTOCOL_OPTIONS,
+ OID_GEN_LINK_SPEED,
+
+/*++
+ Not available
+
+ OID_GEN_TRANSMIT_BUFFER_SPACE,
+ OID_GEN_RECEIVE_BUFFER_SPACE,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+--*/
+
+ OID_GEN_DRIVER_VERSION,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_CURRENT_LOOKAHEAD,
+
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+
+ OID_802_5_PERMANENT_ADDRESS,
+ OID_802_5_CURRENT_ADDRESS,
+ OID_802_5_CURRENT_FUNCTIONAL,
+ OID_802_5_CURRENT_GROUP,
+ OID_802_5_LAST_OPEN_STATUS,
+ OID_802_5_CURRENT_RING_STATUS,
+ OID_802_5_CURRENT_RING_STATE,
+ OID_802_5_LINE_ERRORS,
+ OID_802_5_LOST_FRAMES
+ };
+
+
+
+
+
+
+
+UINT
+MlidCopyOver(
+ OUT PUCHAR Buf, // destination
+ IN PNDIS_PACKET Packet, // source packet
+ IN UINT Offset, // offset in packet
+ IN UINT Length // number of bytes to copy
+ );
+
+
+
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ("_ITEXT","ICODE")
+ #endif
+#endif
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+
+ This is the transfer address of the driver. It initializes
+ MlidMacBlock and calls NdisInitializeWrapper() and
+ NdisRegisterMac().
+
+Arguments:
+
+Return Value:
+
+ Indicates the success or failure of the initialization.
+
+--*/
+
+{
+ PMAC_BLOCK NewMacP = &MlidMacBlock;
+ NDIS_STATUS Status;
+ NDIS_HANDLE NdisWrapperHandle;
+
+#ifdef NDIS_NT
+ NDIS_STRING MacName = NDIS_STRING_CONST("Smc8000n");
+#endif
+
+#ifdef NDIS_WIN
+ NDIS_STRING MacName = NDIS_STRING_CONST("SMC8000W");
+#endif
+
+ //
+ // Ensure that the MAC_RESERVED structure will fit in the
+ // MacReserved section of a packet.
+ //
+
+ ASSERT(sizeof(MAC_RESERVED) <= sizeof(((PNDIS_PACKET)NULL)->MacReserved));
+
+
+ //
+ // Pass the wrapper a pointer to the device object.
+ //
+
+ NdisInitializeWrapper(&NdisWrapperHandle,
+ DriverObject,
+ RegistryPath,
+ NULL
+ );
+
+ //
+ // Set up the driver object.
+ //
+
+ NewMacP->DriverObject = DriverObject;
+
+ NdisAllocateSpinLock(&NewMacP->SpinLock);
+
+ NewMacP->NdisWrapperHandle = NdisWrapperHandle;
+ NewMacP->Unloading = FALSE;
+ NewMacP->NumAdapters = 0;
+ NewMacP->AdapterQueue = (PMLID_ADAPTER)NULL;
+
+
+ //
+ // Prepare to call NdisRegisterMac.
+ //
+
+ NewMacP->MacCharacteristics.MajorNdisVersion = MLID_NDIS_MAJOR_VERSION;
+ NewMacP->MacCharacteristics.MinorNdisVersion = MLID_NDIS_MINOR_VERSION;
+ NewMacP->MacCharacteristics.Reserved = 0;
+ NewMacP->MacCharacteristics.OpenAdapterHandler = MlidOpenAdapter;
+ NewMacP->MacCharacteristics.CloseAdapterHandler = MlidCloseAdapter;
+ NewMacP->MacCharacteristics.SendHandler = MlidSend;
+ NewMacP->MacCharacteristics.TransferDataHandler = MlidTransferData;
+ NewMacP->MacCharacteristics.ResetHandler = MlidReset;
+ NewMacP->MacCharacteristics.RequestHandler = MlidRequest;
+ NewMacP->MacCharacteristics.QueryGlobalStatisticsHandler =
+ MlidQueryGlobalStatistics;
+ NewMacP->MacCharacteristics.UnloadMacHandler = MlidUnload;
+ NewMacP->MacCharacteristics.AddAdapterHandler = MlidAddAdapter;
+ NewMacP->MacCharacteristics.RemoveAdapterHandler = MlidRemoveAdapter;
+
+ NewMacP->MacCharacteristics.Name = MacName;
+
+ NdisRegisterMac(&Status,
+ &NewMacP->NdisMacHandle,
+ NdisWrapperHandle,
+ (NDIS_HANDLE)&MlidMacBlock,
+ &NewMacP->MacCharacteristics,
+ sizeof(NewMacP->MacCharacteristics));
+
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ //
+ // NdisRegisterMac failed.
+ //
+
+ NdisFreeSpinLock(&NewMacP->SpinLock);
+ NdisTerminateWrapper(NdisWrapperHandle, NULL);
+ IF_LOUD( DbgPrint( "NdisRegisterMac failed with code 0x%x\n", Status );)
+ return Status;
+ }
+
+
+ IF_LOUD( DbgPrint( "NdisRegisterMac succeeded\n" );)
+
+ IF_LOUD( DbgPrint("Adapter Initialization Complete\n");)
+
+ return Status;
+
+}
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ()
+ #endif
+#endif
+
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ("_ITEXT","ICODE")
+ #endif
+#endif
+
+NDIS_STATUS
+MlidAddAdapter(
+ IN NDIS_HANDLE MacMacContext,
+ IN NDIS_HANDLE ConfigurationHandle,
+ IN PNDIS_STRING AdapterName
+ )
+/*++
+Routine Description:
+
+ This is the Mlid MacAddAdapter routine. The system calls this routine
+ to add support for a particular Mlid adapter. This routine extracts
+ configuration information from the configuration data base and registers
+ the adapter with NDIS.
+
+Arguments:
+
+ see NDIS 3.0 spec...
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS - Adapter was successfully added.
+ NDIS_STATUS_FAILURE - Adapter was not added, also MAC deregistered.
+
+--*/
+{
+
+ LM_STATUS LmStatus;
+ NDIS_HANDLE ConfigHandle;
+ PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
+ NDIS_STRING MlidDriverNameStr = NDIS_STRING_CONST("MlidDriverName");
+
+ ULONG ConfigErrorValue = 0;
+ BOOLEAN ConfigError = FALSE;
+
+ PMAC_BLOCK NewMacP = &MlidMacBlock;
+ NDIS_STATUS Status;
+ PMLID_ADAPTER Adapter;
+ NDIS_ADAPTER_INFORMATION AdapterInformation; // needed to register adapter
+
+
+ UNREFERENCED_PARAMETER(MacMacContext);
+
+ NdisOpenConfiguration(
+ &Status,
+ &ConfigHandle,
+ ConfigurationHandle
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ return NDIS_STATUS_FAILURE;
+
+ }
+
+#if i386
+#else
+ ASSERT(0);
+#endif
+
+ //
+ // Read MlidDriverName
+ //
+
+ NdisReadConfiguration(
+ &Status,
+ &ReturnedValue,
+ ConfigHandle,
+ &MlidDriverNameStr,
+ NdisParameterString
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ NdisCloseConfiguration(ConfigHandle);
+
+ return(NDIS_STATUS_FAILURE);
+
+ }
+
+ //
+ // Here we load the image for the MLID, get the configuration and make the
+ // appropriate setup calls
+ //*\\ HERE!
+
+ //
+ // Allocate memory for the adapter block now.
+ //
+
+ Status = NdisAllocateMemory( (PVOID *)&Adapter, sizeof(MLID_ADAPTER), 0, HighestAcceptableMax);
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ ConfigError = TRUE;
+ ConfigErrorValue = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
+
+ }
+
+ NdisZeroMemory(Adapter,sizeof(MLID_ADAPTER));
+
+ //
+ // The adapter is initialized, register it with NDIS.
+ // This must occur before interrupts are enabled since the
+ // InitializeInterrupt routine requires the NdisAdapterHandle
+ //
+
+ //
+ // Set up the AdapterInformation structure; zero it
+ // first in case it is extended later.
+ //
+
+ NdisZeroMemory (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION));
+ AdapterInformation.NumberOfPortDescriptors = 0;
+
+ Status = NdisRegisterAdapter(&Adapter->NdisAdapterHandle,
+ MlidMacBlock.NdisMacHandle,
+ (NDIS_HANDLE)Adapter,
+ ConfigurationHandle,
+ AdapterName,
+ &AdapterInformation
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ //
+ // NdisRegisterAdapter failed.
+ //
+
+ NdisCloseConfiguration(ConfigHandle);
+
+ NdisFreeMemory(Adapter, sizeof(MLID_ADAPTER), 0);
+ return NDIS_STATUS_FAILURE;
+
+ }
+
+
+ if (ConfigError) {
+
+ //
+ // Log Error and exit.
+ //
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ ConfigErrorValue,
+ 1
+ );
+
+ NdisCloseConfiguration(ConfigHandle);
+
+ NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
+
+ NdisFreeMemory(Adapter, sizeof(MLID_ADAPTER), 0);
+
+ return(NDIS_STATUS_FAILURE);
+
+ }
+
+ NdisCloseConfiguration(ConfigHandle);
+
+
+ if (MlidRegisterAdapter(Adapter) != NDIS_STATUS_SUCCESS) {
+
+ //
+ // MlidRegisterAdapter failed.
+ //
+
+ NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
+ NdisFreeMemory(Adapter, sizeof(MLID_ADAPTER), 0);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ IF_LOUD( DbgPrint( "MlidRegisterAdapter succeeded\n" );)
+
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ()
+ #endif
+#endif
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ("_ITEXT","ICODE")
+ #endif
+#endif
+
+NDIS_STATUS
+MlidRegisterAdapter(
+ IN PMLID_ADAPTER Adapter
+ )
+
+/*++
+
+
+Routine Description:
+
+ Called when a new adapter should be registered. It allocates space for
+ the adapter and open blocks, initializes the adapters block, and
+ calls NdisRegisterAdapter().
+
+Arguments:
+
+ Adapter - A pointer to the adapter structure.
+
+Return Value:
+
+ Indicates the success or failure of the registration.
+
+--*/
+
+{
+ UINT i;
+ NDIS_PHYSICAL_ADDRESS PhysicalAddress;
+
+ NDIS_STATUS status; //general purpose return from NDIS calls
+
+ Adapter->OpenQueue = (PMLID_OPEN)NULL;
+
+ //
+ // Allocate the Spin lock.
+ //
+ NdisAllocateSpinLock(&Adapter->Lock);
+
+ Adapter->DeferredDpc = (PVOID)MlidReceiveEvents;
+
+ NdisInitializeTimer(&(Adapter->DeferredTimer),
+ Adapter->DeferredDpc,
+ Adapter);
+
+ //
+ // Link us on to the chain of adapters for this MAC.
+ //
+
+ Adapter->MacBlock = &MlidMacBlock;
+ NdisAcquireSpinLock(&MlidMacBlock.SpinLock);
+ Adapter->NextAdapter = MlidMacBlock.AdapterQueue;
+ MlidMacBlock.AdapterQueue = Adapter;
+ NdisReleaseSpinLock(&MlidMacBlock.SpinLock);
+
+ //
+ // Set up the interrupt handlers.
+ //*\\ HERE!
+
+ KernelInterrupt = (CCHAR)(Adapter->irq_value);
+
+ NdisInitializeInterrupt(&status, // status of call
+ &(Adapter->NdisInterrupt), // interrupt info str
+ Adapter->NdisAdapterHandle,
+ (PNDIS_INTERRUPT_SERVICE) MlidInterruptHandler,
+ Adapter, // context for ISR, DPC
+ (PNDIS_DEFERRED_PROCESSING) MlidInterruptDpc,
+ KernelInterrupt, // int #
+ KernelInterrupt, // IRQL
+ FALSE, // NOT shared
+ (Adapter->bus_type == 0) ?
+ NdisInterruptLatched : // ATBus
+ NdisInterruptLevelSensitive // MCA
+ );
+
+
+ if (status != NDIS_STATUS_SUCCESS) {
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_INTERRUPT_CONNECT,
+ 0
+ );
+
+ goto fail3;
+ }
+
+ IF_LOUD( DbgPrint("Interrupt Connected\n");)
+
+ //
+ // Map the memory mapped portion of the card.
+ //
+ //
+
+ NdisSetPhysicalAddressHigh(PhysicalAddress, 0);
+ NdisSetPhysicalAddressLow(PhysicalAddress, (ULONG)(Adapter->ram_base));
+
+ //
+ // Now Initialize the card.
+ //*\\ HERE!
+
+ Adapter->FilterDB = NULL;
+
+ //
+ // Initialize Filter Database
+ //*\\ HERE!
+
+ if (Adapter->TokenRing) {
+
+ //
+ // token ring
+ //*\\ HERE!
+
+ goto fail6;
+
+ } else {
+
+ if (!EthCreateFilter(MulticastListMax,
+ MlidChangeMulticastAddresses,
+ MlidChangeFilterClasses,
+ MlidCloseAction,
+ Adapter->node_address,
+ &Adapter->Lock,
+ &Adapter->FilterDB
+ )) {
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+ 0
+ );
+
+ status = NDIS_STATUS_FAILURE;
+
+ goto fail6;
+
+ }
+
+ }
+
+ //
+ // Initialize the wake up timer to catch interrupts that
+ // don't complete. It fires continuously
+ // every 5 seconds, and we check if there are any
+ // uncompleted operations from the previous two-second
+ // period.
+ //
+
+ Adapter->WakeUpDpc = (PVOID)MlidWakeUpDpc;
+
+ NdisInitializeTimer(&Adapter->WakeUpTimer,
+ (PVOID)(Adapter->WakeUpDpc),
+ Adapter );
+
+ NdisSetTimer(
+ &Adapter->WakeUpTimer,
+ 5000
+ );
+
+ //
+ // Initialization completed successfully.
+ //
+
+ IF_LOUD( { DbgPrint(" MlidLan: [OK]\n");})
+
+ return NDIS_STATUS_SUCCESS;
+
+
+ //
+ // Code to unwind what has already been set up when a part of
+ // initialization fails, which is jumped into at various
+ // points based on where the failure occured. Jumping to
+ // a higher-numbered failure point will execute the code
+ // for that block and all lower-numbered ones.
+ //
+
+fail6:
+
+ NdisUnmapIoSpace(
+ Adapter->NdisAdapterHandle,
+ Adapter->ram_access,
+ Adapter->ram_size * 1024);
+
+failmap:
+
+ NdisRemoveInterrupt(&(Adapter->NdisInterrupt));
+
+ NdisAcquireSpinLock(&MlidMacBlock.SpinLock);
+
+ //
+ // Take us out of the AdapterQueue.
+ //
+
+ if (MlidMacBlock.AdapterQueue == Adapter) {
+
+ MlidMacBlock.AdapterQueue = Adapter->NextAdapter;
+
+ } else {
+
+ PMLID_ADAPTER TmpAdapter = MlidMacBlock.AdapterQueue;
+
+ while (TmpAdapter->NextAdapter != Adapter) {
+
+ TmpAdapter = TmpAdapter->NextAdapter;
+
+ }
+
+ TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
+ }
+
+ NdisReleaseSpinLock(&MlidMacBlock.SpinLock);
+
+fail3:
+ NdisFreeSpinLock(&Adapter->Lock);
+
+fail1:
+
+ return status;
+}
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ()
+ #endif
+#endif
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ("_ITEXT","ICODE")
+ #endif
+#endif
+
+NDIS_STATUS
+MlidOpenAdapter(
+ OUT PNDIS_STATUS OpenErrorStatus,
+ OUT NDIS_HANDLE * MacBindingHandle,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE NdisBindingContext,
+ IN NDIS_HANDLE MacAdapterContext,
+ IN UINT OpenOptions,
+ IN PSTRING AddressingInformation OPTIONAL
+ )
+
+/*++
+
+Routine Description:
+
+ NDIS function. It initializes the open block and links it in
+ the appropriate lists.
+
+Arguments:
+
+ See NDIS 3.0 spec.
+
+--*/
+
+{
+ PMLID_ADAPTER Adapter = ((PMLID_ADAPTER)MacAdapterContext);
+ PMLID_OPEN NewOpen;
+ NDIS_STATUS Status;
+
+ //
+ // Don't use extended error or OpenOptions for Mlid
+ //
+
+ UNREFERENCED_PARAMETER(OpenOptions);
+
+ *OpenErrorStatus=NDIS_STATUS_SUCCESS;
+
+ IF_LOUD( DbgPrint("In Open Adapter\n");)
+
+ //
+ // Scan the media list for our media type (802.3)
+ //
+
+ *SelectedMediumIndex = (UINT)(-1);
+
+ while (MediumArraySize > 0) {
+
+ if (MediumArray[--MediumArraySize] == NdisMedium802_3 ) {
+
+ *SelectedMediumIndex = MediumArraySize;
+
+ break;
+ }
+ }
+
+
+ if (*SelectedMediumIndex == -1) {
+
+ return NDIS_STATUS_UNSUPPORTED_MEDIA;
+
+ }
+
+ //
+ // Link this open to the appropriate lists.
+ //
+
+ if (Adapter->HardwareFailure) {
+
+ return(NDIS_STATUS_FAILURE);
+
+ }
+
+ //
+ // Allocate memory for the open.
+ //
+
+
+ Status = NdisAllocateMemory((PVOID *)&NewOpen, sizeof(MLID_OPEN), 0, HighestAcceptableMax);
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+ 0
+ );
+
+ return(NDIS_STATUS_RESOURCES);
+
+ }
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ Adapter->References++;
+
+ //
+ // Link this open to the appropriate lists.
+ //
+
+ if (Adapter->OpenQueue == NULL) {
+
+ //
+ // The first open on this adapter.
+ //
+
+ if (LM_Open_Adapter(&(Adapter->LMAdapter)) != SUCCESS) {
+
+ IF_LOUD( DbgPrint("OpenFailed!\n");)
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 0
+ );
+
+ return(NDIS_STATUS_FAILURE);
+
+ }
+
+ IF_LOUD( DbgPrint("OpenSuccess!\n");)
+
+ }
+
+ NewOpen->NextOpen = Adapter->OpenQueue;
+ Adapter->OpenQueue = NewOpen;
+
+ if (Adapter->TokenRing) {
+
+ //*\\ token ring
+
+ } else {
+
+ if (!EthNoteFilterOpenAdapter(
+ Adapter->FilterDB,
+ NewOpen,
+ NdisBindingContext,
+ &NewOpen->NdisFilterHandle
+ )) {
+
+ Adapter->References--;
+
+ Adapter->OpenQueue = NewOpen->NextOpen;
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+ 0
+ );
+
+ return NDIS_STATUS_FAILURE;
+
+
+ }
+
+ }
+
+ //
+ // Set up the open block.
+ //
+
+ NewOpen->Adapter = Adapter;
+ NewOpen->MacBlock = Adapter->MacBlock;
+ NewOpen->NdisBindingContext = NdisBindingContext;
+ NewOpen->AddressingInformation = AddressingInformation;
+ NewOpen->Closing = FALSE;
+ NewOpen->LookAhead = MLID_MAX_LOOKAHEAD;
+ NewOpen->ProtOptionFlags = 0;
+
+ Adapter->MaxLookAhead = MLID_MAX_LOOKAHEAD;
+
+ NewOpen->ReferenceCount = 1;
+
+ *MacBindingHandle = (NDIS_HANDLE)NewOpen;
+
+ MLID_DO_DEFERRED(Adapter);
+
+ IF_LOUD( DbgPrint("Out Open Adapter\n");)
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+#ifdef NDIS_WIN
+ #ifndef DEBUG
+ #pragma code_seg ()
+ #endif
+#endif
+
+
+VOID
+MlidAdjustMaxLookAhead(
+ IN PMLID_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine finds the open with the maximum lookahead value and
+ stores that in the adapter block.
+
+ NOTE: THIS ROUTINE MUST BE CALLED WITH THE SPINLOCK HELD.
+
+Arguments:
+
+ Adapter - A pointer to the adapter block.
+
+Returns:
+
+ None.
+
+--*/
+{
+ ULONG CurrentMax = 0;
+ PMLID_OPEN CurrentOpen;
+
+ CurrentOpen = Adapter->OpenQueue;
+
+ while (CurrentOpen != NULL) {
+
+ if (CurrentOpen->LookAhead > CurrentMax) {
+
+ CurrentMax = CurrentOpen->LookAhead;
+
+ }
+
+ CurrentOpen = CurrentOpen->NextOpen;
+ }
+
+ if (CurrentMax == 0) {
+
+ CurrentMax = MLID_MAX_LOOKAHEAD;
+
+ }
+
+ Adapter->MaxLookAhead = CurrentMax;
+
+}
+
+NDIS_STATUS
+MlidCloseAdapter(
+ IN NDIS_HANDLE MacBindingHandle
+ )
+
+/*++
+
+Routine Description:
+
+ NDIS function. Unlinks the open block and frees it.
+
+Arguments:
+
+ See NDIS 3.0 spec.
+
+--*/
+
+{
+ PMLID_OPEN Open = ((PMLID_OPEN)MacBindingHandle);
+ PMLID_ADAPTER Adapter = Open->Adapter;
+ PMLID_OPEN TmpOpen;
+ NDIS_STATUS StatusToReturn;
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ if (Open->Closing) {
+
+ //
+ // The open is already being closed.
+ //
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ return NDIS_STATUS_CLOSING;
+ }
+
+ Adapter->References++;
+
+ Open->ReferenceCount++;
+
+ //
+ // Remove this open from the list for this adapter.
+ //
+
+ if (Open == Adapter->OpenQueue) {
+
+ Adapter->OpenQueue = Open->NextOpen;
+
+ } else {
+
+ TmpOpen = Adapter->OpenQueue;
+
+ while (TmpOpen->NextOpen != Open) {
+
+ TmpOpen = TmpOpen->NextOpen;
+
+ }
+
+ TmpOpen->NextOpen = Open->NextOpen;
+ }
+
+
+
+ //
+ // Remove from Filter package to block all receives.
+ //
+
+ if (Adapter->TokenRing) {
+
+ //*\\ token ring
+
+ } else {
+
+ StatusToReturn = EthDeleteFilterOpenAdapter(
+ Adapter->FilterDB,
+ Open->NdisFilterHandle,
+ NULL
+ );
+
+ }
+
+
+ //
+ // If the status is successful that merely implies that
+ // we were able to delete the reference to the open binding
+ // from the filtering code. If we have a successful status
+ // at this point we still need to check whether the reference
+ // count to determine whether we can close.
+ //
+ //
+ // The delete filter routine can return a "special" status
+ // that indicates that there is a current NdisIndicateReceive
+ // on this binding. See below.
+ //
+
+ if (StatusToReturn == NDIS_STATUS_SUCCESS) {
+
+ //
+ // Check whether the reference count is two. If
+ // it is then we can get rid of the memory for
+ // this open.
+ //
+ // A count of two indicates one for this routine
+ // and one for the filter which we *know* we can
+ // get rid of.
+ //
+
+ if (Open->ReferenceCount != 2) {
+
+ //
+ // We are not the only reference to the open. Remove
+ // it from the open list and delete the memory.
+ //
+
+
+ Open->Closing = TRUE;
+
+ //
+ // Account for this routines reference to the open
+ // as well as reference because of the original open.
+ //
+
+ Open->ReferenceCount -= 2;
+
+ //
+ // Change the status to indicate that we will
+ // be closing this later.
+ //
+
+ StatusToReturn = NDIS_STATUS_PENDING;
+
+ } else {
+
+ Open->ReferenceCount -= 2;
+
+ }
+
+ } else if (StatusToReturn == NDIS_STATUS_PENDING) {
+
+ Open->Closing = TRUE;
+
+ //
+ // Account for this routines reference to the open
+ // as well as reference because of the original open.
+ //
+
+ Open->ReferenceCount -= 2;
+
+ } else if (StatusToReturn == NDIS_STATUS_CLOSING_INDICATING) {
+
+ //
+ // When we have this status it indicates that the filtering
+ // code was currently doing an NdisIndicateReceive. It
+ // would not be wise to delete the memory for the open at
+ // this point. The filtering code will call our close action
+ // routine upon return from NdisIndicateReceive and that
+ // action routine will decrement the reference count for
+ // the open.
+ //
+
+ Open->Closing = TRUE;
+
+ //
+ // This status is private to the filtering routine. Just
+ // tell the caller the the close is pending.
+ //
+
+ StatusToReturn = NDIS_STATUS_PENDING;
+
+ //
+ // Account for this routines reference to the open.
+ //
+
+ Open->ReferenceCount--;
+
+ } else {
+
+ //
+ // Account for this routines reference to the open.
+ //
+
+ Open->ReferenceCount--;
+
+ }
+
+ //
+ // See if this is the last reference to this open.
+ //
+
+ if (Open->ReferenceCount == 0) {
+
+ //
+ // Check if the MaxLookAhead needs adjustment.
+ //
+
+ if (Open->LookAhead == Adapter->MaxLookAhead) {
+
+ MlidAdjustMaxLookAhead(Adapter);
+
+ }
+
+
+ if (Adapter->OpenQueue == NULL) {
+
+ //
+ // We can disable the card.
+ //
+
+ if (NdisSynchronizeWithInterrupt(
+ &(Adapter->NdisInterrupt),
+ (PVOID)MlidSyncCloseAdapter,
+ (PVOID)(&(Adapter->LMAdapter))
+ ) == FALSE) {
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 0
+ );
+
+ IF_LOUD( DbgPrint("CloseAdapter FAILED!\n");)
+
+ } else {
+
+
+ IF_LOUD( DbgPrint("CloseAdapter Success!\n");)
+
+ }
+
+ }
+
+ } else {
+
+ //
+ // Will get removed when count drops to zero.
+ //
+
+ StatusToReturn = NDIS_STATUS_PENDING;
+
+ }
+
+
+ MLID_DO_DEFERRED(Adapter);
+
+ return(StatusToReturn);
+
+}
+
+NDIS_STATUS
+MlidRequest(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_REQUEST NdisRequest
+ )
+
+/*++
+
+Routine Description:
+
+ This routine allows a protocol to query and set information
+ about the MAC.
+
+Arguments:
+
+ MacBindingHandle - The context value returned by the MAC when the
+ adapter was opened. In reality, it is a pointer to PMLID_OPEN.
+
+ NdisRequest - A structure which contains the request type (Set or
+ Query), an array of operations to perform, and an array for holding
+ the results of the operations.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
+
+ PMLID_OPEN Open = (PMLID_OPEN)(MacBindingHandle);
+ PMLID_ADAPTER Adapter = (Open->Adapter);
+
+
+ IF_LOUD( DbgPrint("In Request\n");)
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ //
+ // Ensure that the open does not close while in this function.
+ //
+
+ Open->ReferenceCount++;
+
+ Adapter->References++;
+
+ //
+ // Process request
+ //
+
+ if (Open->Closing) {
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ StatusToReturn = NDIS_STATUS_CLOSING;
+
+ } else if (NdisRequest->RequestType == NdisRequestQueryInformation) {
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ StatusToReturn = MlidQueryInformation(Adapter, Open, NdisRequest);
+
+ } else if (NdisRequest->RequestType == NdisRequestSetInformation) {
+
+ if (Adapter->HardwareFailure) {
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ StatusToReturn = NDIS_STATUS_FAILURE;
+
+ } else {
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ StatusToReturn = MlidSetInformation(Adapter,Open,NdisRequest);
+
+ }
+
+ } else {
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ StatusToReturn = NDIS_STATUS_NOT_RECOGNIZED;
+
+ }
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ MlidRemoveReference(Open);
+
+ MLID_DO_DEFERRED(Adapter);
+
+ IF_LOUD( DbgPrint("Out Request\n");)
+
+ return(StatusToReturn);
+
+}
+
+NDIS_STATUS
+MlidQueryProtocolInformation(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN NDIS_OID Oid,
+ IN BOOLEAN GlobalMode,
+ IN PVOID InfoBuffer,
+ IN UINT BytesLeft,
+ OUT PUINT BytesNeeded,
+ OUT PUINT BytesWritten
+)
+
+/*++
+
+Routine Description:
+
+ The MlidQueryProtocolInformation process a Query request for
+ NDIS_OIDs that are specific to a binding about the MAC. Note that
+ some of the OIDs that are specific to bindings are also queryable
+ on a global basis. Rather than recreate this code to handle the
+ global queries, I use a flag to indicate if this is a query for the
+ global data or the binding specific data.
+
+Arguments:
+
+ Adapter - a pointer to the adapter.
+
+ Open - a pointer to the open instance.
+
+ Oid - the NDIS_OID to process.
+
+ GlobalMode - Some of the binding specific information is also used
+ when querying global statistics. This is a flag to specify whether
+ to return the global value, or the binding specific value.
+
+ PlaceInInfoBuffer - a pointer into the NdisRequest->InformationBuffer
+ into which store the result of the query.
+
+ BytesLeft - the number of bytes left in the InformationBuffer.
+
+ BytesNeeded - If there is not enough room in the information buffer
+ then this will contain the number of bytes needed to complete the
+ request.
+
+ BytesWritten - a pointer to the number of bytes written into the
+ InformationBuffer.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+ NDIS_MEDIUM Medium = NdisMedium802_3;
+ ULONG GenericULong;
+ USHORT GenericUShort;
+ UCHAR GenericArray[6];
+
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
+
+ //
+ // Common variables for pointing to result of query
+ //
+
+ PVOID MoveSource = (PVOID)(&GenericULong);
+ ULONG MoveBytes = sizeof(ULONG);
+
+ NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
+
+ //
+ // General Algorithm:
+ //
+ // Switch(Request)
+ // Get requested information
+ // Store results in a common variable.
+ // Copy result in common variable to result buffer.
+ //
+
+ //
+ // Make sure that ulong is 4 bytes. Else GenericULong must change
+ // to something of size 4.
+ //
+ ASSERT(sizeof(ULONG) == 4);
+
+
+ IF_LOUD( DbgPrint("In QueryProtocol\n");)
+
+ //
+ // Make sure no changes occur while processing.
+ //
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ //
+ // Switch on request type
+ //
+
+ switch (Oid) {
+
+ case OID_GEN_MAC_OPTIONS:
+
+ GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
+ NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
+ NDIS_MAC_OPTION_NO_LOOPBACK
+ );
+
+ break;
+
+ case OID_GEN_SUPPORTED_LIST:
+
+ if (Adapter->TokenRing) {
+
+ //*\\ token ring
+
+ break;
+ }
+
+ if (!GlobalMode) {
+
+ MoveSource = (PVOID)(MlidProtocolSupportedOids);
+ MoveBytes = sizeof(MlidProtocolSupportedOids);
+
+ } else {
+
+ MoveSource = (PVOID)(MlidGlobalSupportedOids);
+ MoveBytes = sizeof(MlidGlobalSupportedOids);
+
+ }
+ break;
+
+ case OID_GEN_HARDWARE_STATUS:
+
+ if (Adapter->HardwareFailure) {
+
+ HardwareStatus = NdisHardwareStatusNotReady;
+
+ } else {
+
+ HardwareStatus = NdisHardwareStatusReady;
+
+ }
+
+ MoveSource = (PVOID)(&HardwareStatus);
+ MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
+
+ break;
+
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+
+ if (Adapter->TokenRing) {
+
+ Medium = NdisMedium802_5;
+
+ }
+
+ MoveSource = (PVOID) (&Medium);
+ MoveBytes = sizeof(NDIS_MEDIUM);
+ break;
+
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+
+ GenericULong = MLID_MAX_LOOKAHEAD;
+
+ break;
+
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+
+ if (Adapter->TokenRing) {
+
+ GenericULong = Adapter->xmit_buf_size - MLID_HEADER_SIZE;
+
+ } else {
+
+ GenericULong = (ULONG)(MLID_MAX_PACKET_SIZE - MLID_HEADER_SIZE);
+
+ }
+
+ break;
+
+
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+
+ if (Adapter->TokenRing) {
+
+ GenericULong = Adapter->xmit_buf_size;
+
+ } else {
+
+ GenericULong = (ULONG)(MLID_MAX_PACKET_SIZE);
+
+ }
+
+ break;
+
+
+ case OID_GEN_LINK_SPEED:
+
+ if (Adapter->TokenRing) {
+
+ if ((Adapter->media_type & MEDIA_UTP_16) ||
+ (Adapter->media_type & MEDIA_STP_16)) {
+
+ GenericULong = 160000;
+
+ } else {
+
+ GenericULong = 40000;
+
+ }
+
+ } else {
+
+ GenericULong = (ULONG)(100000);
+
+ }
+
+ break;
+
+
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+
+ GenericULong = (ULONG)(Adapter->num_of_tx_buffs
+ * Adapter->xmit_buf_size);
+
+ break;
+
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+
+ GenericULong = (ULONG)((Adapter->ram_size * 1024) -
+ (Adapter->num_of_tx_buffs
+ * Adapter->xmit_buf_size));
+
+ break;
+
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+
+ GenericULong = (ULONG)(Adapter->buffer_page_size);
+
+ break;
+
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+
+ GenericULong = (ULONG)(Adapter->buffer_page_size);
+
+ break;
+
+ case OID_GEN_VENDOR_ID:
+
+ NdisMoveMemory(
+ (PVOID)&GenericULong,
+ Adapter->permanent_node_address,
+ 3
+ );
+ GenericULong &= 0xFFFFFF00;
+ MoveSource = (PVOID)(&GenericULong);
+ MoveBytes = sizeof(GenericULong);
+ break;
+
+ case OID_GEN_VENDOR_DESCRIPTION:
+
+ MoveSource = (PVOID)"SMC Adapter.";
+ MoveBytes = 13;
+
+ break;
+
+ case OID_GEN_DRIVER_VERSION:
+
+ GenericUShort = ((USHORT)MLID_NDIS_MAJOR_VERSION << 8) |
+ MLID_NDIS_MINOR_VERSION;
+
+ MoveSource = (PVOID)(&GenericUShort);
+ MoveBytes = sizeof(GenericUShort);
+ break;
+
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+
+ //*\\ token ring
+
+ break;
+ }
+
+ if (GlobalMode) {
+
+ UINT Filter;
+
+ Filter = ETH_QUERY_FILTER_CLASSES(Adapter->FilterDB);
+
+ GenericULong = (ULONG)(Filter);
+
+ } else {
+
+ UINT Filter = 0;
+
+ Filter = ETH_QUERY_PACKET_FILTER(Adapter->FilterDB,
+ Open->NdisFilterHandle);
+
+ GenericULong = (ULONG)(Filter);
+
+ }
+
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ if ( GlobalMode ) {
+
+ GenericULong = (ULONG)(Adapter->MaxLookAhead);
+
+ } else {
+
+ GenericULong = Open->LookAhead;
+
+ }
+
+ break;
+
+ case OID_802_3_PERMANENT_ADDRESS:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ MLID_MOVE_MEM((PCHAR)GenericArray,
+ Adapter->permanent_node_address,
+ ETH_LENGTH_OF_ADDRESS);
+
+ MoveSource = (PVOID)(GenericArray);
+ MoveBytes = sizeof(Adapter->permanent_node_address);
+ break;
+
+ case OID_802_3_CURRENT_ADDRESS:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ MLID_MOVE_MEM((PCHAR)GenericArray,
+ Adapter->node_address,
+ ETH_LENGTH_OF_ADDRESS);
+
+ MoveSource = (PVOID)(GenericArray);
+ MoveBytes = sizeof(Adapter->node_address);
+ break;
+
+ case OID_802_3_MULTICAST_LIST:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+
+ break;
+ }
+
+ {
+ UINT NumAddresses;
+
+
+ if (GlobalMode) {
+
+ NumAddresses = ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES(Adapter->FilterDB);
+
+ if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > BytesLeft) {
+
+ *BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS);
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ break;
+
+ }
+
+ EthQueryGlobalFilterAddresses(
+ &StatusToReturn,
+ Adapter->FilterDB,
+ BytesLeft,
+ &NumAddresses,
+ InfoBuffer
+ );
+
+ *BytesWritten = NumAddresses * ETH_LENGTH_OF_ADDRESS;
+
+ //
+ // Should not be an error since we held the spinlock
+ // nothing should have changed.
+ //
+
+ ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS);
+
+ } else {
+
+ NumAddresses = EthNumberOfOpenFilterAddresses(
+ Adapter->FilterDB,
+ Open->NdisFilterHandle
+ );
+
+ if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > BytesLeft) {
+
+ *BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS);
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ break;
+
+ }
+
+ EthQueryOpenFilterAddresses(
+ &StatusToReturn,
+ Adapter->FilterDB,
+ Open->NdisFilterHandle,
+ BytesLeft,
+ &NumAddresses,
+ InfoBuffer
+ );
+
+ //
+ // Should not be an error since we held the spinlock
+ // nothing should have changed.
+ //
+
+ ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS);
+
+ *BytesWritten = NumAddresses * ETH_LENGTH_OF_ADDRESS;
+
+ }
+
+ }
+
+
+
+ break;
+
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ GenericULong = (ULONG) (Adapter->MulticastListMax);
+
+ break;
+
+
+
+ default:
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ if ((StatusToReturn == NDIS_STATUS_SUCCESS) &&
+ (Oid != OID_802_3_MULTICAST_LIST)) {
+
+ if (MoveBytes > BytesLeft) {
+
+ //
+ // Not enough room in InformationBuffer. Punt
+ //
+
+ *BytesNeeded = MoveBytes - BytesLeft;
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ } else {
+
+ //
+ // Store result.
+ //
+
+ MLID_MOVE_MEM(InfoBuffer, MoveSource, MoveBytes);
+
+ (*BytesWritten) += MoveBytes;
+
+ }
+ }
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ IF_LOUD( DbgPrint("Out QueryProtocol\n");)
+
+ return(StatusToReturn);
+}
+
+NDIS_STATUS
+MlidQueryInformation(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest
+ )
+/*++
+
+Routine Description:
+
+ The MlidQueryInformation is used by MlidRequest to query information
+ about the MAC.
+
+Arguments:
+
+ Adapter - A pointer to the adapter.
+
+ Open - A pointer to a particular open instance.
+
+ NdisRequest - A structure which contains the request type (Query),
+ an array of operations to perform, and an array for holding
+ the results of the operations.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+
+ UINT BytesWritten = 0;
+ UINT BytesNeeded = 0;
+ UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
+ PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
+
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
+
+
+ IF_LOUD( DbgPrint("In QueryInfor\n");)
+
+ StatusToReturn = MlidQueryProtocolInformation(
+ Adapter,
+ Open,
+ NdisRequest->DATA.QUERY_INFORMATION.Oid,
+ FALSE,
+ InfoBuffer,
+ BytesLeft,
+ &BytesNeeded,
+ &BytesWritten
+ );
+
+
+ NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
+
+ NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
+
+ IF_LOUD( DbgPrint("Out QueryInfor\n");)
+
+ return(StatusToReturn);
+}
+
+NDIS_STATUS
+MlidSetInformation(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest
+ )
+/*++
+
+Routine Description:
+
+ The MlidSetInformation is used by MlidRequest to set information
+ about the MAC.
+
+Arguments:
+
+ Adapter - A pointer to the adapter.
+
+ Open - A pointer to an open instance.
+
+ NdisRequest - A structure which contains the request type (Set),
+ an array of operations to perform, and an array for holding
+ the results of the operations.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+
+ //
+ // General Algorithm:
+ //
+ // Verify length
+ // Switch(Request)
+ // Process Request
+ //
+
+ UINT BytesRead = 0;
+ UINT BytesNeeded = 0;
+ UINT BytesLeft = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
+ PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.SET_INFORMATION.InformationBuffer);
+
+ //
+ // Variables for a particular request
+ //
+
+ NDIS_OID Oid;
+ UINT OidLength;
+
+ //
+ // Variables for holding the new values to be used.
+ //
+
+ ULONG LookAhead;
+ ULONG Filter;
+
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
+
+
+ IF_LOUD( DbgPrint("In SetInfo\n");)
+
+
+
+ //
+ // Get Oid and Length of request
+ //
+
+ Oid = NdisRequest->DATA.SET_INFORMATION.Oid;
+
+ OidLength = BytesLeft;
+
+ switch (Oid) {
+
+
+ case OID_802_3_MULTICAST_LIST:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ //
+ // Verify length
+ //
+
+ if ((OidLength % ETH_LENGTH_OF_ADDRESS) != 0){
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
+
+ break;
+
+ }
+
+ StatusToReturn = MlidSetMulticastAddresses(
+ Adapter,
+ Open,
+ NdisRequest,
+ (UINT)(OidLength / ETH_LENGTH_OF_ADDRESS),
+ (PVOID)InfoBuffer
+ );
+ break;
+
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+
+ if (Adapter->TokenRing) {
+
+ //*\\ token ring
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+
+ //
+ // Verify length
+ //
+
+ if (OidLength != 4 ) {
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
+
+ break;
+
+ }
+
+
+ MLID_MOVE_MEM(&Filter, InfoBuffer, 4);
+
+ //
+ // Verify bits
+ //
+
+ if (Filter & (NDIS_PACKET_TYPE_SOURCE_ROUTING |
+ NDIS_PACKET_TYPE_SMT |
+ NDIS_PACKET_TYPE_MAC_FRAME |
+ NDIS_PACKET_TYPE_FUNCTIONAL |
+ NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
+ NDIS_PACKET_TYPE_GROUP
+ )) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = 4;
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
+
+ break;
+
+ }
+
+ StatusToReturn = MlidSetPacketFilter(Adapter,
+ Open,
+ NdisRequest,
+ Filter
+ );
+
+
+
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ //
+ // Verify length
+ //
+
+ if (OidLength != 4) {
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
+
+ break;
+
+ }
+
+ MLID_MOVE_MEM(&LookAhead, InfoBuffer, 4);
+
+ if (LookAhead <= (MLID_MAX_LOOKAHEAD)) {
+
+ if (LookAhead > Adapter->MaxLookAhead) {
+
+ Adapter->MaxLookAhead = LookAhead;
+
+ Open->LookAhead = LookAhead;
+
+ } else {
+
+ if ((Open->LookAhead == Adapter->MaxLookAhead) &&
+ (LookAhead < Open->LookAhead)) {
+
+ Open->LookAhead = LookAhead;
+
+ MlidAdjustMaxLookAhead(Adapter);
+
+ } else {
+
+ Open->LookAhead = LookAhead;
+
+ }
+
+ }
+
+
+ } else {
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ }
+
+ break;
+
+ case OID_GEN_PROTOCOL_OPTIONS:
+
+ //
+ // Verify length
+ //
+
+ if (OidLength != 4) {
+
+ StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
+
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
+
+ break;
+
+ }
+
+ MLID_MOVE_MEM(&Open->ProtOptionFlags, InfoBuffer, 4);
+ StatusToReturn = NDIS_STATUS_SUCCESS;
+
+ break;
+
+ default:
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
+
+ break;
+
+ }
+
+
+ if (StatusToReturn == NDIS_STATUS_SUCCESS) {
+
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = BytesLeft;
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
+
+ }
+
+
+ IF_LOUD( DbgPrint("Out SetInfo\n");)
+
+ return(StatusToReturn);
+}
+
+
+STATIC
+NDIS_STATUS
+MlidSetPacketFilter(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest,
+ IN UINT PacketFilter
+ )
+
+/*++
+
+Routine Description:
+
+ The MlidSetPacketFilter request allows a protocol to control the types
+ of packets that it receives from the MAC.
+
+Arguments:
+
+ Adapter - A pointer to the adapter structure.
+
+ Open - A pointer to the open block giving the request.
+
+ NdisRequest - The NDIS_REQUEST with the set packet filter command in it.
+
+ PacketFilter - A bit mask that contains flags that correspond to specific
+ classes of received packets. If a particular bit is set in the mask,
+ then packet reception for that class of packet is enabled. If the
+ bit is clear, then packets that fall into that class are not received
+ by the client. A single exception to this rule is that if the promiscuous
+ bit is set, then the client receives all packets on the network, regardless
+ of the state of the other flags.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+ //
+ // Keeps track of the *MAC's* status. The status will only be
+ // reset if the filter change action routine is called.
+ //
+ NDIS_STATUS StatusOfFilterChange = NDIS_STATUS_SUCCESS;
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ IF_LOUD( DbgPrint("In SetFilter\n");)
+
+ if (!Open->Closing) {
+
+ //
+ // Increment the open while it is going through the filtering
+ // routines.
+ //
+
+ Open->ReferenceCount++;
+
+ StatusOfFilterChange = EthFilterAdjust(
+ Adapter->FilterDB,
+ Open->NdisFilterHandle,
+ NdisRequest,
+ PacketFilter,
+ TRUE
+ );
+
+ Open->ReferenceCount--;
+
+ } else {
+
+ StatusOfFilterChange = NDIS_STATUS_CLOSING;
+
+ }
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ IF_LOUD( DbgPrint("Out SetFilter\n");)
+
+ return StatusOfFilterChange;
+}
+
+
+
+
+STATIC
+NDIS_STATUS
+MlidSetMulticastAddresses(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest,
+ IN UINT NumAddresses,
+ IN CHAR AddressList[][ETH_LENGTH_OF_ADDRESS]
+ )
+
+/*++
+
+Routine Description:
+
+ This function calls into the filter package in order to set the
+ multicast address list for the card to the specified list.
+
+Arguments:
+
+ Adapter - A pointer to the adapter block.
+
+ Open - A pointer to the open block submitting the request.
+
+ NdisRequest - The NDIS_REQUEST with the set multicast address list command
+ in it.
+
+ NumAddresses - A count of the number of addresses in the addressList.
+
+ AddressList - An array of multicast addresses that this open instance
+ wishes to accept.
+
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+
+ //
+ // Keeps track of the *MAC's* status. The status will only be
+ // reset if the filter change action routine is called.
+ //
+ NDIS_STATUS StatusOfFilterChange = NDIS_STATUS_SUCCESS;
+
+ IF_LOUD( DbgPrint("In SetMulticast\n");)
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ if (!Open->Closing) {
+
+ //
+ // Increment the open while it is going through the filtering
+ // routines.
+ //
+
+ Open->ReferenceCount++;
+
+ StatusOfFilterChange = EthChangeFilterAddresses(
+ Adapter->FilterDB,
+ Open->NdisFilterHandle,
+ NdisRequest,
+ NumAddresses,
+ AddressList,
+ TRUE
+ );
+ Open->ReferenceCount--;
+
+ } else {
+
+ StatusOfFilterChange = NDIS_STATUS_CLOSING;
+
+ }
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ IF_LOUD( DbgPrint("Out SetMulticast\n");)
+
+ return StatusOfFilterChange;
+}
+
+
+
+NDIS_STATUS
+MlidFillInGlobalData(
+ IN PMLID_ADAPTER Adapter,
+ IN PNDIS_REQUEST NdisRequest
+ )
+
+/*++
+
+Routine Description:
+
+ This routine completes a GlobalStatistics request. It is critical that
+ if information is needed from the Adapter->* fields, they have been
+ updated before this routine is called.
+
+Arguments:
+
+ Adapter - A pointer to the Adapter.
+
+ NdisRequest - A structure which contains the request type (Global
+ Query), an array of operations to perform, and an array for holding
+ the results of the operations.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+{
+ //
+ // General Algorithm:
+ //
+ // Switch(Request)
+ // Get requested information
+ // Store results in a common variable.
+ // default:
+ // Try protocol query information
+ // If that fails, fail query.
+ //
+ // Copy result in common variable to result buffer.
+ // Finish processing
+
+ UINT BytesWritten = 0;
+ UINT BytesNeeded = 0;
+ UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
+ PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
+
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
+
+ //
+ // This variable holds result of query
+ //
+
+ ULONG GenericULong;
+
+ //
+ // Make sure that long is 4 bytes. Else GenericULong must change
+ // to something of size 4.
+ //
+ ASSERT(sizeof(ULONG) == 4);
+
+
+ StatusToReturn = MlidQueryProtocolInformation(
+ Adapter,
+ NULL,
+ NdisRequest->DATA.QUERY_INFORMATION.Oid,
+ TRUE,
+ InfoBuffer,
+ BytesLeft,
+ &BytesNeeded,
+ &BytesWritten
+ );
+
+
+ if (StatusToReturn == NDIS_STATUS_NOT_SUPPORTED) {
+
+ StatusToReturn = NDIS_STATUS_SUCCESS;
+
+ //
+ // Switch on request type
+ //
+
+ switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) {
+
+ case OID_GEN_XMIT_OK:
+
+ GenericULong = (ULONG)(Adapter->FramesXmitGood);
+
+ break;
+
+ case OID_GEN_RCV_OK:
+
+ GenericULong = (ULONG)(Adapter->FramesRcvGood);
+
+ break;
+
+ case OID_GEN_XMIT_ERROR:
+
+ GenericULong = (ULONG)(Adapter->FramesXmitBad);
+
+ break;
+
+ case OID_GEN_RCV_ERROR:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ GenericULong = (ULONG)(Adapter->CrcErrors);
+
+ break;
+
+ case OID_GEN_RCV_NO_BUFFER:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ GenericULong = (ULONG)(Adapter->MissedPackets);
+
+ break;
+
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ GenericULong = (ULONG)(Adapter->FrameAlignmentErrors);
+
+ break;
+
+ case OID_802_3_XMIT_ONE_COLLISION:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ GenericULong = (ULONG)(Adapter->FramesXmitOneCollision);
+
+ break;
+
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ GenericULong = (ULONG)(Adapter->FramesXmitManyCollisions);
+
+ break;
+
+
+ default:
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+
+ break;
+
+ }
+
+
+ //
+ // Check to make sure there is enough room in the
+ // buffer to store the result.
+ //
+
+ if (BytesLeft >= sizeof(ULONG)) {
+
+ //
+ // Store the result.
+ //
+
+ MLID_MOVE_MEM(
+ (PVOID)InfoBuffer,
+ (PVOID)(&GenericULong),
+ sizeof(ULONG)
+ );
+
+ BytesWritten += sizeof(ULONG);
+
+ }
+
+ }
+
+ NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
+
+ NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
+
+ return(StatusToReturn);
+}
+
+NDIS_STATUS
+MlidQueryGlobalStatistics(
+ IN NDIS_HANDLE MacAdapterContext,
+ IN PNDIS_REQUEST NdisRequest
+ )
+
+/*++
+
+Routine Description:
+
+ The MlidQueryGlobalStatistics is used by the protocol to query
+ global information about the MAC.
+
+Arguments:
+
+ MacAdapterContext - The value associated with the adapter that is being
+ opened when the MAC registered the adapter with NdisRegisterAdapter.
+
+ NdisRequest - A structure which contains the request type (Query),
+ an array of operations to perform, and an array for holding
+ the results of the operations.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+
+ //
+ // General Algorithm:
+ //
+ //
+ // Check if a request is going to pend...
+ // If so, pend the entire operation.
+ //
+ // Else
+ // Fill in the request block.
+ //
+ //
+
+ PMLID_ADAPTER Adapter = (PMLID_ADAPTER)(MacAdapterContext);
+
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
+
+ //
+ // Check if a request is valid and going to pend...
+ // If so, pend the entire operation.
+ //
+
+
+ //
+ // Switch on request type
+ //
+
+ switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) {
+ case OID_GEN_SUPPORTED_LIST:
+ case OID_GEN_HARDWARE_STATUS:
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ case OID_GEN_MAC_OPTIONS:
+ case OID_GEN_LINK_SPEED:
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ case OID_GEN_VENDOR_ID:
+ case OID_GEN_VENDOR_DESCRIPTION:
+ case OID_GEN_DRIVER_VERSION:
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ case OID_GEN_XMIT_OK:
+ case OID_GEN_RCV_OK:
+ case OID_GEN_XMIT_ERROR:
+ case OID_GEN_RCV_ERROR:
+
+ break;
+
+ case OID_802_3_PERMANENT_ADDRESS:
+ case OID_802_3_CURRENT_ADDRESS:
+ case OID_GEN_RCV_NO_BUFFER:
+ case OID_802_3_MULTICAST_LIST:
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+ case OID_802_3_XMIT_ONE_COLLISION:
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+
+ if (Adapter->TokenRing) {
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+
+ }
+ break;
+
+ default:
+
+ StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
+
+ break;
+ }
+
+ NdisInterlockedAddUlong(&Adapter->References, 1, &Adapter->Lock);
+
+ if (StatusToReturn == NDIS_STATUS_SUCCESS) {
+
+ StatusToReturn = MlidFillInGlobalData(Adapter, NdisRequest);
+
+ }
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ MLID_DO_DEFERRED(Adapter);
+
+ return(StatusToReturn);
+}
+
+
+VOID
+MlidRemoveAdapter(
+ IN PVOID MacAdapterContext
+ )
+/*++
+
+Routine Description:
+
+ MlidRemoveAdapter removes an adapter previously registered
+ with NdisRegisterAdapter.
+
+Arguments:
+
+ MacAdapterContext - The context value that the MAC passed
+ to NdisRegisterAdapter; actually as pointer to an
+ MLID_ADAPTER.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ PMLID_ADAPTER Adapter;
+ BOOLEAN Canceled;
+
+ Adapter = PMLID_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
+
+ LM_Free_Resources(&Adapter->LMAdapter);
+
+ ASSERT(Adapter->OpenQueue == (PMLID_OPEN)NULL);
+
+ //
+ // There are no opens left, so remove ourselves.
+ //
+
+ NdisCancelTimer(&Adapter->WakeUpTimer, &Canceled);
+
+ if ( !Canceled ) {
+ NdisStallExecution(500000);
+ }
+
+ //
+ // Take us out of the AdapterQueue.
+ //
+
+ NdisAcquireSpinLock(&MlidMacBlock.SpinLock);
+
+ Adapter->Removed = TRUE;
+
+ if (MlidMacBlock.AdapterQueue == Adapter) {
+
+ MlidMacBlock.AdapterQueue = Adapter->NextAdapter;
+
+ } else {
+
+ PMLID_ADAPTER TmpAdaptP = MlidMacBlock.AdapterQueue;
+
+ while (TmpAdaptP->NextAdapter != Adapter) {
+
+ TmpAdaptP = TmpAdaptP->NextAdapter;
+
+ }
+
+ TmpAdaptP->NextAdapter = TmpAdaptP->NextAdapter->NextAdapter;
+ }
+
+ NdisReleaseSpinLock(&MlidMacBlock.SpinLock);
+
+ NdisRemoveInterrupt(&(Adapter->NdisInterrupt));
+
+ NdisUnmapIoSpace(
+ Adapter->NdisAdapterHandle,
+ Adapter->ram_access,
+ Adapter->ram_size * 1024);
+
+ if (Adapter->TokenRing) {
+
+ //*\\ token ring
+
+ } else {
+
+ EthDeleteFilter(Adapter->FilterDB);
+
+ }
+
+ NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
+
+ NdisFreeSpinLock(&Adapter->Lock);
+
+ NdisFreeMemory(Adapter, sizeof(MLID_ADAPTER), 0);
+
+ return;
+}
+
+VOID
+MlidUnload(
+ IN NDIS_HANDLE MacMacContext
+ )
+
+/*++
+
+Routine Description:
+
+ MlidUnload is called when the MAC is to unload itself.
+
+Arguments:
+
+ MacMacContext - actually a pointer to MlidMacBlock.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ NDIS_STATUS InitStatus;
+
+ UNREFERENCED_PARAMETER(MacMacContext);
+
+ NdisDeregisterMac(
+ &InitStatus,
+ MlidMacBlock.NdisMacHandle
+ );
+
+ NdisFreeSpinLock(&MlidMacBlock.SpinLock);
+
+ NdisTerminateWrapper(
+ MlidMacBlock.NdisWrapperHandle,
+ NULL
+ );
+
+ return;
+}
+
+NDIS_STATUS
+MlidSend(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_PACKET Packet
+ )
+/*++
+
+Routine Description:
+
+ NDIS function. Sends a packet on the wire
+
+Arguments:
+
+ See NDIS 3.0 spec.
+
+--*/
+
+{
+ PMLID_OPEN Open = PMLID_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
+ PMLID_ADAPTER Adapter = Open->Adapter;
+ PMAC_RESERVED Reserved = RESERVED(Packet);
+ UINT PacketLength;
+ NDIS_STATUS Status;
+
+
+ //
+ // Check that the packet is not too short or too long.
+ //
+
+ NdisQueryPacket(Packet, NULL, NULL, NULL, &PacketLength);
+
+ if (PacketLength < (ETH_LENGTH_OF_ADDRESS*2) || PacketLength > 1514) {
+
+ return NDIS_STATUS_FAILURE;
+
+ }
+
+
+
+
+ if (Adapter->HardwareFailure) {
+
+ return(NDIS_STATUS_FAILURE);
+
+ }
+
+ if (Adapter->ResetInProgress) {
+
+ return(NDIS_STATUS_RESET_IN_PROGRESS);
+
+ }
+
+ //
+ // Ensure that the open won't close during this function.
+ //
+
+ if (Open->Closing) {
+
+ return NDIS_STATUS_CLOSING;
+
+ }
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ IF_LOG(LOG('s'));
+
+ Open->ReferenceCount++;
+
+ Adapter->References++;
+
+ //
+ // Set up the MacReserved section of the packet.
+ //
+
+ Reserved->Open = Open;
+
+ Reserved->NextPacket = (PNDIS_PACKET)NULL;
+
+
+
+
+ //
+ // Set Reserved->Loopback
+ //
+
+ MlidSetLoopbackFlag(Adapter, Open, Packet);
+
+
+
+
+ IF_LOUD( DbgPrint("Sending a packet for Open 0x%lx\n", Reserved->Open);)
+
+
+ //
+ // We do not Open->ReferenceCount-- because that will be done when
+ // then send completes.
+ //
+
+
+ if (Reserved->Directed) {
+
+ //
+ // Put it directly on loopback queue.
+ //
+
+ IF_VERY_LOUD( DbgPrint("Putting Packet 0x%lx on Loopback queue\n",Packet);)
+
+ IF_LOG(LOG('l'));
+
+ if (Adapter->LoopbackQueue == NULL) {
+
+ Adapter->LoopbackQueue = Adapter->LoopbackQTail = Packet;
+
+ } else {
+
+ RESERVED(Adapter->LoopbackQTail)->NextPacket = Packet;
+
+ Adapter->LoopbackQTail = Packet;
+
+ }
+
+ Status = NDIS_STATUS_PENDING;
+
+ } else {
+
+ //
+ // Put Packet on queue to hit the wire.
+ //
+
+ if (Adapter->XmitQueue != NULL) {
+
+ IF_LOG(LOG('q'));
+
+ RESERVED(Adapter->XmitQTail)->NextPacket = Packet;
+
+ Adapter->XmitQTail = Packet;
+
+ } else {
+
+ PNDIS_PACKET PreviousTail;
+
+ //
+ // We have to assume it will be sent. In case the send completes
+ // before we have time to add it.
+ //
+
+ if (Adapter->PacketsOnCard == NULL) {
+
+ PreviousTail = NULL;
+
+ Adapter->PacketsOnCard = Adapter->PacketsOnCardTail = Packet;
+
+ } else {
+
+ PreviousTail = Adapter->PacketsOnCardTail;
+
+ RESERVED(Adapter->PacketsOnCardTail)->NextPacket = Packet;
+
+ Adapter->PacketsOnCardTail = Packet;
+
+ }
+
+ IF_LOG(LOG('t'));
+
+ if (LM_Send(Packet, &Adapter->LMAdapter) == OUT_OF_RESOURCES) {
+
+ IF_LOG(LOG('Q'));
+
+ //
+ // Remove it from list of packets on card and add it to xmit
+ // queue.
+ //
+
+ if (PreviousTail == NULL) {
+
+ Adapter->PacketsOnCard = Adapter->PacketsOnCardTail = NULL;
+
+ } else {
+
+ Adapter->PacketsOnCardTail = PreviousTail;
+
+ RESERVED(Adapter->PacketsOnCardTail)->NextPacket = NULL;
+
+ }
+
+ Adapter->XmitQueue = Packet;
+
+ Adapter->XmitQTail = Packet;
+
+ }
+
+ }
+
+ Status = NDIS_STATUS_PENDING;
+
+ }
+
+
+ MLID_DO_DEFERRED(Adapter);
+
+ IF_LOG(LOG('S'));
+
+ return Status;
+
+}
+
+UINT
+MlidCompareMemory(
+ IN PUCHAR String1,
+ IN PUCHAR String2,
+ IN UINT Length
+ )
+/*++
+
+Routine Description:
+
+ Determines if two arrays of bytes are equal.
+
+Arguments:
+
+ String1, String2 - the two arrays to check.
+
+ Length - the first length bytes to compare.
+
+Return Value:
+
+ 0 if equal, -1 if not.
+
+--*/
+{
+ UINT i;
+
+ for (i=0; i<Length; i++) {
+ if (String1[i] != String2[i]) {
+ return (UINT)(-1);
+ }
+ }
+ return 0;
+}
+
+
+NDIS_STATUS
+MlidReset(
+ IN NDIS_HANDLE MacBindingHandle
+ )
+
+/*++
+
+Routine Description:
+
+ NDIS function.
+
+Arguments:
+
+ See NDIS 3.0 spec.
+
+--*/
+
+{
+ PMLID_OPEN Open = ((PMLID_OPEN)MacBindingHandle);
+ PMLID_ADAPTER Adapter = Open->Adapter;
+
+
+ if (Open->Closing) {
+
+ return(NDIS_STATUS_CLOSING);
+
+ }
+
+ if (Adapter->ResetRequested) {
+
+ return(NDIS_STATUS_SUCCESS);
+
+ }
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ IF_LOUD( DbgPrint("In MlidReset\n");)
+
+ IF_LOG(LOG('r'));
+
+ //
+ // Ensure that the open does not close while in this function.
+ //
+
+ Open->ReferenceCount++;
+
+ Adapter->References++;
+
+
+ Adapter->ResetRequested = TRUE;
+
+ //
+ // Needed in case the reset pends somewhere along the line.
+ //
+
+ Adapter->ResetOpen = Open;
+
+ MLID_DO_DEFERRED(Adapter);
+
+ IF_LOUD( DbgPrint("Out MlidReset\n");)
+
+ return(NDIS_STATUS_PENDING);
+
+}
+
+STATIC
+NDIS_STATUS
+MlidChangeMulticastAddresses(
+ IN UINT OldFilterCount,
+ IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS],
+ IN UINT NewFilterCount,
+ IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS],
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_REQUEST NdisRequest,
+ IN BOOLEAN Set
+ )
+
+/*++
+
+Routine Description:
+
+ Action routine that will get called when a particular filter
+ class is first used or last cleared.
+
+ NOTE: This routine assumes that it is called with the lock
+ acquired.
+
+Arguments:
+
+
+ OldFilterCount - The number of addresses that used to be on the card.
+
+ OldAddresses - A list of all the addresses that used to be on the card.
+
+ NewFilterCount - The number of addresses that should now be on the card.
+
+ NewAddresses - A list of addresses that should be put on the card.
+
+ MacBindingHandle - The context value returned by the MAC when the
+ adapter was opened. In reality, it is a pointer to MLID_OPEN.
+
+ NdisRequest - The request which submitted the filter change.
+ Must use when completing this request with the NdisCompleteRequest
+ service, if the MAC completes this request asynchronously.
+
+ Set - If true the change resulted from a set, otherwise the
+ change resulted from a open closing.
+
+Return Value:
+
+ None.
+
+
+--*/
+
+{
+
+
+ PMLID_ADAPTER Adapter = PMLID_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
+
+ UNREFERENCED_PARAMETER(Set);
+ UNREFERENCED_PARAMETER(NdisRequest);
+ UNREFERENCED_PARAMETER(OldAddresses);
+ UNREFERENCED_PARAMETER(OldFilterCount);
+
+ if (LM_Set_Multi_Address(NewAddresses, NewFilterCount, &Adapter->LMAdapter)
+ != SUCCESS) {
+
+ return(NDIS_STATUS_FAILURE);
+
+ } else {
+
+ return(NDIS_STATUS_SUCCESS);
+
+ }
+
+}
+
+STATIC
+NDIS_STATUS
+MlidChangeFilterClasses(
+ IN UINT OldFilterClasses,
+ IN UINT NewFilterClasses,
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_REQUEST NdisRequest,
+ IN BOOLEAN Set
+ )
+
+/*++
+
+Routine Description:
+
+ Action routine that will get called when an address is added to
+ the filter that wasn't referenced by any other open binding.
+
+ NOTE: This routine assumes that it is called with the lock
+ acquired.
+
+Arguments:
+
+ OldFilterClasses - A bit mask that is currently on the card telling
+ which packet types to accept.
+
+ NewFilterClasses - A bit mask that should be put on the card telling
+ which packet types to accept.
+
+ MacBindingHandle - The context value returned by the MAC when the
+ adapter was opened. In reality, it is a pointer to MLID_OPEN.
+
+ NdisRequest - The NDIS_REQUEST which submitted the filter change command.
+
+ Set - A flag telling if the command is a result of a close or not.
+
+Return Value:
+
+ Status of the change (successful or pending).
+
+
+--*/
+
+{
+
+ PMLID_ADAPTER Adapter = PMLID_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
+
+ UNREFERENCED_PARAMETER(Set);
+ UNREFERENCED_PARAMETER(OldFilterClasses);
+ UNREFERENCED_PARAMETER(NewFilterClasses);
+ UNREFERENCED_PARAMETER(NdisRequest);
+
+
+ if (LM_Set_Receive_Mask(&(Adapter->LMAdapter)) != SUCCESS) {
+
+ return(NDIS_STATUS_FAILURE);
+
+ } else {
+
+ return(NDIS_STATUS_SUCCESS);
+
+ }
+
+}
+
+STATIC
+VOID
+MlidCloseAction(
+ IN NDIS_HANDLE MacBindingHandle
+ )
+
+/*++
+
+Routine Description:
+
+ Action routine that will get called when a particular binding
+ was closed while it was indicating through NdisIndicateReceive
+
+ All this routine needs to do is to decrement the reference count
+ of the binding.
+
+ NOTE: This routine assumes that it is called with the lock acquired.
+
+Arguments:
+
+ MacBindingHandle - The context value returned by the MAC when the
+ adapter was opened. In reality, it is a pointer to MLID_OPEN.
+
+Return Value:
+
+ None.
+
+
+--*/
+
+{
+
+ PMLID_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->ReferenceCount--;
+
+}
+
+BOOLEAN
+MlidInterruptHandler(
+ IN PVOID ServiceContext
+ )
+
+/*++
+
+Routine Description:
+
+ This is the interrupt handler which is registered with the operating
+ system. Only one interrupt is handled at one time, even if several
+ are pending (i.e. transmit complete and receive).
+
+Arguments:
+
+ ServiceContext - pointer to the adapter object
+
+Return Value:
+
+ TRUE, if the DPC is to be executed, otherwise FALSE.
+
+--*/
+
+{
+ PMLID_ADAPTER Adapter = ((PMLID_ADAPTER)ServiceContext);
+
+ IF_LOUD( DbgPrint("In MlidISR\n");)
+
+ IF_LOG(LOG('i'));
+
+ //
+ // Force the INT signal from the chip low. When the
+ // interrupt is acknowledged interrupts will be unblocked,
+ // which will cause a rising edge on the interrupt line
+ // if there is another interrupt pending on the card.
+ //
+
+ IF_LOUD( DbgPrint( " blocking interrupts\n" );)
+
+ LM_Disable_Adapter(&Adapter->LMAdapter);
+
+ IF_LOG(LOG('I'));
+
+ return(TRUE);
+
+}
+
+VOID
+MlidInterruptDpc(
+ IN PVOID SystemSpecific1,
+ IN PVOID InterruptContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ )
+/*++
+
+Routine Description:
+
+ This is the deffered processing routine for interrupts, it examines the
+ global 'InterruptReg' to determine what deffered processing is necessary
+ and dispatches control to the Rcv and Xmt handlers.
+
+Arguments:
+ SystemSpecific1, SystemSpecific2, SystemSpecific3 - not used
+ InterruptContext - a handle to the adapter block.
+
+Return Value:
+
+ NONE.
+
+--*/
+{
+ PMLID_ADAPTER Adapter = ((PMLID_ADAPTER)InterruptContext);
+ BOOLEAN RequeueRcv = FALSE;
+
+ UNREFERENCED_PARAMETER(SystemSpecific1);
+ UNREFERENCED_PARAMETER(SystemSpecific2);
+ UNREFERENCED_PARAMETER(SystemSpecific3);
+
+ IF_LOG(LOG('d'));
+
+
+ IF_LOUD( DbgPrint("==>IntDpc\n");)
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ if ( Adapter->ProcessingDpc ) {
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+ return;
+ }
+
+ Adapter->ProcessingDpc = TRUE;
+ Adapter->References++;
+
+ do {
+
+ Adapter->WakeUpTimeout = FALSE;
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ RequeueRcv = MlidReceiveEvents(NULL, (PVOID)Adapter, NULL, NULL);
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ MlidTransmitEvents(Adapter);
+
+ //
+ // This causes any transmit that may have caused a tranmitted packet
+ // to loopback and indicate the packet.
+ //
+
+ } while ( (Adapter->LoopbackQueue != (PNDIS_PACKET)NULL) || RequeueRcv);
+
+ Adapter->ProcessingDpc = FALSE;
+
+ //
+ // Reenable interrupts
+ //
+
+ Adapter->InterruptMask = PACKET_RECEIVE_ENABLE |
+ PACKET_TRANSMIT_ENABLE |
+ RECEIVE_ERROR_ENABLE |
+ TRANSMIT_ERROR_ENABLE |
+ OVERWRITE_WARNING_ENABLE |
+ COUNTER_OVERFLOW_ENABLE;
+
+ NdisSynchronizeWithInterrupt(
+ &(Adapter->NdisInterrupt),
+ LM_Enable_Adapter,
+ &Adapter->LMAdapter
+ );
+
+ MLID_DO_DEFERRED(Adapter);
+
+ IF_LOUD( DbgPrint("<==IntDpc\n");)
+
+ IF_LOG(LOG('D'));
+
+}
+
+VOID
+MlidIndicateLoopbackPacket(
+ IN PMLID_ADAPTER Adapter,
+ IN PNDIS_PACKET Packet
+ )
+/*++
+
+Routine Description:
+
+ This routine indicates a packet to the current host.
+
+ NOTE: THIS ROUTINE MUST BE CALLED WITH THE SPINLOCK HELD.
+
+Arguments:
+
+ Adapter - Pointer to the adapter structure.
+
+ Packet - Pointer to the packet to indicate.
+
+Return Value:
+
+ NONE.
+
+--*/
+{
+ UINT IndicateLen;
+ UINT PacketLen;
+
+ //
+ // Store that we are indicating a loopback packet
+ //
+
+ Adapter->IndicatingPacket = Packet;
+ Adapter->IndicatedAPacket = TRUE;
+
+ //
+ // Indicate packet.
+ //
+
+ IF_LOUD( DbgPrint("Indicating loopback packet\n");)
+
+ //
+ // Indicate up to 252 bytes.
+ //
+
+ NdisQueryPacket(Packet, NULL, NULL, NULL, &PacketLen);
+
+ if (PacketLen >= ETH_LENGTH_OF_ADDRESS) {
+
+ IndicateLen = (PacketLen > (Adapter->MaxLookAhead + MLID_HEADER_SIZE) ?
+ (Adapter->MaxLookAhead + MLID_HEADER_SIZE) :
+ PacketLen
+ );
+
+ //
+ // Copy the lookahead data into a contiguous buffer.
+ //
+
+ MlidCopyOver(Adapter->LookAhead,
+ Packet,
+ 0,
+ IndicateLen
+ );
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+
+ //
+ // Indicate packet
+ //
+
+ if (Adapter->TokenRing) {
+
+ //*\\ token ring
+
+ } else {
+
+ if (PacketLen < MLID_HEADER_SIZE) {
+
+ //
+ // Runt packet
+ //
+
+ EthFilterIndicateReceive(
+ Adapter->FilterDB,
+ (NDIS_HANDLE)Adapter,
+ (PCHAR)Adapter->LookAhead,
+ Adapter->LookAhead,
+ PacketLen,
+ NULL,
+ 0,
+ 0
+ );
+
+ } else {
+
+ EthFilterIndicateReceive(
+ Adapter->FilterDB,
+ (NDIS_HANDLE)Adapter,
+ (PCHAR)Adapter->LookAhead,
+ Adapter->LookAhead,
+ MLID_HEADER_SIZE,
+ Adapter->LookAhead + MLID_HEADER_SIZE,
+ IndicateLen - MLID_HEADER_SIZE,
+ PacketLen - MLID_HEADER_SIZE
+ );
+
+ }
+
+ }
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ }
+
+}
+
+BOOLEAN
+MlidReceiveEvents(
+ IN PVOID SystemSpecific1,
+ IN PVOID Context,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ )
+/*++
+
+Routine Description:
+
+ This routine handles all Receive deferred processing, this includes any
+ packets that never went through the XmitQueue and need to be indicated
+ (Loopbacked), and all card events.
+
+Arguments:
+
+ Context - a handle to the adapter block.
+
+Return Value:
+
+ Do we need to requeue this Rcv.
+
+--*/
+{
+
+ PMLID_ADAPTER Adapter = (PMLID_ADAPTER)(Context);
+ PNDIS_PACKET Packet;
+ PMLID_OPEN TmpOpen;
+ NDIS_STATUS Status;
+ BOOLEAN RequeueRcv;
+
+ IF_LOG(LOG('e'));
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ Adapter->References++;
+
+ RequeueRcv = (BOOLEAN)(LM_Service_Receive_Events(&Adapter->LMAdapter) ==
+ REQUEUE_LATER);
+
+ while (Adapter->LoopbackQueue != NULL) {
+
+ //
+ // Take packet off queue.
+ //
+
+ Packet = Adapter->LoopbackQueue;
+
+ if (Packet == Adapter->LoopbackQTail) {
+
+ Adapter->LoopbackQTail = NULL;
+
+ }
+
+ Adapter->LoopbackQueue = RESERVED(Packet)->NextPacket;
+
+ //
+ // Indicate the packet
+ //
+
+ MlidIndicateLoopbackPacket(Adapter,Packet);
+
+
+ //
+ // Complete the packet send.
+ //
+
+ Adapter->FramesXmitGood++;
+
+ //
+ // Save this, since once we complete the send
+ // Reserved is no longer valid.
+ //
+
+ TmpOpen = RESERVED(Packet)->Open;
+
+ IF_VERY_LOUD( DbgPrint("Completing send for packet 0x%x\n",Packet);)
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ NdisCompleteSend(TmpOpen->NdisBindingContext,
+ Packet,
+ NDIS_STATUS_SUCCESS
+ );
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ MlidRemoveReference(TmpOpen);
+
+ }
+
+ //
+ // If any indications done, then
+ //
+ // CompleteIndications();
+ //
+
+ if (Adapter->IndicatedAPacket) {
+
+ Adapter->IndicatedAPacket = FALSE;
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ if (Adapter->TokenRing) {
+
+ //*\\ token ring
+
+ } else {
+
+ EthFilterIndicateReceiveComplete(Adapter->FilterDB);
+
+ }
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ }
+
+
+
+ if ((Adapter->ResetRequested) && (Adapter->References == 1)) {
+
+ PNDIS_PACKET Packet;
+ PMLID_OPEN TmpOpen;
+
+ IF_LOG(LOG('R'));
+
+ IF_VERY_LOUD( DbgPrint("Starting Reset\n");)
+
+ Adapter->ResetInProgress = TRUE;
+
+ NdisSynchronizeWithInterrupt(
+ &(Adapter->NdisInterrupt),
+ LM_Disable_Adapter,
+ &Adapter->LMAdapter
+ );
+
+ //
+ // Indicate Status to all opens
+ //
+
+ IF_VERY_LOUD( DbgPrint("Indicating status\n");)
+
+ TmpOpen = Adapter->OpenQueue;
+
+ while (TmpOpen != (PMLID_OPEN)NULL) {
+
+ AddRefWhileHoldingSpinLock(Adapter, TmpOpen);
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ NdisIndicateStatus(TmpOpen->NdisBindingContext,
+ NDIS_STATUS_RESET_START,
+ NULL,
+ 0
+ );
+
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ MlidRemoveReference(TmpOpen);
+
+ TmpOpen = TmpOpen->NextOpen;
+
+ }
+
+ //
+ // Reset the Card.
+ //
+
+ IF_VERY_LOUD( DbgPrint("Resetting the card\n");)
+
+ if (LM_Initialize_Adapter(&Adapter->LMAdapter) != SUCCESS) {
+
+ Adapter->HardwareFailure = TRUE;
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 0
+ );
+
+ } else {
+
+ Adapter->HardwareFailure = FALSE;
+
+ }
+
+
+
+ //
+ // Put packets that were on the card on to the front of the xmit
+ // queue.
+ //
+
+ if (Adapter->PacketsOnCard != NULL) {
+
+ IF_VERY_LOUD( DbgPrint("Moving Packets On card\n");)
+
+ RESERVED(Adapter->PacketsOnCardTail)->NextPacket = Adapter->XmitQueue;
+
+ Adapter->XmitQueue = Adapter->PacketsOnCard;
+
+ Adapter->PacketsOnCard = Adapter->PacketsOnCardTail = NULL;
+
+ }
+
+
+ //
+ // Put packets on loopback queue on xmit queue
+ //
+
+ if (Adapter->LoopbackQueue != NULL) {
+
+ RESERVED(Adapter->LoopbackQTail)->NextPacket = Adapter->XmitQueue;
+
+ Adapter->XmitQueue = Adapter->LoopbackQueue;
+
+ }
+
+
+ //
+ // Wipe out loopback queue.
+ //
+
+ Adapter->LoopbackQueue = Adapter->LoopbackQTail = (PNDIS_PACKET)NULL;
+
+
+ //
+ // Abort all xmits
+ //
+
+ IF_VERY_LOUD( DbgPrint("Killing Xmits\n");)
+
+ while (Adapter->XmitQueue != NULL) {
+
+ Packet = Adapter->XmitQueue;
+
+ Adapter->XmitQueue = RESERVED(Packet)->NextPacket;
+
+ TmpOpen = RESERVED(Packet)->Open;
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ NdisCompleteSend(TmpOpen->NdisBindingContext,
+ Packet,
+ NDIS_STATUS_REQUEST_ABORTED
+ );
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ MlidRemoveReference(TmpOpen);
+
+ }
+
+ Adapter->XmitQTail = NULL;
+
+ if (!Adapter->HardwareFailure) {
+
+ LM_Open_Adapter(&Adapter->LMAdapter);
+
+ }
+
+ Adapter->ResetInProgress = FALSE;
+
+ IF_VERY_LOUD( DbgPrint("Indicating Done\n");)
+
+ //
+ // Indicate Reset is done
+ //
+
+ //
+ // Indicate Status to all opens
+ //
+
+ IF_VERY_LOUD( DbgPrint("Indicating status\n");)
+
+ TmpOpen = Adapter->OpenQueue;
+
+ while (TmpOpen != (PMLID_OPEN)NULL) {
+
+ AddRefWhileHoldingSpinLock(Adapter, TmpOpen);
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ if (Adapter->HardwareFailure) {
+
+ NdisIndicateStatus(TmpOpen->NdisBindingContext,
+ NDIS_STATUS_CLOSED,
+ NULL,
+ 0
+ );
+
+ }
+
+ Status = (Adapter->HardwareFailure) ?
+ NDIS_STATUS_FAILURE :
+ NDIS_STATUS_SUCCESS;
+
+
+ NdisIndicateStatus(TmpOpen->NdisBindingContext,
+ NDIS_STATUS_RESET_END,
+ &Status,
+ sizeof(Status)
+ );
+
+ NdisIndicateStatusComplete(TmpOpen->NdisBindingContext);
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ MlidRemoveReference(TmpOpen);
+
+ TmpOpen = TmpOpen->NextOpen;
+
+ }
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ NdisCompleteReset(Adapter->ResetOpen->NdisBindingContext,
+ (Adapter->HardwareFailure) ?
+ NDIS_STATUS_FAILURE :
+ NDIS_STATUS_SUCCESS
+ );
+
+ NdisDprAcquireSpinLock(&Adapter->Lock);
+
+ MlidRemoveReference(Adapter->ResetOpen);
+
+ //
+ // Reset the flag
+ //
+
+
+ IF_VERY_LOUD( DbgPrint("Restarting Adapter\n");)
+
+ Adapter->ResetRequested = FALSE;
+
+ LM_Open_Adapter(&Adapter->LMAdapter);
+
+ }
+
+#if DBG
+
+ else if (Adapter->ResetRequested) {
+
+ IF_LOUD( DbgPrint("No reset because count is... 0x%x\n", Adapter->References);)
+
+ }
+
+#endif
+
+ Adapter->References--;
+
+ IF_LOG(LOG('E'));
+
+ NdisDprReleaseSpinLock(&Adapter->Lock);
+
+ return(RequeueRcv);
+
+}
+
+
+VOID
+MlidTransmitEvents(
+ IN PMLID_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine handles all transmit deferred processing.
+
+ NOTE : Called with lock held!!
+
+Arguments:
+
+ Adapter - pointer to the adapter structure.
+
+Return Value:
+
+ NONE.
+
+--*/
+{
+
+ if (Adapter->ResetInProgress) {
+
+ return;
+
+ }
+
+ IF_LOG(LOG('w'));
+
+ LM_Service_Transmit_Events(&Adapter->LMAdapter);
+
+ IF_LOG(LOG('W'));
+
+}
+
+UINT
+MlidCopyOver(
+ OUT PUCHAR Buf, // destination
+ IN PNDIS_PACKET Packet, // source packet
+ IN UINT Offset, // offset in packet
+ IN UINT Length // number of bytes to copy
+ )
+
+/*++
+
+Routine Description:
+
+ Copies bytes from a packet into a buffer. Used to copy data
+ out of a packet during loopback indications.
+
+Arguments:
+
+ Buf - the destination buffer
+ Packet - the source packet
+ Offset - the offset in the packet to start copying at
+ Length - the number of bytes to copy
+
+Return Value:
+
+ The actual number of bytes copied; will be less than Length if
+ the packet length is less than Offset+Length.
+
+--*/
+
+{
+ PNDIS_BUFFER CurBuffer;
+ UINT BytesCopied;
+ PUCHAR BufVA;
+ UINT BufLen;
+ UINT ToCopy;
+ UINT CurOffset;
+
+
+ BytesCopied = 0;
+
+ //
+ // First find a spot Offset bytes into the packet.
+ //
+
+ CurOffset = 0;
+
+ NdisQueryPacket(Packet, NULL, NULL, &CurBuffer, NULL);
+
+ while (CurBuffer != (PNDIS_BUFFER)NULL) {
+
+ NdisQueryBuffer(CurBuffer, (PVOID *)&BufVA, &BufLen);
+
+ if (CurOffset + BufLen > Offset) {
+
+ break;
+
+ }
+
+ CurOffset += BufLen;
+
+ NdisGetNextBuffer(CurBuffer, &CurBuffer);
+
+ }
+
+
+ //
+ // See if the end of the packet has already been passed.
+ //
+
+ if (CurBuffer == (PNDIS_BUFFER)NULL) {
+
+ return 0;
+
+ }
+
+
+ //
+ // Now copy over Length bytes.
+ //
+
+ BufVA += (Offset - CurOffset);
+
+ BufLen -= (Offset - CurOffset);
+
+ for (;;) {
+
+ ToCopy = (BytesCopied+BufLen > Length) ? Length - BytesCopied : BufLen;
+
+ MLID_MOVE_MEM(Buf+BytesCopied, BufVA, ToCopy);
+
+ BytesCopied += ToCopy;
+
+
+ if (BytesCopied == Length) {
+
+ return BytesCopied;
+
+ }
+
+ NdisGetNextBuffer(CurBuffer, &CurBuffer);
+
+ if (CurBuffer == (PNDIS_BUFFER)NULL) {
+
+ break;
+
+ }
+
+ NdisQueryBuffer(CurBuffer, (PVOID *)&BufVA, &BufLen);
+
+ }
+
+ return BytesCopied;
+
+}
+
+
+
+NDIS_STATUS
+MlidTransferData(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer,
+ OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred
+ )
+
+/*++
+
+Routine Description:
+
+ NDIS function.
+
+Arguments:
+
+ see NDIS 3.0 spec.
+
+Notes:
+
+ - The MacReceiveContext will be a pointer to the open block for
+ the packet.
+ - The LoopbackPacket field in the adapter block will be NULL if this
+ is a call for a normal packet, otherwise it will be set to point
+ to the loopback packet.
+
+--*/
+{
+ PMLID_OPEN Open = PMLID_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
+ PMLID_ADAPTER Adapter = Open->Adapter;
+ PNDIS_BUFFER CurrentBuffer;
+ PUCHAR BufferVA;
+ UINT BufferLength, Copied;
+ UINT CurrentOffset;
+
+ UNREFERENCED_PARAMETER(MacReceiveContext);
+
+ ByteOffset += MLID_HEADER_SIZE;
+
+ if (Adapter->IndicatingPacket != NULL) {
+
+ IF_LOUD( DbgPrint("Transferring data for loopback packet\n");)
+
+ //
+ // It is a loopback packet
+ //
+
+ NdisQueryPacket(Packet, NULL, NULL, &CurrentBuffer, NULL);
+
+ CurrentOffset = ByteOffset;
+
+ while (CurrentBuffer != (PNDIS_BUFFER)NULL) {
+
+ NdisQueryBuffer(CurrentBuffer, (PVOID *)&BufferVA, &BufferLength);
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ Copied =
+ MlidCopyOver(BufferVA,
+ Adapter->IndicatingPacket,
+ CurrentOffset,
+ BufferLength
+ );
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ CurrentOffset += Copied;
+
+ if (Copied < BufferLength) {
+
+ break;
+
+ }
+
+ NdisGetNextBuffer(CurrentBuffer, &CurrentBuffer);
+
+ }
+
+ //
+ // We are done, return.
+ //
+
+
+ *BytesTransferred = CurrentOffset - ByteOffset;
+
+ return(NDIS_STATUS_SUCCESS);
+
+ } else if (Adapter->IndicatedAPacket) {
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ IF_LOUD( DbgPrint("Transferring data for card packet\n");)
+
+ if (LM_Receive_Copy(
+ BytesTransferred,
+ BytesToTransfer,
+ ByteOffset,
+ Packet,
+ &(Adapter->LMAdapter)) != SUCCESS) {
+
+ //
+ // Copy failed.
+ //
+
+ *BytesTransferred = 0;
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ return(NDIS_STATUS_FAILURE);
+
+ } else {
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ return(NDIS_STATUS_SUCCESS);
+
+ }
+
+ } else {
+
+ return(NDIS_STATUS_NOT_INDICATING);
+
+ }
+
+}
+
+BOOLEAN
+MlidSyncCloseAdapter(
+ IN PVOID Context
+ )
+/*++
+
+Routine Description:
+
+ This function is used to synchronize with the lower MAC layer close
+ calls that may access the same areas of the LM that are accessed in
+ the ISR.
+
+Arguments:
+
+ see NDIS 3.0 spec.
+
+Notes:
+
+ returns TRUE on success, else FALSE.
+
+--*/
+{
+
+ if (LM_Close_Adapter((Ptr_Adapter_Struc)Context) == SUCCESS) {
+
+ return(TRUE);
+
+ } else {
+
+ return(FALSE);
+
+ }
+
+}
+
+
+VOID
+MlidWakeUpDpc(
+ IN PVOID SystemSpecific1,
+ IN PVOID Context,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ )
+
+/*++
+
+Routine Description:
+
+ This DPC routine is queued every 5 seconds to check on the
+ queues. If an interrupt was not received
+ in the last 5 seconds and there should have been one,
+ then we abort all operations.
+
+Arguments:
+
+ Context - Really a pointer to the adapter.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PMLID_ADAPTER Adapter = (PMLID_ADAPTER)Context;
+ PMLID_OPEN TmpOpen;
+ PNDIS_PACKET TransmitPacket;
+ PMAC_RESERVED Reserved;
+
+ UNREFERENCED_PARAMETER(SystemSpecific1);
+ UNREFERENCED_PARAMETER(SystemSpecific2);
+ UNREFERENCED_PARAMETER(SystemSpecific3);
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ if ((Adapter->WakeUpTimeout) &&
+ ((Adapter->PacketsOnCard != NULL) ||
+ (Adapter->XmitQueue != NULL))) {
+
+ //
+ // We had a pending operation the last time we ran,
+ // and it has not been completed...we need to complete
+ // it now.
+
+ Adapter->WakeUpTimeout = FALSE;
+
+ Adapter->HardwareFailure = TRUE;
+
+ if (Adapter->WakeUpErrorCount < 10) {
+
+ Adapter->WakeUpErrorCount++;
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 0
+ );
+
+ }
+
+ while (Adapter->PacketsOnCard != NULL) {
+
+ TransmitPacket = Adapter->PacketsOnCard;
+
+ Reserved = RESERVED(TransmitPacket);
+
+ Adapter->PacketsOnCard = Reserved->NextPacket;
+
+ if (Adapter->PacketsOnCard == NULL) {
+
+ Adapter->PacketsOnCardTail = NULL;
+
+ }
+
+ TmpOpen = Reserved->Open;
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ NdisCompleteSend(
+ TmpOpen->NdisBindingContext,
+ TransmitPacket,
+ NDIS_STATUS_SUCCESS
+ );
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ TmpOpen->ReferenceCount--;
+
+ }
+
+ while (Adapter->XmitQueue != NULL) {
+
+ TransmitPacket = Adapter->XmitQueue;
+
+ Reserved = RESERVED(TransmitPacket);
+
+ //
+ // Remove the packet from the queue.
+ //
+
+ Adapter->XmitQueue = Reserved->NextPacket;
+
+ if (Adapter->XmitQueue == NULL) {
+
+ Adapter->XmitQTail = NULL;
+
+ }
+
+ TmpOpen = Reserved->Open;
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ NdisCompleteSend(
+ TmpOpen->NdisBindingContext,
+ TransmitPacket,
+ NDIS_STATUS_SUCCESS
+ );
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ TmpOpen->ReferenceCount--;
+
+ }
+
+ Adapter->WakeUpTimeout = FALSE;
+
+ //
+ // reinitialize the card
+ //
+
+ if (LM_Initialize_Adapter(&Adapter->LMAdapter) != SUCCESS) {
+
+ Adapter->HardwareFailure = TRUE;
+
+ NdisWriteErrorLogEntry(
+ Adapter->NdisAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 0
+ );
+
+ } else {
+
+ Adapter->HardwareFailure = FALSE;
+
+ }
+
+ //
+ // reenable interrupts
+ //
+
+ LM_Enable_Adapter(&Adapter->LMAdapter);
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ } else {
+
+ if ((Adapter->PacketsOnCard != NULL) ||
+ (Adapter->XmitQueue != NULL)) {
+
+ Adapter->WakeUpTimeout = TRUE;
+
+ }
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+
+ }
+
+ //
+ // Fire off another Dpc to execute after 5 seconds
+ //
+
+ NdisSetTimer(
+ &Adapter->WakeUpTimer,
+ 5000
+ );
+
+}
+
+
+
diff --git a/private/ntos/ndis/odimac/mlidsft.h b/private/ntos/ndis/odimac/mlidsft.h
new file mode 100644
index 000000000..f705b1357
--- /dev/null
+++ b/private/ntos/ndis/odimac/mlidsft.h
@@ -0,0 +1,814 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ MLIDsft.h
+
+Abstract:
+
+ The main header for an Western Digital MAC driver.
+
+Author:
+
+ Anthony V. Ercolano (tonye) creation-date 19-Jun-1990 (Driver Model)
+
+ Sean Selitrennikoff (seanse) original MLID code.
+
+Environment:
+
+ This driver is expected to work in DOS, OS2 and NT at the equivalent
+ of kernal mode.
+
+ Architecturally, there is an assumption in this driver that we are
+ on a little endian machine.
+
+Notes:
+
+ optional-notes
+
+Revision History:
+
+
+--*/
+
+#ifndef _MLIDSFT_
+#define _MLIDSFT_
+
+#define MLID_NDIS_MAJOR_VERSION 3
+#define MLID_NDIS_MINOR_VERSION 0
+
+//
+// This macro is used along with the flags to selectively
+// turn on debugging.
+//
+
+#if DBG
+
+#define IF_MLIDDEBUG(f) if (MlidDebugFlag & (f))
+
+extern ULONG MlidDebugFlag;
+
+#define MLID_DEBUG_LOUD 0x00000001 // debugging info
+#define MLID_DEBUG_VERY_LOUD 0x00000002 // excessive debugging info
+#define MLID_DEBUG_LOG 0x00000004 // enable MLIDLog
+#define MLID_DEBUG_CHECK_DUP_SENDS 0x00000008 // check for duplicate sends
+#define MLID_DEBUG_TRACK_PACKET_LENS 0x00000010 // track directed packet lens
+#define MLID_DEBUG_WORKAROUND1 0x00000020 // drop DFR/DIS packets
+#define MLID_DEBUG_CARD_BAD 0x00000040 // dump data if CARD_BAD
+#define MLID_DEBUG_CARD_TESTS 0x00000080 // print reason for failing
+
+
+
+//
+// Macro for deciding whether to dump lots of debugging information.
+//
+
+#define IF_LOUD(A) IF_MLIDDEBUG( MLID_DEBUG_LOUD ) { A }
+#define IF_VERY_LOUD(A) IF_MLIDDEBUG( MLID_DEBUG_VERY_LOUD ) { A }
+
+#else
+
+#define IF_LOUD(A)
+#define IF_VERY_LOUD(A)
+
+#endif
+
+
+//
+// Macros for services that differ between DOS and NT, we may consider adding these
+// into the NDIS spec.
+//
+
+
+//
+// controls the number of transmit buffers on the packet.
+// Choices are 1 or 2.
+//
+
+#define DEFAULT_NUMBUFFERS 2
+
+
+//
+// Macros for moving memory around
+//
+
+#define MLID_MOVE_MEM(dest,src,size) NdisMoveMemory(dest,src,size)
+#define MLID_MOVE_MEM_TO_SHARED_RAM(dest,src,size) NdisMoveToMappedMemory(dest,src,size)
+#define MLID_MOVE_SHARED_RAM_TO_MEM(dest,src,size) NdisMoveFromMappedMemory(dest,src,size)
+
+#define MLID_MOVE_DWORD_TO_SHARED_RAM(dest,src) NdisWriteRegisterUlong((PULONG)(dest),(ULONG)(src))
+#define MLID_MOVE_SHARED_RAM_TO_DWORD(dest,src) NdisReadRegisterUlong((PULONG)(src),(PULONG)(dest))
+
+#define MLID_MOVE_UCHAR_TO_SHARED_RAM(dest,src) NdisWriteRegisterUchar((PUCHAR)(dest),(UCHAR)(src))
+#define MLID_MOVE_SHARED_RAM_TO_UCHAR(dest,src) NdisReadRegisterUchar((PUCHAR)(src),(PUCHAR)(dest))
+
+#define MLID_MOVE_USHORT_TO_SHARED_RAM(dest,src) NdisWriteRegisterUshort((PUSHORT)(dest),(USHORT)(src))
+#define MLID_MOVE_SHARED_RAM_TO_USHORT(dest,src) NdisReadRegisterUshort((PUSHORT)(src),(PUSHORT)(dest))
+
+
+//
+// Only have one of these structures.
+//
+
+typedef struct _MAC_BLOCK {
+
+ //
+ // NDIS wrapper information.
+ //
+
+ NDIS_HANDLE NdisMacHandle; // returned from NdisRegisterMac
+ NDIS_HANDLE NdisWrapperHandle; // returned from NdisInitializeWrapper
+ NDIS_MAC_CHARACTERISTICS MacCharacteristics;
+
+ //
+ // Adapters registered for this MAC.
+ //
+
+ UINT NumAdapters;
+ struct _MLID_ADAPTER * AdapterQueue;
+ NDIS_SPIN_LOCK SpinLock; // guards NumAdapter and AdapterQueue
+
+ //
+ // driver object.
+ //
+
+ PDRIVER_OBJECT DriverObject;
+
+ BOOLEAN Unloading;
+
+} MAC_BLOCK, * PMAC_BLOCK;
+
+
+
+
+
+
+//
+// One of these structures per adapter registered.
+//
+
+typedef struct _MLID_ADAPTER {
+
+ //
+ // Adapter structure for LMI.
+ // This must occur first in the adapter structure.
+ //
+
+ Adapter_Struc LMAdapter;
+
+ //
+ // Spin lock for adapter structure
+ //
+ NDIS_SPIN_LOCK Lock;
+
+
+ //
+ // Links with our MAC.
+ //
+
+ PMAC_BLOCK MacBlock;
+ struct _MLID_ADAPTER * NextAdapter; // used by MacBlock->OpenQueue
+
+ //
+ // Opens for this adapter.
+ //
+
+ struct _MLID_OPEN * OpenQueue;
+
+
+ //
+ // Number of references to the adapter.
+ //
+ ULONG References;
+
+ UINT MulticastListMax;
+
+ //
+ // Transmit queue.
+ //
+
+ PNDIS_PACKET XmitQueue; // packets waiting to be transmitted
+ PNDIS_PACKET XmitQTail;
+
+ PNDIS_PACKET PacketsOnCard; // List of packets that the card is
+ // is currently transmitting
+ PNDIS_PACKET PacketsOnCardTail;
+
+ //
+ // Loopback queue;
+ //
+
+ PNDIS_PACKET LoopbackQueue; // directed packets waiting to be received
+ PNDIS_PACKET LoopbackQTail;
+ PNDIS_PACKET IndicatingPacket;
+ BOOLEAN IndicatedAPacket;
+
+ //
+ // These are for the current packet being indicated.
+ //
+
+ UCHAR PacketHeader[4]; // the NIC appended header
+ UINT PacketLen; // the overall length of the packet
+
+
+
+ //
+ // Statistics used by Set/QueryInformation.
+ //
+
+ ULONG FramesXmitGood; // Good Frames Transmitted
+ ULONG FramesRcvGood; // Good Frames Received
+
+ ULONG FramesXmitBad; // Bad Frames Transmitted
+ ULONG FramesXmitOneCollision; // Frames Transmitted with one collision
+ ULONG FramesXmitManyCollisions; // Frames Transmitted with > 1 collision
+ ULONG FramesXmitDeferred; // Frames where xmit was deferred
+ ULONG FramesXmitOverWrite; // Frames where xmit was overwritten
+ ULONG FramesXmitHeartbeat; // Frames lost heartbeat
+ ULONG FramesXmitUnderruns; // Frames where FIFO underran
+
+ ULONG FrameAlignmentErrors; // FAE errors counted
+ ULONG CrcErrors; // CRC errors counted
+ ULONG MissedPackets; // missed packet counted
+ ULONG TooBig; // received packets too large counted
+ ULONG Overruns; // received packets with FIFO overrun
+
+ ULONG CongestionCount;
+ ULONG FCSErrors;
+ ULONG BurstErrors;
+ ULONG ACErrors;
+ ULONG AbortDelimiters;
+ ULONG FailedReturns;
+ ULONG FramesCopied;
+ ULONG FrequencyErrors;
+ ULONG MonitorCount;
+ ULONG DMAUnderruns;
+
+ //
+ // Reset information.
+ //
+
+ BOOLEAN HardwareFailure; // Did the hardware fail in some way
+ BOOLEAN ResetRequested; // TRUE if a reset is needed
+ BOOLEAN ResetInProgress; // TRUE if a reset is in progress
+ struct _MLID_OPEN * ResetOpen; // who called MLIDReset
+
+ UINT ByteToWrite; // temp storage
+
+
+ //
+ // Look Ahead information.
+ //
+
+ ULONG MaxLookAhead;
+
+
+ //
+ // Handling deferred events
+ //
+
+ NDIS_TIMER DeferredTimer;
+ PVOID DeferredDpc;
+
+ BOOLEAN ReceiveEventsQueued;
+ BOOLEAN TransmitEventsQueued;
+
+ BOOLEAN Removed;
+
+ //
+ // For handling missing interrupts (caused by user mis-configs)
+ //
+
+ PVOID WakeUpDpc;
+ NDIS_TIMER WakeUpTimer;
+ BOOLEAN WakeUpTimeout;
+ UCHAR WakeUpErrorCount;
+ BOOLEAN ProcessingDpc;
+
+} MLID_ADAPTER, * PMLID_ADAPTER;
+
+
+
+
+//
+// Given a MacBindingHandle this macro returns a pointer to the
+// MLID_ADAPTER.
+//
+#define PMLID_ADAPTER_FROM_BINDING_HANDLE(Handle) \
+ (((PMLID_OPEN)(Handle))->Adapter)
+
+//
+// Given a MacContextHandle return the PMLID_ADAPTER
+// it represents.
+//
+#define PMLID_ADAPTER_FROM_CONTEXT_HANDLE(Handle) \
+ ((PMLID_ADAPTER)(Handle))
+
+//
+// Given a pointer to a MLID_ADAPTER return the
+// proper MacContextHandle.
+//
+#define CONTEXT_HANDLE_FROM_PMLID_ADAPTER(Ptr) \
+ ((NDIS_HANDLE)(Ptr))
+
+
+//
+// Given a pointer to a MLID_ADAPTER, return the
+// pointer to the LMAdapter.
+//
+#define Ptr_Adapter_Struc_FROM_PMLID_ADAPTER(P)\
+ (&((P)->LMAdapter))
+
+//
+// Given a pointer to a LMAdapter, return the
+// pointer to the MLID_ADAPTER.
+//
+#define PMLID_ADAPTER_FROM_Ptr_Adapter_Struc(P)\
+ ((PMLID_ADAPTER)(P))
+
+
+
+
+//
+// Macros to extract high and low bytes of a word.
+//
+
+#define MSB(Value) ((UCHAR)(((Value) >> 8) & 0xff))
+#define LSB(Value) ((UCHAR)((Value) & 0xff))
+
+
+//
+// One of these per open on an adapter.
+//
+
+typedef struct _MLID_OPEN {
+
+ //
+ // NDIS wrapper information.
+ //
+
+ NDIS_HANDLE NdisBindingContext; // passed to MacOpenAdapter
+ PSTRING AddressingInformation; // not used currently
+
+ //
+ // Links to our adapter.
+ //
+
+ PMLID_ADAPTER Adapter;
+ struct _MLID_OPEN * NextOpen;
+
+ //
+ // Links to our MAC.
+ //
+
+ PMAC_BLOCK MacBlock; // faster than using AdapterBlock->MacBlock
+
+
+ //
+ // Handle of this adapter in the filter database.
+ //
+ NDIS_HANDLE NdisFilterHandle;
+
+ //
+ // Indication information
+ //
+
+ UINT LookAhead;
+
+ //
+ // Reset/Close information.
+ //
+
+ UINT ReferenceCount; // number of reasons this open can't close
+ BOOLEAN Closing; // is a close pending
+
+ NDIS_REQUEST CloseFilterRequest; // Holds Requests for pending close op
+ NDIS_REQUEST CloseAddressRequest;// Holds Requests for pending close op
+
+ UINT ProtOptionFlags;
+
+} MLID_OPEN, * PMLID_OPEN;
+
+
+//
+// This macro returns a pointer to a PMLID_OPEN given a MacBindingHandle.
+//
+#define PMLID_OPEN_FROM_BINDING_HANDLE(Handle) \
+ ((PMLID_OPEN)(Handle))
+
+//
+// This macro returns a NDIS_HANDLE from a PMLID_OPEN
+//
+#define BINDING_HANDLE_FROM_PMLID_OPEN(Open) \
+ ((NDIS_HANDLE)(Open))
+
+
+
+
+
+//
+// What we map into the reserved section of a packet.
+// Cannot be more than 16 bytes (see ASSERT in MLID.c).
+//
+
+typedef struct _MAC_RESERVED {
+ PNDIS_PACKET NextPacket; // used to link in the queues (4 bytes)
+ PMLID_OPEN Open; // open that called MLIDSend (4 bytes)
+ BOOLEAN Loopback; // is this a loopback packet (1 byte)
+ BOOLEAN Directed; // is this a directed packet (1 byte)
+} MAC_RESERVED, * PMAC_RESERVED;
+
+
+//
+// These appear in the status field of MAC_RESERVED; they are
+// used because there is not enough room for a full NDIS_HANDLE.
+//
+
+#define RESERVED_SUCCESS ((USHORT)0)
+#define RESERVED_FAILURE ((USHORT)1)
+
+
+//
+// Retrieve the MAC_RESERVED structure from a packet.
+//
+
+#define RESERVED(Packet) ((PMAC_RESERVED)((Packet)->MacReserved))
+
+
+//
+// This macro will act a "epilogue" to every routine in the
+// *interface*. It will check whether any requests need
+// to defer their processing. It will also decrement the reference
+// count on the adapter. If the reference count is zero and there
+// is deferred work to do it will insert the interrupt processing
+// routine in the DPC queue.
+//
+// Note that we don't need to include checking for blocked receives
+// since blocked receives imply that there will eventually be an
+// interrupt.
+//
+// NOTE: This macro assumes that it is called with the lock acquired.
+//
+//
+#define MLID_DO_DEFERRED(Adapter) \
+{ \
+ PMLID_ADAPTER _A = (Adapter); \
+ _A->References--; \
+ if ((!_A->References) && \
+ ((_A->ResetRequested && (!_A->ReceiveEventsQueued)) || \
+ ((_A->LoopbackQueue != NULL) && (!_A->ReceiveEventsQueued)))) \
+ {\
+ _A->ReceiveEventsQueued = TRUE; \
+ NdisReleaseSpinLock(&_A->Lock); \
+ NdisSetTimer(&_A->DeferredTimer, 0);\
+ } else { \
+ NdisReleaseSpinLock(&_A->Lock); \
+ } \
+}
+
+
+
+
+//
+// Declarations for functions in MLID.c.
+//
+
+NDIS_STATUS
+MlidRegisterAdapter(
+ IN PMLID_ADAPTER Adapter,
+ IN UINT NumBuffers,
+ IN UINT MulticastListMax,
+ IN UCHAR NodeAddress[ETH_LENGTH_OF_ADDRESS]
+ );
+
+
+BOOLEAN
+MlidInterruptHandler(
+ IN PVOID ServiceContext // will be a pointer to the adapter block
+ );
+
+VOID
+MlidInterruptDpc(
+ IN PVOID SystemSpecific1,
+ IN PVOID InterruptContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ );
+
+NDIS_STATUS
+MlidOpenAdapter(
+ OUT PNDIS_STATUS OpenErrorStatus,
+ OUT NDIS_HANDLE * MacBindingHandle,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE NdisBindingContext,
+ IN NDIS_HANDLE MacAdapterContext,
+ IN UINT OpenOptions,
+ IN PSTRING AddressingInformation OPTIONAL
+ );
+
+
+NDIS_STATUS
+MlidCloseAdapter(
+ IN NDIS_HANDLE MacBindingHandle
+ );
+
+
+BOOLEAN
+MlidAddReference(
+ IN PMLID_OPEN OpenP
+ );
+
+
+#define MlidRemoveReference(_Open) \
+{ \
+ PMLID_ADAPTER _Adapter = _Open->Adapter; \
+ PMLID_OPEN _TmpOpen = _Open; \
+ --_TmpOpen->ReferenceCount; \
+ if (_TmpOpen->ReferenceCount == 0) { \
+ if (_TmpOpen == _Adapter->OpenQueue) { \
+ _Adapter->OpenQueue = _TmpOpen->NextOpen; \
+ } else { \
+ _TmpOpen = _Adapter->OpenQueue; \
+ while (_TmpOpen->NextOpen != _Open) { \
+ _TmpOpen = _TmpOpen->NextOpen; \
+ } \
+ _TmpOpen->NextOpen = _Open->NextOpen; \
+ _TmpOpen = _Open; \
+ } \
+ if (_TmpOpen->LookAhead == _Adapter->MaxLookAhead) {\
+ MlidAdjustMaxLookAhead(_Adapter); \
+ } \
+ NdisReleaseSpinLock(&_Adapter->Lock); \
+ NdisCompleteCloseAdapter (_TmpOpen->NdisBindingContext, NDIS_STATUS_SUCCESS); \
+ NdisFreeMemory(_TmpOpen, sizeof(MLID_OPEN), 0); \
+ NdisAcquireSpinLock(&_Adapter->Lock); \
+ if (_Adapter->OpenQueue == NULL) { \
+ NdisSynchronizeWithInterrupt( \
+ &(_Adapter->LMAdapter.NdisInterrupt), \
+ (PVOID)MlidSyncCloseAdapter, \
+ (PVOID)(&(_Adapter->LMAdapter)) \
+ ); \
+ } \
+ } \
+}
+
+VOID
+MlidAdjustMaxLookAhead(
+ IN PMLID_ADAPTER Adapter
+ );
+
+NDIS_STATUS
+MlidReset(
+ IN NDIS_HANDLE MacBindingHandle
+ );
+
+NDIS_STATUS
+MlidRequest(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_REQUEST NdisRequest
+ );
+
+NDIS_STATUS
+MlidQueryInformation(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest
+ );
+
+NDIS_STATUS
+MlidSetInformation(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest
+ );
+
+NDIS_STATUS
+MlidSetMulticastAddresses(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest,
+ IN UINT NumAddresses,
+ IN CHAR AddressList[][ETH_LENGTH_OF_ADDRESS]
+ );
+
+NDIS_STATUS
+MlidSetPacketFilter(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN PNDIS_REQUEST NdisRequest,
+ IN UINT PacketFilter
+ );
+
+NDIS_STATUS
+MlidQueryGlobalStatistics(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_REQUEST NdisRequest
+ );
+
+VOID
+MlidUnload(
+ IN NDIS_HANDLE MacMacContext
+ );
+
+NDIS_STATUS
+MlidAddAdapter(
+ IN NDIS_HANDLE NdisMacContext,
+ IN NDIS_HANDLE ConfigurationHandle,
+ IN PNDIS_STRING AdaptName
+ );
+
+VOID
+MlidRemoveAdapter(
+ IN PVOID MacAdapterContext
+ );
+
+VOID
+MlidInterruptDpc(
+ IN PVOID SystemSpecific1,
+ IN PVOID InterruptContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ );
+
+NDIS_STATUS
+MlidChangeMulticastAddresses(
+ IN UINT OldFilterCount,
+ IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS],
+ IN UINT NewFilterCount,
+ IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS],
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_REQUEST NdisRequest,
+ IN BOOLEAN Set
+ );
+
+NDIS_STATUS
+MlidChangeFilterClasses(
+ IN UINT OldFilterClasses,
+ IN UINT NewFilterClasses,
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_REQUEST NdisRequest,
+ IN BOOLEAN Set
+ );
+
+
+VOID
+MlidCloseAction(
+ IN NDIS_HANDLE MacBindingHandle
+ );
+
+
+UINT
+MlidPacketSize(
+ IN PNDIS_PACKET Packet
+ );
+
+
+INDICATE_STATUS
+MlidIndicatePacket(
+ IN PMLID_ADAPTER Adapter
+ );
+
+
+NDIS_STATUS
+MlidTransferData(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer,
+ OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred
+ );
+
+BOOLEAN
+MlidReceiveEvents(
+ IN PVOID SystemSpecific1,
+ IN PVOID Context,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ );
+
+VOID
+MlidTransmitEvents(
+ IN PMLID_ADAPTER Adapter
+ );
+
+NDIS_STATUS
+MlidSend(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN PNDIS_PACKET Packet
+ );
+
+UINT
+MlidCompareMemory(
+ IN PUCHAR String1,
+ IN PUCHAR String2,
+ IN UINT Length
+ );
+
+VOID
+MlidSetLoopbackFlag(
+ IN PMLID_ADAPTER Adapter,
+ IN PMLID_OPEN Open,
+ IN OUT PNDIS_PACKET Packet
+ );
+
+VOID
+MlidIndicateLoopbackPacket(
+ IN PMLID_ADAPTER Adapter,
+ IN PNDIS_PACKET Packet
+ );
+
+BOOLEAN
+MlidSyncCloseAdapter(
+ IN PVOID Context
+ );
+
+BOOLEAN
+MlidSyncSend(
+ IN PVOID Context
+ );
+
+BOOLEAN
+MlidSyncSetMulticastAddress(
+ IN PVOID Context
+ );
+
+VOID
+MlidWakeUpDpc(
+ IN PVOID SystemSpecific1,
+ IN PVOID Context,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ );
+
+//++
+//
+// VOID
+// AddRefWhileHoldingSpinLock(
+// IN PMLID_ADAPTER Adapter,
+// IN PMLID_OPEN OpenP
+// )
+//
+// Routine Description:
+//
+// Adds a reference to an open. Similar to AddReference, but
+// called with Adapter->Lock held.
+//
+// Arguments:
+//
+// Adapter - The adapter block of OpenP.
+// OpenP - The open block that is being referenced.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+#define AddRefWhileHoldingSpinLock(Adapter, OpenP) { \
+ ++((OpenP)->ReferenceCount); \
+}
+
+
+
+//++
+//
+// BOOLEAN
+// MlidAddressEqual(
+// IN UCHAR Address1[ETH_LENGTH_OF_ADDRESS],
+// IN UCHAR Address2[ETH_LENGTH_OF_ADDRESS]
+// )
+//
+// Routine Description:
+//
+// Compares two Ethernet addresses.
+//
+// Arguments:
+//
+// Address1 - The first address.
+// Address2 - The second address.
+//
+// Return Value:
+//
+// TRUE if the addresses are equal.
+// FALSE if they are not.
+//
+//--
+
+#define MlidAddressEqual(Address1, Address2) \
+ ((Address1)[4] == (Address2)[4] && \
+ MlidCompareMemory((Address1), (Address2), ETH_LENGTH_OF_ADDRESS) == 0)
+
+
+#endif // MLIDSFT
+
+
+
+
+
+
+
diff --git a/private/ntos/ndis/odimac/odihsm.h b/private/ntos/ndis/odimac/odihsm.h
new file mode 100644
index 000000000..0d17f1c0c
--- /dev/null
+++ b/private/ntos/ndis/odimac/odihsm.h
@@ -0,0 +1,418 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ odihsm.h
+
+Abstract:
+
+ This contains all the definitions for the ODI HSM structures.
+
+Author:
+
+ Sean Selitrennikoff (seanse) 15-Jan-92
+
+Environment:
+
+ Kernel mode, FSD
+
+Revision History:
+
+
+--*/
+
+
+typedef struct _ADAPTER_STRUC{
+
+ UCHAR bus_type; // 0 = ISA, 1 = MCA
+
+ UCHAR mc_slot_num; // MCA bus only
+
+ USHORT pos_id; // Adapter POS ID (Mca only)
+
+ USHORT io_base; // Adapter I/O Base
+
+ PUCHAR adapter_text_ptr; // See LM_Get_Config
+
+ USHORT irq_value; // IRQ line used by hardware
+
+ USHORT rom_size; // num of 1K blocks
+
+ ULONG rom_base; // physical address of ROM
+
+ PVOID rom_access; // Pointer into VM of rom_base
+
+ USHORT ram_size; // num of 1K blocks
+
+ ULONG ram_base; // physical address of RAM
+
+ PVOID ram_access; // Pointer into VM of ram_base
+
+ USHORT ram_usable; // num of 1K blocks that can be accessed at once
+
+ USHORT io_base_new; // new i/o base addr for LM_Put_Config
+
+ UCHAR node_address[6]; // network address
+
+ UCHAR permanent_node_address[6]; // network address burned into card.
+
+ UCHAR multi_address[6]; // multicase address
+
+ USHORT max_packet_size; // for this MAC driver
+
+ USHORT buffer_page_size; // size of adapters RAM TX/RX buffer pages.
+
+ USHORT num_of_tx_buffs; // TX bufss in adapter RAM
+
+ USHORT receive_lookahead_size;
+
+ USHORT receive_mask;
+
+ USHORT adapter_status;
+
+ USHORT media_type;
+
+ USHORT bic_type;
+
+ USHORT nic_type;
+
+ USHORT adapter_type;
+
+ NDIS_HANDLE NdisAdapterHandle;
+
+ NDIS_MCA_POS_DATA PosData;
+
+ BOOLEAN TokenRing;
+
+ //
+ // Token Ring Specific stuff
+ //
+
+
+ USHORT ring_status;
+
+ UCHAR funct_address[4];
+
+ UCHAR group_address[6];
+
+ //
+ // These counters must be initialized by the upper layer.
+ //
+
+
+ //
+ // Common counters...
+ //
+
+ PULONG ptr_rx_CRC_errors;
+
+ PULONG ptr_rx_lost_pkts;
+
+
+ //
+ // Token Ring counters
+ //
+
+ PULONG ptr_rx_congestion;
+
+ PULONG ptr_FCS_error;
+
+ PULONG ptr_burst_error;
+
+ PULONG ptr_AC_error;
+
+ PULONG ptr_tx_abort_delimiter;
+
+ PULONG ptr_tx_failed_return;
+
+ PULONG ptr_frames_copied;
+
+ PULONG ptr_frequency_error;
+
+ PULONG ptr_monitor_gen_count;
+
+ PULONG ptr_DMA_underruns;
+
+ //
+ // Ethernet specific counters. Must be initialized by upper layer.
+ //
+
+ PULONG ptr_rx_too_big;
+
+ PULONG ptr_rx_align_errors;
+
+ PULONG ptr_rx_overruns;
+
+ PULONG ptr_tx_deferred;
+
+ PULONG ptr_tx_max_collisions;
+
+ PULONG ptr_tx_one_collision;
+
+ PULONG ptr_tx_mult_collisions;
+
+ PULONG ptr_tx_ow_collision;
+
+ PULONG ptr_tx_CD_heartbeat;
+
+ PULONG ptr_tx_carrier_lost;
+
+ PULONG ptr_tx_underruns;
+
+
+
+
+ ULONG board_id;
+
+ USHORT mode_bits;
+
+ USHORT status_bits;
+
+ USHORT xmit_buf_size;
+
+ USHORT config_mode; // 1 == Store config in EEROM
+
+
+
+
+ UCHAR State;
+
+ BOOLEAN BufferOverflow; // does an overflow need to be handled
+
+ UCHAR InterruptMask;
+
+ BOOLEAN UMRequestedInterrupt; // Has LM_Interrupt() been called.
+
+
+
+ NDIS_INTERRUPT NdisInterrupt; // interrupt info used by wrapper
+
+ UCHAR Current;
+
+ //
+ // Transmit information.
+ //
+
+ XMIT_BUF NextBufToFill; // where to copy next packet to
+ XMIT_BUF NextBufToXmit; // valid if CurBufXmitting is -1
+ XMIT_BUF CurBufXmitting; // -1 if none is
+ BOOLEAN TransmitInterruptPending; // transmit interrupt and overwrite error?
+ UINT PacketLens[MAX_XMIT_BUFS];
+ BUFFER_STATUS BufferStatus[MAX_XMIT_BUFS];
+
+ PUCHAR ReceiveStart; // start of card receive area
+ PUCHAR ReceiveStop; // end of card receive area
+
+
+ //
+ // Loopback information
+ //
+
+ PNDIS_PACKET LoopbackQueue; // queue of packets to loop back
+ PNDIS_PACKET LoopbackQTail;
+ PNDIS_PACKET LoopbackPacket; // current one we are looping back
+
+ //
+ // Receive information
+ //
+
+ PUCHAR IndicatingPacket;
+ BOOLEAN OverWriteHandling; // Currently handling an overwrite
+ BOOLEAN OverWriteStartTransmit;
+ UCHAR StartBuffer; // Start buffer number to receive into
+ UCHAR LastBuffer; // Last buffer number + 1
+ UINT PacketLen;
+
+ //
+ // Interrupt Information
+ //
+
+ UCHAR LaarHold;
+
+ //
+ // Pointer to the filter database for the MAC.
+ //
+ PETH_FILTER FilterDB;
+
+}Adapter_Struc, *Ptr_Adapter_Struc;
+
+
+
+
+//
+// LMI Status and Return codes
+//
+
+typedef USHORT LM_STATUS;
+
+#define SUCCESS 0x0
+#define ADAPTER_AND_CONFIG 0x1 // Adapter found and config info gotten
+#define ADAPTER_NO_CONFIG 0x2 // Adapter found, no config info found
+#define NOT_MY_INTERRUPT 0x3 // No interrupt found in LM_Service_Events
+#define FRAME_REJECTED 0x4
+#define EVENTS_DISABLED 0x5 // Disables LM_Service_Events from reporting
+ // any further interrupts.
+#define OUT_OF_RESOURCES 0x6
+#define OPEN_FAILED 0x7
+#define HARDWARE_FAILED 0x8
+#define INITIALIZE_FAILED 0x9
+#define CLOSE_FAILED 0xA
+#define MAX_COLLISIONS 0xB
+#define FIFO_UNDERRUN 0xC
+#define BUFFER_TOO_SMALL 0xD
+#define ADAPTER_CLOSED 0xE
+#define FAILURE 0xF
+
+#define REQUEUE_LATER 0x12
+
+#define INVALID_FUNCTION 0x80
+#define INVALID_PARAMETER 0x81
+
+#define ADAPTER_NOT_FOUND 0xFFFF
+
+
+
+//
+// Function Definitions.
+//
+
+
+extern
+LM_STATUS
+LM_Send(
+ PNDIS_PACKET Packet,
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+
+extern
+LM_STATUS
+LM_Interrupt_req(
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+extern
+LM_STATUS
+LM_Service_Receive_Events(
+ Ptr_Adapter_Struc Adapter
+ );
+
+extern
+LM_STATUS
+LM_Service_Transmit_Events(
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+extern
+LM_STATUS
+LM_Receive_Copy(
+ PULONG Bytes_Transferred,
+ ULONG Byte_Count,
+ ULONG Offset,
+ PNDIS_PACKET Packet,
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+extern
+LM_STATUS
+LM_Receive_Lookahead(
+ ULONG Byte_Count,
+ ULONG Offset,
+ PUCHAR Buffer,
+ Ptr_Adapter_Struc Adapter
+ );
+
+extern
+LM_STATUS
+LM_Get_Mca_Io_Base_Address(
+ IN Ptr_Adapter_Struc Adapt,
+ IN NDIS_HANDLE ConfigurationHandle,
+ OUT USHORT *IoBaseAddress
+ );
+
+extern
+LM_STATUS
+LM_Get_Config(
+ Ptr_Adapter_Struc Adapter
+ );
+
+extern
+LM_STATUS
+LM_Free_Resources(
+ Ptr_Adapter_Struc Adapt
+ );
+
+extern
+LM_STATUS
+LM_Initialize_Adapter(
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+extern
+LM_STATUS
+LM_Open_Adapter(
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+extern
+LM_STATUS
+LM_Close_Adapter(
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+extern
+LM_STATUS
+LM_Disable_Adapter(
+ Ptr_Adapter_Struc Adapter
+ );
+
+extern
+LM_STATUS
+LM_Disable_Adapter_Receives(
+ Ptr_Adapter_Struc Adapt
+ );
+
+extern
+LM_STATUS
+LM_Disable_Adapter_Transmits(
+ Ptr_Adapter_Struc Adapt
+ );
+
+extern
+LM_STATUS
+LM_Enable_Adapter(
+ Ptr_Adapter_Struc Adapter
+ );
+
+
+extern
+LM_STATUS
+LM_Enable_Adapter_Receives(
+ Ptr_Adapter_Struc Adapt
+ );
+
+extern
+LM_STATUS
+LM_Enable_Adapter_Transmits(
+ Ptr_Adapter_Struc Adapt
+ );
+
+#define LM_Set_Multi_Address(Addresses, Count, Adapter) (SUCCESS)
+
+
+extern
+LM_STATUS
+LM_Set_Receive_Mask(
+ Ptr_Adapter_Struc Adapter
+ );
+
+
diff --git a/private/ntos/ndis/odimac/umi.c b/private/ntos/ndis/odimac/umi.c
new file mode 100644
index 000000000..d007f8af8
--- /dev/null
+++ b/private/ntos/ndis/odimac/umi.c
@@ -0,0 +1,336 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ umi.c
+
+Abstract:
+
+ Upper MAC Interface functions for the NDIS 3.0 Western Digital driver.
+
+Author:
+
+ Sean Selitrennikoff (seanse) 15-Jan-92
+
+Environment:
+
+ Kernel mode, FSD
+
+Revision History:
+
+
+--*/
+
+#include <ndis.h>
+#include <efilter.h>
+#include "wdlmi.h"
+#include "wdhrd.h"
+#include "wdsft.h"
+#include "wdumi.h"
+
+
+
+#if DBG
+
+extern UCHAR WdDebugLog[];
+extern UCHAR WdDebugLogPlace;
+
+#define IF_LOG(A) A
+
+#else
+
+#define IF_LOG(A)
+
+#endif
+
+
+LM_STATUS
+UM_Send_Complete(
+ LM_STATUS Status,
+ Ptr_Adapter_Struc Adapt
+ )
+/*++
+
+Routine Description:
+
+ This routine is called back when the packet on the front of
+ PacketsOnCard has been fully transmitted by the Lower MAC.
+
+
+ NOTE: The lock is held before the LM_ routines are called and
+ therefore held at the beginning of this call.
+
+Arguments:
+
+ Status - Status of the send.
+
+ Adapt - A pointer to an LMI adapter structure.
+
+Return:
+
+ SUCCESS
+ EVENTS_DISABLED
+
+--*/
+{
+
+ PWD_ADAPTER Adapter = PWD_ADAPTER_FROM_Ptr_Adapter_Struc(Adapt);
+ PWD_OPEN Open;
+ PNDIS_PACKET Packet;
+
+
+
+ ASSERT(Adapter->PacketsOnCard != NULL);
+
+ IF_LOG(LOG('c'));
+
+ //
+ // Remove Packet from list.
+ //
+
+ Packet = Adapter->PacketsOnCard;
+
+ Adapter->PacketsOnCard = RESERVED(Packet)->NextPacket;
+
+ if (Adapter->PacketsOnCard == NULL) {
+
+ Adapter->PacketsOnCardTail = NULL;
+
+ }
+
+ Open = RESERVED(Packet)->Open;
+
+
+ IF_LOUD( DbgPrint("Completing send for open 0x%lx\n",Open);)
+
+
+ if (RESERVED(Packet)->Loopback) {
+
+ //
+ // Put packet on loopback
+ //
+
+ if (Adapter->LoopbackQueue == NULL) {
+
+ Adapter->LoopbackQueue = Adapter->LoopbackQTail = Packet;
+
+ } else {
+
+ RESERVED(Adapter->LoopbackQTail)->NextPacket = Packet;
+
+ Adapter->LoopbackQTail = Packet;
+
+ }
+
+ RESERVED(Packet)->NextPacket = NULL;
+
+ } else {
+
+ IF_LOUD( DbgPrint("Not a loopback packet\n");)
+
+ //
+ // Complete send
+ //
+
+ if (Status == SUCCESS) {
+ Adapter->FramesXmitGood++;
+ } else {
+ Adapter->FramesXmitBad++;
+ }
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ NdisCompleteSend(Open->NdisBindingContext,
+ Packet,
+ (Status == SUCCESS ? NDIS_STATUS_SUCCESS :
+ NDIS_STATUS_FAILURE)
+ );
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ WdRemoveReference(Open);
+
+ }
+
+ //
+ // If there are any sends waiting and there is not a reset to be
+ // done, queue them up
+ //
+
+ if ((Adapter->XmitQueue != NULL) && !(Adapter->ResetRequested)) {
+
+ //
+ // Remove packet from front.
+ //
+
+ Packet = Adapter->XmitQueue;
+
+ Adapter->XmitQueue = RESERVED(Packet)->NextPacket;
+
+ if (Adapter->XmitQueue == NULL) {
+
+ Adapter->XmitQTail = NULL;
+
+ }
+
+ //
+ // Start packet send.
+ //
+
+ IF_LOG(LOG('t'));
+
+ Status = LM_Send(Packet, Adapt);
+
+ if (Status == OUT_OF_RESOURCES) {
+
+ IF_LOG(LOG('2'));
+
+ //
+ // Put packet back on xmit queue.
+ //
+
+ if (Adapter->XmitQueue != NULL) {
+
+ RESERVED(Packet)->NextPacket = Adapter->XmitQueue;
+
+ Adapter->XmitQueue = Packet;
+
+ } else {
+
+ Adapter->XmitQueue = Packet;
+
+ Adapter->XmitQTail = Packet;
+
+ }
+
+ } else if (Status == SUCCESS) {
+
+ //
+ // Put packet at end of card list.
+ //
+
+ if (Adapter->PacketsOnCard == NULL) {
+
+ Adapter->PacketsOnCard = Adapter->PacketsOnCardTail = Packet;
+
+ } else {
+
+ RESERVED(Adapter->PacketsOnCardTail)->NextPacket = Packet;
+
+ Adapter->PacketsOnCardTail = Packet;
+
+ }
+
+ RESERVED(Packet)->NextPacket = NULL;
+
+ }
+
+ }
+
+ IF_LOG(LOG('C'));
+
+ return(SUCCESS);
+
+}
+
+
+LM_STATUS
+UM_Receive_Packet(
+ ULONG PacketSize,
+ Ptr_Adapter_Struc Adapt
+ )
+/*++
+
+Routine Description:
+
+ This routine is called whenever the lower MAC receives a packet.
+
+
+Arguments:
+
+ PacketSize - Total size of the packet
+
+ Adapt - A pointer to an LMI adapter structure.
+
+Return:
+
+ SUCCESS
+ EVENTS_DISABLED
+
+--*/
+{
+ PWD_ADAPTER Adapter = PWD_ADAPTER_FROM_Ptr_Adapter_Struc(Adapt);
+ ULONG IndicateLen;
+
+ //
+ // Setup for indication
+ //
+
+ Adapter->IndicatedAPacket = TRUE;
+
+ Adapter->IndicatingPacket = (PNDIS_PACKET)NULL;
+
+ IndicateLen = ((Adapter->MaxLookAhead + WD_HEADER_SIZE) > PacketSize ?
+ PacketSize :
+ Adapter->MaxLookAhead + WD_HEADER_SIZE
+ );
+
+ if (LM_Receive_Lookahead(
+ IndicateLen,
+ 0,
+ Adapter->LookAhead,
+ &(Adapter->LMAdapter)) != SUCCESS) {
+
+ return(SUCCESS);
+
+ }
+
+ //
+ // Indicate packet
+ //
+
+ Adapter->FramesRcvGood++;
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ if (PacketSize < WD_HEADER_SIZE) {
+
+ if (PacketSize >= ETH_LENGTH_OF_ADDRESS) {
+
+ //
+ // Runt packet
+ //
+
+ EthFilterIndicateReceive(
+ Adapt->FilterDB,
+ (NDIS_HANDLE)Adapter,
+ (PCHAR)Adapter->LookAhead,
+ Adapter->LookAhead,
+ PacketSize,
+ NULL,
+ 0,
+ 0
+ );
+
+ }
+
+ } else {
+
+ EthFilterIndicateReceive(
+ Adapt->FilterDB,
+ (NDIS_HANDLE)Adapter,
+ (PCHAR)Adapter->LookAhead,
+ Adapter->LookAhead,
+ WD_HEADER_SIZE,
+ Adapter->LookAhead + WD_HEADER_SIZE,
+ IndicateLen - WD_HEADER_SIZE,
+ PacketSize - WD_HEADER_SIZE
+ );
+ }
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ return(SUCCESS);
+}