[E1000] Basic initialization of the card
authorMark Jansen <mark.jansen@reactos.org>
Sun, 27 May 2018 22:09:10 +0000 (00:09 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Thu, 7 Feb 2019 18:48:54 +0000 (19:48 +0100)
Initialize some registers, allocate basic resources

CORE-14675

drivers/network/dd/e1000/CMakeLists.txt
drivers/network/dd/e1000/debug.c [new file with mode: 0644]
drivers/network/dd/e1000/debug.h
drivers/network/dd/e1000/e1000hw.h
drivers/network/dd/e1000/hardware.c
drivers/network/dd/e1000/info.c
drivers/network/dd/e1000/ndis.c
drivers/network/dd/e1000/nic.h

index eeee376..591f01d 100644 (file)
@@ -11,6 +11,7 @@ list(APPEND SOURCE
     interrupt.c
     nic.h
     e1000hw.h
+    debug.c
     debug.h)
 
 add_library(e1000 SHARED ${SOURCE} e1000.rc)
diff --git a/drivers/network/dd/e1000/debug.c b/drivers/network/dd/e1000/debug.c
new file mode 100644 (file)
index 0000000..d3008bc
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * PROJECT:     ReactOS Intel PRO/1000 Driver
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Translate NDIS_OID to readable string
+ * COPYRIGHT:   Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
+ */
+
+#include "nic.h"
+
+#include <debug.h>
+
+const char* Oid2Str(IN NDIS_OID Oid)
+{
+#if DBG
+    switch (Oid)
+    {
+#define RETURN_X(x) case x: return #x;
+        /* Required Object IDs (OIDs) */
+        RETURN_X(OID_GEN_SUPPORTED_LIST);
+        RETURN_X(OID_GEN_HARDWARE_STATUS);
+        RETURN_X(OID_GEN_MEDIA_SUPPORTED);
+        RETURN_X(OID_GEN_MEDIA_IN_USE);
+        RETURN_X(OID_GEN_MAXIMUM_LOOKAHEAD);
+        RETURN_X(OID_GEN_MAXIMUM_FRAME_SIZE);
+        RETURN_X(OID_GEN_LINK_SPEED);
+        RETURN_X(OID_GEN_TRANSMIT_BUFFER_SPACE);
+        RETURN_X(OID_GEN_RECEIVE_BUFFER_SPACE);
+        RETURN_X(OID_GEN_TRANSMIT_BLOCK_SIZE);
+        RETURN_X(OID_GEN_RECEIVE_BLOCK_SIZE);
+        RETURN_X(OID_GEN_VENDOR_ID);
+        RETURN_X(OID_GEN_VENDOR_DESCRIPTION);
+        RETURN_X(OID_GEN_CURRENT_PACKET_FILTER);
+        RETURN_X(OID_GEN_CURRENT_LOOKAHEAD);
+        RETURN_X(OID_GEN_DRIVER_VERSION);
+        RETURN_X(OID_GEN_MAXIMUM_TOTAL_SIZE);
+        RETURN_X(OID_GEN_PROTOCOL_OPTIONS);
+        RETURN_X(OID_GEN_MAC_OPTIONS);
+        RETURN_X(OID_GEN_MEDIA_CONNECT_STATUS);
+        RETURN_X(OID_GEN_MAXIMUM_SEND_PACKETS);
+        RETURN_X(OID_GEN_VENDOR_DRIVER_VERSION);
+        RETURN_X(OID_GEN_SUPPORTED_GUIDS);
+        RETURN_X(OID_GEN_NETWORK_LAYER_ADDRESSES);
+        RETURN_X(OID_GEN_TRANSPORT_HEADER_OFFSET);
+        RETURN_X(OID_GEN_MACHINE_NAME);
+        RETURN_X(OID_GEN_RNDIS_CONFIG_PARAMETER);
+        RETURN_X(OID_GEN_VLAN_ID);
+
+        /* Optional OIDs */
+        RETURN_X(OID_GEN_MEDIA_CAPABILITIES);
+        RETURN_X(OID_GEN_PHYSICAL_MEDIUM);
+
+        /* Required statistics OIDs */
+        RETURN_X(OID_GEN_XMIT_OK);
+        RETURN_X(OID_GEN_RCV_OK);
+        RETURN_X(OID_GEN_XMIT_ERROR);
+        RETURN_X(OID_GEN_RCV_ERROR);
+        RETURN_X(OID_GEN_RCV_NO_BUFFER);
+
+        /* Optional statistics OIDs */
+        RETURN_X(OID_GEN_DIRECTED_BYTES_XMIT);
+        RETURN_X(OID_GEN_DIRECTED_FRAMES_XMIT);
+        RETURN_X(OID_GEN_MULTICAST_BYTES_XMIT);
+        RETURN_X(OID_GEN_MULTICAST_FRAMES_XMIT);
+        RETURN_X(OID_GEN_BROADCAST_BYTES_XMIT);
+        RETURN_X(OID_GEN_BROADCAST_FRAMES_XMIT);
+        RETURN_X(OID_GEN_DIRECTED_BYTES_RCV);
+        RETURN_X(OID_GEN_DIRECTED_FRAMES_RCV);
+        RETURN_X(OID_GEN_MULTICAST_BYTES_RCV);
+        RETURN_X(OID_GEN_MULTICAST_FRAMES_RCV);
+        RETURN_X(OID_GEN_BROADCAST_BYTES_RCV);
+        RETURN_X(OID_GEN_BROADCAST_FRAMES_RCV);
+        RETURN_X(OID_GEN_RCV_CRC_ERROR);
+        RETURN_X(OID_GEN_TRANSMIT_QUEUE_LENGTH);
+        RETURN_X(OID_GEN_GET_TIME_CAPS);
+        RETURN_X(OID_GEN_GET_NETCARD_TIME);
+        RETURN_X(OID_GEN_NETCARD_LOAD);
+        RETURN_X(OID_GEN_DEVICE_PROFILE);
+        RETURN_X(OID_GEN_INIT_TIME_MS);
+        RETURN_X(OID_GEN_RESET_COUNTS);
+        RETURN_X(OID_GEN_MEDIA_SENSE_COUNTS);
+        RETURN_X(OID_GEN_FRIENDLY_NAME);
+        RETURN_X(OID_GEN_MINIPORT_INFO);
+        RETURN_X(OID_GEN_RESET_VERIFY_PARAMETERS);
+
+        /* IEEE 802.3 (Ethernet) OIDs */
+        //RETURN_X(NDIS_802_3_MAC_OPTION_PRIORITY);     /*Duplicate ID */
+
+        RETURN_X(OID_802_3_PERMANENT_ADDRESS);
+        RETURN_X(OID_802_3_CURRENT_ADDRESS);
+        RETURN_X(OID_802_3_MULTICAST_LIST);
+        RETURN_X(OID_802_3_MAXIMUM_LIST_SIZE);
+        RETURN_X(OID_802_3_MAC_OPTIONS);
+        RETURN_X(OID_802_3_RCV_ERROR_ALIGNMENT);
+        RETURN_X(OID_802_3_XMIT_ONE_COLLISION);
+        RETURN_X(OID_802_3_XMIT_MORE_COLLISIONS);
+        RETURN_X(OID_802_3_XMIT_DEFERRED);
+        RETURN_X(OID_802_3_XMIT_MAX_COLLISIONS);
+        RETURN_X(OID_802_3_RCV_OVERRUN);
+        RETURN_X(OID_802_3_XMIT_UNDERRUN);
+        RETURN_X(OID_802_3_XMIT_HEARTBEAT_FAILURE);
+        RETURN_X(OID_802_3_XMIT_TIMES_CRS_LOST);
+        RETURN_X(OID_802_3_XMIT_LATE_COLLISIONS);
+
+        /* IEEE 802.11 (WLAN) OIDs */
+        RETURN_X(OID_802_11_BSSID);
+        RETURN_X(OID_802_11_SSID);
+        RETURN_X(OID_802_11_NETWORK_TYPES_SUPPORTED);
+        RETURN_X(OID_802_11_NETWORK_TYPE_IN_USE);
+        RETURN_X(OID_802_11_TX_POWER_LEVEL);
+        RETURN_X(OID_802_11_RSSI);
+        RETURN_X(OID_802_11_RSSI_TRIGGER);
+        RETURN_X(OID_802_11_INFRASTRUCTURE_MODE);
+        RETURN_X(OID_802_11_FRAGMENTATION_THRESHOLD);
+        RETURN_X(OID_802_11_RTS_THRESHOLD);
+        RETURN_X(OID_802_11_NUMBER_OF_ANTENNAS);
+        RETURN_X(OID_802_11_RX_ANTENNA_SELECTED);
+        RETURN_X(OID_802_11_TX_ANTENNA_SELECTED);
+        RETURN_X(OID_802_11_SUPPORTED_RATES);
+        RETURN_X(OID_802_11_DESIRED_RATES);
+        RETURN_X(OID_802_11_CONFIGURATION);
+        RETURN_X(OID_802_11_STATISTICS);
+        RETURN_X(OID_802_11_ADD_WEP);
+        RETURN_X(OID_802_11_REMOVE_WEP);
+        RETURN_X(OID_802_11_DISASSOCIATE);
+        RETURN_X(OID_802_11_POWER_MODE);
+        RETURN_X(OID_802_11_BSSID_LIST);
+        RETURN_X(OID_802_11_AUTHENTICATION_MODE);
+        RETURN_X(OID_802_11_PRIVACY_FILTER);
+        RETURN_X(OID_802_11_BSSID_LIST_SCAN);
+        RETURN_X(OID_802_11_WEP_STATUS);
+        RETURN_X(OID_802_11_RELOAD_DEFAULTS);
+
+        /* OID_GEN_MINIPORT_INFO constants */
+        RETURN_X(NDIS_MINIPORT_BUS_MASTER);
+        RETURN_X(NDIS_MINIPORT_WDM_DRIVER);
+        RETURN_X(NDIS_MINIPORT_SG_LIST);
+        RETURN_X(NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY);
+        RETURN_X(NDIS_MINIPORT_INDICATES_PACKETS);
+        RETURN_X(NDIS_MINIPORT_IGNORE_PACKET_QUEUE);
+        RETURN_X(NDIS_MINIPORT_IGNORE_REQUEST_QUEUE);
+        RETURN_X(NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS);
+        RETURN_X(NDIS_MINIPORT_INTERMEDIATE_DRIVER);
+        RETURN_X(NDIS_MINIPORT_IS_NDIS_5);
+        RETURN_X(NDIS_MINIPORT_IS_CO);
+        RETURN_X(NDIS_MINIPORT_DESERIALIZE);
+        RETURN_X(NDIS_MINIPORT_REQUIRES_MEDIA_POLLING);
+        RETURN_X(NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE);
+        RETURN_X(NDIS_MINIPORT_NETBOOT_CARD);
+        RETURN_X(NDIS_MINIPORT_PM_SUPPORTED);
+        RETURN_X(NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE);
+        RETURN_X(NDIS_MINIPORT_USES_SAFE_BUFFER_APIS);
+        RETURN_X(NDIS_MINIPORT_HIDDEN);
+        RETURN_X(NDIS_MINIPORT_SWENUM);
+        RETURN_X(NDIS_MINIPORT_SURPRISE_REMOVE_OK);
+        RETURN_X(NDIS_MINIPORT_NO_HALT_ON_SUSPEND);
+        RETURN_X(NDIS_MINIPORT_HARDWARE_DEVICE);
+        RETURN_X(NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS);
+        RETURN_X(NDIS_MINIPORT_64BITS_DMA);
+    default:
+        return "<UNKNOWN>";
+    }
+#else
+    return "!DBG";
+#endif
+}
+
+
index b6ff2cf..481f604 100644 (file)
@@ -62,3 +62,5 @@ extern ULONG DebugTraceLevel;
     } while (0)
 
 
+const char* Oid2Str(IN NDIS_OID Oid);
+
index 57ac8fc..9932974 100644 (file)
@@ -9,6 +9,18 @@
 
 #define IEEE_802_ADDR_LENGTH 6
 
+#define HW_VENDOR_INTEL     0x8086
+
+#define MAX_RESET_ATTEMPTS  10
+
+#define MAX_PHY_REG_ADDRESS         0x1F
+#define MAX_PHY_READ_ATTEMPTS       1800
+
+#define MAX_EEPROM_READ_ATTEMPTS    10000
+
+
+#define MAXIMUM_MULTICAST_ADDRESSES 16
+
 
 /* Ethernet frame header */
 typedef struct _ETH_HEADER {
@@ -17,3 +29,91 @@ typedef struct _ETH_HEADER {
     USHORT PayloadType;
 } ETH_HEADER, *PETH_HEADER;
 
+
+
+
+
+/* Registers */
+#define E1000_REG_CTRL              0x0000      /* Device Control Register, R/W */
+#define E1000_REG_STATUS            0x0008      /* Device Status Register, R */
+#define E1000_REG_EERD              0x0014      /* EEPROM Read Register, R/W */
+#define E1000_REG_MDIC              0x0020      /* MDI Control Register, R/W */
+#define E1000_REG_VET               0x0038      /* VLAN Ether Type, R/W */
+#define E1000_REG_ICR               0x00C0      /* Interrupt Cause Read, R/clr */
+
+#define E1000_REG_IMS               0x00D0      /* Interrupt Mask Set/Read Register, R/W */
+#define E1000_REG_IMC               0x00D8      /* Interrupt Mask Clear, W */
+#define E1000_REG_RCTL              0x0100      /* Receive Control, R/W */
+
+#define E1000_REG_RAL               0x5400      /* Receive Address Low, R/W */
+#define E1000_REG_RAH               0x5404      /* Receive Address High, R/W */
+
+
+/* E1000_REG_CTRL */
+#define E1000_CTRL_RST              (1 << 26)   /* Device Reset, Self clearing */
+
+
+/* E1000_REG_STATUS */
+#define E1000_STATUS_LU             (1 << 0)    /* Link Up Indication */
+#define E1000_STATUS_SPEEDSHIFT     6           /* Link speed setting */
+#define E1000_STATUS_SPEEDMASK      (3 << E1000_STATUS_SPEEDSHIFT)
+
+
+/* E1000_REG_EERD */
+#define E1000_EERD_START            (1 << 0)    /* Start Read*/
+#define E1000_EERD_DONE             (1 << 4)    /* Read Done */
+#define E1000_EERD_ADDR_SHIFT       8
+#define E1000_EERD_DATA_SHIFT       16
+
+
+/* E1000_REG_MDIC */
+#define E1000_MDIC_REGADD_SHIFT     16          /* PHY Register Address */
+#define E1000_MDIC_PHYADD_SHIFT     21          /* PHY Address (1=Gigabit, 2=PCIe) */
+#define E1000_MDIC_PHYADD_GIGABIT   1
+#define E1000_MDIC_OP_READ          (2 << 26)   /* Opcode */
+#define E1000_MDIC_R                (1 << 28)   /* Ready Bit */
+#define E1000_MDIC_E                (1 << 30)   /* Error */
+
+
+/* E1000_REG_IMS */
+#define E1000_IMS_LSC               (1 << 2)    /* Sets mask for Link Status Change */
+
+
+/* E1000_REG_RCTL */
+#define E1000_RCTL_EN               (1 << 1)    /* Receiver Enable */
+#define E1000_RCTL_SBP              (1 << 2)    /* Store Bad Packets */
+#define E1000_RCTL_UPE              (1 << 3)    /* Unicast Promiscuous Enabled */
+#define E1000_RCTL_MPE              (1 << 4)    /* Multicast Promiscuous Enabled */
+#define E1000_RCTL_BAM              (1 << 15)   /* Broadcast Accept Mode */
+#define E1000_RCTL_PMCF             (1 << 23)   /* Pass MAC Control Frames */
+
+#define E1000_RCTL_FILTER_BITS      (E1000_RCTL_SBP | E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_BAM | E1000_RCTL_PMCF)
+
+/* E1000_REG_RAH */
+#define E1000_RAH_AV                (1 << 31)   /* Address Valid */
+
+
+
+
+/* NVM */
+#define E1000_NVM_REG_CHECKSUM      0x03f
+#define NVM_MAGIC_SUM               0xBABA
+
+
+
+/* PHY (Read with MDIC) */
+
+#define E1000_PHY_STATUS            0x01
+#define E1000_PHY_SPECIFIC_STATUS   0x11
+
+
+/* E1000_PHY_STATUS */
+#define E1000_PS_LINK_STATUS        (1 << 2)
+
+
+
+/* E1000_PHY_SPECIFIC_STATUS */
+#define E1000_PSS_SPEED_AND_DUPLEX  (1 << 11)   /* Speed and Duplex Resolved */
+#define E1000_PSS_SPEEDSHIFT        14
+#define E1000_PSS_SPEEDMASK         (3 << E1000_PSS_SPEEDSHIFT)
+
index b238be0..5308afa 100644 (file)
 
 #include <debug.h>
 
+
+static USHORT SupportedDevices[] =
+{
+    0x100f,     // Intel 82545EM (VMWare E1000)
+};
+
+
+static ULONG E1000WriteFlush(IN PE1000_ADAPTER Adapter)
+{
+    volatile ULONG Value;
+
+    NdisReadRegisterUlong(Adapter->IoBase + E1000_REG_STATUS, &Value);
+    return Value;
+}
+
+static VOID E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value)
+{
+    NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value);
+}
+
+static VOID E1000ReadUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, OUT PULONG Value)
+{
+    NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value);
+}
+
+static VOID E1000WriteIoUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value)
+{
+    NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address);
+    E1000WriteFlush(Adapter);
+    NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value);
+}
+
+static BOOLEAN E1000ReadMdic(IN PE1000_ADAPTER Adapter, IN ULONG Address, USHORT *Result)
+{
+    ULONG ResultAddress;
+    ULONG Mdic;
+    UINT n;
+
+    if (Address > MAX_PHY_REG_ADDRESS)
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("PHY Address %d is invalid\n", Address));
+        return 1;
+    }
+
+    Mdic = (Address << E1000_MDIC_REGADD_SHIFT);
+    Mdic |= (E1000_MDIC_PHYADD_GIGABIT << E1000_MDIC_PHYADD_SHIFT);
+    Mdic |= E1000_MDIC_OP_READ;
+
+    E1000WriteUlong(Adapter, E1000_REG_MDIC, Mdic);
+
+    for (n = 0; n < MAX_PHY_READ_ATTEMPTS; n++)
+    {
+        NdisStallExecution(50);
+        E1000ReadUlong(Adapter, E1000_REG_MDIC, &Mdic);
+        if (Mdic & E1000_MDIC_R)
+            break;
+    }
+    if (!(Mdic & E1000_MDIC_R))
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("MDI Read incomplete\n"));
+        return FALSE;
+    }
+    if (Mdic & E1000_MDIC_E)
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("MDI Read error\n"));
+        return FALSE;
+    }
+
+    ResultAddress = (Mdic >> E1000_MDIC_REGADD_SHIFT) & MAX_PHY_REG_ADDRESS;
+
+    if (ResultAddress!= Address)
+    {
+        /* Add locking? */
+        NDIS_DbgPrint(MIN_TRACE, ("MDI Read got wrong address (%d instead of %d)\n",
+                                  ResultAddress, Address));
+        return FALSE;
+    }
+    *Result = (USHORT) Mdic;
+    return TRUE;
+}
+
+
+static BOOLEAN E1000ReadEeprom(IN PE1000_ADAPTER Adapter, IN UCHAR Address, USHORT *Result)
+{
+    UINT Value;
+    UINT n;
+
+    E1000WriteUlong(Adapter, E1000_REG_EERD, E1000_EERD_START | ((UINT)Address << E1000_EERD_ADDR_SHIFT));
+
+    for (n = 0; n < MAX_EEPROM_READ_ATTEMPTS; ++n)
+    {
+        NdisStallExecution(5);
+
+        E1000ReadUlong(Adapter, E1000_REG_EERD, &Value);
+
+        if (Value & E1000_EERD_DONE)
+            break;
+    }
+    if (!(Value & E1000_EERD_DONE))
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("EEPROM Read incomplete\n"));
+        return FALSE;
+    }
+    *Result = (USHORT)(Value >> E1000_EERD_DATA_SHIFT);
+    return TRUE;
+}
+
+BOOLEAN E1000ValidateNvmChecksum(IN PE1000_ADAPTER Adapter)
+{
+    USHORT Checksum = 0, Data;
+    UINT n;
+
+    /* 5.6.35 Checksum Word Calculation (Word 3Fh) */
+    for (n = 0; n <= E1000_NVM_REG_CHECKSUM; n++)
+    {
+        if (!E1000ReadEeprom(Adapter, n, &Data))
+        {
+            return FALSE;
+        }
+        Checksum += Data;
+    }
+
+    if (Checksum != NVM_MAGIC_SUM)
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("EEPROM has an invalid checksum of 0x%x\n", (ULONG)Checksum));
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
 BOOLEAN
 NTAPI
 NICRecognizeHardware(
     IN PE1000_ADAPTER Adapter)
 {
+    UINT n;
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
+    if (Adapter->VendorID != HW_VENDOR_INTEL)
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("Unknown vendor: 0x%x\n", Adapter->VendorID));
+        return FALSE;
+    }
+
+    for (n = 0; n < ARRAYSIZE(SupportedDevices); ++n)
+    {
+        if (SupportedDevices[n] == Adapter->DeviceID)
+        {
+            return TRUE;
+        }
+    }
+
+    NDIS_DbgPrint(MIN_TRACE, ("Unknown device: 0x%x\n", Adapter->DeviceID));
+
     return FALSE;
 }
 
@@ -25,19 +174,92 @@ NICInitializeAdapterResources(
     IN PE1000_ADAPTER Adapter,
     IN PNDIS_RESOURCE_LIST ResourceList)
 {
+    UINT n;
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    for (n = 0; n < ResourceList->Count; n++)
+    {
+        PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor = ResourceList->PartialDescriptors + n;
+
+        switch (ResourceDescriptor->Type)
+        {
+        case CmResourceTypePort:
+            ASSERT(Adapter->IoPortAddress == 0);
+            ASSERT(ResourceDescriptor->u.Port.Start.HighPart == 0);
+
+            Adapter->IoPortAddress = ResourceDescriptor->u.Port.Start.LowPart;
+            Adapter->IoPortLength = ResourceDescriptor->u.Port.Length;
+
+            NDIS_DbgPrint(MID_TRACE, ("I/O port range is %p to %p\n",
+                                      Adapter->IoPortAddress,
+                                      Adapter->IoPortAddress + Adapter->IoPortLength));
+            break;
+        case CmResourceTypeInterrupt:
+            ASSERT(Adapter->InterruptVector == 0);
+            ASSERT(Adapter->InterruptLevel == 0);
+
+            Adapter->InterruptVector = ResourceDescriptor->u.Interrupt.Vector;
+            Adapter->InterruptLevel = ResourceDescriptor->u.Interrupt.Level;
+            Adapter->InterruptShared = (ResourceDescriptor->ShareDisposition == CmResourceShareShared);
+            Adapter->InterruptFlags = ResourceDescriptor->Flags;
+
+            NDIS_DbgPrint(MID_TRACE, ("IRQ vector is %d\n", Adapter->InterruptVector));
+            break;
+        case CmResourceTypeMemory:
+            /* Internal registers and memories (including PHY) */
+            if (ResourceDescriptor->u.Memory.Length ==  (128 * 1024))
+            {
+                ASSERT(Adapter->IoAddress.LowPart == 0);
+                ASSERT(ResourceDescriptor->u.Port.Start.HighPart == 0);
+
+
+                Adapter->IoAddress.QuadPart = ResourceDescriptor->u.Memory.Start.QuadPart;
+                Adapter->IoLength = ResourceDescriptor->u.Memory.Length;
+                NDIS_DbgPrint(MID_TRACE, ("Memory range is %I64x to %I64x\n",
+                                          Adapter->IoAddress.QuadPart,
+                                          Adapter->IoAddress.QuadPart + Adapter->IoLength));
+            }
+            break;
+
+        default:
+            NDIS_DbgPrint(MIN_TRACE, ("Unrecognized resource type: 0x%x\n", ResourceDescriptor->Type));
+            break;
+        }
+    }
+
+    if (Adapter->IoAddress.QuadPart == 0 || Adapter->IoPortAddress == 0 || Adapter->InterruptVector == 0)
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n"));
+        return NDIS_STATUS_RESOURCES;
+    }
+
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
 NTAPI
-NICAllocateResources(
+NICAllocateIoResources(
     IN PE1000_ADAPTER Adapter)
 {
+    NDIS_STATUS Status;
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    Status = NdisMRegisterIoPortRange((PVOID*)&Adapter->IoPort,
+                                      Adapter->AdapterHandle,
+                                      Adapter->IoPortAddress,
+                                      Adapter->IoPortLength);
+    if (Status != NDIS_STATUS_SUCCESS)
+    {
+        NDIS_DbgPrint(MIN_TRACE, ("Unable to register IO port range (0x%x)\n", Status));
+        return NDIS_STATUS_RESOURCES;
+    }
+
+    Status = NdisMMapIoSpace((PVOID*)&Adapter->IoBase,
+                             Adapter->AdapterHandle,
+                             Adapter->IoAddress,
+                             Adapter->IoLength);
+
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
@@ -45,9 +267,24 @@ NTAPI
 NICRegisterInterrupts(
     IN PE1000_ADAPTER Adapter)
 {
+    NDIS_STATUS Status;
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    Status = NdisMRegisterInterrupt(&Adapter->Interrupt,
+                                    Adapter->AdapterHandle,
+                                    Adapter->InterruptVector,
+                                    Adapter->InterruptLevel,
+                                    TRUE, // We always want ISR calls
+                                    Adapter->InterruptShared,
+                                    (Adapter->InterruptFlags & CM_RESOURCE_INTERRUPT_LATCHED) ?
+                                    NdisInterruptLatched : NdisInterruptLevelSensitive);
+
+    if (Status == NDIS_STATUS_SUCCESS)
+    {
+        Adapter->InterruptRegistered = TRUE;
+    }
+
+    return Status;
 }
 
 NDIS_STATUS
@@ -57,7 +294,13 @@ NICUnregisterInterrupts(
 {
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    if (Adapter->InterruptRegistered)
+    {
+        NdisMDeregisterInterrupt(&Adapter->Interrupt);
+        Adapter->InterruptRegistered = FALSE;
+    }
+
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
@@ -67,7 +310,21 @@ NICReleaseIoResources(
 {
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    if (Adapter->IoPort)
+    {
+        NdisMDeregisterIoPortRange(Adapter->AdapterHandle,
+                                   Adapter->IoPortAddress,
+                                   Adapter->IoPortLength,
+                                   Adapter->IoPort);
+    }
+
+    if (Adapter->IoBase)
+    {
+        NdisMUnmapIoSpace(Adapter->AdapterHandle, Adapter->IoBase, Adapter->IoLength);
+    }
+
+
+    return NDIS_STATUS_SUCCESS;
 }
 
 
@@ -76,18 +333,61 @@ NTAPI
 NICPowerOn(
     IN PE1000_ADAPTER Adapter)
 {
+    NDIS_STATUS Status;
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    Status = NICSoftReset(Adapter);
+    if (Status != NDIS_STATUS_SUCCESS)
+    {
+        return Status;
+    }
+
+    if (!E1000ValidateNvmChecksum(Adapter))
+    {
+        return NDIS_STATUS_INVALID_DATA;
+    }
+
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
 NTAPI
 NICSoftReset(
-    IN PE1000_ADAPTER adapter)
+    IN PE1000_ADAPTER Adapter)
 {
+    ULONG Value, ResetAttempts;
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
+    //em_get_hw_control(adapter);
+
+    NICDisableInterrupts(Adapter);
+    E1000WriteUlong(Adapter, E1000_REG_RCTL, 0);
+    E1000ReadUlong(Adapter, E1000_REG_CTRL, &Value);
+    /* Write this using IO port, some devices cannot ack this otherwise */
+    E1000WriteIoUlong(Adapter, E1000_REG_CTRL, Value | E1000_CTRL_RST);
+
+
+    for (ResetAttempts = 0; ResetAttempts < MAX_RESET_ATTEMPTS; ResetAttempts++)
+    {
+        NdisStallExecution(100);
+        E1000ReadUlong(Adapter, E1000_REG_CTRL, &Value);
+
+        if (!(Value & E1000_CTRL_RST))
+        {
+            NDIS_DbgPrint(MAX_TRACE, ("Device is back (%u)\n", ResetAttempts));
+
+            NICDisableInterrupts(Adapter);
+            /* Clear out interrupts */
+            E1000ReadUlong(Adapter, E1000_REG_ICR, &Value);
+
+            //NdisWriteRegisterUlong(Adapter->IoBase + E1000_REG_WUFC, 0);
+            //NdisWriteRegisterUlong(Adapter->IoBase + E1000_REG_VET, E1000_VET_VLAN);
+
+            return NDIS_STATUS_SUCCESS;
+        }
+    }
+
+    NDIS_DbgPrint(MIN_TRACE, ("Device did not recover\n"));
     return NDIS_STATUS_FAILURE;
 }
 
@@ -98,7 +398,7 @@ NICEnableTxRx(
 {
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
@@ -108,7 +408,7 @@ NICDisableTxRx(
 {
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
@@ -117,9 +417,97 @@ NICGetPermanentMacAddress(
     IN PE1000_ADAPTER Adapter,
     OUT PUCHAR MacAddress)
 {
+    USHORT AddrWord;
+    UINT n;
+
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    /* Should we read from RAL/RAH first? */
+    for (n = 0; n < (IEEE_802_ADDR_LENGTH / 2); ++n)
+    {
+        if (!E1000ReadEeprom(Adapter, (UCHAR)n, &AddrWord))
+            return NDIS_STATUS_FAILURE;
+        Adapter->PermanentMacAddress[n * 2 + 0] = AddrWord & 0xff;
+        Adapter->PermanentMacAddress[n * 2 + 1] = (AddrWord >> 8) & 0xff;
+    }
+
+    NDIS_DbgPrint(MIN_TRACE, ("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                              Adapter->PermanentMacAddress[0],
+                              Adapter->PermanentMacAddress[1],
+                              Adapter->PermanentMacAddress[2],
+                              Adapter->PermanentMacAddress[3],
+                              Adapter->PermanentMacAddress[4],
+                              Adapter->PermanentMacAddress[5]));
+    return NDIS_STATUS_SUCCESS;
+}
+
+NDIS_STATUS
+NTAPI
+NICUpdateMulticastList(
+    IN PE1000_ADAPTER Adapter)
+{
+    UINT n;
+    NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+    for (n = 0; n < MAXIMUM_MULTICAST_ADDRESSES; ++n)
+    {
+        ULONG Ral = *(ULONG *)Adapter->MulticastList[n].MacAddress;
+        ULONG Rah = *(USHORT *)&Adapter->MulticastList[n].MacAddress[4];
+
+        if (Rah || Ral)
+        {
+            Rah |= E1000_RAH_AV;
+
+            E1000WriteUlong(Adapter, E1000_REG_RAL + (8*n), Ral);
+            E1000WriteUlong(Adapter, E1000_REG_RAH + (8*n), Rah);
+        }
+        else
+        {
+            E1000WriteUlong(Adapter, E1000_REG_RAH + (8*n), 0);
+            E1000WriteUlong(Adapter, E1000_REG_RAL + (8*n), 0);
+        }
+    }
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+NDIS_STATUS
+NTAPI
+NICApplyPacketFilter(
+    IN PE1000_ADAPTER Adapter)
+{
+    ULONG FilterMask = 0;
+
+    E1000ReadUlong(Adapter, E1000_REG_RCTL, &FilterMask);
+
+    FilterMask &= ~E1000_RCTL_FILTER_BITS;
+
+    if (Adapter->PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
+    {
+        /* Multicast Promiscuous Enabled */
+        FilterMask |= E1000_RCTL_MPE;
+    }
+    if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
+    {
+        /* Unicast Promiscuous Enabled */
+        FilterMask |= E1000_RCTL_UPE;
+        /* Multicast Promiscuous Enabled */
+        FilterMask |= E1000_RCTL_MPE;
+    }
+    if (Adapter->PacketFilter & NDIS_PACKET_TYPE_MAC_FRAME)
+    {
+        /* Pass MAC Control Frames */
+        FilterMask |= E1000_RCTL_PMCF;
+    }
+    if (Adapter->PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
+    {
+        /* Broadcast Accept Mode */
+        FilterMask |= E1000_RCTL_BAM;
+    }
+
+    E1000WriteUlong(Adapter, E1000_REG_RCTL, FilterMask);
+
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
@@ -129,7 +517,8 @@ NICApplyInterruptMask(
 {
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask);
+    return NDIS_STATUS_SUCCESS;
 }
 
 NDIS_STATUS
@@ -139,7 +528,8 @@ NICDisableInterrupts(
 {
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+    E1000WriteUlong(Adapter, E1000_REG_IMC, ~0);
+    return NDIS_STATUS_SUCCESS;
 }
 
 USHORT
@@ -166,17 +556,48 @@ NTAPI
 NICUpdateLinkStatus(
     IN PE1000_ADAPTER Adapter)
 {
-    NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
-}
+    ULONG SpeedIndex;
+    USHORT PhyStatus;
+    static ULONG SpeedValues[] = { 10, 100, 1000, 1000 };
 
-NDIS_STATUS
-NTAPI
-NICApplyPacketFilter(
-    IN PE1000_ADAPTER Adapter)
-{
     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    return NDIS_STATUS_FAILURE;
+#if 0
+    /* This does not work */
+    E1000ReadUlong(Adapter, E1000_REG_STATUS, &DeviceStatus);
+    E1000ReadUlong(Adapter, E1000_REG_STATUS, &DeviceStatus);
+    Adapter->MediaState = (DeviceStatus & E1000_STATUS_LU) ? NdisMediaStateConnected : NdisMediaStateDisconnected;
+    SpeedIndex = (DeviceStatus & E1000_STATUS_SPEEDMASK) >> E1000_STATUS_SPEEDSHIFT;
+    Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex];
+#else
+    /* Link bit can be sticky on some boards, read it twice */
+    if (!E1000ReadMdic(Adapter, E1000_PHY_STATUS, &PhyStatus))
+        NdisStallExecution(100);
+
+    Adapter->MediaState = NdisMediaStateDisconnected;
+    Adapter->LinkSpeedMbps = 0;
+
+    if (!E1000ReadMdic(Adapter, E1000_PHY_STATUS, &PhyStatus))
+        return;
+
+    if (!(PhyStatus & E1000_PS_LINK_STATUS))
+        return;
+
+    Adapter->MediaState = NdisMediaStateConnected;
+
+    if (E1000ReadMdic(Adapter, E1000_PHY_SPECIFIC_STATUS, &PhyStatus))
+    {
+        if (PhyStatus & E1000_PSS_SPEED_AND_DUPLEX)
+        {
+            SpeedIndex = (PhyStatus & E1000_PSS_SPEEDMASK) >> E1000_PSS_SPEEDSHIFT;
+            Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex];
+        }
+        else
+        {
+            NDIS_DbgPrint(MIN_TRACE, ("Speed and duplex not yet resolved, retry?.\n"));
+        }
+    }
+#endif
 }
 
 NDIS_STATUS
index 8481795..2c98034 100644 (file)
 static ULONG SupportedOidList[] =
 {
     OID_GEN_SUPPORTED_LIST,
+    OID_GEN_CURRENT_PACKET_FILTER,
     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_SEND_PACKETS,
     OID_GEN_LINK_SPEED,
     OID_GEN_TRANSMIT_BUFFER_SPACE,
     OID_GEN_RECEIVE_BUFFER_SPACE,
@@ -27,14 +29,23 @@ static ULONG SupportedOidList[] =
     OID_GEN_VENDOR_DESCRIPTION,
     OID_GEN_VENDOR_DRIVER_VERSION,
     OID_GEN_CURRENT_LOOKAHEAD,
+    OID_802_3_MULTICAST_LIST,
     OID_GEN_DRIVER_VERSION,
     OID_GEN_MAXIMUM_TOTAL_SIZE,
     OID_GEN_MAC_OPTIONS,
     OID_GEN_MEDIA_CONNECT_STATUS,
     OID_802_3_PERMANENT_ADDRESS,
     OID_802_3_CURRENT_ADDRESS,
+    OID_802_3_MAXIMUM_LIST_SIZE,
+    /* Statistics */
+    OID_GEN_XMIT_OK,
+    OID_GEN_RCV_OK,
+    OID_GEN_XMIT_ERROR,
+    OID_GEN_RCV_ERROR,
+    OID_GEN_RCV_NO_BUFFER,
 };
 
+
 NDIS_STATUS
 NTAPI
 MiniportQueryInformation(
@@ -64,6 +75,10 @@ MiniportQueryInformation(
         copyLength = sizeof(SupportedOidList);
         break;
 
+    case OID_GEN_CURRENT_PACKET_FILTER:
+        genericUlong = Adapter->PacketFilter;
+        break;
+
     case OID_GEN_HARDWARE_STATUS:
         UNIMPLEMENTED_DBGBREAK();
         genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME
@@ -86,8 +101,12 @@ MiniportQueryInformation(
         genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER);
         break;
 
+    case OID_802_3_MAXIMUM_LIST_SIZE:
+        genericUlong = MAXIMUM_MULTICAST_ADDRESSES;
+        break;
+
     case OID_GEN_LINK_SPEED:
-        genericUlong = Adapter->LinkSpeedMbps * 1000;
+        genericUlong = Adapter->LinkSpeedMbps * 10000;
         break;
 
     case OID_GEN_TRANSMIT_BUFFER_SPACE:
@@ -131,6 +150,10 @@ MiniportQueryInformation(
         genericUlong = MAXIMUM_FRAME_SIZE;
         break;
 
+    case OID_GEN_MAXIMUM_SEND_PACKETS:
+        genericUlong = 1;
+        break;
+
     case OID_GEN_MAC_OPTIONS:
         genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
             NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
@@ -144,7 +167,7 @@ MiniportQueryInformation(
 
 
     case OID_802_3_CURRENT_ADDRESS:
-        copySource = Adapter->CurrentMacAddress;
+        copySource = Adapter->MulticastList[0].MacAddress;
         copyLength = IEEE_802_ADDR_LENGTH;
         break;
 
@@ -153,8 +176,24 @@ MiniportQueryInformation(
         copyLength = IEEE_802_ADDR_LENGTH;
         break;
 
+    case OID_GEN_XMIT_OK:
+        genericUlong = 0;
+        break;
+    case OID_GEN_RCV_OK:
+        genericUlong = 0;
+        break;
+    case OID_GEN_XMIT_ERROR:
+        genericUlong = 0;
+        break;
+    case OID_GEN_RCV_ERROR:
+        genericUlong = 0;
+        break;
+    case OID_GEN_RCV_NO_BUFFER:
+        genericUlong = 0;
+        break;
+
     default:
-        NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x\n", Oid));
+        NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid)));
         status = NDIS_STATUS_NOT_SUPPORTED;
         break;
     }
@@ -181,9 +220,12 @@ MiniportQueryInformation(
     }
 
     NdisReleaseSpinLock(&Adapter->Lock);
-
-    NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x: Completed with status 0x%x (%d, %d)\n",
-                              Oid, status, *BytesWritten, *BytesNeeded));
+    /* XMIT_ERROR and RCV_ERROR are really noisy, so do not log those. */
+    if (Oid != OID_GEN_XMIT_ERROR && Oid != OID_GEN_RCV_ERROR)
+    {
+        NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x(%s): Completed with status 0x%x (%d, %d)\n",
+                                  Oid, Oid2Str(Oid), status, *BytesWritten, *BytesNeeded));
+    }
 
     return status;
 }
@@ -208,6 +250,42 @@ MiniportSetInformation(
 
     switch (Oid)
     {
+    case OID_GEN_CURRENT_PACKET_FILTER:
+        if (InformationBufferLength < sizeof(ULONG))
+        {
+            *BytesRead = 0;
+            *BytesNeeded = sizeof(ULONG);
+            status = NDIS_STATUS_INVALID_LENGTH;
+            break;
+        }
+
+        NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG));
+
+        if (genericUlong & 
+            (NDIS_PACKET_TYPE_SOURCE_ROUTING |
+             NDIS_PACKET_TYPE_SMT |
+             NDIS_PACKET_TYPE_ALL_LOCAL |
+             NDIS_PACKET_TYPE_GROUP |
+             NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
+             NDIS_PACKET_TYPE_FUNCTIONAL))
+        {
+            *BytesRead = sizeof(ULONG);
+            *BytesNeeded = sizeof(ULONG);
+            status = NDIS_STATUS_NOT_SUPPORTED;
+            break;
+        }
+
+        Adapter->PacketFilter = genericUlong;
+
+        status = NICApplyPacketFilter(Adapter);
+        if (status != NDIS_STATUS_SUCCESS)
+        {
+            NDIS_DbgPrint(MIN_TRACE, ("Failed to apply new packet filter (0x%x)\n", status));
+            break;
+        }
+
+        break;
+
     case OID_GEN_CURRENT_LOOKAHEAD:
         if (InformationBufferLength < sizeof(ULONG))
         {
@@ -230,8 +308,29 @@ MiniportSetInformation(
 
         break;
 
+    case OID_802_3_MULTICAST_LIST:
+        if (InformationBufferLength % IEEE_802_ADDR_LENGTH)
+        {
+            *BytesRead = 0;
+            *BytesNeeded = InformationBufferLength + (InformationBufferLength % IEEE_802_ADDR_LENGTH);
+            status = NDIS_STATUS_INVALID_LENGTH;
+            break;
+        }
+        
+        if (InformationBufferLength / 6 > MAXIMUM_MULTICAST_ADDRESSES)
+        {
+            *BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH;
+            *BytesRead = 0;
+            status = NDIS_STATUS_INVALID_LENGTH;
+            break;
+        }
+
+        NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength);
+        NICUpdateMulticastList(Adapter);
+        break;
+
     default:
-        NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x\n", Oid));
+        NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid)));
         status = NDIS_STATUS_NOT_SUPPORTED;
         *BytesRead = 0;
         *BytesNeeded = 0;
@@ -248,3 +347,4 @@ MiniportSetInformation(
 
     return status;
 }
+
index b02f397..50b5c44 100644 (file)
@@ -224,7 +224,9 @@ MiniportInitialize(
         goto Cleanup;
     }
 
-    RtlCopyMemory(Adapter->CurrentMacAddress, Adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH);
+    RtlCopyMemory(Adapter->MulticastList[0].MacAddress, Adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH);
+
+    NICUpdateMulticastList(Adapter);
 
     /* Update link state and speed */
     NICUpdateLinkStatus(Adapter);
@@ -238,7 +240,7 @@ MiniportInitialize(
     }
 
     /* Enable interrupts on the NIC */
-    //Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK;
+    Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK;
     Status = NICApplyInterruptMask(Adapter);
     if (Status != NDIS_STATUS_SUCCESS)
     {
index ea6922e..9586b61 100644 (file)
@@ -21,6 +21,8 @@
 #define DRIVER_VERSION 1
 
 
+#define DEFAULT_INTERRUPT_MASK      (E1000_IMS_LSC)
+
 typedef struct _E1000_ADAPTER
 {
     NDIS_SPIN_LOCK Lock;
@@ -31,10 +33,34 @@ typedef struct _E1000_ADAPTER
     USHORT SubsystemVendorID;
 
     UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH];
-    UCHAR CurrentMacAddress[IEEE_802_ADDR_LENGTH];
+    struct {
+        UCHAR MacAddress[IEEE_802_ADDR_LENGTH];
+    } MulticastList[MAXIMUM_MULTICAST_ADDRESSES];
 
     ULONG LinkSpeedMbps;
     ULONG MediaState;
+    ULONG PacketFilter;
+
+    /* Io Port */
+    ULONG IoPortAddress;
+    ULONG IoPortLength;
+    volatile PUCHAR IoPort;
+
+    /* NIC Memory */
+    NDIS_PHYSICAL_ADDRESS IoAddress;
+    ULONG IoLength;
+    volatile PUCHAR IoBase;
+
+    /* Interrupt */
+    ULONG InterruptVector;
+    ULONG InterruptLevel;
+    BOOLEAN InterruptShared;
+    ULONG InterruptFlags;
+
+    NDIS_MINIPORT_INTERRUPT Interrupt;
+    BOOLEAN InterruptRegistered;
+
+    ULONG InterruptMask;
     ULONG InterruptPending;
 
 } E1000_ADAPTER, *PE1000_ADAPTER;
@@ -53,7 +79,7 @@ NICInitializeAdapterResources(
 
 NDIS_STATUS
 NTAPI
-NICAllocateResources(
+NICAllocateIoResources(
     IN PE1000_ADAPTER Adapter);
 
 NDIS_STATUS
@@ -97,6 +123,11 @@ NICGetPermanentMacAddress(
     IN PE1000_ADAPTER Adapter,
     OUT PUCHAR MacAddress);
 
+NDIS_STATUS
+NTAPI
+NICUpdateMulticastList(
+    IN PE1000_ADAPTER Adapter);
+
 NDIS_STATUS
 NTAPI
 NICApplyPacketFilter(