diff --git a/board/qemu-mips/qemu-mips.c b/board/qemu-mips/qemu-mips.c
index 7a69a00f99a0f0293c1be8127e5ab615933be857..2b3a1d6b0992f79157246655f3bfed5daff4a6fd 100644
--- a/board/qemu-mips/qemu-mips.c
+++ b/board/qemu-mips/qemu-mips.c
@@ -25,6 +25,7 @@
 #include <command.h>
 #include <asm/mipsregs.h>
 #include <asm/io.h>
+#include <netdev.h>
 
 phys_size_t initdram(int board_type)
 {
@@ -87,3 +88,8 @@ int misc_init_r(void)
 	set_io_port_base(0);
 	return 0;
 }
+
+int board_eth_init(bd_t *bis)
+{
+	return ne2k_register();
+}
diff --git a/board/renesas/r7780mp/r7780mp.c b/board/renesas/r7780mp/r7780mp.c
index 0b800990479fdb37b6e44eed324ee4c5f24c4519..82cef025adef60035e19379e21a9503e5191943d 100644
--- a/board/renesas/r7780mp/r7780mp.c
+++ b/board/renesas/r7780mp/r7780mp.c
@@ -81,5 +81,6 @@ void pci_init_board(void)
 
 int board_eth_init(bd_t *bis)
 {
-	return pci_eth_init(bis);
+	/* return >= 0 if a chip is found, the board's AX88796L is n2k-based */
+	return ne2k_register() + pci_eth_init(bis);
 }
diff --git a/board/shmin/shmin.c b/board/shmin/shmin.c
index 8742f10218267099de9a1522d3478e0ca47a0f2b..7348f52aa620949d35d8bfad049bfd16c4fe8cd5 100644
--- a/board/shmin/shmin.c
+++ b/board/shmin/shmin.c
@@ -28,6 +28,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/processor.h>
+#include <netdev.h>
 
 int checkboard(void)
 {
@@ -55,6 +56,11 @@ int dram_init(void)
 	return 0;
 }
 
+int board_eth_init(bd_t *bis)
+{
+	return ne2k_register();
+}
+
 void led_set_state(unsigned short value)
 {
 
diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c
index f0cd2b62eb3e8132910dbf8533846543c80756b5..88f2b379f37bbb5f73907d5631b56ed7763c78d7 100644
--- a/drivers/net/ne2000_base.c
+++ b/drivers/net/ne2000_base.c
@@ -94,8 +94,12 @@ void uboot_push_tx_done(int key, int val);
 
 static dp83902a_priv_data_t nic; /* just one instance of the card supported */
 
+/**
+ * This function reads the MAC address from the serial EEPROM,
+ * used if PROM read fails. Does nothing for ax88796 chips (sh boards)
+ */
 static bool
-dp83902a_init(void)
+dp83902a_init(unsigned char *enetaddr)
 {
 	dp83902a_priv_data_t *dp = &nic;
 	u8* base;
@@ -129,6 +133,7 @@ dp83902a_init(void)
 		dp->esa[4],
 		dp->esa[5] );
 
+	memcpy(enetaddr, dp->esa, 6); /* Use MAC from serial EEPROM */
 #endif	/* NE2000_BASIC_INIT */
 	return true;
 }
@@ -161,6 +166,8 @@ dp83902a_start(u8 * enaddr)
 	u8 *base = dp->base;
 	int i;
 
+	debug("The MAC is %pM\n", enaddr);
+
 	DEBUG_FUNCTION();
 
 	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
@@ -665,12 +672,16 @@ void uboot_push_tx_done(int key, int val) {
 	pkey = key;
 }
 
-int eth_init(bd_t *bd) {
-	int r;
-	u8 dev_addr[6];
-	char ethaddr[20];
-
-	PRINTK("### eth_init\n");
+/**
+ * Setup the driver and init MAC address according to doc/README.enetaddr
+ * Called by ne2k_register() before registering the driver @eth layer
+ *
+ * @param struct ethdevice of this instance of the driver for dev->enetaddr
+ * @return 0 on success, -1 on error (causing caller to print error msg)
+ */
+static int ne2k_setup_driver(struct eth_device *dev)
+{
+	PRINTK("### ne2k_setup_driver\n");
 
 	if (!pbuf) {
 		pbuf = malloc(2000);
@@ -692,49 +703,56 @@ int eth_init(bd_t *bd) {
 
 	nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
 
-	r = get_prom(dev_addr, nic.base);
-	if (!r)
-		return -1;
-
-	sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 dev_addr[0], dev_addr[1],
-		 dev_addr[2], dev_addr[3],
-		 dev_addr[4], dev_addr[5]) ;
-	PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
-	setenv ("ethaddr", ethaddr);
-
 	nic.data = nic.base + DP_DATA;
 	nic.tx_buf1 = START_PG;
 	nic.tx_buf2 = START_PG2;
 	nic.rx_buf_start = RX_START;
 	nic.rx_buf_end = RX_END;
 
-	if (dp83902a_init() == false)
-		return -1;
+	/*
+	 * According to doc/README.enetaddr, drivers shall give priority
+	 * to the MAC address value in the environment, so we do not read
+	 * it from the prom or eeprom if it is specified in the environment.
+	 */
+	if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) {
+		/* If the MAC address is not in the environment, get it: */
+		if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */
+			dp83902a_init(dev->enetaddr);   /* fallback: seeprom */
+		/* And write it into the environment otherwise eth_write_hwaddr
+		 * returns -1 due to eth_getenv_enetaddr_by_index() failing,
+		 * and this causes "Warning: failed to set MAC address", and
+		 * cmd_bdinfo has no ethaddr value which it can show: */
+		eth_setenv_enetaddr("ethaddr", dev->enetaddr);
+	}
+	return 0;
+}
 
-	dp83902a_start(dev_addr);
+static int ne2k_init(struct eth_device *dev, bd_t *bd)
+{
+	dp83902a_start(dev->enetaddr);
 	initialized = 1;
-
 	return 0;
 }
 
-void eth_halt() {
-
-	PRINTK("### eth_halt\n");
+static void ne2k_halt(struct eth_device *dev)
+{
+	debug("### ne2k_halt\n");
 	if(initialized)
 		dp83902a_stop();
 	initialized = 0;
 }
 
-int eth_rx() {
+static int ne2k_recv(struct eth_device *dev)
+{
 	dp83902a_poll();
 	return 1;
 }
 
-int eth_send(volatile void *packet, int length) {
+static int ne2k_send(struct eth_device *dev, volatile void *packet, int length)
+{
 	int tmo;
 
-	PRINTK("### eth_send\n");
+	debug("### ne2k_send\n");
 
 	pkey = -1;
 
@@ -754,3 +772,28 @@ int eth_send(volatile void *packet, int length) {
 	}
 	return 0;
 }
+
+/**
+ * Setup the driver for use and register it with the eth layer
+ * @return 0 on success, -1 on error (causing caller to print error msg)
+ */
+int ne2k_register(void)
+{
+	struct eth_device *dev;
+
+	dev = calloc(sizeof(*dev), 1);
+	if (dev == NULL)
+		return -1;
+
+	if (ne2k_setup_driver(dev))
+		return -1;
+
+	dev->init = ne2k_init;
+	dev->halt = ne2k_halt;
+	dev->send = ne2k_send;
+	dev->recv = ne2k_recv;
+
+	sprintf(dev->name, "NE2000");
+
+	return eth_register(dev);
+}
diff --git a/include/netdev.h b/include/netdev.h
index 04d9f75b771d36b422539523285a20520cf9dc8d..150fa8e4d59f0217b417e91828ade78b89a7fd4f 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -80,6 +80,7 @@ int mpc8220_fec_initialize(bd_t *bis);
 int mpc82xx_scc_enet_initialize(bd_t *bis);
 int mvgbe_initialize(bd_t *bis);
 int natsemi_initialize(bd_t *bis);
+int ne2k_register(void);
 int npe_initialize(bd_t *bis);
 int ns8382x_initialize(bd_t *bis);
 int pcnet_initialize(bd_t *bis);