https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d9b0601ceb6ec4d583467…
commit d9b0601ceb6ec4d5834678a561167d2e78c3a368
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Mon May 28 00:09:10 2018 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Thu Feb 7 19:48:54 2019 +0100
[E1000] Basic initialization of the card
Initialize some registers, allocate basic resources
CORE-14675
---
drivers/network/dd/e1000/CMakeLists.txt | 1 +
drivers/network/dd/e1000/debug.c | 167 ++++++++++++
drivers/network/dd/e1000/debug.h | 2 +
drivers/network/dd/e1000/e1000hw.h | 100 +++++++
drivers/network/dd/e1000/hardware.c | 463 ++++++++++++++++++++++++++++++--
drivers/network/dd/e1000/info.c | 114 +++++++-
drivers/network/dd/e1000/ndis.c | 6 +-
drivers/network/dd/e1000/nic.h | 35 ++-
8 files changed, 856 insertions(+), 32 deletions(-)
diff --git a/drivers/network/dd/e1000/CMakeLists.txt
b/drivers/network/dd/e1000/CMakeLists.txt
index eeee376c2e..591f01d796 100644
--- a/drivers/network/dd/e1000/CMakeLists.txt
+++ b/drivers/network/dd/e1000/CMakeLists.txt
@@ -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
index 0000000000..d3008bcc92
--- /dev/null
+++ b/drivers/network/dd/e1000/debug.c
@@ -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(a)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
+}
+
+
diff --git a/drivers/network/dd/e1000/debug.h b/drivers/network/dd/e1000/debug.h
index b6ff2cf92e..481f60429c 100644
--- a/drivers/network/dd/e1000/debug.h
+++ b/drivers/network/dd/e1000/debug.h
@@ -62,3 +62,5 @@ extern ULONG DebugTraceLevel;
} while (0)
+const char* Oid2Str(IN NDIS_OID Oid);
+
diff --git a/drivers/network/dd/e1000/e1000hw.h b/drivers/network/dd/e1000/e1000hw.h
index 57ac8fc2e8..9932974281 100644
--- a/drivers/network/dd/e1000/e1000hw.h
+++ b/drivers/network/dd/e1000/e1000hw.h
@@ -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)
+
diff --git a/drivers/network/dd/e1000/hardware.c b/drivers/network/dd/e1000/hardware.c
index b238be0997..5308afadd5 100644
--- a/drivers/network/dd/e1000/hardware.c
+++ b/drivers/network/dd/e1000/hardware.c
@@ -9,13 +9,162 @@
#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
diff --git a/drivers/network/dd/e1000/info.c b/drivers/network/dd/e1000/info.c
index 84817956e4..2c98034fe6 100644
--- a/drivers/network/dd/e1000/info.c
+++ b/drivers/network/dd/e1000/info.c
@@ -13,11 +13,13 @@
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;
}
+
diff --git a/drivers/network/dd/e1000/ndis.c b/drivers/network/dd/e1000/ndis.c
index b02f397bd9..50b5c44e93 100644
--- a/drivers/network/dd/e1000/ndis.c
+++ b/drivers/network/dd/e1000/ndis.c
@@ -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)
{
diff --git a/drivers/network/dd/e1000/nic.h b/drivers/network/dd/e1000/nic.h
index ea6922ed17..9586b615f6 100644
--- a/drivers/network/dd/e1000/nic.h
+++ b/drivers/network/dd/e1000/nic.h
@@ -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(