net: e1000: Prepare for driver model conversion

Since struct eth_device does not exist with CONFIG_DM_ETH defined, avoid
using it in the driver unless necessary. Most of the time it is better to
pass the private driver pointer anyway.

Also refactor the code so that code that the driver model implementation
will share are available in functions that can be called. Add stubs where
necessary.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Tested-on: Apalis T30 2GB on Apalis Evaluation Board
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 187517b..807012c 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -30,6 +30,8 @@
  */
 
 #include <common.h>
+#include <errno.h>
+#include <pci.h>
 #include "e1000.h"
 
 #define TOUT_LOOP   100000
@@ -53,67 +55,67 @@
 static int rx_tail, rx_last;
 
 static struct pci_device_id e1000_supported[] = {
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF},
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF) },
 	/* E1000 PCIe card */
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER      },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES     },
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82574L},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_UNPROGRAMMED},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_UNPROGRAMMED},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_COPPER},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER_FLASHLESS},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES_FLASHLESS},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_1000BASEKX},
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82574L) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_UNPROGRAMMED) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_UNPROGRAMMED) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I211_COPPER) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER_FLASHLESS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES_FLASHLESS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_1000BASEKX) },
 
 	{}
 };
 
 /* Function forward declarations */
-static int e1000_setup_link(struct eth_device *nic);
-static int e1000_setup_fiber_link(struct eth_device *nic);
-static int e1000_setup_copper_link(struct eth_device *nic);
+static int e1000_setup_link(struct e1000_hw *hw);
+static int e1000_setup_fiber_link(struct e1000_hw *hw);
+static int e1000_setup_copper_link(struct e1000_hw *hw);
 static int e1000_phy_setup_autoneg(struct e1000_hw *hw);
 static void e1000_config_collision_dist(struct e1000_hw *hw);
 static int e1000_config_mac_to_phy(struct e1000_hw *hw);
 static int e1000_config_fc_after_link_up(struct e1000_hw *hw);
-static int e1000_check_for_link(struct eth_device *nic);
+static int e1000_check_for_link(struct e1000_hw *hw);
 static int e1000_wait_autoneg(struct e1000_hw *hw);
 static int e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed,
 				       uint16_t * duplex);
@@ -906,13 +908,13 @@
 	/* Allocate a temporary buffer */
 	buf = malloc(sizeof(buf[0]) * (EEPROM_CHECKSUM_REG + 1));
 	if (!buf) {
-		E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n");
+		E1000_ERR(hw, "Unable to allocate EEPROM buffer!\n");
 		return -E1000_ERR_EEPROM;
 	}
 
 	/* Read the EEPROM */
 	if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) {
-		E1000_ERR(hw->nic, "Unable to read EEPROM!\n");
+		E1000_ERR(hw, "Unable to read EEPROM!\n");
 		return -E1000_ERR_EEPROM;
 	}
 
@@ -928,9 +930,9 @@
 		return 0;
 
 	/* Hrm, verification failed, print an error */
-	E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n");
-	E1000_ERR(hw->nic, "  ...register was 0x%04hx, calculated 0x%04hx\n",
-			checksum_reg, checksum);
+	E1000_ERR(hw, "EEPROM checksum is incorrect!\n");
+	E1000_ERR(hw, "  ...register was 0x%04hx, calculated 0x%04hx\n",
+		  checksum_reg, checksum);
 
 	return -E1000_ERR_EEPROM;
 }
@@ -1177,9 +1179,8 @@
  * nic - Struct containing variables accessed by shared code
  *****************************************************************************/
 static int
-e1000_read_mac_addr(struct eth_device *nic)
+e1000_read_mac_addr(struct e1000_hw *hw, unsigned char enetaddr[6])
 {
-	struct e1000_hw *hw = nic->priv;
 	uint16_t offset;
 	uint16_t eeprom_data;
 	uint32_t reg_data = 0;
@@ -1202,19 +1203,19 @@
 			DEBUGOUT("EEPROM Read Error\n");
 			return -E1000_ERR_EEPROM;
 		}
-		nic->enetaddr[i] = eeprom_data & 0xff;
-		nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff;
+		enetaddr[i] = eeprom_data & 0xff;
+		enetaddr[i + 1] = (eeprom_data >> 8) & 0xff;
 	}
 
 	/* Invert the last bit if this is the second device */
 	if (e1000_is_second_port(hw))
-		nic->enetaddr[5] ^= 1;
+		enetaddr[5] ^= 1;
 
 #ifdef CONFIG_E1000_FALLBACK_MAC
 	if (!is_valid_ethaddr(nic->enetaddr)) {
 		unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC;
 
-		memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE);
+		memcpy(enetaddr, fb_mac, NODE_ADDRESS_SIZE);
 	}
 #endif
 	return 0;
@@ -1231,9 +1232,8 @@
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
 static void
-e1000_init_rx_addrs(struct eth_device *nic)
+e1000_init_rx_addrs(struct e1000_hw *hw, unsigned char enetaddr[6])
 {
-	struct e1000_hw *hw = nic->priv;
 	uint32_t i;
 	uint32_t addr_low;
 	uint32_t addr_high;
@@ -1242,11 +1242,11 @@
 
 	/* Setup the receive address. */
 	DEBUGOUT("Programming MAC Address into RAR[0]\n");
-	addr_low = (nic->enetaddr[0] |
-		    (nic->enetaddr[1] << 8) |
-		    (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24));
+	addr_low = (enetaddr[0] |
+		    (enetaddr[1] << 8) |
+		    (enetaddr[2] << 16) | (enetaddr[3] << 24));
 
-	addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV);
+	addr_high = (enetaddr[4] | (enetaddr[5] << 8) | E1000_RAH_AV);
 
 	E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
 	E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
@@ -1653,9 +1653,8 @@
  * the transmit and receive units disabled and uninitialized.
  *****************************************************************************/
 static int
-e1000_init_hw(struct eth_device *nic)
+e1000_init_hw(struct e1000_hw *hw, unsigned char enetaddr[6])
 {
-	struct e1000_hw *hw = nic->priv;
 	uint32_t ctrl;
 	uint32_t i;
 	int32_t ret_val;
@@ -1708,7 +1707,7 @@
 	/* Setup the receive address. This involves initializing all of the Receive
 	 * Address Registers (RARs 0 - 15).
 	 */
-	e1000_init_rx_addrs(nic);
+	e1000_init_rx_addrs(hw, enetaddr);
 
 	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
 	if (hw->mac_type == e1000_82542_rev2_0) {
@@ -1777,7 +1776,7 @@
 		mdelay(15);
 
 	/* Call a subroutine to configure the link and setup flow control. */
-	ret_val = e1000_setup_link(nic);
+	ret_val = e1000_setup_link(hw);
 
 	/* Set the transmit descriptor write-back policy */
 	if (hw->mac_type > e1000_82544) {
@@ -1877,9 +1876,8 @@
  * transmitter and receiver are not enabled.
  *****************************************************************************/
 static int
-e1000_setup_link(struct eth_device *nic)
+e1000_setup_link(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = nic->priv;
 	int32_t ret_val;
 #ifndef CONFIG_E1000_NO_NVM
 	uint32_t ctrl_ext;
@@ -1967,7 +1965,7 @@
 
 	/* Call the necessary subroutine to configure the link. */
 	ret_val = (hw->media_type == e1000_media_type_fiber) ?
-	    e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic);
+	    e1000_setup_fiber_link(hw) : e1000_setup_copper_link(hw);
 	if (ret_val < 0) {
 		return ret_val;
 	}
@@ -2024,9 +2022,8 @@
  * and receiver are not enabled.
  *****************************************************************************/
 static int
-e1000_setup_fiber_link(struct eth_device *nic)
+e1000_setup_fiber_link(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = nic->priv;
 	uint32_t ctrl;
 	uint32_t status;
 	uint32_t txcw = 0;
@@ -2045,7 +2042,7 @@
 	else
 		signal = 0;
 
-	printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal,
+	printf("signal for %s is %x (ctrl %08x)!!!!\n", hw->name, signal,
 	       ctrl);
 	/* Take the link out of reset */
 	ctrl &= ~(E1000_CTRL_LRST);
@@ -2133,7 +2130,7 @@
 			 */
 			DEBUGOUT("Never got a valid link from auto-neg!!!\n");
 			hw->autoneg_failed = 1;
-			ret_val = e1000_check_for_link(nic);
+			ret_val = e1000_check_for_link(hw);
 			if (ret_val < 0) {
 				DEBUGOUT("Error while checking for link\n");
 				return ret_val;
@@ -3050,9 +3047,8 @@
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
 static int
-e1000_setup_copper_link(struct eth_device *nic)
+e1000_setup_copper_link(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = nic->priv;
 	int32_t ret_val;
 	uint16_t i;
 	uint16_t phy_data;
@@ -3675,9 +3671,8 @@
  * Called by any function that needs to check the link status of the adapter.
  *****************************************************************************/
 static int
-e1000_check_for_link(struct eth_device *nic)
+e1000_check_for_link(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = nic->priv;
 	uint32_t rxcw;
 	uint32_t ctrl;
 	uint32_t status;
@@ -4874,9 +4869,8 @@
  **/
 
 static int
-e1000_sw_init(struct eth_device *nic)
+e1000_sw_init(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = (typeof(hw)) nic->priv;
 	int result;
 
 	/* PCI config space info */
@@ -4892,7 +4886,7 @@
 	/* identify the MAC */
 	result = e1000_set_mac_type(hw);
 	if (result) {
-		E1000_ERR(hw->nic, "Unknown MAC Type\n");
+		E1000_ERR(hw, "Unknown MAC Type\n");
 		return result;
 	}
 
@@ -5152,9 +5146,8 @@
 POLL - Wait for a frame
 ***************************************************************************/
 static int
-e1000_poll(struct eth_device *nic)
+_e1000_poll(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = nic->priv;
 	struct e1000_rx_desc *rd;
 	unsigned long inval_start, inval_end;
 	uint32_t len;
@@ -5175,18 +5168,12 @@
 	invalidate_dcache_range((unsigned long)packet,
 				(unsigned long)packet +
 				roundup(len, ARCH_DMA_MINALIGN));
-	net_process_received_packet((uchar *)packet, len);
-	fill_rx(hw);
-	return 1;
+	return len;
 }
 
-/**************************************************************************
-TRANSMIT - Transmit a frame
-***************************************************************************/
-static int e1000_transmit(struct eth_device *nic, void *txpacket, int length)
+static int _e1000_transmit(struct e1000_hw *hw, void *txpacket, int length)
 {
 	void *nv_packet = (void *)txpacket;
-	struct e1000_hw *hw = nic->priv;
 	struct e1000_tx_desc *txp;
 	int i = 0;
 	unsigned long flush_start, flush_end;
@@ -5223,27 +5210,9 @@
 	return 1;
 }
 
-/*reset function*/
-static inline int
-e1000_reset(struct eth_device *nic)
-{
-	struct e1000_hw *hw = nic->priv;
-
-	e1000_reset_hw(hw);
-	if (hw->mac_type >= e1000_82544) {
-		E1000_WRITE_REG(hw, WUC, 0);
-	}
-	return e1000_init_hw(nic);
-}
-
-/**************************************************************************
-DISABLE - Turn off ethernet interface
-***************************************************************************/
 static void
-e1000_disable(struct eth_device *nic)
+_e1000_disable(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = nic->priv;
-
 	/* Turn off the ethernet interface */
 	E1000_WRITE_REG(hw, RCTL, 0);
 	E1000_WRITE_REG(hw, TCTL, 0);
@@ -5261,32 +5230,38 @@
 	E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST);
 #endif
 	mdelay(10);
+}
 
+/*reset function*/
+static inline int
+e1000_reset(struct e1000_hw *hw, unsigned char enetaddr[6])
+{
+	e1000_reset_hw(hw);
+	if (hw->mac_type >= e1000_82544)
+		E1000_WRITE_REG(hw, WUC, 0);
+
+	return e1000_init_hw(hw, enetaddr);
 }
 
-/**************************************************************************
-INIT - set up ethernet interface(s)
-***************************************************************************/
 static int
-e1000_init(struct eth_device *nic, bd_t * bis)
+_e1000_init(struct e1000_hw *hw, unsigned char enetaddr[6])
 {
-	struct e1000_hw *hw = nic->priv;
 	int ret_val = 0;
 
-	ret_val = e1000_reset(nic);
+	ret_val = e1000_reset(hw, enetaddr);
 	if (ret_val < 0) {
 		if ((ret_val == -E1000_ERR_NOLINK) ||
 		    (ret_val == -E1000_ERR_TIMEOUT)) {
-			E1000_ERR(hw->nic, "Valid Link not detected\n");
+			E1000_ERR(hw, "Valid Link not detected: %d\n", ret_val);
 		} else {
-			E1000_ERR(hw->nic, "Hardware Initialization Failed\n");
+			E1000_ERR(hw, "Hardware Initialization Failed\n");
 		}
-		return 0;
+		return ret_val;
 	}
 	e1000_configure_tx(hw);
 	e1000_setup_rctl(hw);
 	e1000_configure_rx(hw);
-	return 1;
+	return 0;
 }
 
 /******************************************************************************
@@ -5323,6 +5298,138 @@
 /* A list of all registered e1000 devices */
 static LIST_HEAD(e1000_hw_list);
 
+static int e1000_init_one(struct e1000_hw *hw, int cardnum, pci_dev_t devno,
+			  unsigned char enetaddr[6])
+{
+	u32 val;
+
+	/* Assign the passed-in values */
+	hw->pdev = devno;
+	hw->cardnum = cardnum;
+
+	/* Print a debug message with the IO base address */
+	pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &val);
+	E1000_DBG(hw, "iobase 0x%08x\n", val & 0xfffffff0);
+
+	/* Try to enable I/O accesses and bus-mastering */
+	val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+	pci_write_config_dword(devno, PCI_COMMAND, val);
+
+	/* Make sure it worked */
+	pci_read_config_dword(devno, PCI_COMMAND, &val);
+	if (!(val & PCI_COMMAND_MEMORY)) {
+		E1000_ERR(hw, "Can't enable I/O memory\n");
+		return -ENOSPC;
+	}
+	if (!(val & PCI_COMMAND_MASTER)) {
+		E1000_ERR(hw, "Can't enable bus-mastering\n");
+		return -EPERM;
+	}
+
+	/* Are these variables needed? */
+	hw->fc = e1000_fc_default;
+	hw->original_fc = e1000_fc_default;
+	hw->autoneg_failed = 0;
+	hw->autoneg = 1;
+	hw->get_link_status = true;
+#ifndef CONFIG_E1000_NO_NVM
+	hw->eeprom_semaphore_present = true;
+#endif
+	hw->hw_addr = pci_map_bar(devno,	PCI_BASE_ADDRESS_0,
+						PCI_REGION_MEM);
+	hw->mac_type = e1000_undefined;
+
+	/* MAC and Phy settings */
+	if (e1000_sw_init(hw) < 0) {
+		E1000_ERR(hw, "Software init failed\n");
+		return -EIO;
+	}
+	if (e1000_check_phy_reset_block(hw))
+		E1000_ERR(hw, "PHY Reset is blocked!\n");
+
+	/* Basic init was OK, reset the hardware and allow SPI access */
+	e1000_reset_hw(hw);
+
+#ifndef CONFIG_E1000_NO_NVM
+	/* Validate the EEPROM and get chipset information */
+#if !defined(CONFIG_MVBC_1G)
+	if (e1000_init_eeprom_params(hw)) {
+		E1000_ERR(hw, "EEPROM is invalid!\n");
+		return -EINVAL;
+	}
+	if ((E1000_READ_REG(hw, I210_EECD) & E1000_EECD_FLUPD) &&
+	    e1000_validate_eeprom_checksum(hw))
+		return -ENXIO;
+#endif
+	e1000_read_mac_addr(hw, enetaddr);
+#endif
+	e1000_get_bus_type(hw);
+
+#ifndef CONFIG_E1000_NO_NVM
+	printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n       ",
+	       enetaddr[0], enetaddr[1], enetaddr[2],
+	       enetaddr[3], enetaddr[4], enetaddr[5]);
+#else
+	memset(enetaddr, 0, 6);
+	printf("e1000: no NVM\n");
+#endif
+
+	return 0;
+}
+
+/* Put the name of a device in a string */
+static void e1000_name(char *str, int cardnum)
+{
+	sprintf(str, "e1000#%u", cardnum);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static int e1000_transmit(struct eth_device *nic, void *txpacket, int length)
+{
+	struct e1000_hw *hw = nic->priv;
+
+	return _e1000_transmit(hw, txpacket, length);
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void
+e1000_disable(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+
+	_e1000_disable(hw);
+}
+
+/**************************************************************************
+INIT - set up ethernet interface(s)
+***************************************************************************/
+static int
+e1000_init(struct eth_device *nic, bd_t *bis)
+{
+	struct e1000_hw *hw = nic->priv;
+
+	return _e1000_init(hw, nic->enetaddr);
+}
+
+static int
+e1000_poll(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	int len;
+
+	len = _e1000_poll(hw);
+	if (len) {
+		net_process_received_packet((uchar *)packet, len);
+		fill_rx(hw);
+	}
+
+	return len ? 1 : 0;
+}
+
 /**************************************************************************
 PROBE - Look for an adapter, this routine's visible to the outside
 You should omit the last argument struct pci_device * for a non-PCI NIC
@@ -5332,13 +5439,12 @@
 {
 	unsigned int i;
 	pci_dev_t devno;
+	int ret;
 
 	DEBUGFUNC();
 
 	/* Find and probe all the matching PCI devices */
 	for (i = 0; (devno = pci_find_devices(e1000_supported, i)) >= 0; i++) {
-		u32 val;
-
 		/*
 		 * These will never get freed due to errors, this allows us to
 		 * perform SPI EEPROM programming from U-boot, for example.
@@ -5355,83 +5461,18 @@
 		/* Make sure all of the fields are initially zeroed */
 		memset(nic, 0, sizeof(*nic));
 		memset(hw, 0, sizeof(*hw));
-
-		/* Assign the passed-in values */
-		hw->cardnum = i;
-		hw->pdev = devno;
-		hw->nic = nic;
 		nic->priv = hw;
 
 		/* Generate a card name */
-		sprintf(nic->name, "e1000#%u", hw->cardnum);
-
-		/* Print a debug message with the IO base address */
-		pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &val);
-		E1000_DBG(nic, "iobase 0x%08x\n", val & 0xfffffff0);
-
-		/* Try to enable I/O accesses and bus-mastering */
-		val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
-		pci_write_config_dword(devno, PCI_COMMAND, val);
-
-		/* Make sure it worked */
-		pci_read_config_dword(devno, PCI_COMMAND, &val);
-		if (!(val & PCI_COMMAND_MEMORY)) {
-			E1000_ERR(nic, "Can't enable I/O memory\n");
-			continue;
-		}
-		if (!(val & PCI_COMMAND_MASTER)) {
-			E1000_ERR(nic, "Can't enable bus-mastering\n");
-			continue;
-		}
+		e1000_name(nic->name, i);
+		hw->name = nic->name;
 
-		/* Are these variables needed? */
-		hw->fc = e1000_fc_default;
-		hw->original_fc = e1000_fc_default;
-		hw->autoneg_failed = 0;
-		hw->autoneg = 1;
-		hw->get_link_status = true;
-#ifndef CONFIG_E1000_NO_NVM
-		hw->eeprom_semaphore_present = true;
-#endif
-		hw->hw_addr = pci_map_bar(devno,	PCI_BASE_ADDRESS_0,
-							PCI_REGION_MEM);
-		hw->mac_type = e1000_undefined;
-
-		/* MAC and Phy settings */
-		if (e1000_sw_init(nic) < 0) {
-			E1000_ERR(nic, "Software init failed\n");
+		ret = e1000_init_one(hw, i, devno, nic->enetaddr);
+		if (ret)
 			continue;
-		}
-		if (e1000_check_phy_reset_block(hw))
-			E1000_ERR(nic, "PHY Reset is blocked!\n");
-
-		/* Basic init was OK, reset the hardware and allow SPI access */
-		e1000_reset_hw(hw);
 		list_add_tail(&hw->list_node, &e1000_hw_list);
 
-#ifndef CONFIG_E1000_NO_NVM
-		/* Validate the EEPROM and get chipset information */
-#if !defined(CONFIG_MVBC_1G)
-		if (e1000_init_eeprom_params(hw)) {
-			E1000_ERR(nic, "EEPROM is invalid!\n");
-			continue;
-		}
-		if ((E1000_READ_REG(hw, I210_EECD) & E1000_EECD_FLUPD) &&
-		    e1000_validate_eeprom_checksum(hw))
-			continue;
-#endif
-		e1000_read_mac_addr(nic);
-#endif
-		e1000_get_bus_type(hw);
-
-#ifndef CONFIG_E1000_NO_NVM
-		printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n       ",
-		       nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2],
-		       nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]);
-#else
-		memset(nic->enetaddr, 0, 6);
-		printf("e1000: no NVM\n");
-#endif
+		hw->nic = nic;
 
 		/* Set up the function pointers and register the device */
 		nic->init = e1000_init;
@@ -5459,6 +5500,7 @@
 static int do_e1000(cmd_tbl_t *cmdtp, int flag,
 		int argc, char * const argv[])
 {
+	unsigned char *mac = NULL;
 	struct e1000_hw *hw;
 
 	if (argc < 3) {
@@ -5467,14 +5509,16 @@
 	}
 
 	/* Make sure we can find the requested e1000 card */
-	hw = e1000_find_card(simple_strtoul(argv[1], NULL, 10));
-	if (!hw) {
+	cardnum = simple_strtoul(argv[1], NULL, 10);
+	hw = e1000_find_card(cardnum);
+	if (hw)
+		mac = hw->nic->enetaddr;
+	if (!mac) {
 		printf("e1000: ERROR: No such device: e1000#%s\n", argv[1]);
 		return 1;
 	}
 
 	if (!strcmp(argv[2], "print-mac-address")) {
-		unsigned char *mac = hw->nic->enetaddr;
 		printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
 			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 		return 0;
diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h
index 989f01d..da04cabd 100644
--- a/drivers/net/e1000.h
+++ b/drivers/net/e1000.h
@@ -1071,6 +1071,7 @@
 
 /* Structure containing variables used by the shared code (e1000_hw.c) */
 struct e1000_hw {
+	const char *name;
 	struct list_head list_node;
 	struct eth_device *nic;
 #ifdef CONFIG_E1000_SPI