DevE1000.cpp revision 930d38501dd9f9230ba37a263919a07da5500ad6
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * DevE1000 - Intel 82540EM Ethernet Controller Emulation.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Implemented in accordance with the specification:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * PCI/PCI-X Family of Gigabit Ethernet Controllers Software Developer's Manual
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * 82540EP/EM, 82541xx, 82544GC/EI, 82545GM/EM, 82546GB/EB, and 82547xx
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * 317453-002 Revision 3.5
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @todo IPv6 checksum offloading support
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @todo VLAN checksum offloading support
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * @todo Flexible Filter / Wakeup (optional?)
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2007-2010 Sun Microsystems, Inc.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * available from http://www.virtualbox.org. This file is free software;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * General Public License (GPL) as published by the Free Software
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
da957c069c2a3c582fe265ff88170ce4c42b499dvboxsync * additional information or have any questions.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1kLogRel(a) LogRel(a)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/* Options */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1K_GLOBAL_MUTEX
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1K_USE_TX_TIMERS
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1K_NO_TAD
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1K_REL_DEBUG
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1K_INT_STATS
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1K_REL_STATS
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//#define E1K_USE_SUPLIB_SEMEVENT
9496f2d398b49813176939d7a339ae513d5175efvboxsync/* Little helpers ************************************************************/
9496f2d398b49813176939d7a339ae513d5175efvboxsync#define htons(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync# define STAM_PROFILE_ADV_START STAM_REL_PROFILE_ADV_START
9496f2d398b49813176939d7a339ae513d5175efvboxsync# define STAM_PROFILE_ADV_STOP STAM_REL_PROFILE_ADV_STOP
9496f2d398b49813176939d7a339ae513d5175efvboxsync//# define E1kLog3(a) do {} while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync# define E1kLog(a) do {} while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync# define E1kLog2(a) do {} while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync# define E1kLog3(a) do {} while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync//# define E1kLog(a) do {} while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync//# define E1kLog2(a) do {} while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync//# define E1kLog3(a) do {} while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync//#undef DEBUG
9496f2d398b49813176939d7a339ae513d5175efvboxsync#define STATE_TO_DEVINS(pState) (((E1KSTATE *)pState)->CTX_SUFF(pDevIns))
9496f2d398b49813176939d7a339ae513d5175efvboxsync#else /* E1K_INT_STATS */
9496f2d398b49813176939d7a339ae513d5175efvboxsync#endif /* E1K_INT_STATS */
9496f2d398b49813176939d7a339ae513d5175efvboxsync/*****************************************************************************/
9496f2d398b49813176939d7a339ae513d5175efvboxsync const char *pcszName;
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* Vendor Device SSVendor SubSys Name */
9496f2d398b49813176939d7a339ae513d5175efvboxsync { 0x8086, 0x100E, 0x8086, 0x001E, "82540EM" }, /* Intel 82540EM-A in Intel PRO/1000 MT Desktop */
9496f2d398b49813176939d7a339ae513d5175efvboxsync { 0x8086, 0x1004, 0x8086, 0x1004, "82543GC" }, /* Intel 82543GC in Intel PRO/1000 T Server */
9496f2d398b49813176939d7a339ae513d5175efvboxsync { 0x8086, 0x100F, 0x15AD, 0x0750, "82545EM" } /* Intel 82545EM-A in VMWare Network Adapter */
9496f2d398b49813176939d7a339ae513d5175efvboxsync/* The size of register area mapped to I/O space */
9496f2d398b49813176939d7a339ae513d5175efvboxsync/* The size of memory-mapped register area */
9496f2d398b49813176939d7a339ae513d5175efvboxsync/*****************************************************************************/
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** Gets the specfieid bits from the register. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync#define GET_BITS(reg, bits) ((reg & reg##_##bits##_MASK) >> reg##_##bits##_SHIFT)
9496f2d398b49813176939d7a339ae513d5175efvboxsync#define GET_BITS_V(val, reg, bits) ((val & reg##_##bits##_MASK) >> reg##_##bits##_SHIFT)
9496f2d398b49813176939d7a339ae513d5175efvboxsync#define BITS(reg, bits, bitval) (bitval << reg##_##bits##_SHIFT)
9496f2d398b49813176939d7a339ae513d5175efvboxsync#define SET_BITS(reg, bits, bitval) do { reg = (reg & ~reg##_##bits##_MASK) | (bitval << reg##_##bits##_SHIFT); } while (0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync#define SET_BITS_V(val, reg, bits, bitval) do { val = (val & ~reg##_##bits##_MASK) | (bitval << reg##_##bits##_SHIFT); } while (0)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#define RCTL_LBM_TCVR 3 /**< PHY or external SerDes loopback. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsynctypedef struct
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/* Register access macros ****************************************************/
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Indices of memory-mapped registers in register table
9496f2d398b49813176939d7a339ae513d5175efvboxsynctypedef enum
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Define E1000-specific EEPROM layout.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Initialize EEPROM content.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @param macAddr MAC address of E1000.
9496f2d398b49813176939d7a339ae513d5175efvboxsync memcpy(eeprom.m_au16Data, macAddr.au16, sizeof(macAddr.au16));
9496f2d398b49813176939d7a339ae513d5175efvboxsync * bit 3 - full support for power management
9496f2d398b49813176939d7a339ae513d5175efvboxsync * bit 10 - full duplex
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Compute the checksum as required by E1000 and store it
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync * in the last word.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync eeprom.m_au16Data[eeprom.SIZE-1] = 0xBABA - u16Checksum;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * First 6 bytes of EEPROM contain MAC address.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns MAC address of E1000.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync memcpy(pMac->au16, eeprom.m_au16Data, sizeof(pMac->au16));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync bool readWord(uint32_t u32Addr, uint16_t *pu16Value)
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync#endif /* IN_RING3 */
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync /** @name Descriptor Status field (3.2.3.1)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned fIXSM : 1; /**< Ignore checksum indication. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned : 1;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned fTCPCS : 1; /**< RCP Checksum calculated on the packet. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned fIPCS : 1; /**< IP Checksum calculated on the packet. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** @name Descriptor Errors field (3.2.3.2)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * (Only valid when fEOP and fDD are set.)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned : 4; /**< Reserved, varies with different models... */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned fTCPE : 1; /**< TCP/UDP checksum error. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** @name Descriptor Special field (3.2.3.3)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned fCFI : 1; /**< Canonical form indicator (VLAN). */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync uint64_t u64BufAddr; /**< Address of data buffer */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync uint16_t u16Length; /**< Length of data in buffer */
9496f2d398b49813176939d7a339ae513d5175efvboxsync uint64_t u64BufAddr; /**< Address of data buffer */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* CMD field : 8 */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* STA field */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* RSV field */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* CSS field */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Special field*/
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync * TCP/IP Context Transmit Descriptor, section 3.3.6.
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync /** TSE: Header start. !TSE: Checksum start. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Checksum offset - where to store it. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Checksum ending (inclusive) offset, 0 = end of packet. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** TSE: The total number of payload bytes for this context. Sans header. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** The descriptor type - E1K_DTYP_CONTEXT (0). */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** TUCMD field, 8 bits
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** TSE: TCP (set) or UDP (clear). */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** TSE: IPv4 (set) or IPv6 (clear) - for finding the payload length field in
9496f2d398b49813176939d7a339ae513d5175efvboxsync * the IP header. Does not affect the checksumming.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @remarks 82544GC/EI interprets a cleared field differently. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** TSE: TCP segmentation enable. When clear the context describes */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Report status (only applies to dw3.fDD for here). */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Reserved, MBZ. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Descriptor extension, must be set for this descriptor type. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Reserved, MBZ. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Interrupt delay enable. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Descriptor Done. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Reserved, MBZ. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** TSO: The header (prototype) length (Ethernet[, VLAN tag], IP, TCP/UDP. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** TSO: Maximum segment size. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * TCP/IP Data Transmit Descriptor, section 3.3.7.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync uint64_t u64BufAddr; /**< Address of data buffer */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** The total length of data pointed to by this descriptor. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** The descriptor type - E1K_DTYP_DATA (1). */
05d0c18daabd17b1b434b3684ae642fbc8313ef2vboxsync /** @name DCMD field, 8 bits (3.3.7.1).
05d0c18daabd17b1b434b3684ae642fbc8313ef2vboxsync /** End of packet. Note TSCTFC update. */
05d0c18daabd17b1b434b3684ae642fbc8313ef2vboxsync /** Insert Ethernet FCS/CRC (requires fEOP to be set). */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Use the TSE context when set and the normal when clear. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Report status (dw3.STA). */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Reserved. 82544GC/EI defines this report packet set (RPS). */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Descriptor extension, must be set for this descriptor type. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** VLAN enable, requires CTRL.VME, auto enables FCS/CRC.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * Insert dw3.SPECIAL after ethernet header. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Interrupt delay enable. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** @name STA field (3.3.7.2)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Reserved, except for the usual oddball (82544GC/EI) where it's called TU. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** @name POPTS (Packet Option) field (3.3.7.3)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned fTXSM : 1; /**< Insert TCP/UDP checksum. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** @name SPECIAL field - VLAN tag to be inserted after ethernet header.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Requires fEOP, fVLE and CTRL.VME to be set.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned fCFI : 1; /**< Canonical form indicator (VLAN). */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#define E1K_IP_RF 0x8000 /* reserved fragment flag */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#define E1K_IP_OFFMASK 0x1fff /* mask for fragmenting bits */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** @todo use+extend RTNETIPV4 */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* type of service / version / header length */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* total length */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* identification */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* fragment offset field */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* time to live / protocol*/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* checksum */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* source IP address */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* destination IP address */
struct E1kTcpHeader
struct E1kState_st
#ifndef E1K_GLOBAL_MUTEX
# ifdef E1K_USE_SUPLIB_SEMEVENT
bool fIntRaised;
bool fCableConnected;
bool fR0Enabled;
bool fGCEnabled;
bool fLocked;
bool fDelayInts;
bool fIntMaskUsed;
bool volatile fMaybeOutOfSpace;
} uTxFallback;
bool fIPcsum;
bool fTCPcsum;
#ifdef E1K_INT_STATS
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
PDMBOTHCBDECL(int) e1kMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
PDMBOTHCBDECL(int) e1kMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
PDMBOTHCBDECL(int) e1kIOPortIn (PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) e1kIOPortOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t u32, unsigned cb);
static int e1kRegReadUnimplemented (E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value);
static int e1kRegWriteUnimplemented(E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t u32Value);
static int e1kRegReadAutoClear (E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value);
static int e1kRegReadDefault (E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value);
static int e1kRegWriteDefault (E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t u32Value);
const static struct E1kRegMap_st
const char *abbrev;
const char *name;
/*------- ------- ---------- ---------- ----------------------- ------------------------ ---------- ------------------------------*/
{ 0x00000, 0x00004, 0xDBF31BE9, 0xDBF31BE9, e1kRegReadDefault , e1kRegWriteCTRL , "CTRL" , "Device Control" },
{ 0x00008, 0x00004, 0x0000FDFF, 0x00000000, e1kRegReadDefault , e1kRegWriteUnimplemented, "STATUS" , "Device Status" },
{ 0x00010, 0x00004, 0x000027F0, 0x00000070, e1kRegReadEECD , e1kRegWriteEECD , "EECD" , "EEPROM/Flash Control/Data" },
{ 0x00014, 0x00004, 0xFFFFFF10, 0xFFFFFF00, e1kRegReadDefault , e1kRegWriteEERD , "EERD" , "EEPROM Read" },
{ 0x00018, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "CTRL_EXT", "Extended Device Control" },
{ 0x0001c, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FLA" , "Flash Access (N/A)" },
{ 0x00020, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteMDIC , "MDIC" , "MDI Control" },
{ 0x00028, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FCAL" , "Flow Control Address Low" },
{ 0x0002c, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FCAH" , "Flow Control Address High" },
{ 0x00030, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FCT" , "Flow Control Type" },
{ 0x00038, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteDefault , "VET" , "VLAN EtherType" },
{ 0x000c0, 0x00004, 0x0001F6DF, 0x0001F6DF, e1kRegReadICR , e1kRegWriteICR , "ICR" , "Interrupt Cause Read" },
{ 0x000c4, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteDefault , "ITR" , "Interrupt Throttling" },
{ 0x000c8, 0x00004, 0x00000000, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteICS , "ICS" , "Interrupt Cause Set" },
{ 0x000d0, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteIMS , "IMS" , "Interrupt Mask Set/Read" },
{ 0x000d8, 0x00004, 0x00000000, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteIMC , "IMC" , "Interrupt Mask Clear" },
{ 0x00100, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteRCTL , "RCTL" , "Receive Control" },
{ 0x00170, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FCTTV" , "Flow Control Transmit Timer Value" },
{ 0x00178, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TXCW" , "Transmit Configuration Word (N/A)" },
{ 0x00180, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RXCW" , "Receive Configuration Word (N/A)" },
{ 0x00400, 0x00004, 0x017FFFFA, 0x017FFFFA, e1kRegReadDefault , e1kRegWriteDefault , "TCTL" , "Transmit Control" },
{ 0x00410, 0x00004, 0x3FFFFFFF, 0x3FFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "TIPG" , "Transmit IPG" },
{ 0x00458, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteDefault , "AIFS" , "Adaptive IFS Throttle - AIT" },
{ 0x00e00, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "LEDCTL" , "LED Control" },
{ 0x01000, 0x00004, 0xFFFF007F, 0x0000007F, e1kRegReadDefault , e1kRegWritePBA , "PBA" , "Packet Buffer Allocation" },
{ 0x02160, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FCRTL" , "Flow Control Receive Threshold Low" },
{ 0x02168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FCRTH" , "Flow Control Receive Threshold High" },
{ 0x02410, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RDFH" , "Receive Data FIFO Head" },
{ 0x02418, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RDFT" , "Receive Data FIFO Tail" },
{ 0x02420, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RDFHS" , "Receive Data FIFO Head Saved Register" },
{ 0x02428, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RDFTS" , "Receive Data FIFO Tail Saved Register" },
{ 0x02430, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RDFPC" , "Receive Data FIFO Packet Count" },
{ 0x02800, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "RDBAL" , "Receive Descriptor Base Low" },
{ 0x02804, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "RDBAH" , "Receive Descriptor Base High" },
{ 0x02808, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "RDLEN" , "Receive Descriptor Length" },
{ 0x02810, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "RDH" , "Receive Descriptor Head" },
{ 0x02818, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteRDT , "RDT" , "Receive Descriptor Tail" },
{ 0x02820, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteRDTR , "RDTR" , "Receive Delay Timer" },
{ 0x02828, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RXDCTL" , "Receive Descriptor Control" },
{ 0x0282c, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteDefault , "RADV" , "Receive Interrupt Absolute Delay Timer" },
{ 0x02c00, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RSRPD" , "Receive Small Packet Detect Interrupt" },
{ 0x03000, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TXDMAC" , "TX DMA Control (N/A)" },
{ 0x03410, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TDFH" , "Transmit Data FIFO Head" },
{ 0x03418, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TDFT" , "Transmit Data FIFO Tail" },
{ 0x03420, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TDFHS" , "Transmit Data FIFO Head Saved Register" },
{ 0x03428, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TDFTS" , "Transmit Data FIFO Tail Saved Register" },
{ 0x03430, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TDFPC" , "Transmit Data FIFO Packet Count" },
{ 0x03800, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "TDBAL" , "Transmit Descriptor Base Low" },
{ 0x03804, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "TDBAH" , "Transmit Descriptor Base High" },
{ 0x03808, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "TDLEN" , "Transmit Descriptor Length" },
{ 0x03810, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteDefault , "TDH" , "Transmit Descriptor Head" },
{ 0x03818, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteTDT , "TDT" , "Transmit Descriptor Tail" },
{ 0x03820, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteDefault , "TIDV" , "Transmit Interrupt Delay Value" },
{ 0x03828, 0x00004, 0xFF3F3F3F, 0xFF3F3F3F, e1kRegReadDefault , e1kRegWriteDefault , "TXDCTL" , "Transmit Descriptor Control" },
{ 0x0382c, 0x00004, 0x0000FFFF, 0x0000FFFF, e1kRegReadDefault , e1kRegWriteDefault , "TADV" , "Transmit Absolute Interrupt Delay Timer" },
{ 0x03830, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "TSPMT" , "TCP Segmentation Pad and Threshold" },
{ 0x04000, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "CRCERRS" , "CRC Error Count" },
{ 0x04004, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "ALGNERRC", "Alignment Error Count" },
{ 0x04008, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "SYMERRS" , "Symbol Error Count" },
{ 0x0400c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RXERRC" , "RX Error Count" },
{ 0x04010, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "MPC" , "Missed Packets Count" },
{ 0x04014, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "SCC" , "Single Collision Count" },
{ 0x04018, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "ECOL" , "Excessive Collisions Count" },
{ 0x0401c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "MCC" , "Multiple Collision Count" },
{ 0x04020, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "LATECOL" , "Late Collisions Count" },
{ 0x04028, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "COLC" , "Collision Count" },
{ 0x04030, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "DC" , "Defer Count" },
{ 0x04034, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "TNCRS" , "Transmit - No CRS" },
{ 0x04038, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "SEC" , "Sequence Error Count" },
{ 0x0403c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "CEXTERR" , "Carrier Extension Error Count" },
{ 0x04040, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RLEC" , "Receive Length Error Count" },
{ 0x04048, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "XONRXC" , "XON Received Count" },
{ 0x0404c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "XONTXC" , "XON Transmitted Count" },
{ 0x04050, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "XOFFRXC" , "XOFF Received Count" },
{ 0x04054, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "XOFFTXC" , "XOFF Transmitted Count" },
{ 0x04058, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FCRUC" , "FC Received Unsupported Count" },
{ 0x0405c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PRC64" , "Packets Received (64 Bytes) Count" },
{ 0x04060, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PRC127" , "Packets Received (65-127 Bytes) Count" },
{ 0x04064, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PRC255" , "Packets Received (128-255 Bytes) Count" },
{ 0x04068, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PRC511" , "Packets Received (256-511 Bytes) Count" },
{ 0x0406c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PRC1023" , "Packets Received (512-1023 Bytes) Count" },
{ 0x04070, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PRC1522" , "Packets Received (1024-Max Bytes)" },
{ 0x04074, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "GPRC" , "Good Packets Received Count" },
{ 0x04078, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "BPRC" , "Broadcast Packets Received Count" },
{ 0x0407c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "MPRC" , "Multicast Packets Received Count" },
{ 0x04080, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "GPTC" , "Good Packets Transmitted Count" },
{ 0x04088, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "GORCL" , "Good Octets Received Count (Low)" },
{ 0x0408c, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "GORCH" , "Good Octets Received Count (Hi)" },
{ 0x04090, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "GOTCL" , "Good Octets Transmitted Count (Low)" },
{ 0x04094, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "GOTCH" , "Good Octets Transmitted Count (Hi)" },
{ 0x040a0, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RNBC" , "Receive No Buffers Count" },
{ 0x040a4, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RUC" , "Receive Undersize Count" },
{ 0x040a8, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RFC" , "Receive Fragment Count" },
{ 0x040ac, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "ROC" , "Receive Oversize Count" },
{ 0x040b0, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "RJC" , "Receive Jabber Count" },
{ 0x040b4, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "MGTPRC" , "Management Packets Received Count" },
{ 0x040b8, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "MGTPDC" , "Management Packets Dropped Count" },
{ 0x040bc, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "MGTPTC" , "Management Pkts Transmitted Count" },
{ 0x040c0, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TORL" , "Total Octets Received (Lo)" },
{ 0x040c4, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TORH" , "Total Octets Received (Hi)" },
{ 0x040c8, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TOTL" , "Total Octets Transmitted (Lo)" },
{ 0x040cc, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TOTH" , "Total Octets Transmitted (Hi)" },
{ 0x040d0, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TPR" , "Total Packets Received" },
{ 0x040d4, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TPT" , "Total Packets Transmitted" },
{ 0x040d8, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PTC64" , "Packets Transmitted (64 Bytes) Count" },
{ 0x040dc, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PTC127" , "Packets Transmitted (65-127 Bytes) Count" },
{ 0x040e0, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PTC255" , "Packets Transmitted (128-255 Bytes) Count" },
{ 0x040e4, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PTC511" , "Packets Transmitted (256-511 Bytes) Count" },
{ 0x040e8, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PTC1023" , "Packets Transmitted (512-1023 Bytes) Count" },
{ 0x040ec, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "PTC1522" , "Packets Transmitted (1024 Bytes or Greater) Count" },
{ 0x040f0, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "MPTC" , "Multicast Packets Transmitted Count" },
{ 0x040f4, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "BPTC" , "Broadcast Packets Transmitted Count" },
{ 0x040f8, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TSCTC" , "TCP Segmentation Context Transmitted Count" },
{ 0x040fc, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadAutoClear , e1kRegWriteUnimplemented, "TSCTFC" , "TCP Segmentation Context Tx Fail Count" },
{ 0x05000, 0x00004, 0x000007FF, 0x000007FF, e1kRegReadDefault , e1kRegWriteDefault , "RXCSUM" , "Receive Checksum Control" },
{ 0x05800, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "WUC" , "Wakeup Control" },
{ 0x05808, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "WUFC" , "Wakeup Filter Control" },
{ 0x05810, 0x00004, 0xFFFFFFFF, 0x00000000, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "WUS" , "Wakeup Status" },
{ 0x05820, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadDefault , e1kRegWriteDefault , "MANC" , "Management Control" },
{ 0x05838, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "IPAV" , "IP Address Valid" },
{ 0x05900, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "WUPL" , "Wakeup Packet Length" },
{ 0x05200, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadMTA , e1kRegWriteMTA , "MTA" , "Multicast Table Array (n)" },
{ 0x05400, 0x00080, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadRA , e1kRegWriteRA , "RA" , "Receive Address (64-bit) (n)" },
{ 0x05600, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadVFTA , e1kRegWriteVFTA , "VFTA" , "VLAN Filter Table Array (n)" },
{ 0x05840, 0x0001c, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "IP4AT" , "IPv4 Address Table" },
{ 0x05880, 0x00010, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "IP6AT" , "IPv6 Address Table" },
{ 0x05a00, 0x00080, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "WUPM" , "Wakeup Packet Memory" },
{ 0x05f00, 0x0001c, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FFLT" , "Flexible Filter Length Table" },
{ 0x09000, 0x003fc, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FFMT" , "Flexible Filter Mask Table" },
{ 0x09800, 0x003fc, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FFVT" , "Flexible Filter Value Table" },
{ 0x10000, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "PBM" , "Packet Buffer Memory (n)" },
{ 0x00040, 0x00080, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadRA , e1kRegWriteRA , "RA" , "Receive Address (64-bit) (n) (82542)" },
{ 0x00200, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadMTA , e1kRegWriteMTA , "MTA" , "Multicast Table Array (n) (82542)" },
{ 0x00600, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadVFTA , e1kRegWriteVFTA , "VFTA" , "VLAN Filter Table Array (n) (82542)" }
#ifdef DEBUG
return buf;
#ifdef E1K_GLOBAL_MUTEX
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
#ifdef IN_RING3
* @remarks Refer to http://www.netfor2.com/checksum.html for short intro.
if (cb)
return ~csum;
DECLINLINE(void) e1kPacketDump(E1KSTATE* pState, const uint8_t *cpPacket, size_t cb, const char *cszText)
#ifdef DEBUG
E1kLogRel(("E1000: %s packet #%d, seq=%x ack=%x\n", cszText, pState->u32PktNo++, ntohl(*(uint32_t*)(cpPacket+0x26)), ntohl(*(uint32_t*)(cpPacket+0x2A))));
return E1K_DTYP_LEGACY;
case E1K_DTYP_CONTEXT:
case E1K_DTYP_DATA:
case E1K_DTYP_LEGACY:
#ifdef E1K_INIT_RA0
return rc;
#ifdef E1K_ITR_ENABLED
/* interrupts/sec = 1 / (256 * 10E-9 * ITR) */
return VINF_SUCCESS;
RDH = 0;
E1kLogRel(("E1000: low on RX descriptors, RDH=%x RDT=%x len=%x threshold=%x\n", RDH, RDT, uRQueueLen, uMinRQThreshold));
static DECLCALLBACK(void) e1kStoreRxFragment(E1KSTATE *pState, E1KRXDESC *pDesc, const void *pvBuf, size_t cb)
E1kLog2(("%s e1kStoreRxFragment: store fragment of %04X at %016LX, EOP=%d\n", pState->szInstance, cb, pDesc->u64BufAddr, pDesc->status.fEOP));
PDMDevHlpPhysWrite(pState->CTX_SUFF(pDevIns), e1kDescAddr(RDBAH, RDBAL, RDH), pDesc, sizeof(E1KRXDESC));
//E1kLog2(("%s e1kStoreRxFragment: EOP=%d RDTR=%08X RADV=%08X\n", INSTANCE(pState), pDesc->fEOP, RDTR, RADV));
#ifdef E1K_USE_RX_TIMERS
if (RDTR)
#ifdef E1K_USE_RX_TIMERS
static int e1kRxChecksumOffload(E1KSTATE* pState, const uint8_t *pFrame, size_t cb, E1KRXDST *pStatus)
switch (uEtherType)
return VINF_SUCCESS;
#ifndef E1K_GLOBAL_MUTEX
return rc;
return rc;
return VINF_SUCCESS;
if (cb > 0)
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
#ifdef IN_RING3
return VINF_SUCCESS;
return VINF_IOM_HC_MMIO_WRITE;
#ifdef IN_RING3
return rc;
return VINF_IOM_HC_MMIO_READ;
#ifdef IN_RING3
return VINF_SUCCESS;
return VINF_IOM_HC_MMIO_WRITE;
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
if (value)
ICR = 0;
E1kLog(("%s e1kRegReadICR: Suppressing auto-clear due to disabled interrupts (%08x)\n", INSTANCE(pState), ICR));
return rc;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef IN_RING3
#ifdef IN_RING3 /** @todo bird: Use SUPSem* for this so we can signal it in ring-0 as well. (reduces latency) */
if (pItem)
return rc;
#ifdef E1K_USE_RX_TIMERS
return VINF_SUCCESS;
#ifdef IN_RING3
#ifdef E1K_USE_TX_TIMERS
#ifndef E1K_NO_TAD
#ifdef E1K_USE_RX_TIMERS
if (RT_UNLIKELY( pCtx->tu.u8CSS < (size_t)pCtx->ip.u8CSS + (pCtx->dw2.fIP ? RTNETIPV4_MIN_LEN : RTNETIPV6_MIN_LEN) ))
/* The end of the TCP/UDP checksum should stop at the end of the packet or at least after the headers. */
if (RT_UNLIKELY( pCtx->dw2.fIP && (size_t)pCtx->ip.u8CSO - pCtx->ip.u8CSS != RT_UOFFSETOF(RTNETIPV4, ip_sum) ))
E1kLog(("e1kSetupGsoCtx: TUCSO=%#x TUCSS=%#x TCP=%d\n", pCtx->ip.u8CSO, pCtx->ip.u8CSS, pCtx->dw2.fTCP));
pCtx->dw3.u8HDRLEN, pCtx->dw2.u20PAYLEN, pCtx->dw3.u8HDRLEN + pCtx->dw2.u20PAYLEN, VBOX_MAX_GSO_SIZE));
pGso->cbMaxSeg, pGso->cbHdrs, pGso->offHdr1, pGso->offHdr2, PDMNetGsoTypeName((PDMNETWORKGSOTYPE)pGso->u8Type) ));
if (pSg)
if (pDrv)
if (!fExactSize)
return VERR_NET_DOWN;
return rc;
return VINF_SUCCESS;
if (!pTxSg)
if (pDrv)
else if (pSg)
static void e1kInsertChecksum(E1KSTATE* pState, uint8_t *pPkt, uint16_t u16PktLen, uint8_t cso, uint8_t css, uint16_t cse)
if (cse == 0)
static void e1kFallbackAddSegment(E1KSTATE* pState, RTGCPHYS PhysAddr, uint16_t u16Len, bool fSend, bool fOnWorkerThread)
if (fSend)
static bool e1kFallbackAddToFrame(E1KSTATE* pState, E1KTXDESC* pDesc, uint32_t cbFragment, bool fOnWorkerThread)
e1kFallbackAddSegment(pState, pDesc->data.u64BufAddr, cb, pDesc->data.cmd.fEOP /*fSend*/, fOnWorkerThread);
} while (cbFragment > 0);
E1kLog(("%s Transmit packet is too large: %u > %u(max)\n", INSTANCE(pThis), cbNewPkt, E1K_MAX_TX_PKT_SIZE));
E1kLog(("%s Transmit packet is too large: %u > %u(max)/GSO\n", INSTANCE(pThis), cbNewPkt, pTxSg->cbAvailable));
#ifdef E1K_USE_TX_TIMERS
# ifndef E1K_NO_TAD
# ifndef E1K_NO_TAD
#ifdef E1K_USE_TX_TIMERS
#ifdef E1K_USE_TX_TIMERS
case E1K_DTYP_CONTEXT:
case E1K_DTYP_DATA:
if ( fRc
&& pState->CTX_SUFF(pTxSg)->cbUsed == (size_t)pState->contextTSE.dw3.u8HDRLEN + pState->contextTSE.dw2.u20PAYLEN)
if (fRc)
case E1K_DTYP_LEGACY:
int rc;
if (pDrv)
return rc;
TDH = 0;
if (pDrv)
return rc;
#ifdef IN_RING3
#ifdef E1K_USE_SUPLIB_SEMEVENT
return VINF_SUCCESS;
#ifdef E1K_USE_SUPLIB_SEMEVENT
int rc = SUPSemEventWaitNoResume(PDMDevHlpGetVM(pDevIns)->pSession, pState->hTxSem, RT_INDEFINITE_WAIT);
return VINF_SUCCESS;
# ifdef E1K_USE_SUPLIB_SEMEVENT
return rc;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
AssertReturn(offset - s_e1kRegMap[index].offset < sizeof(pState->aRecAddr.au32), VERR_DEV_IO_ERROR);
pState->aRecAddr.au32[(offset - s_e1kRegMap[index].offset)/sizeof(pState->aRecAddr.au32[0])] = value;
return VINF_SUCCESS;
*pu32Value = pState->aRecAddr.au32[(offset - s_e1kRegMap[index].offset)/sizeof(pState->aRecAddr.au32[0])];
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
static int e1kRegReadUnimplemented(E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value)
*pu32Value = 0;
return VINF_SUCCESS;
static int e1kRegReadAutoClear(E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value)
return rc;
static int e1kRegReadDefault(E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t *pu32Value)
return VINF_SUCCESS;
static int e1kRegWriteUnimplemented(E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t value)
return VINF_SUCCESS;
return VINF_SUCCESS;
int index;
if (s_e1kRegMap[index].offset <= uOffset && uOffset < s_e1kRegMap[index].offset + s_e1kRegMap[index].size)
return index;
#ifdef DEBUG
switch (cb)
if (!mask)
#ifdef E1K_GLOBAL_MUTEX
return rc;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef E1K_GLOBAL_MUTEX
return rc;
return rc;
return rc;
int rc;
rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "e1kMMIOWrite: invalid op size: offset=%#10x cb=%#10x\n", uOffset, cb);
return rc;
rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "%s e1kIOPortIn: invalid op size: port=%RTiop cb=%08x\n", szInst, port, cb);
switch (port)
E1kLog2(("%s e1kIOPortIn: IOADDR(0), selecting register %#010x, val=%#010x\n", szInst, pState->uSelectedReg, *pu32));
E1kLog2(("%s e1kIOPortIn: IODATA(4), reading from selected register %#010x, val=%#010x\n", szInst, pState->uSelectedReg, *pu32));
return rc;
rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "%s e1kIOPortOut: invalid op size: port=%RTiop cb=%08x\n", szInst, port, cb);
switch (port)
E1kLog2(("%s e1kIOPortOut: IODATA(4), writing to selected register %#010x, value=%#010x\n", szInst, pState->uSelectedReg, u32));
return rc;
#ifdef IN_RING3
for (int i = 0; i<E1K_NUM_OF_32BIT_REGS; ++i)
#ifdef E1K_INT_STATS
int rc;
switch (enmType)
case PCI_ADDRESS_SPACE_IO:
case PCI_ADDRESS_SPACE_MEM:
return rc;
return VERR_NET_NO_BUFFER_SPACE;
return VERR_NET_NO_BUFFER_SPACE;
cb = 0;
static DECLCALLBACK(int) e1kNetworkDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)
return VINF_SUCCESS;
return VERR_NET_NO_BUFFER_SPACE;
cMillies));
return rc;
static DECLCALLBACK(int) e1kNetworkDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb)
return VINF_SUCCESS;
return VINF_SUCCESS;
if (fPassed)
return rc;
if (iLUN == 0)
return rc;
return VINF_SUCCESS;
return PDMNETWORKLINKSTATE_UP;
return PDMNETWORKLINKSTATE_DOWN;
static DECLCALLBACK(int) e1kSetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)
if (fNewUp)
return VINF_SUCCESS;
return NULL;
return VINF_SSM_DONT_CALL_AGAIN;
return rc;
return VINF_SUCCESS;
return rc;
#ifdef E1K_USE_TX_TIMERS
#ifndef E1K_NO_TAD
#ifdef E1K_USE_RX_TIMERS
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
static DECLCALLBACK(int) e1kLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
int rc;
LogRel(("%s: The mac address differs: config=%RTmac saved=%RTmac\n", INSTANCE(pState), &pState->macConfigured, &macConfigured));
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("The chip type differs: config=%u saved=%u"), pState->eChip, eChip);
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
#ifdef VBOX_DYNAMIC_NET_ATTACH
#ifdef RT_OS_LINUX
N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
return rc;
#ifdef E1K_USE_RX_TIMERS
#ifdef E1K_USE_TX_TIMERS
# ifndef E1K_NO_TAD
# ifdef E1K_USE_SUPLIB_SEMEVENT
#ifndef E1K_GLOBAL_MUTEX
return VINF_SUCCESS;
int rc;
E1kLog(("%s Constructing new instance sizeof(E1KRXDESC)=%d\n", INSTANCE(pState), sizeof(E1KRXDESC)));
# ifdef E1K_USE_SUPLIB_SEMEVENT
#ifdef E1K_INT_STATS
return rc;
return rc;
#ifndef E1K_GLOBAL_MUTEX
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
#ifdef E1K_USE_TX_TIMERS
return rc;
# ifndef E1K_NO_TAD
return rc;
#ifdef E1K_USE_RX_TIMERS
return rc;
return rc;
return rc;
return rc;
N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
pState->pDrvR0 = PDMIBASER0_QUERY_INTERFACE(PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMIBASER0), PDMINETWORKUP);
pState->pDrvRC = PDMIBASERC_QUERY_INTERFACE(PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMIBASERC), PDMINETWORKUP);
# ifdef E1K_USE_SUPLIB_SEMEVENT
return rc;
return rc;
rc = PDMDevHlpThreadCreate(pDevIns, &pState->pTxThread, pState, e1kTxThread, e1kTxThreadWakeUp, 0, RTTHREADTYPE_IO, "E1000_TX");
return rc;
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatMMIOReadGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling MMIO reads in GC", "/Devices/E1k%d/MMIO/ReadGC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatMMIOReadHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling MMIO reads in HC", "/Devices/E1k%d/MMIO/ReadHC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatMMIOWriteGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling MMIO writes in GC", "/Devices/E1k%d/MMIO/WriteGC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatMMIOWriteHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling MMIO writes in HC", "/Devices/E1k%d/MMIO/WriteHC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatEEPROMRead, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling EEPROM reads", "/Devices/E1k%d/EEPROM/Read", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatEEPROMWrite, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling EEPROM writes", "/Devices/E1k%d/EEPROM/Write", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatIOReadGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO reads in GC", "/Devices/E1k%d/IO/ReadGC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatIOReadHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO reads in HC", "/Devices/E1k%d/IO/ReadHC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatIOWriteGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO writes in GC", "/Devices/E1k%d/IO/WriteGC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatIOWriteHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO writes in HC", "/Devices/E1k%d/IO/WriteHC", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatLateIntTimer, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling late int timer", "/Devices/E1k%d/LateInt/Timer", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatLateInts, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of late interrupts", "/Devices/E1k%d/LateInt/Occured", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatIntsRaised, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of raised interrupts", "/Devices/E1k%d/Interrupts/Raised", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatIntsPrevented, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of prevented interrupts", "/Devices/E1k%d/Interrupts/Prevented", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive", "/Devices/E1k%d/Receive/Total", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveFilter, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive filtering", "/Devices/E1k%d/Receive/Filter", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveStore, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing", "/Devices/E1k%d/Receive/Store", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows", "/Devices/E1k%d/RxOverflow", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of RX overflow wakeups", "/Devices/E1k%d/RxOverflowWakeup", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data received", "/Devices/E1k%d/ReceiveBytes", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC", "/Devices/E1k%d/Transmit/Total", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data transmitted", "/Devices/E1k%d/TransmitBytes", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSend, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in HC", "/Devices/E1k%d/Transmit/Send", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxDescCtxNormal, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of normal context descriptors","/Devices/E1k%d/TxDesc/ContexNormal", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxDescCtxTSE, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TSE context descriptors", "/Devices/E1k%d/TxDesc/ContextTSE", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxDescData, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TX data descriptors", "/Devices/E1k%d/TxDesc/Data", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxDescLegacy, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TX legacy descriptors", "/Devices/E1k%d/TxDesc/Legacy", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxDescTSEData, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TX TSE data descriptors", "/Devices/E1k%d/TxDesc/TSEData", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxPathFallback, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Fallback TSE descriptor path", "/Devices/E1k%d/TxPath/Fallback", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxPathGSO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "GSO TSE descriptor path", "/Devices/E1k%d/TxPath/GSO", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxPathRegular, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Regular descriptor path", "/Devices/E1k%d/TxPath/Normal", iInstance);
PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatPHYAccesses, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of PHY accesses", "/Devices/E1k%d/PHYAccesses", iInstance);
return VINF_SUCCESS;
sizeof(E1KSTATE),
NULL,
NULL,
NULL,
NULL,
#ifdef VBOX_DYNAMIC_NET_ATTACH
NULL,
NULL,
NULL,
NULL,
NULL,