mirror of
https://github.com/reactos/reactos.git
synced 2025-04-05 05:01:03 +00:00
[E1000] Basic initialization of the card
Initialize some registers, allocate basic resources CORE-14675
This commit is contained in:
parent
4561998a45
commit
d9b0601ceb
8 changed files with 856 additions and 32 deletions
|
@ -11,6 +11,7 @@ list(APPEND SOURCE
|
||||||
interrupt.c
|
interrupt.c
|
||||||
nic.h
|
nic.h
|
||||||
e1000hw.h
|
e1000hw.h
|
||||||
|
debug.c
|
||||||
debug.h)
|
debug.h)
|
||||||
|
|
||||||
add_library(e1000 SHARED ${SOURCE} e1000.rc)
|
add_library(e1000 SHARED ${SOURCE} e1000.rc)
|
||||||
|
|
167
drivers/network/dd/e1000/debug.c
Normal file
167
drivers/network/dd/e1000/debug.c
Normal file
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,3 +62,5 @@ extern ULONG DebugTraceLevel;
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
const char* Oid2Str(IN NDIS_OID Oid);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,18 @@
|
||||||
|
|
||||||
#define IEEE_802_ADDR_LENGTH 6
|
#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 */
|
/* Ethernet frame header */
|
||||||
typedef struct _ETH_HEADER {
|
typedef struct _ETH_HEADER {
|
||||||
|
@ -17,3 +29,91 @@ typedef struct _ETH_HEADER {
|
||||||
USHORT PayloadType;
|
USHORT PayloadType;
|
||||||
} ETH_HEADER, *PETH_HEADER;
|
} 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)
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,162 @@
|
||||||
|
|
||||||
#include <debug.h>
|
#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
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
NICRecognizeHardware(
|
NICRecognizeHardware(
|
||||||
IN PE1000_ADAPTER Adapter)
|
IN PE1000_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
|
UINT n;
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,19 +174,92 @@ NICInitializeAdapterResources(
|
||||||
IN PE1000_ADAPTER Adapter,
|
IN PE1000_ADAPTER Adapter,
|
||||||
IN PNDIS_RESOURCE_LIST ResourceList)
|
IN PNDIS_RESOURCE_LIST ResourceList)
|
||||||
{
|
{
|
||||||
|
UINT n;
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\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
|
NDIS_STATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NICAllocateResources(
|
NICAllocateIoResources(
|
||||||
IN PE1000_ADAPTER Adapter)
|
IN PE1000_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
|
NDIS_STATUS Status;
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
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
|
NDIS_STATUS
|
||||||
|
@ -45,9 +267,24 @@ NTAPI
|
||||||
NICRegisterInterrupts(
|
NICRegisterInterrupts(
|
||||||
IN PE1000_ADAPTER Adapter)
|
IN PE1000_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
|
NDIS_STATUS Status;
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
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
|
NDIS_STATUS
|
||||||
|
@ -57,7 +294,13 @@ NICUnregisterInterrupts(
|
||||||
{
|
{
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
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
|
NDIS_STATUS
|
||||||
|
@ -67,7 +310,21 @@ NICReleaseIoResources(
|
||||||
{
|
{
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
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(
|
NICPowerOn(
|
||||||
IN PE1000_ADAPTER Adapter)
|
IN PE1000_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
|
NDIS_STATUS Status;
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
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
|
NDIS_STATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NICSoftReset(
|
NICSoftReset(
|
||||||
IN PE1000_ADAPTER adapter)
|
IN PE1000_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
|
ULONG Value, ResetAttempts;
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
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;
|
return NDIS_STATUS_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +398,7 @@ NICEnableTxRx(
|
||||||
{
|
{
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||||
|
|
||||||
return NDIS_STATUS_FAILURE;
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
|
@ -108,7 +408,7 @@ NICDisableTxRx(
|
||||||
{
|
{
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||||
|
|
||||||
return NDIS_STATUS_FAILURE;
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
|
@ -117,9 +417,97 @@ NICGetPermanentMacAddress(
|
||||||
IN PE1000_ADAPTER Adapter,
|
IN PE1000_ADAPTER Adapter,
|
||||||
OUT PUCHAR MacAddress)
|
OUT PUCHAR MacAddress)
|
||||||
{
|
{
|
||||||
|
USHORT AddrWord;
|
||||||
|
UINT n;
|
||||||
|
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\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
|
NDIS_STATUS
|
||||||
|
@ -129,7 +517,8 @@ NICApplyInterruptMask(
|
||||||
{
|
{
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||||
|
|
||||||
return NDIS_STATUS_FAILURE;
|
E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask);
|
||||||
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
|
@ -139,7 +528,8 @@ NICDisableInterrupts(
|
||||||
{
|
{
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||||
|
|
||||||
return NDIS_STATUS_FAILURE;
|
E1000WriteUlong(Adapter, E1000_REG_IMC, ~0);
|
||||||
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USHORT
|
USHORT
|
||||||
|
@ -166,17 +556,48 @@ NTAPI
|
||||||
NICUpdateLinkStatus(
|
NICUpdateLinkStatus(
|
||||||
IN PE1000_ADAPTER Adapter)
|
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"));
|
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
|
NDIS_STATUS
|
||||||
|
|
|
@ -13,11 +13,13 @@
|
||||||
static ULONG SupportedOidList[] =
|
static ULONG SupportedOidList[] =
|
||||||
{
|
{
|
||||||
OID_GEN_SUPPORTED_LIST,
|
OID_GEN_SUPPORTED_LIST,
|
||||||
|
OID_GEN_CURRENT_PACKET_FILTER,
|
||||||
OID_GEN_HARDWARE_STATUS,
|
OID_GEN_HARDWARE_STATUS,
|
||||||
OID_GEN_MEDIA_SUPPORTED,
|
OID_GEN_MEDIA_SUPPORTED,
|
||||||
OID_GEN_MEDIA_IN_USE,
|
OID_GEN_MEDIA_IN_USE,
|
||||||
OID_GEN_MAXIMUM_LOOKAHEAD,
|
OID_GEN_MAXIMUM_LOOKAHEAD,
|
||||||
OID_GEN_MAXIMUM_FRAME_SIZE,
|
OID_GEN_MAXIMUM_FRAME_SIZE,
|
||||||
|
OID_GEN_MAXIMUM_SEND_PACKETS,
|
||||||
OID_GEN_LINK_SPEED,
|
OID_GEN_LINK_SPEED,
|
||||||
OID_GEN_TRANSMIT_BUFFER_SPACE,
|
OID_GEN_TRANSMIT_BUFFER_SPACE,
|
||||||
OID_GEN_RECEIVE_BUFFER_SPACE,
|
OID_GEN_RECEIVE_BUFFER_SPACE,
|
||||||
|
@ -27,14 +29,23 @@ static ULONG SupportedOidList[] =
|
||||||
OID_GEN_VENDOR_DESCRIPTION,
|
OID_GEN_VENDOR_DESCRIPTION,
|
||||||
OID_GEN_VENDOR_DRIVER_VERSION,
|
OID_GEN_VENDOR_DRIVER_VERSION,
|
||||||
OID_GEN_CURRENT_LOOKAHEAD,
|
OID_GEN_CURRENT_LOOKAHEAD,
|
||||||
|
OID_802_3_MULTICAST_LIST,
|
||||||
OID_GEN_DRIVER_VERSION,
|
OID_GEN_DRIVER_VERSION,
|
||||||
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||||||
OID_GEN_MAC_OPTIONS,
|
OID_GEN_MAC_OPTIONS,
|
||||||
OID_GEN_MEDIA_CONNECT_STATUS,
|
OID_GEN_MEDIA_CONNECT_STATUS,
|
||||||
OID_802_3_PERMANENT_ADDRESS,
|
OID_802_3_PERMANENT_ADDRESS,
|
||||||
OID_802_3_CURRENT_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
|
NDIS_STATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiniportQueryInformation(
|
MiniportQueryInformation(
|
||||||
|
@ -64,6 +75,10 @@ MiniportQueryInformation(
|
||||||
copyLength = sizeof(SupportedOidList);
|
copyLength = sizeof(SupportedOidList);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||||
|
genericUlong = Adapter->PacketFilter;
|
||||||
|
break;
|
||||||
|
|
||||||
case OID_GEN_HARDWARE_STATUS:
|
case OID_GEN_HARDWARE_STATUS:
|
||||||
UNIMPLEMENTED_DBGBREAK();
|
UNIMPLEMENTED_DBGBREAK();
|
||||||
genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME
|
genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME
|
||||||
|
@ -86,8 +101,12 @@ MiniportQueryInformation(
|
||||||
genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER);
|
genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||||
|
genericUlong = MAXIMUM_MULTICAST_ADDRESSES;
|
||||||
|
break;
|
||||||
|
|
||||||
case OID_GEN_LINK_SPEED:
|
case OID_GEN_LINK_SPEED:
|
||||||
genericUlong = Adapter->LinkSpeedMbps * 1000;
|
genericUlong = Adapter->LinkSpeedMbps * 10000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_TRANSMIT_BUFFER_SPACE:
|
case OID_GEN_TRANSMIT_BUFFER_SPACE:
|
||||||
|
@ -131,6 +150,10 @@ MiniportQueryInformation(
|
||||||
genericUlong = MAXIMUM_FRAME_SIZE;
|
genericUlong = MAXIMUM_FRAME_SIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OID_GEN_MAXIMUM_SEND_PACKETS:
|
||||||
|
genericUlong = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case OID_GEN_MAC_OPTIONS:
|
case OID_GEN_MAC_OPTIONS:
|
||||||
genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
|
genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
|
||||||
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
||||||
|
@ -144,7 +167,7 @@ MiniportQueryInformation(
|
||||||
|
|
||||||
|
|
||||||
case OID_802_3_CURRENT_ADDRESS:
|
case OID_802_3_CURRENT_ADDRESS:
|
||||||
copySource = Adapter->CurrentMacAddress;
|
copySource = Adapter->MulticastList[0].MacAddress;
|
||||||
copyLength = IEEE_802_ADDR_LENGTH;
|
copyLength = IEEE_802_ADDR_LENGTH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -153,8 +176,24 @@ MiniportQueryInformation(
|
||||||
copyLength = IEEE_802_ADDR_LENGTH;
|
copyLength = IEEE_802_ADDR_LENGTH;
|
||||||
break;
|
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:
|
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;
|
status = NDIS_STATUS_NOT_SUPPORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -181,9 +220,12 @@ MiniportQueryInformation(
|
||||||
}
|
}
|
||||||
|
|
||||||
NdisReleaseSpinLock(&Adapter->Lock);
|
NdisReleaseSpinLock(&Adapter->Lock);
|
||||||
|
/* XMIT_ERROR and RCV_ERROR are really noisy, so do not log those. */
|
||||||
NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x: Completed with status 0x%x (%d, %d)\n",
|
if (Oid != OID_GEN_XMIT_ERROR && Oid != OID_GEN_RCV_ERROR)
|
||||||
Oid, status, *BytesWritten, *BytesNeeded));
|
{
|
||||||
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -208,6 +250,42 @@ MiniportSetInformation(
|
||||||
|
|
||||||
switch (Oid)
|
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:
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||||
if (InformationBufferLength < sizeof(ULONG))
|
if (InformationBufferLength < sizeof(ULONG))
|
||||||
{
|
{
|
||||||
|
@ -230,8 +308,29 @@ MiniportSetInformation(
|
||||||
|
|
||||||
break;
|
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:
|
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;
|
status = NDIS_STATUS_NOT_SUPPORTED;
|
||||||
*BytesRead = 0;
|
*BytesRead = 0;
|
||||||
*BytesNeeded = 0;
|
*BytesNeeded = 0;
|
||||||
|
@ -248,3 +347,4 @@ MiniportSetInformation(
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,9 @@ MiniportInitialize(
|
||||||
goto Cleanup;
|
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 */
|
/* Update link state and speed */
|
||||||
NICUpdateLinkStatus(Adapter);
|
NICUpdateLinkStatus(Adapter);
|
||||||
|
@ -238,7 +240,7 @@ MiniportInitialize(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable interrupts on the NIC */
|
/* Enable interrupts on the NIC */
|
||||||
//Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK;
|
Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK;
|
||||||
Status = NICApplyInterruptMask(Adapter);
|
Status = NICApplyInterruptMask(Adapter);
|
||||||
if (Status != NDIS_STATUS_SUCCESS)
|
if (Status != NDIS_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#define DRIVER_VERSION 1
|
#define DRIVER_VERSION 1
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC)
|
||||||
|
|
||||||
typedef struct _E1000_ADAPTER
|
typedef struct _E1000_ADAPTER
|
||||||
{
|
{
|
||||||
NDIS_SPIN_LOCK Lock;
|
NDIS_SPIN_LOCK Lock;
|
||||||
|
@ -31,10 +33,34 @@ typedef struct _E1000_ADAPTER
|
||||||
USHORT SubsystemVendorID;
|
USHORT SubsystemVendorID;
|
||||||
|
|
||||||
UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH];
|
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 LinkSpeedMbps;
|
||||||
ULONG MediaState;
|
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;
|
ULONG InterruptPending;
|
||||||
|
|
||||||
} E1000_ADAPTER, *PE1000_ADAPTER;
|
} E1000_ADAPTER, *PE1000_ADAPTER;
|
||||||
|
@ -53,7 +79,7 @@ NICInitializeAdapterResources(
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NICAllocateResources(
|
NICAllocateIoResources(
|
||||||
IN PE1000_ADAPTER Adapter);
|
IN PE1000_ADAPTER Adapter);
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
|
@ -97,6 +123,11 @@ NICGetPermanentMacAddress(
|
||||||
IN PE1000_ADAPTER Adapter,
|
IN PE1000_ADAPTER Adapter,
|
||||||
OUT PUCHAR MacAddress);
|
OUT PUCHAR MacAddress);
|
||||||
|
|
||||||
|
NDIS_STATUS
|
||||||
|
NTAPI
|
||||||
|
NICUpdateMulticastList(
|
||||||
|
IN PE1000_ADAPTER Adapter);
|
||||||
|
|
||||||
NDIS_STATUS
|
NDIS_STATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NICApplyPacketFilter(
|
NICApplyPacketFilter(
|
||||||
|
|
Loading…
Reference in a new issue