started pcnet driver - incomplete but builds and loads
authorVizzini <vizzini@plasmic.com>
Wed, 3 Sep 2003 23:59:56 +0000 (23:59 +0000)
committerVizzini <vizzini@plasmic.com>
Wed, 3 Sep 2003 23:59:56 +0000 (23:59 +0000)
svn path=/trunk/; revision=5970

reactos/drivers/net/dd/pcnet/Makefile [new file with mode: 0644]
reactos/drivers/net/dd/pcnet/pci.h [new file with mode: 0644]
reactos/drivers/net/dd/pcnet/pcnet.c [new file with mode: 0644]
reactos/drivers/net/dd/pcnet/pcnet.h [new file with mode: 0644]
reactos/drivers/net/dd/pcnet/pcnet.rc [new file with mode: 0644]
reactos/drivers/net/dd/pcnet/pcnethw.h [new file with mode: 0644]

diff --git a/reactos/drivers/net/dd/pcnet/Makefile b/reactos/drivers/net/dd/pcnet/Makefile
new file mode 100644 (file)
index 0000000..c9f5f3a
--- /dev/null
@@ -0,0 +1,14 @@
+PATH_TO_TOP = ../../../..
+TARGET_TYPE = driver
+TARGET_NAME = pcnet
+
+#
+# - must define NDIS40 to get the right characteristics struct
+# - must define anonymous unions to make physical addresses work right
+#
+TARGET_CFLAGS = -I. -DDBG=1 -Wall -Werror -DNDIS40 -DANONYMOUSUNIONS 
+
+TARGET_OBJECTS = pcnet.o 
+TARGET_DDKLIBS = ndis.a
+include $(PATH_TO_TOP)/rules.mak
+include $(TOOLS_PATH)/helper.mk
diff --git a/reactos/drivers/net/dd/pcnet/pci.h b/reactos/drivers/net/dd/pcnet/pci.h
new file mode 100644 (file)
index 0000000..7e79a5f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  ReactOS AMD PCNet Driver
+ *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * PROJECT:         ReactOS AMD PCNet Driver
+ * FILE:            pcnet/pci.h
+ * PURPOSE:         PCI configuration constants
+ * PROGRAMMER:      Vizzini (vizzini@plasmic.com)
+ * REVISIONS:
+ *                  1-Sept-2003 vizzini - Created
+ */
+
+
+/* PCI Config Space Offset Definitions */
+#define PCI_PCIID    0x0        /* pci id - query 32 bits */
+#define PCI_VENID    0x0        /* vendor ID */
+#define PCI_DEVID    0x2        /* device ID */
+#define PCI_COMMAND  0x4        /* command register */
+#define PCI_STATUS   0x6        /* status register */
+#define PCI_REVID    0x8        /* revision ID */
+#define PCI_PIR      0x9        /* programming interface register */
+#define PCI_SCR      0xa        /* sub-class register */
+#define PCI_BCR      0xb        /* base-class register */
+#define PCI_LTR      0xd        /* latency timer register */
+#define PCI_HTR      0xe        /* header type register */
+#define PCI_IOBAR    0x10       /* i/o base address register */
+#define PCI_MMBAR    0x14       /* i/o memory-mapped base address register */
+#define PCI_ERBAR    0x30       /* expansion rom base address register */
+#define PCI_ILR      0x3c       /* interrupt line register */
+#define PCI_IPR      0x3d       /* interrupt pin register */
+#define PCI_MINGNT   0x3e       /* min_gnt register */
+#define PCI_MAXLAT   0x3f       /* max_lat register */
+
+/* PCI Command Register Bits */
+#define PCI_IOEN     0x1        /* i/o space access enable */
+#define PCI_MEMEN    0x2        /* memory space access enable */
+#define PCI_BMEN     0x4        /* bus master enable */
+#define PCI_SCYCEN   0x8        /* special cycle enable */
+#define PCI_MWIEN    0X10       /* memory write and invalidate cycle enable */
+#define PCI_VGASNOOP 0x20       /* vga palette snoop */
+#define PCI_PERREN   0x40       /* parity error response enable */
+#define PCI_ADSTEP   0x80       /* address/data stepping */
+#define PCI_SERREN   0x100      /* signalled error enable */
+#define PCI_FBTBEN   0X200      /* fast back-to-back enable */
+
+/* PCI Status Register Bits */
+#define PCI_FBTBC    0x80       /* fast back-to-back capable */
+#define PCI_DATAPERR 0x100      /* data parity error detected */
+#define PCI_DEVSEL1  0x200      /* device select timing lsb */
+#define PCI_DEVSEL2  0x400      /* device select timing msb */
+#define PCI_STABORT  0x800      /* send target abort */
+#define PCI_RTABORT  0x1000     /* received target abort */
+#define PCI_SERR     0x2000     /* signalled error */
+#define PCI_PERR     0x4000     /* parity error */
+
diff --git a/reactos/drivers/net/dd/pcnet/pcnet.c b/reactos/drivers/net/dd/pcnet/pcnet.c
new file mode 100644 (file)
index 0000000..7174658
--- /dev/null
@@ -0,0 +1,949 @@
+/*
+ *  ReactOS AMD PCNet Driver
+ *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * PROJECT:         ReactOS AMD PCNet Driver
+ * FILE:            drivers/net/dd/pcnet/pcnet.c
+ * PURPOSE:         PCNet Device Driver
+ * PROGRAMMER:      Vizzini (vizzini@plasmic.com)
+ * REVISIONS:
+ *                  9-Sept-2003 vizzini - Created
+ * NOTES:
+ *     - this is hard-coded to NDIS4
+ *     - this assumes a little-endian machine
+ *     - this assumes a 32-bit machine
+ *     - this doesn't handle multiple PCNET NICs yet
+ *     - this driver includes both NdisRaw and NdisImmediate calls
+ *       for NDIS testing purposes.  Pick your poison below.
+ */
+#include <ndis.h>
+#include "pci.h"
+#include "pcnethw.h"
+#include "pcnet.h"
+
+#define USE_IMMEDIATE_PORT_IO 1
+\f
+VOID
+STDCALL
+MiniportHalt(
+    IN NDIS_HANDLE MiniportAdapterContext)
+/*
+ * FUNCTION: Stop the miniport and prepare for unload
+ * ARGUMENTS:
+ *     MiniportAdapterContext: context specified to NdisMSetAttributes
+ * NOTES:
+ *     - Called by NDIS at PASSIVE_LEVEL
+ */
+{
+  /* XXX Implement me */
+  PCNET_DbgPrint(("Called\n"));
+}
+
+\f
+VOID
+STDCALL
+MiniportHandleInterrupt(
+    IN NDIS_HANDLE MiniportAdapterContext)
+/*
+ * FUNCTION: Handle an interrupt if told to by MiniportISR
+ * ARGUMENTS: 
+ *     MiniportAdapterContext: context specified to NdisMSetAttributes
+ * NOTES:
+ *     - Called by NDIS at DISPATCH_LEVEL
+ */
+{
+  /* XXX Implement me */
+  PCNET_DbgPrint(("Called\n"));
+}
+
+\f
+NDIS_STATUS 
+MiQueryCard(
+    IN PADAPTER Adapter)
+/*
+ * FUNCTION: Detect the PCNET NIC in the configured slot and query its I/O address and interrupt vector
+ * ARGUMENTS:
+ *     MiniportAdapterContext: context supplied to NdisMSetAttributes
+ * RETURNS:
+ *     NDIS_STATUS_FAILURE on a general error
+ *     NDIS_STATUS_ADAPTER_NOT_FOUND on not finding the adapter
+ *     NDIS_STATUS_SUCCESS on succes
+ */
+{
+  ULONG  buf32 = 0;
+  UCHAR  buf8  = 0;
+  NDIS_STATUS Status;
+
+  /* Detect the card in the configured slot */
+  Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber, PCI_PCIID, &buf32, 4);
+  if(Status != 4)
+    {
+      Status =  NDIS_STATUS_FAILURE;
+      PCNET_DbgPrint(("NdisReadPciSlotInformation failed\n"));
+      BREAKPOINT;
+      return Status;
+    }
+
+  if(buf32 != PCI_ID)
+    {
+      Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+      PCNET_DbgPrint(("card in slot 0x%x isn't us: 0x%x\n", Adapter->SlotNumber, buf32));
+      BREAKPOINT;
+      return Status;
+    }
+
+  Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber,
+      PCI_COMMAND, &buf32, 4);
+  if(Status != 4)
+    {
+      PCNET_DbgPrint(("NdisReadPciSlotInformation failed\n"));
+      BREAKPOINT;
+      return NDIS_STATUS_FAILURE;
+    }
+
+  PCNET_DbgPrint(("config/status register: 0x%x\n", buf32));
+
+  if(buf32 & 0x1)
+    {
+      PCNET_DbgPrint(("io space access is enabled.\n"));
+    }
+  else
+    {
+      PCNET_DbgPrint(("io space is NOT enabled!\n"));
+      BREAKPOINT;
+      return NDIS_STATUS_FAILURE;
+    }
+
+  /* get IO base physical address */
+  buf32 = 0;
+  Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber, PCI_IOBAR, &buf32, 4);
+  if(Status != 4)
+    {
+      Status = NDIS_STATUS_FAILURE;
+      PCNET_DbgPrint(("NdisReadPciSlotInformation failed\n"));
+      BREAKPOINT;
+      return Status;
+    }
+
+  if(!buf32)
+    {
+      PCNET_DbgPrint(("No base i/o address set\n"));
+      return NDIS_STATUS_FAILURE;
+    }
+
+  buf32 &= ~1;  /* even up address - comes out odd for some reason */
+
+  PCNET_DbgPrint(("detected io address 0x%x\n", buf32));
+  Adapter->IoBaseAddress = buf32;
+
+  /* get interrupt vector */
+  Status = NdisReadPciSlotInformation(Adapter->MiniportAdapterHandle, Adapter->SlotNumber, PCI_ILR, &buf8, 1);
+  if(Status != 1)
+    {
+      Status = NDIS_STATUS_FAILURE;
+      PCNET_DbgPrint(("NdisReadPciSlotInformation failed\n"));
+      BREAKPOINT;
+      return Status;
+    }
+
+  PCNET_DbgPrint(("interrupt: 0x%x\n", buf8));
+  Adapter->InterruptVector = buf8;
+
+  return NDIS_STATUS_SUCCESS;
+}
+
+\f
+NDIS_STATUS
+MiGetConfig(
+    PADAPTER Adapter, 
+    NDIS_HANDLE WrapperConfigurationContext)
+/*
+ * FUNCTION: Get configuration parameters from the registry
+ * ARGUMENTS:
+ *     Adapter: pointer to the Adapter struct for this NIC
+ *     WrapperConfigurationContext: Context passed into MiniportInitialize
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on success
+ *     NDIS_STATUS_{something} on failure (return val from other Ndis calls)
+ */
+{
+  PNDIS_CONFIGURATION_PARAMETER Parameter; 
+  NDIS_HANDLE ConfigurationHandle = 0;
+  UNICODE_STRING Keyword;
+  NDIS_STATUS Status;
+
+  NdisOpenConfiguration(&Status, &ConfigurationHandle, WrapperConfigurationContext);
+  if(Status != NDIS_STATUS_SUCCESS)
+    {
+      PCNET_DbgPrint(("Unable to open configuration: 0x%x\n", Status));
+      BREAKPOINT;
+      return Status;
+    }
+
+  RtlInitUnicodeString(&Keyword, L"SlotNumber");
+  NdisReadConfiguration(&Status, &Parameter, ConfigurationHandle, &Keyword, NdisParameterInteger);
+  if(Status != NDIS_STATUS_SUCCESS)
+    {
+      PCNET_DbgPrint(("Unable to read slot number: 0x%x\n", Status));
+      BREAKPOINT;
+    }
+  else 
+    Adapter->SlotNumber = Parameter->ParameterData.IntegerData;
+
+  NdisCloseConfiguration(ConfigurationHandle);
+
+  return NDIS_STATUS_SUCCESS;
+}
+
+\f
+NDIS_STATUS
+MiAllocateSharedMemory(
+    PADAPTER Adapter)
+/*
+ * FUNCTION: Allocate all shared memory used by the miniport
+ * ARGUMENTS:
+ *     Adapter: Pointer to the miniport's adapter object
+ * RETURNS:
+ *     NDIS_STATUS_RESOURCES on insufficient memory
+ *     NDIS_STATUS_SUCCESS on success
+ */
+{
+  PTRANSMIT_DESCRIPTOR TransmitDescriptor;
+  PRECEIVE_DESCRIPTOR  ReceiveDescriptor;
+  ULONG i;
+
+  /* allocate the initialization block */
+  Adapter->InitializationBlockLength = sizeof(INITIALIZATION_BLOCK);
+  NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->InitializationBlockLength, 
+      FALSE, (PVOID *)&Adapter->InitializationBlockVirt, &Adapter->InitializationBlockPhys);
+  if(!Adapter->InitializationBlockVirt)
+    {
+      PCNET_DbgPrint(("insufficient resources\n"));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  if(((ULONG)Adapter->InitializationBlockVirt & 0x00000003) != 0)
+    {
+      PCNET_DbgPrint(("address 0x%x not dword-aligned\n", Adapter->InitializationBlockVirt));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  memset(Adapter->InitializationBlockVirt, 0, sizeof(INITIALIZATION_BLOCK));
+
+  /* allocate the transport descriptor ring */
+  Adapter->TransmitDescriptorRingLength = sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS;
+  NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitDescriptorRingLength,
+      FALSE, (PVOID *)&Adapter->TransmitDescriptorRingVirt, &Adapter->TransmitDescriptorRingPhys);
+  if(!Adapter->TransmitDescriptorRingVirt)
+    {
+      PCNET_DbgPrint(("insufficient resources\n"));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  if(((ULONG)Adapter->TransmitDescriptorRingVirt & 0x00000003) != 0)
+    {
+      PCNET_DbgPrint(("address 0x%x not dword-aligned\n", Adapter->TransmitDescriptorRingVirt));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  memset(Adapter->TransmitDescriptorRingVirt, 0, sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS);
+
+  /* allocate the receive descriptor ring */
+  Adapter->ReceiveDescriptorRingLength = sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS;
+  NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveDescriptorRingLength,
+      FALSE, (PVOID *)&Adapter->ReceiveDescriptorRingVirt, &Adapter->ReceiveDescriptorRingPhys);
+  if(!Adapter->ReceiveDescriptorRingVirt)
+    {
+      PCNET_DbgPrint(("insufficient resources\n"));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  if(((ULONG)Adapter->ReceiveDescriptorRingVirt & 0x00000003) != 0)
+    {
+      PCNET_DbgPrint(("address 0x%x not dword-aligned\n", Adapter->ReceiveDescriptorRingVirt));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  memset(Adapter->ReceiveDescriptorRingVirt, 0, sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS);
+
+  /* allocate transmit buffers */
+  Adapter->TransmitBufferLength = BUFFER_SIZE * NUMBER_OF_BUFFERS;
+  NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitBufferLength, 
+      FALSE, (PVOID *)&Adapter->TransmitBufferPtrVirt, &Adapter->TransmitBufferPtrPhys);
+  if(!Adapter->TransmitBufferPtrVirt)
+    {
+      PCNET_DbgPrint(("insufficient resources\n"));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  if(((ULONG)Adapter->TransmitBufferPtrVirt & 0x00000003) != 0)
+    {
+      PCNET_DbgPrint(("address 0x%x not dword-aligned\n", Adapter->TransmitBufferPtrVirt));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  memset(Adapter->TransmitBufferPtrVirt, 0, BUFFER_SIZE * NUMBER_OF_BUFFERS);
+
+  /* allocate receive buffers */
+  Adapter->ReceiveBufferLength = BUFFER_SIZE * NUMBER_OF_BUFFERS;
+  NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveBufferLength, 
+      FALSE, (PVOID *)&Adapter->ReceiveBufferPtrVirt, &Adapter->ReceiveBufferPtrPhys);
+  if(!Adapter->ReceiveBufferPtrVirt)
+    {
+      PCNET_DbgPrint(("insufficient resources\n"));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  if(((ULONG)Adapter->ReceiveBufferPtrVirt & 0x00000003) != 0)
+    {
+      PCNET_DbgPrint(("address 0x%x not dword-aligned\n", Adapter->ReceiveBufferPtrVirt));
+      BREAKPOINT;
+      return NDIS_STATUS_RESOURCES;
+    }
+
+  memset(Adapter->ReceiveBufferPtrVirt, 0, BUFFER_SIZE * NUMBER_OF_BUFFERS);
+
+  /* initialize tx descriptors */
+  TransmitDescriptor = Adapter->TransmitDescriptorRingVirt;
+  for(i = 0; i < NUMBER_OF_BUFFERS; i++)
+    {
+      (TransmitDescriptor+i)->TBADR = NdisGetPhysicalAddressLow(Adapter->TransmitBufferPtrPhys) + i * BUFFER_SIZE;
+      (TransmitDescriptor+i)->BCNT = 0xf000;
+      (TransmitDescriptor+i)->FLAGS = TD1_STP | TD1_ENP;
+    }
+
+  PCNET_DbgPrint(("transmit ring initialized\n"));
+
+  /* initialize rx */
+  ReceiveDescriptor = Adapter->ReceiveDescriptorRingVirt;
+  for(i = 0; i < NUMBER_OF_BUFFERS; i++)
+    {
+      (ReceiveDescriptor+i)->RBADR = NdisGetPhysicalAddressLow(Adapter->ReceiveBufferPtrPhys) + i * BUFFER_SIZE;
+      (ReceiveDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment */
+      (ReceiveDescriptor+i)->FLAGS |= RD_OWN;
+    }
+
+  PCNET_DbgPrint(("receive ring initialized\n"));
+
+  return NDIS_STATUS_SUCCESS;
+}
+
+\f
+VOID
+MiPrepareInitializationBlock(
+    PADAPTER Adapter)
+/*
+ * FUNCTION: Initialize the initialization block
+ * ARGUMENTS:
+ *     Adapter: pointer to the miniport's adapter object
+ */
+{
+  ULONG i = 0;
+
+  /* read burned-in address from card */
+  for(i = 0; i < 6; i++)
+#if USE_IMMEDIATE_PORT_IO
+    NdisImmediateReadPortUchar(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + i, 
+                               Adapter->InitializationBlockVirt->PADR);
+#else
+    NdisRawReadPortUchar(Adapter->PortOffset + i, Adapter->InitializationBlockVirt->PADR + i);
+#endif
+
+  /* set up receive ring */
+  Adapter->InitializationBlockVirt->RDRA = NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorRingPhys);
+  Adapter->InitializationBlockVirt->RLEN = LOG_NUMBER_OF_BUFFERS;
+
+  /* set up transmit ring */
+  Adapter->InitializationBlockVirt->TDRA = NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorRingPhys);
+  Adapter->InitializationBlockVirt->TLEN = LOG_NUMBER_OF_BUFFERS;
+}
+
+\f
+VOID
+MiFreeSharedMemory(
+    PADAPTER Adapter)
+/*
+ * FUNCTION: Free all allocated shared memory
+ * ARGUMENTS:
+ *     Adapter: pointer to the miniport's adapter struct
+ */
+{
+  if(Adapter->InitializationBlockVirt)
+    NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->InitializationBlockLength, 
+        FALSE, (PVOID *)&Adapter->InitializationBlockVirt, &Adapter->InitializationBlockPhys);
+
+  if(Adapter->TransmitDescriptorRingVirt)
+    NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitDescriptorRingLength,
+        FALSE, (PVOID *)&Adapter->TransmitDescriptorRingVirt, &Adapter->TransmitDescriptorRingPhys);
+
+  if(Adapter->ReceiveDescriptorRingVirt)
+    NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveDescriptorRingLength,
+        FALSE, (PVOID *)&Adapter->ReceiveDescriptorRingVirt, &Adapter->ReceiveDescriptorRingPhys);
+
+  if(Adapter->TransmitBufferPtrVirt)
+    NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitBufferLength, 
+        FALSE, (PVOID *)&Adapter->TransmitBufferPtrVirt, &Adapter->TransmitBufferPtrPhys);
+
+  if(Adapter->ReceiveBufferPtrVirt)
+    NdisMAllocateSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveBufferLength, 
+        FALSE, (PVOID *)&Adapter->ReceiveBufferPtrVirt, &Adapter->ReceiveBufferPtrPhys);
+}
+
+\f
+VOID
+MiInitChip(
+    PADAPTER Adapter)
+/*
+ * FUNCTION: Initialize and start the PCNET chip
+ * ARGUMENTS:
+ *     Adapter: pointer to the miniport's adapter struct
+ * NOTES:
+ *     - should be coded to detect failure and return an error
+ */
+{
+  ULONG Data = 0;
+
+  PCNET_DbgPrint(("Called\n"));
+
+  /* stop the chip */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RAP, CSR0);
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, CSR0_STOP);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RAP, CSR0);
+  NdisRawWritePortUlong(Adapter->PortOffset + RDP, CSR0_STOP);
+#endif
+
+  NdisStallExecution(5);
+
+  PCNET_DbgPrint(("chip stopped\n"));
+
+  /* set the software style to 32 bits */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RAP, CSR58);
+  NdisImmediateReadPortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, &Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RAP, CSR58);
+  NdisRawReadPortUlong(Adapter->PortOffset + RDP, &Data);
+#endif
+
+  Data |= CSR58_SSIZE32;
+  Data |= SW_STYLE_2;
+
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RDP, Data);
+#endif
+
+  PCNET_DbgPrint(("software style set to 2 / 32-bit\n"));
+
+  /* set up csr4: auto transmit pad, disable polling, disable transmit interrupt, dmaplus */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RAP, CSR4);
+  NdisImmediateReadPortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, &Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RAP, CSR4);
+  NdisRawReadPortUlong(Adapter->PortOffset + RDP, &Data);
+#endif
+
+  Data |= CSR4_APAD_XMT | CSR4_DPOLL | CSR4_TXSTRTM | CSR4_DMAPLUS;
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RDP, Data);
+#endif
+
+  /* set up bcr18: burst read/write enable */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RAP, BCR18);
+  NdisImmediateReadPortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + BDP, &Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RAP, BCR18);
+  NdisRawReadPortUlong(Adapter->PortOffset + BDP, &Data);
+#endif
+
+  Data |= BCR18_BREADE | BCR18_BWRITE ;
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + BDP, Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + BDP, Data);
+#endif
+
+  /* set up csr1 and csr2 with init block */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RAP, CSR1);
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, 
+                              NdisGetPhysicalAddressLow(Adapter->InitializationBlockPhys) & 0xffff);
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP,
+                              (NdisGetPhysicalAddressLow(Adapter->InitializationBlockPhys) >> 16) & 0xffff);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RAP, CSR1);
+  NdisRawWritePortUlong(Adapter->PortOffset + RDP, NdisGetPhysicalAddressLow(Adapter->InitializationBlockPhys) & 0xffff);
+  NdisRawWritePortUlong(Adapter->PortOffset + RDP, (NdisGetPhysicalAddressLow(Adapter->InitializationBlockPhys) >> 16) & 0xffff);
+#endif
+
+  PCNET_DbgPrint(("programmed with init block\n"));
+
+  /* load init block and start the card */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RAP, CSR0);
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, CSR0_STRT|CSR0_INIT|CSR0_IENA);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RAP, CSR0);
+  NdisRawWritePortUlong(Adapter->PortOffset + RDP, CSR0_STRT|CSR0_INIT|CSR0_IENA);
+#endif
+
+  PCNET_DbgPrint(("card started\n"));
+
+  Adapter->Flags &= ~RESET_IN_PROGRESS;
+}
+
+\f
+BOOLEAN
+MiTestCard(
+    PADAPTER Adapter)
+/*
+ * FUNCTION: Test the NIC
+ * ARGUMENTS:
+ *     Adapter: pointer to the miniport's adapter struct
+ * RETURNS:
+ *     TRUE if the test succeeds
+ *     FALSE otherwise
+ * NOTES:
+ *     - this is where to add diagnostics.  This is called
+ *       at the very end of initialization.
+ */
+{
+  int i = 0;
+  UCHAR address[6];
+
+#if !(USE_IMMEDIATE_PORT_IO)
+  /* see if we can read/write now */
+    {
+      ULONG Data = 0;
+      NdisRawWritePortUlong(Adapter->PortOffset + RAP, CSR0);
+      NdisRawReadPortUlong(Adapter->PortOffset + RDP, &Data);
+
+      PCNET_DbgPrint(("Port 0x%x RAP 0x%x CSR0 0x%x RDP 0x%x, Interupt status register is 0x%x\n", 
+          Adapter->PortOffset, RAP, CSR0, RDP, Data));
+    }
+#endif
+
+  /* read the BIA */
+  for(i=0; i < 6; i++)
+    {
+#if USE_IMMEDIATE_PORT_IO
+      NdisImmediateReadPortUchar(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + i, &address[i]);
+#else
+      NdisRawReadPortUchar(Adapter->PortOffset + i, &address[i]);
+#endif
+    }
+
+  PCNET_DbgPrint(("burned-in address: %x:%x:%x:%x:%x:%x\n", address[0], address[1], address[2], address[3],
+                  address[4], address[5]));
+
+  return TRUE;
+}
+
+\f
+NDIS_STATUS
+STDCALL
+MiniportInitialize(
+    OUT PNDIS_STATUS OpenErrorStatus,
+    OUT PUINT SelectedMediumIndex,
+    IN PNDIS_MEDIUM MediumArray,
+    IN UINT MediumArraySize,
+    IN NDIS_HANDLE MiniportAdapterHandle,
+    IN NDIS_HANDLE WrapperConfigurationContext)
+/*
+ * FUNCTION:  Initialize a new miniport
+ * ARGUMENTS:
+ *     OpenErrorStatus:  pointer to a var to return status info in
+ *     SelectedMediumIndex: index of the selected medium (will be NdisMedium802_3)
+ *     MediumArray: array of media that we can pick from
+ *     MediumArraySize: size of MediumArray
+ *     MiniportAdapterHandle: NDIS-assigned handle for this miniport instance
+ *     WrapperConfigurationContext: temporary NDIS-assigned handle for passing
+ *                                  to configuration APIs
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on success
+ *     NDIS_STATUS_FAILURE on general failure
+ *     NDIS_STATUS_UNSUPPORTED_MEDIA on not finding 802_3 in the MediaArray
+ *     NDIS_STATUS_RESOURCES on insufficient system resources
+ *     NDIS_STATUS_ADAPTER_NOT_FOUND on not finding the adapter
+ * NOTES:
+ *     - Called by NDIS at PASSIVE_LEVEL, once per detected card
+ *     - Will int 3 on failure of MiTestCard if DBG=1
+ */
+{
+  UINT i = 0;
+  PADAPTER Adapter = 0;
+  NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+  BOOLEAN InterruptRegistered = FALSE;
+
+  /* Pick a medium */
+  for(i = 0; i < MediumArraySize; i++)
+    if(MediumArray[i] == NdisMedium802_3)
+      break;
+
+  if(i == MediumArraySize)
+    {
+      Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
+      PCNET_DbgPrint(("unsupported media\n"));
+      BREAKPOINT;
+      *OpenErrorStatus = Status;
+      return Status;
+    }
+
+  *SelectedMediumIndex = i;
+
+  /* allocate our adapter struct */
+  Status = NdisAllocateMemoryWithTag((PVOID *)&Adapter, sizeof(ADAPTER), PCNET_TAG);
+  if(Status != NDIS_STATUS_SUCCESS)
+    {
+      Status =  NDIS_STATUS_RESOURCES;
+      PCNET_DbgPrint(("Insufficient resources\n"));
+      BREAKPOINT;
+      *OpenErrorStatus = Status;
+      return Status;
+    }
+
+  memset(Adapter,0,sizeof(ADAPTER));
+
+  Adapter->MiniportAdapterHandle = MiniportAdapterHandle;
+
+  /* register our adapter structwith ndis */
+  NdisMSetAttributesEx(Adapter->MiniportAdapterHandle, Adapter, 0, NDIS_ATTRIBUTE_BUS_MASTER, NdisInterfacePci);
+
+  do
+    {
+      /* get registry config */
+      Status = MiGetConfig(Adapter, WrapperConfigurationContext);
+      if(Status != NDIS_STATUS_SUCCESS)
+        {
+          PCNET_DbgPrint(("MiGetConfig failed\n"));
+          Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+          BREAKPOINT;
+          break;
+        }
+
+      /* Card-specific detection and setup */
+      Status = MiQueryCard(Adapter);
+      if(Status != NDIS_STATUS_SUCCESS)
+        {
+          PCNET_DbgPrint(("MiQueryCard failed\n"));
+          Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+          BREAKPOINT;
+          break;
+        }
+
+      /* register an IO port range */
+      Status = NdisMRegisterIoPortRange(&Adapter->PortOffset, Adapter->MiniportAdapterHandle, 
+          Adapter->IoBaseAddress, NUMBER_OF_PORTS);
+      if(Status != NDIS_STATUS_SUCCESS)
+        {
+          PCNET_DbgPrint(("NdisMRegisterIoPortRange failed: 0x%x\n", Status));
+          BREAKPOINT
+          break;
+        }
+
+      /* Allocate map registers */
+      Status = NdisMAllocateMapRegisters(Adapter->MiniportAdapterHandle, 0, 
+          NDIS_DMA_32BITS, 8, BUFFER_SIZE);
+      if(Status != NDIS_STATUS_SUCCESS)
+        {
+          PCNET_DbgPrint(("NdisMAllocateMapRegisters failed: 0x%x\n", Status));
+          BREAKPOINT
+          break;
+        }
+
+      /* set up the interrupt */
+      memset(&Adapter->InterruptObject, 0, sizeof(NDIS_MINIPORT_INTERRUPT));
+      Status = NdisMRegisterInterrupt(&Adapter->InterruptObject, Adapter->MiniportAdapterHandle, Adapter->InterruptVector,
+          Adapter->InterruptVector, FALSE, TRUE, NdisInterruptLevelSensitive);
+      if(Status != NDIS_STATUS_SUCCESS)
+        {
+          PCNET_DbgPrint(("NdisMRegisterInterrupt failed: 0x%x\n", Status));
+          BREAKPOINT
+          break;
+        }
+
+      InterruptRegistered = TRUE;
+
+      /* Allocate and initialize shared data structures */
+      Status = MiAllocateSharedMemory(Adapter);
+      if(Status != NDIS_STATUS_SUCCESS)
+        {
+          Status = NDIS_STATUS_RESOURCES;
+          PCNET_DbgPrint(("MiAllocateSharedMemory failed", Status));
+          BREAKPOINT
+          break;
+        }
+
+      /* set up the initialization block */
+      MiPrepareInitializationBlock(Adapter);
+
+      PCNET_DbgPrint(("Interrupt registered successfully\n"));
+
+      /* Initialize and start the chip */
+      MiInitChip(Adapter);
+
+      Status = NDIS_STATUS_SUCCESS;
+    }
+  while(0);
+
+  if(Status != NDIS_STATUS_SUCCESS && Adapter)
+    {
+      PCNET_DbgPrint(("Error; freeing stuff\n"));
+
+      NdisMFreeMapRegisters(Adapter->MiniportAdapterHandle); /* doesn't hurt to free if we never alloc'd? */
+
+      if(Adapter->PortOffset)
+        NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress, NUMBER_OF_PORTS, Adapter->PortOffset);
+
+      if(InterruptRegistered)
+        NdisMDeregisterInterrupt(&Adapter->InterruptObject);
+
+      MiFreeSharedMemory(Adapter);
+
+      NdisFreeMemory(Adapter, 0, 0);
+    }
+
+#if DBG
+  if(!MiTestCard(Adapter))
+    __asm__("int $3\n");
+#endif
+
+  PCNET_DbgPrint(("returning 0x%x\n", Status));
+  *OpenErrorStatus = Status;
+  return Status;
+}
+
+\f
+VOID
+STDCALL
+MiniportISR(
+    OUT PBOOLEAN InterruptRecognized,
+    OUT PBOOLEAN QueueMiniportHandleInterrupt,
+    IN NDIS_HANDLE MiniportAdapterContext)
+/*
+ * FUNCTION: Miniport interrupt service routine
+ * ARGUMENTS:
+ *     InterruptRecognized: the interrupt was ours
+ *     QueueMiniportHandleInterrupt: whether to queue a DPC to handle this interrupt
+ *     MiniportAdapterContext: the context originally passed to NdisMSetAttributes
+ * NOTES:
+ *     - called by NDIS at DIRQL
+ *     - by setting QueueMiniportHandleInterrupt to TRUE, MiniportHandleInterrupt
+ *       will be called
+ */
+{
+  ULONG Data;
+  PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
+
+  PCNET_DbgPrint(("Called\n"));
+
+  /* XXX change this once MiniportHandleInterrupt does something */
+  *QueueMiniportHandleInterrupt = FALSE;
+
+  /* is this ours? */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RAP, CSR0);
+  NdisImmediateReadPortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, &Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RAP, CSR0);
+  NdisRawReadPortUlong(Adapter->PortOffset + RDP, &Data);
+#endif
+
+  if(!(Data & CSR0_INTR))
+    {
+      *InterruptRecognized = FALSE;
+      return;
+    }
+
+  /* clear the interrupt by writing back what we read */
+#if USE_IMMEDIATE_PORT_IO
+  NdisImmediateWritePortUlong(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress + RDP, Data);
+#else
+  NdisRawWritePortUlong(Adapter->PortOffset + RDP, Data);
+#endif
+
+  *InterruptRecognized = TRUE;
+}
+
+\f
+NDIS_STATUS
+STDCALL
+MiniportQueryInformation(
+    IN NDIS_HANDLE MiniportAdapterContext,
+    IN NDIS_OID Oid,
+    IN PVOID InformationBuffer,
+    IN ULONG InformationBufferLength,
+    OUT PULONG BytesWritten,
+    OUT PULONG BytesNeeded)
+/*
+ * FUNCTION: Query an OID from the driver
+ * ARGUMENTS:
+ *     MiniportAdapterContext: context originally passed to NdisMSetAttributes
+ *     Oid: OID NDIS is querying
+ *     InformationBuffer: pointer to buffer into which to write the results of the query
+ *     InformationBufferLength: size in bytes of InformationBuffer
+ *     BytesWritten: number of bytes written into InformationBuffer in response to the query
+ *     BytesNeeded: number of bytes needed to answer the query
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on all queries
+ * NOTES:
+ *     - Called by NDIS at PASSIVE_LEVEL
+ *     - If InformationBufferLength is insufficient to store the results, return the amount
+ *       needed in BytesNeeded and return NDIS_STATUS_INVALID_LENGTH
+ */
+{
+  PCNET_DbgPrint(("Called\n"));
+  return NDIS_STATUS_SUCCESS;
+}
+
+\f
+NDIS_STATUS
+STDCALL
+MiniportReset(
+    OUT PBOOLEAN AddressingReset,
+    IN NDIS_HANDLE MiniportAdapterContext)
+/*
+ * FUNCTION: Reset the miniport
+ * ARGUMENTS:
+ *     AddressingReset: Whether or not we want NDIS to subsequently call MiniportSetInformation
+ *                      to reset our addresses and filters
+ *     MiniportAdapterContext: context originally passed to NdisMSetAttributes
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on all requests
+ * Notes:
+ *     - Called by NDIS at PASSIVE_LEVEL when it thinks we need a reset
+ */
+{
+  PCNET_DbgPrint(("Called\n"));
+  return NDIS_STATUS_SUCCESS;
+}
+
+\f
+NDIS_STATUS
+STDCALL
+MiniportSetInformation(
+    IN NDIS_HANDLE MiniportAdapterContext,
+    IN NDIS_OID Oid,
+    IN PVOID InformationBuffer,
+    IN ULONG InformationBufferLength,
+    OUT PULONG BytesRead,
+    OUT PULONG BytesNeeded)
+/*
+ * FUNCTION: Set a miniport variable (OID)
+ * ARGUMENTS:
+ *     MiniportAdapterContext: context originally passed into NdisMSetAttributes
+ *     Oid: the variable being set
+ *     InformationBuffer: the data to set the variable to
+ *     InformationBufferLength: number of bytes in InformationBuffer
+ *     BytesRead: number of bytes read by us out of the buffer
+ *     BytesNeeded: number of bytes required to satisfy the request if InformationBufferLength
+ *                  is insufficient
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on all requests
+ * NOTES:
+ *     - Called by NDIS at PASSIVE_LEVEL
+ */
+{
+  PCNET_DbgPrint(("Called\n"));
+  return NDIS_STATUS_SUCCESS;
+}
+
+\f
+NDIS_STATUS
+STDCALL
+MiniportSend(
+    IN NDIS_HANDLE MiniportAdapterContext,
+    IN PNDIS_PACKET Packet,
+    IN UINT Flags)
+/*
+ * FUNCTION: Called by NDIS when it has a packet for the NIC to send out
+ * ARGUMENTS:
+ *     MiniportAdapterContext: context originally input to NdisMSetAttributes
+ *     Packet: The NDIS_PACKET to be sent
+ *     Flags: Flags associated with Packet
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on all requests
+ * NOTES:
+ *     - Called by NDIS at DISPATCH_LEVEL
+ */
+{
+  PCNET_DbgPrint(("Called\n"));
+  return NDIS_STATUS_SUCCESS;
+}
+
+\f
+NTSTATUS
+STDCALL
+DriverEntry(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PUNICODE_STRING RegistryPath)
+/*
+ * FUNCTION: Start this driver
+ * ARGUMENTS:
+ *     DriverObject: Pointer to the system-allocated driver object
+ *     RegistryPath: Pointer to our SCM database entry
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on success
+ *     NDIS_STATUS_FAILURE on failure
+ * NOTES:
+ *     - Called by the I/O manager when the driver starts at PASSIVE_LEVEL
+ *     - TODO: convert this to NTSTATUS return values
+ */
+{
+  NDIS_HANDLE WrapperHandle;
+  NDIS_MINIPORT_CHARACTERISTICS Characteristics;
+  NDIS_STATUS Status;
+
+  memset(&Characteristics, 0, sizeof(Characteristics));
+  Characteristics.MajorNdisVersion = 4;
+  Characteristics.HaltHandler = MiniportHalt;
+  Characteristics.HandleInterruptHandler = MiniportHandleInterrupt;
+  Characteristics.InitializeHandler = MiniportInitialize;
+  Characteristics.ISRHandler = MiniportISR;
+  Characteristics.QueryInformationHandler = MiniportQueryInformation;
+  Characteristics.ResetHandler = MiniportReset;
+  Characteristics.SetInformationHandler = MiniportSetInformation;
+  Characteristics.u1.SendHandler = MiniportSend;
+
+  NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, 0);
+
+  Status = NdisMRegisterMiniport(WrapperHandle, &Characteristics, sizeof(Characteristics));
+  if(Status != NDIS_STATUS_SUCCESS)
+    {
+      NdisTerminateWrapper(WrapperHandle, 0);
+      return NDIS_STATUS_FAILURE;
+    }
+
+  return NDIS_STATUS_SUCCESS;
+}
+
diff --git a/reactos/drivers/net/dd/pcnet/pcnet.h b/reactos/drivers/net/dd/pcnet/pcnet.h
new file mode 100644 (file)
index 0000000..ad5e14f
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  ReactOS AMD PCNet Driver
+ *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * PROJECT:         ReactOS AMD PCNet Driver
+ * FILE:            pcnet/pcnet.h
+ * PURPOSE:         PCNet Device Driver
+ * PROGRAMMER:      Vizzini (vizzini@plasmic.com)
+ * REVISIONS:
+ *                  1-Sept-2003 vizzini - Created
+ * NOTES:
+ *     - this is hard-coded to NDIS4
+ *     - this assumes a little-endian machine
+ */
+
+#ifndef _PCNET_H_
+#define _PCNET_H_
+
+/* adapter struct */
+typedef struct _ADAPTER 
+{
+  NDIS_HANDLE MiniportAdapterHandle;
+  ULONG Flags;
+  ULONG BusNumber;
+  ULONG SlotNumber;
+  ULONG InterruptVector;
+  ULONG IoBaseAddress;
+  PVOID PortOffset;
+  NDIS_MINIPORT_INTERRUPT InterruptObject;
+
+  /* initialization block */
+  ULONG InitializationBlockLength;
+  PINITIALIZATION_BLOCK InitializationBlockVirt;
+  NDIS_PHYSICAL_ADDRESS InitializationBlockPhys;
+
+  /* transmit descriptor ring */
+  ULONG TransmitDescriptorRingLength;
+  PTRANSMIT_DESCRIPTOR TransmitDescriptorRingVirt;
+  NDIS_PHYSICAL_ADDRESS TransmitDescriptorRingPhys;
+
+  /* transmit buffers */
+  ULONG TransmitBufferLength;
+  PCHAR TransmitBufferPtrVirt;
+  NDIS_PHYSICAL_ADDRESS TransmitBufferPtrPhys;
+
+  /* receive descriptor ring */
+  ULONG ReceiveDescriptorRingLength;
+  PRECEIVE_DESCRIPTOR ReceiveDescriptorRingVirt;
+  NDIS_PHYSICAL_ADDRESS ReceiveDescriptorRingPhys;
+
+  /* receive buffers */
+  ULONG ReceiveBufferLength;
+  PCHAR ReceiveBufferPtrVirt;
+  NDIS_PHYSICAL_ADDRESS ReceiveBufferPtrPhys;
+
+} ADAPTER, *PADAPTER;
+
+/* operational constants */
+#define NUMBER_OF_BUFFERS     0x20
+#define LOG_NUMBER_OF_BUFFERS 5         /* log2(NUMBER_OF_BUFFERS) */
+#define BUFFER_SIZE           0x600
+
+/* flags */
+#define RESET_IN_PROGRESS 0x1
+
+/* debugging */
+#if DBG
+#define PCNET_DbgPrint(_x) \
+{\
+  DbgPrint("%s:%d %s: ", __FILE__, __LINE__, __FUNCTION__); \
+  DbgPrint _x; \
+}
+#else
+#define PCNET_DbgPrint(_x)
+#endif
+
+#if DBG
+#define BREAKPOINT __asm__ ("int $3\n");
+#else
+#define BREAKPOINT
+#endif
+
+/* memory pool tag */
+#define PCNET_TAG 0xbaadf00d
+
+/* stack validation */
+#define STACKENTER __asm__("movl %%esp, %0\n" : "=m" (esp));
+
+#define STACKLEAVE {\
+  unsigned long esptemp = esp; \
+  __asm__ ("movl %%esp, %0\n": "=m" (esp)); \
+  if(esp != esptemp) \
+    __asm__ ("int $3\n"); \
+}
+
+#endif // _PCNET_H_
+
diff --git a/reactos/drivers/net/dd/pcnet/pcnet.rc b/reactos/drivers/net/dd/pcnet/pcnet.rc
new file mode 100644 (file)
index 0000000..5c0dcea
--- /dev/null
@@ -0,0 +1,38 @@
+#include <defines.h>
+#include <reactos/resource.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+       FILEVERSION     RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
+       PRODUCTVERSION  RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
+       FILEFLAGSMASK   0x3fL
+#ifdef _DEBUG
+       FILEFLAGS       0x1L
+#else
+       FILEFLAGS       0x0L
+#endif
+       FILEOS          0x40004L
+       FILETYPE        0x2L
+       FILESUBTYPE     0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName",      RES_STR_COMPANY_NAME
+            VALUE "FileDescription",  "PCNet Ethernet PCI Driver\0"
+            VALUE "FileVersion",         "0.0.1\0"
+            VALUE "InternalName",        "pcnet\0"
+            VALUE "LegalCopyright",      RES_STR_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename", "pcnet.sys\0"
+            VALUE "ProductName",         RES_STR_PRODUCT_NAME
+            VALUE "ProductVersion",      RES_STR_PRODUCT_VERSION
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
diff --git a/reactos/drivers/net/dd/pcnet/pcnethw.h b/reactos/drivers/net/dd/pcnet/pcnethw.h
new file mode 100644 (file)
index 0000000..e63f4fe
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ *  ReactOS AMD PCNet Driver
+ *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * PROJECT:         ReactOS AMD PCNet Driver
+ * FILE:            drivers/net/dd/pcnet/pcnethw.h
+ * PURPOSE:         PCNet hardware configuration constants
+ * PROGRAMMER:      Vizzini (vizzini@plasmic.com)
+ * REVISIONS:
+ *                  1-Sept-2003 vizzini - Created
+ * NOTES:
+ *     - This file represents a clean re-implementation from the AMD
+ *       PCNet II chip documentation (Am79C790A, pub# 19436).
+ */
+
+#define NUMBER_OF_PORTS 0x20    /* number of i/o ports the board requires */
+
+/* offsets of important registers */
+#define RDP   0x10
+#define RAP   0x12
+#define RESET 0x14
+#define BDP   0x16
+
+/* pci id of the device */
+#define PCI_ID 0x20001022
+#define VEN_ID 0x1022
+#define DEV_ID 0x2000
+
+/* software style constants */
+#define SW_STYLE_0 0
+#define SW_STYLE_1 1
+#define SW_STYLE_2 2
+#define SW_STYLE_3 3
+
+/* control and status registers */
+#define CSR0   0x0      /* controller status register */
+#define CSR1   0x1      /* init block address 0 */
+#define CSR2   0x2      /* init block address 1 */
+#define CSR3   0x3      /* interrupt masks and deferral control */
+#define CSR4   0x4      /* test and features control */
+#define CSR5   0x5      /* extended control and interrupt */
+#define CSR6   0x6      /* rx/tx descriptor table length */
+#define CSR8   0x8      /* logical address filter 0 */
+#define CSR9   0x9      /* logical address filter 1 */
+#define CSR10  0xa      /* logical address filter 2 */
+#define CSR11  0xb      /* logical address filter 3 */
+#define CSR12  0xc      /* physical address register 0 */
+#define CSR13  0xd      /* physical address register 1 */
+#define CSR14  0xe      /* physical address register 2 */
+#define CSR15  0xf      /* Mode */
+#define CSR16  0x10     /* initialization block address lower */
+#define CSR17  0x11     /* initialization block address upper */
+#define CSR18  0x12     /* current receive buffer address lower */
+#define CSR19  0x13     /* current receive buffer address upper */
+#define CSR20  0x14     /* current transmit buffer address lower */
+#define CSR21  0x15     /* current transmit buffer address upper */
+#define CSR22  0x16     /* next receive buffer address lower */
+#define CSR23  0x17     /* next receive buffer address upper */
+#define CSR24  0x18     /* base address of receive descriptor ring lower */
+#define CSR25  0x19     /* base address of receive descriptor ring upper */
+#define CSR26  0x1a     /* next receive descriptor address lower */
+#define CSR27  0x1b     /* next receive descriptor address upper */
+#define CSR28  0x1c     /* current receive descriptor address lower */
+#define CSR29  0x1d     /* current receive descriptor address upper */
+#define CSR30  0x1e     /* base address of transmit descriptor ring lower */
+#define CSR31  0x1f     /* base address of transmit descriptor ring upper */
+#define CSR32  0x20     /* next transmit descriptor address lower */
+#define CSR33  0x21     /* next transmit descriptor address upper */
+#define CSR34  0x22     /* current transmit descriptor address lower */
+#define CSR35  0x23     /* current transmit descriptor address upper */
+#define CSR36  0x24     /* next next receive descriptor address lower */
+#define CSR37  0x25     /* next next receive descriptor address upper */
+#define CSR38  0x26     /* next next transmit descriptor address lower */
+#define CSR39  0x27     /* next next transmit descriptor address upper */
+#define CSR40  0x28     /* current receive byte count */
+#define CSR41  0x29     /* current receive status */
+#define CSR42  0x2a     /* current transmit byte count */
+#define CSR43  0x2b     /* current transmit status */
+#define CSR44  0x2c     /* next receive byte count */
+#define CSR45  0x2d     /* next receive status */
+#define CSR46  0x2e     /* poll time counter */
+#define CSR47  0x2f     /* polling interval */
+#define CSR58  0x3a     /* software style */
+#define CSR60  0x3c     /* previous transmit descriptor address lower */
+#define CSR61  0x3d     /* previous transmit descriptor address upper */
+#define CSR62  0x3e     /* previous transmit byte count */
+#define CSR63  0x3f     /* previous transmit status */
+#define CSR64  0x40     /* next transmit buffer address lower */
+#define CSR65  0x41     /* next transmit buffer address upper */
+#define CSR66  0x42     /* next transmit byte count */
+#define CSR67  0x43     /* next transmit status */
+#define CSR72  0x48     /* receive descriptor ring counter */
+#define CSR74  0x4a     /* transmit descriptor ring counter */
+#define CSR76  0x4c     /* receive descriptor ring length */
+#define CSR78  0x4e     /* transmit descriptor ring length */
+#define CSR80  0x50     /* dma transfer counter and fifo watermark control */
+#define CSR82  0x52     /* bus activity timer */
+#define CSR84  0x54     /* dma address register lower */
+#define CSR85  0x55     /* dma address register upper */
+#define CSR86  0x56     /* buffer byte counter */
+#define CSR88  0x58     /* chip id register lower */
+#define CSR89  0x59     /* chip id register upper */
+#define CSR94  0x5e     /* transmit time domain reflectometry count */
+#define CSR100 0x64     /* bus timeout */
+#define CSR112 0x70     /* missed frame count */
+#define CSR114 0x72     /* receive collision count */
+#define CSR122 0x7a     /* advanced feature control */
+#define CSR124 0x7c     /* test register control */
+
+/* bus configuration registers */
+#define BCR2   0x2      /* miscellaneous configuration */
+#define BCR4   0x4      /* link status led */
+#define BCR5   0x5      /* led1 status */
+#define BCR6   0x6      /* led2 status */
+#define BCR7   0x7      /* led3 status */
+#define BCR9   0x9      /* full-duplex control */
+#define BCR16  0x10     /* i/o base address lower */
+#define BCR17  0x11     /* i/o base address upper */
+#define BCR18  0x12     /* burst and bus control register */
+#define BCR19  0x13     /* eeprom control and status */
+#define BCR20  0x14     /* software style */
+#define BCR21  0x15     /* interrupt control */
+#define BCR22  0x16     /* pci latency register */
+
+/* CSR0 bits */
+#define CSR0_INIT  0x1          /* read initialization block */
+#define CSR0_STRT  0x2          /* start the chip */
+#define CSR0_STOP  0x4          /* stop the chip */
+#define CSR0_TDMD  0x8          /* transmit demand */
+#define CSR0_TXON  0x10         /* transmit on */
+#define CSR0_RXON  0x20         /* receive on */
+#define CSR0_IENA  0x40         /* interrupt enabled */
+#define CSR0_INTR  0x80         /* interrupting */
+#define CSR0_IDON  0x100        /* initialization done */
+#define CSR0_TINT  0x200        /* transmit interrupt */
+#define CSR0_RINT  0x400        /* receive interrupt */
+#define CSR0_MERR  0x800        /* memory error */
+#define CSR0_MISS  0x1000       /* missed frame */
+#define CSR0_CERR  0x2000       /* collision error */
+#define CSR0_BABL  0x4000       /* babble */
+#define CSR0_ERR   0x8000       /* error */
+
+/* CSR3 bits */
+#define CSR3_BSWP    0x4        /* byte swap */
+#define CSR3_EMBA    0x8        /* enable modified backoff algorithm */
+#define CSR3_DXMT2PD 0x10       /* disable transmit two-part deferral */
+#define CSR3_LAPPEN  0x20       /* lookahead packet processing enable */
+#define CSR3_DXSUFLO 0x40       /* disable transmit stop on underflow */
+#define CSR3_IDONM   0x100      /* initialization done mask */
+#define CSR3_TINTM   0x200      /* transmit interrupt mask */
+#define CSR3_RINTM   0x400      /* receive interrupt mask */
+#define CSR3_MERRM   0x800      /* memory error interrupt mask */
+#define CSR3_MISSM   0x1000     /* missed frame interrupt mask */
+#define CSR3_BABLM   0x4000     /* babble interrupt mask */
+
+/* CSR4 bits */
+#define CSR4_JABM      0x1      /* jabber interrupt mask */
+#define CSR4_JAB       0x2      /* interrupt on jabber error */
+#define CSR4_TXSTRTM   0x4      /* transmit start interrupt mask */
+#define CSR4_TXSTRT    0x8      /* interrupt on transmit start */
+#define CSR4_RCVCCOM   0x10     /* receive collision counter overflow mask */
+#define CSR4_RCVCCO    0X20     /* interrupt on receive collision counter overflow */
+#define CSR4_UINT      0x40     /* user interrupt */
+#define CSR4_UINTCMD   0x80     /* user interrupt command */
+#define CSR4_MFCOM     0x100    /* missed frame counter overflow mask */
+#define CSR4_MFCO      0x200    /* interrupt on missed frame counter overflow */
+#define CSR4_ASTRP_RCV 0x400    /* auto pad strip on receive */
+#define CSR4_APAD_XMT  0x800    /* auto pad on transmit */
+#define CSR4_DPOLL     0x1000   /* disable transmit polling */
+#define CSR4_TIMER     0x2000   /* enable bus activity timer */
+#define CSR4_DMAPLUS   0x4000   /* set to 1 for pci */
+#define CSR4_EN124     0x8000   /* enable CSR124 access */
+
+/* CSR5 bits */
+#define CSR5_SPND      0x1      /* suspend */
+#define CSR5_MPMODE    0x2      /* magic packet mode */
+#define CSR5_MPEN      0x4      /* magic packet enable */
+#define CSR5_MPINTE    0x8      /* magic packet interrupt enable */
+#define CSR5_MPINT     0x10     /* magic packet interrupt */
+#define CSR5_MPPLBA    0x20     /* magic packet physical logical broadcast accept */
+#define CSR5_EXDINTE   0x40     /* excessive deferral interrupt enable */
+#define CSR5_EXDINT    0x80     /* excessive deferral interrupt */
+#define CSR5_SLPINTE   0x100    /* sleep interrupt enable */
+#define CSR5_SLPINT    0x200    /* sleep interrupt */
+#define CSR5_SINE      0x400    /* system interrupt enable */
+#define CSR5_SINT      0x800    /* system interrupt */
+#define CSR5_LTINTEN   0x4000   /* last transmit interrupt enable */
+#define CSR5_TOKINTD   0x8000   /* transmit ok interrupt disable */
+
+/* CSR15 bits */
+#define CSR15_DRX      0x1      /* disable receiver */
+#define CSR15_DTX      0x2      /* disable transmitter */
+#define CSR15_LOOP     0x4      /* loopback enable */
+#define CSR15_DXMTFCS  0x8      /* disable transmit fcs */
+#define CSR15_FCOLL    0x10     /* force collision */
+#define CSR15_DRTY     0x20     /* disable retry */
+#define CSR15_INTL     0x40     /* internal loopback */
+#define CSR15_PORTSEL0 0x80     /* port selection bit 0 */
+#define CSR15_PORTSEL1 0x100    /* port selection bit 1 */
+#define CSR15_LRT      0x200    /* low receive threshold - same as TSEL */
+#define CSR15_TSEL     0x200    /* transmit mode select - same as LRT */
+#define CSR15_MENDECL  0x400    /* mendec loopback mode */
+#define CSR15_DAPC     0x800    /* disable automatic parity correction */
+#define CSR15_DLNKTST  0x1000   /* disable link status */
+#define CSR15_DRCVPA   0x2000   /* disable receive physical address */
+#define CSR15_DRCVBC   0x4000   /* disable receive broadcast */
+#define CSR15_PROM     0x8000   /* promiscuous mode */
+
+/* CSR58 bits */
+#define CSR58_SSIZE32  0x100    /* 32-bit software size */
+#define CSR58_CSRPCNET 0x200    /* csr pcnet-isa configuration */
+#define CSR58_APERREN  0x400    /* advanced parity error handling enable */
+
+/* CSR124 bits */
+#define CSR124_RPA     0x4      /* runt packet accept */
+
+/* BCR2 bits */
+#define BCR2_ASEL      0x2      /* auto-select media */
+#define BCR2_AWAKE     0x4      /* select sleep mode */
+#define BCR2_EADISEL   0x8      /* eadi select */
+#define BCR2_DXCVRPOL  0x10     /* dxcvr polarity */
+#define BCR2_DXCVRCTL  0x20     /* dxcvr control */
+#define BCR2_INTLEVEL  0x80     /* interrupt level/edge */
+#define BCR2_APROMWE   0x100    /* address prom write enable */
+#define BCR2_TMAULOOP  0x4000   /* t-mau transmit on loopback */
+
+/* BCR4 bits */
+#define BCR4_COLE      0x1      /* collision status enable */
+#define BCR4_JABE      0x2      /* jabber status enable */
+#define BCR4_RCVE      0x4      /* receive status enable */
+#define BCR4_RXPOLE    0x8      /* receive polarity status enable */
+#define BCR4_XMTE      0x10     /* transmit status enable */
+#define BCR4_RCVME     0x20     /* receive match status enable */
+#define BCR4_LNKSTE    0x40     /* link status enable */
+#define BCR4_PSE       0x80     /* pulse stretcher enable */
+#define BCR4_FDLSE     0x100    /* full-duplex link status enable */
+#define BCR4_MPSE      0x200    /* magic packet status enable */
+#define BCR4_LEDDIS    0x2000   /* led disable */
+#define BCR4_LEDPOL    0x4000   /* led polarity */
+#define BCR4_LEDOUT    0x8000   /* led output pin value */
+
+/* BCR5 bits */
+#define BCR5_COLE      0x1      /* collision status enable */
+#define BCR5_JABE      0x2      /* jabber status enable */
+#define BCR5_RCVE      0x4      /* receive status enable */
+#define BCR5_RXPOLE    0x8      /* receive polarity status enable */
+#define BCR5_XMTE      0x10     /* transmit status enable */
+#define BCR5_RCVME     0x20     /* receive match status enable */
+#define BCR5_LNKSTE    0x40     /* link status enable */
+#define BCR5_PSE       0x80     /* pulse stretcher enable */
+#define BCR5_FDLSE     0x100    /* full-duplex link status enable */
+#define BCR5_MPSE      0x200    /* magic packet status enable */
+#define BCR5_LEDDIS    0x2000   /* led disable */
+#define BCR5_LEDPOL    0x4000   /* led polarity */
+#define BCR5_LEDOUT    0x8000   /* led output pin value */
+
+/* BCR6 bits */
+#define BCR6_COLE      0x1      /* collision status enable */
+#define BCR6_JABE      0x2      /* jabber status enable */
+#define BCR6_RCVE      0x4      /* receive status enable */
+#define BCR6_RXPOLE    0x8      /* receive polarity status enable */
+#define BCR6_XMTE      0x10     /* transmit status enable */
+#define BCR6_RCVME     0x20     /* receive match status enable */
+#define BCR6_LNKSTE    0x40     /* link status enable */
+#define BCR6_PSE       0x80     /* pulse stretcher enable */
+#define BCR6_FDLSE     0x100    /* full-duplex link status enable */
+#define BCR6_MPSE      0x200    /* magic packet status enable */
+#define BCR6_LEDDIS    0x2000   /* led disable */
+#define BCR6_LEDPOL    0x4000   /* led polarity */
+#define BCR6_LEDOUT    0x8000   /* led output pin value */
+
+/* BCR7 bits */
+#define BCR7_COLE      0x1      /* collision status enable */
+#define BCR7_JABE      0x2      /* jabber status enable */
+#define BCR7_RCVE      0x4      /* receive status enable */
+#define BCR7_RXPOLE    0x8      /* receive polarity status enable */
+#define BCR7_XMTE      0x10     /* transmit status enable */
+#define BCR7_RCVME     0x20     /* receive match status enable */
+#define BCR7_LNKSTE    0x40     /* link status enable */
+#define BCR7_PSE       0x80     /* pulse stretcher enable */
+#define BCR7_FDLSE     0x100    /* full-duplex link status enable */
+#define BCR7_MPSE      0x200    /* magic packet status enable */
+#define BCR7_LEDDIS    0x2000   /* led disable */
+#define BCR7_LEDPOL    0x4000   /* led polarity */
+#define BCR7_LEDOUT    0x8000   /* led output pin value */
+
+/* BCR9 bits */
+#define BCR9_FDEN      0x1      /* full-duplex enable */
+#define BCR9_AUIFD     0x2      /* aui full-duplex */
+#define BCR9_FDRPAD    0x4      /* full-duplex runt packet accept disable */
+
+/* BCR18 bits */
+#define BCR18_BWRITE   0x20     /* burst write enable */
+#define BCR18_BREADE   0x40     /* burst read enable */
+#define BCR18_DWIO     0x80     /* dword i/o enable */
+#define BCR18_EXTREQ   0x100    /* extended request */
+#define BCR18_MEMCMD   0x200    /* memory command */
+
+/* BCR19 bits */
+#define BCR19_EDI      0x1      /* eeprom data in - same as EDO */
+#define BCR19_ED0      0x1      /* eeprom data out - same as EDI */
+#define BCR19_ESK      0x2      /* eeprom serial clock */
+#define BCR19_ECS      0x4      /* eeprom chip select */
+#define BCR19_EEN      0x8      /* eeprom port enable */
+#define BCR19_EEDET    0x2000   /* eeprom detect */
+#define BCR19_PREAD    0x4000   /* eeprom read */
+#define BCR19_PVALID   0x8000   /* eeprom valid */
+
+/* BCR20 bits */
+#define BCR20_SSIZE32  0x100    /* 32-bit software size */
+#define BCR20_CSRPCNET 0x200    /* csr pcnet-isa configuration */
+#define BCR20_APERREN  0x400    /* advanced parity error handling enable */
+
+/* initialization block for 32-bit software style */
+typedef struct _INITIALIZATION_BLOCK
+{
+  USHORT MODE;          /* card mode (csr15) */
+  UCHAR  RLEN;          /* encoded number of receive descriptor ring entries */
+  UCHAR  TLEN;          /* encoded number of transmit descriptor ring entries */
+  UCHAR  PADR[6];       /* physical address */
+  USHORT RES;           /* reserved */
+  UCHAR  LADR[8];       /* logical address */
+  ULONG  RDRA;          /* receive descriptor ring address */
+  ULONG  TDRA;          /* transmit descriptor ring address */
+} INITIALIZATION_BLOCK, *PINITIALIZATION_BLOCK;
+
+/* receive descriptor, software stle 2 (32-bit) */
+typedef struct _RECEIVE_DESCRIPTOR
+{
+  ULONG  RBADR;         /* receive buffer address */
+  USHORT BCNT;          /* two's compliment buffer byte count - NOTE: always OR with 0xf000 */
+  UCHAR  FLAGS;         /* flags - always and with 0xfff0 */
+  USHORT MCNT;          /* message byte count ; always AND with 0x0fff */
+  UCHAR  RPC;           /* runt packet count */
+  UCHAR  RCC;           /* receive collision count */
+  ULONG  RES;           /* resereved */
+} RECEIVE_DESCRIPTOR, *PRECEIVE_DESCRIPTOR;
+
+/* receive descriptor flags */
+#define RD_BAM         0x10     /* broadcast address match */
+#define RD_LAFM        0x20     /* logical address filter match */
+#define RD_PAM         0x40     /* physical address match */
+#define RD_BPE         0x80     /* bus parity error */
+#define RD_ENP         0x100    /* end of packet */
+#define RD_STP         0x200    /* start of packet */
+#define RD_BUFF        0x400    /* buffer error */
+#define RD_CRC         0x800    /* crc error */
+#define RD_OFLO        0x1000   /* overflow error */
+#define RD_FRAM        0x2000   /* framing error */
+#define RD_ERR         0x4000   /* an error bit is set */
+#define RD_OWN         0x8000   /* buffer ownership (0=host, 1=nic) */
+
+/* transmit descriptor, software style 2 */
+typedef struct _TRANSMIT_DESCRIPTOR
+{
+  ULONG  TBADR;         /* transmit buffer address */
+  USHORT BCNT;          /* two's compliment buffer byte count - OR with 0xf000 */
+  USHORT FLAGS;         /* flags */
+  USHORT TRC;           /* transmit retry count (AND with 0x000f */
+  USHORT FLAGS2;        /* more flags */
+  ULONG  RES;           /* reserved */
+} TRANSMIT_DESCRIPTOR, *PTRANSMIT_DESCRIPTOR;
+
+/* transmit descriptor flags */
+#define TD1_BPE         0x80    /* bus parity error */
+#define TD1_ENP         0x100   /* end of packet */
+#define TD1_STP         0x200   /* start of packet */
+#define TD1_DEF         0x400   /* frame transmission deferred */
+#define TD1_ONE         0x800   /* exactly one retry was needed for transmission */
+#define TD1_MORE        0x1000  /* more than 1 transmission retry required - same as LTINT */
+#define TD1_LTINT       0x1000  /* suppress transmit success interrupt - same as MORE */
+#define TD1_ADD_FCS     0x2000  /* force fcs generation - same as NO_FCS */
+#define TD1_NO_FCS      0x2000  /* prevent fcs generation - same as ADD_FCS */
+#define TD1_ERR         0x4000  /* an error bit is set */
+#define TD1_OWN         0x8000  /* buffer ownership */
+
+/* transmit descriptor flags2 flags */
+#define TD2_RTRY        0x400   /* retry error */
+#define TD2_LCAR        0x800   /* loss of carrier */
+#define TD2_LCOL        0x1000  /* late collision */
+#define TD2_EXDEF       0x2000  /* excessive deferral */
+#define TD2_UFLO        0x4000  /* buffer underflow */
+#define TD2_BUFF        0x8000  /* buffer error */
+
+