diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c
index 63992f6093c392e955f224e77ca1577050a7937b..5b619be11b390f90cceafa3f4ee4ef88615a4dac 100644
--- a/board/bf537-stamp/bf537-stamp.c
+++ b/board/bf537-stamp/bf537-stamp.c
@@ -34,22 +34,6 @@
 #include <asm/mach-common/bits/bootrom.h>
 #include <netdev.h>
 
-/**
- * is_valid_ether_addr - Determine if the given Ethernet address is valid
- * @addr: Pointer to a six-byte array containing the Ethernet address
- *
- * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
- * a multicast address, and is not FF:FF:FF:FF:FF:FF.
- *
- * Return true if the address is valid.
- */
-static inline int is_valid_ether_addr(const u8 * addr)
-{
-	/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
-	 * explicitly check for it here. */
-	return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
-}
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #define POST_WORD_ADDR 0xFF903FFC
diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile
index 80d785229c523be3a20bbf7545eef5a9223717e7..9f0c2dd50cc706ce32cc0c0234091036b30f3a09 100644
--- a/cpu/mpc8260/Makefile
+++ b/cpu/mpc8260/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000-2006
+# (C) Copyright 2000-2008
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -27,9 +27,13 @@ LIB	= $(obj)lib$(CPU).a
 
 START	= start.o kgdb.o
 COBJS	= traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
-	  interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \
+	  interrupts.o ether_fcc.o i2c.o commproc.o \
 	  bedbug_603e.o pci.o spi.o
 
+COBJS-$(CONFIG_ETHER_ON_SCC) = ether_scc.o
+
+COBJS	+= $(COBJS-y)
+
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 START	:= $(addprefix $(obj),$(START))
diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c
index b9e748ab8b822c33e1be42b324bd68f5cd09a973..f4beca55be0d673392aacc4e68e679d5b411d0bf 100644
--- a/cpu/mpc8260/cpu.c
+++ b/cpu/mpc8260/cpu.c
@@ -325,6 +325,9 @@ int cpu_eth_init(bd_t *bis)
 {
 #if defined(CONFIG_ETHER_ON_FCC)
 	fec_initialize(bis);
+#endif
+#if defined(CONFIG_ETHER_ON_SCC)
+	mpc82xx_scc_enet_initialize(bd);
 #endif
 	return 0;
 }
diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c
index c65f0e068f7ad9e29c3445c0b01ee67778874a4f..3671ef1dfba4a971f6741f9f26f9c94f9d68ad1d 100644
--- a/cpu/mpc8260/ether_scc.c
+++ b/cpu/mpc8260/ether_scc.c
@@ -10,6 +10,12 @@
  * Advent Networks, Inc. <http://www.adventnetworks.com>
  * Jay Monkman <jtm@smoothsmoothie.com>
  *
+ * Modified so that it plays nicely when more than one ETHERNET interface
+ * is in use a la ether_fcc.c.
+ * (C) Copyright 2008
+ * DENX Software Engineerin GmbH
+ * Gary Jennejohn <garyj@denx.de>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -32,11 +38,14 @@
 #include <common.h>
 #include <asm/cpm_8260.h>
 #include <mpc8260.h>
+#include <malloc.h>
 #include <net.h>
 #include <command.h>
 #include <config.h>
 
-#if defined(CONFIG_ETHER_ON_SCC) && defined(CONFIG_CMD_NET)
+#ifndef CONFIG_NET_MULTI
+#error "CONFIG_NET_MULTI must be defined."
+#endif
 
 #if (CONFIG_ETHER_INDEX == 1)
 #  define PROFF_ENET            PROFF_SCC1
@@ -100,7 +109,7 @@ typedef volatile struct CommonBufferDescriptor {
 static RTXBD *rtx;
 
 
-int eth_send(volatile void *packet, int length)
+static int sec_send(struct eth_device *dev, volatile void *packet, int length)
 {
     int i;
     int result = 0;
@@ -137,7 +146,7 @@ int eth_send(volatile void *packet, int length)
 }
 
 
-int eth_rx(void)
+static int sec_rx(struct eth_device *dev)
 {
     int length;
 
@@ -184,7 +193,7 @@ int eth_rx(void)
  *
  *************************************************************/
 
-int eth_init(bd_t *bis)
+static int sec_init(struct eth_device *dev, bd_t *bis)
 {
     int i;
     volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
@@ -194,9 +203,14 @@ int eth_init(bd_t *bis)
     rxIdx = 0;
     txIdx = 0;
 
-    /* assign static pointer to BD area */
-    dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16);
-    rtx = (RTXBD *)&immr->im_dprambase[dpaddr];
+    /*
+     * Assign static pointer to BD area.
+     * Avoid exhausting DPRAM, which would cause a panic.
+     */
+    if (rtx == NULL) {
+	    dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16);
+	    rtx = (RTXBD *)&immr->im_dprambase[dpaddr];
+    }
 
     /* 24.21 - (1-3): ioports have been set up already */
 
@@ -338,7 +352,7 @@ int eth_init(bd_t *bis)
 }
 
 
-void eth_halt(void)
+static void sec_halt(struct eth_device *dev)
 {
     volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
     immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl &= ~(SCC_GSMRL_ENR |
@@ -346,7 +360,7 @@ void eth_halt(void)
 }
 
 #if 0
-void restart(void)
+static void sec_restart(void)
 {
     volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
     immr->im_cpm.cp_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR |
@@ -354,4 +368,20 @@ void restart(void)
 }
 #endif
 
-#endif
+int mpc82xx_scc_enet_initialize(bd_t *bis)
+{
+	struct eth_device *dev;
+
+	dev = (struct eth_device *) malloc(sizeof *dev);
+	memset(dev, 0, sizeof *dev);
+
+	sprintf(dev->name, "SCC ETHERNET");
+	dev->init   = sec_init;
+	dev->halt   = sec_halt;
+	dev->send   = sec_send;
+	dev->recv   = sec_rx;
+
+	eth_register(dev);
+
+	return 1;
+}
diff --git a/cpu/sh4/cpu.c b/cpu/sh4/cpu.c
index d94e139815e9ac0e063bd644c06e5cd8e5c155d3..52b6cfd684ee38e19edec3ec29dc2b59ff406e94 100644
--- a/cpu/sh4/cpu.c
+++ b/cpu/sh4/cpu.c
@@ -82,3 +82,11 @@ int dcache_status (void)
 {
 	return 0;
 }
+
+int cpu_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_SH_ETHER
+	sh_eth_initialize(bis);
+#endif
+	return 0;
+}
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 631336ab447070474ee86c49ebc610036993b17b..128dc11ac5e5310e82bc91fdc145c40670b8cf1d 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	:= $(obj)libnet.a
 
 COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
+COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
 COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
 COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
 COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o
@@ -54,11 +55,11 @@ COBJS-$(CONFIG_NS8382X) += ns8382x.o
 COBJS-$(CONFIG_DRIVER_NS9750_ETHERNET) += ns9750_eth.o
 COBJS-$(CONFIG_PCNET) += pcnet.o
 COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o
-COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
 COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o
 COBJS-$(CONFIG_RTL8139) += rtl8139.o
 COBJS-$(CONFIG_RTL8169) += rtl8169.o
 COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
+COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
 COBJS-$(CONFIG_DRIVER_SMC91111) += smc91111.o
 COBJS-$(CONFIG_DRIVER_SMC911X) += smc911x.o
 COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o
@@ -68,7 +69,6 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o
 COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
 COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o
 COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
-COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 98e8c73cabb41a5599bcddfcd6a9759720bbb47b..af0409bd2cf0347bfe7c74c6264edcff35808cce 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -317,6 +317,30 @@ static void macb_phy_reset(struct macb_device *macb)
 		       netdev->name, status);
 }
 
+#ifdef CONFIG_MACB_SEARCH_PHY
+static int macb_phy_find(struct macb_device *macb)
+{
+	int i;
+	u16 phy_id;
+
+	/* Search for PHY... */
+	for (i = 0; i < 32; i++) {
+		macb->phy_addr = i;
+		phy_id = macb_mdio_read(macb, MII_PHYSID1);
+		if (phy_id != 0xffff) {
+			printf("%s: PHY present at %d\n", macb->netdev.name, i);
+			return 1;
+		}
+	}
+
+	/* PHY isn't up to snuff */
+	printf("%s: PHY not found", macb->netdev.name);
+
+	return 0;
+}
+#endif /* CONFIG_MACB_SEARCH_PHY */
+
+
 static int macb_phy_init(struct macb_device *macb)
 {
 	struct eth_device *netdev = &macb->netdev;
@@ -325,6 +349,13 @@ static int macb_phy_init(struct macb_device *macb)
 	int media, speed, duplex;
 	int i;
 
+#ifdef CONFIG_MACB_SEARCH_PHY
+	/* Auto-detect phy_addr */
+	if (!macb_phy_find(macb)) {
+		return 0;
+	}
+#endif /* CONFIG_MACB_SEARCH_PHY */
+
 	/* Check if the PHY is up to snuff... */
 	phy_id = macb_mdio_read(macb, MII_PHYSID1);
 	if (phy_id == 0xffff) {
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 9e3cf98b3b633191efb780ca44dab5a240101516..ebe858894c275e17363342e08ddc7aa45bf79ef2 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -24,6 +24,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <net.h>
+#include <netdev.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 
@@ -36,12 +37,7 @@
 # error "Please define CONFIG_SH_ETHER_PHY_ADDR"
 #endif
 
-extern int eth_init(bd_t *bd);
-extern void eth_halt(void);
-extern int eth_rx(void);
-extern int eth_send(volatile void *packet, int length);
-
-static struct dev_info_s *dev;
+#define SH_ETH_PHY_DELAY 50000
 
 /*
  * Bits are written to the PHY serially using the
@@ -89,7 +85,7 @@ static void sh_eth_mii_ind_bus_release(int port)
 	udelay(1);
 }
 
-static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len)
+static void sh_eth_mii_read_phy_bits(int port, u32 *val, int len)
 {
 	int i;
 	u32 pir;
@@ -106,8 +102,6 @@ static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len)
 		outl(0, PIR(port));
 		udelay(1);
 	}
-
-	return 0;
 }
 
 #define PHY_INIT	0xFFFFFFFF
@@ -183,26 +177,23 @@ static void sh_eth_mii_write_phy_reg(int port, u8 phy_addr, int reg, u16 val)
 	sh_eth_mii_ind_bus_release(port);
 }
 
-void eth_halt(void)
-{
-}
-
-int eth_send(volatile void *packet, int len)
+int sh_eth_send(struct eth_device *dev, volatile void *packet, int len)
 {
-	int port = dev->port;
-	struct port_info_s *port_info = &dev->port_info[port];
-	int timeout;
-	int rc = 0;
+	struct sh_eth_dev *eth = dev->priv;
+	int port = eth->port, ret = 0, timeout;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 
 	if (!packet || len > 0xffff) {
-		printf("eth_send: Invalid argument\n");
-		return -EINVAL;
+		printf(SHETHER_NAME ": %s: Invalid argument\n", __func__);
+		ret = -EINVAL;
+		goto err;
 	}
 
 	/* packet must be a 4 byte boundary */
 	if ((int)packet & (4 - 1)) {
-		printf("eth_send: packet not 4 byte alligned\n");
-		return -EFAULT;
+		printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n", __func__);
+		ret = -EFAULT;
+		goto err;
 	}
 
 	/* Update tx descriptor */
@@ -224,24 +215,25 @@ int eth_send(volatile void *packet, int len)
 		udelay(100);
 
 	if (timeout < 0) {
-		printf("eth_send: transmit timeout\n");
-		rc = -1;
+		printf(SHETHER_NAME ": transmit timeout\n");
+		ret = -ETIMEDOUT;
 		goto err;
 	}
 
-err:
 	port_info->tx_desc_cur++;
 	if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC)
 		port_info->tx_desc_cur = port_info->tx_desc_base;
 
-	return rc;
+	return ret;
+err:
+	return ret;
 }
 
-int eth_rx(void)
+int sh_eth_recv(struct eth_device *dev)
 {
-	int port = dev->port;
-	struct port_info_s *port_info = &dev->port_info[port];
-	int len = 0;
+	struct sh_eth_dev *eth = dev->priv;
+	int port = eth->port, len = 0;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 	volatile u8 *packet;
 
 	/* Check if the rx descriptor is ready */
@@ -275,10 +267,10 @@ int eth_rx(void)
 }
 
 #define EDMR_INIT_CNT 1000
-static int sh_eth_reset(struct dev_info_s *dev)
+static int sh_eth_reset(struct sh_eth_dev *eth)
 {
-	int port = dev->port;
-	int i;
+	int port = eth->port;
+	int ret = 0, i;
 
 	/* Start e-dmac transmitter and receiver */
 	outl(EDSR_ENALL, EDSR(port));
@@ -292,33 +284,36 @@ static int sh_eth_reset(struct dev_info_s *dev)
 	}
 
 	if (i == EDMR_INIT_CNT) {
-		printf("Error: Software reset timeout\n");
-		return -1;
+		printf(SHETHER_NAME  ": Software reset timeout\n");
+		ret = -EIO;
 	}
-	return 0;
+
+	return ret;
 }
 
-static int sh_eth_tx_desc_init(struct dev_info_s *dev)
+static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
 {
-	int port = dev->port;
-	struct port_info_s *port_info = &dev->port_info[port];
+	int port = eth->port, i, ret = 0;
 	u32 tmp_addr;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 	struct tx_desc_s *cur_tx_desc;
-	int i;
 
-	/* Allocate tx descriptors. They must be TX_DESC_SIZE bytes
-	   aligned */
-	if (!(port_info->tx_desc_malloc = malloc(NUM_TX_DESC *
+	/*
+	 * Allocate tx descriptors. They must be TX_DESC_SIZE bytes aligned
+	 */
+	port_info->tx_desc_malloc = malloc(NUM_TX_DESC *
 						 sizeof(struct tx_desc_s) +
-						 TX_DESC_SIZE - 1))) {
-		printf("Error: malloc failed\n");
-		return -ENOMEM;
+						 TX_DESC_SIZE - 1);
+	if (!port_info->tx_desc_malloc) {
+		printf(SHETHER_NAME ": malloc failed\n");
+		ret = -ENOMEM;
+		goto err;
 	}
+
 	tmp_addr = (u32) (((int)port_info->tx_desc_malloc + TX_DESC_SIZE - 1) &
 			  ~(TX_DESC_SIZE - 1));
 	/* Make sure we use a P2 address (non-cacheable) */
 	port_info->tx_desc_base = (struct tx_desc_s *)ADDR_TO_P2(tmp_addr);
-
 	port_info->tx_desc_cur = port_info->tx_desc_base;
 
 	/* Initialize all descriptors */
@@ -340,26 +335,30 @@ static int sh_eth_tx_desc_init(struct dev_info_s *dev)
 	outl(ADDR_TO_PHY(cur_tx_desc), TDFXR(port));
 	outl(0x01, TDFFR(port));/* Last discriptor bit */
 
-	return 0;
+err:
+	return ret;
 }
 
-static int sh_eth_rx_desc_init(struct dev_info_s *dev)
+static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
 {
-	int port = dev->port;
-	struct port_info_s *port_info = &dev->port_info[port];
-	u32 tmp_addr;
+	int port = eth->port, i , ret = 0;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 	struct rx_desc_s *cur_rx_desc;
+	u32 tmp_addr;
 	u8 *rx_buf;
-	int i;
 
-	/* Allocate rx descriptors. They must be RX_DESC_SIZE bytes
-	   aligned */
-	if (!(port_info->rx_desc_malloc = malloc(NUM_RX_DESC *
+	/*
+	 * Allocate rx descriptors. They must be RX_DESC_SIZE bytes aligned
+	 */
+	port_info->rx_desc_malloc = malloc(NUM_RX_DESC *
 						 sizeof(struct rx_desc_s) +
-						 RX_DESC_SIZE - 1))) {
-		printf("Error: malloc failed\n");
-		return -ENOMEM;
+						 RX_DESC_SIZE - 1);
+	if (!port_info->rx_desc_malloc) {
+		printf(SHETHER_NAME ": malloc failed\n");
+		ret = -ENOMEM;
+		goto err;
 	}
+
 	tmp_addr = (u32) (((int)port_info->rx_desc_malloc + RX_DESC_SIZE - 1) &
 			  ~(RX_DESC_SIZE - 1));
 	/* Make sure we use a P2 address (non-cacheable) */
@@ -367,15 +366,17 @@ static int sh_eth_rx_desc_init(struct dev_info_s *dev)
 
 	port_info->rx_desc_cur = port_info->rx_desc_base;
 
-	/* Allocate rx data buffers. They must be 32 bytes aligned  and in
-	   P2 area */
-	if (!(port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE +
-						31))) {
-		printf("Error: malloc failed\n");
-		free(port_info->rx_desc_malloc);
-		port_info->rx_desc_malloc = NULL;
-		return -ENOMEM;
+	/*
+	 * Allocate rx data buffers. They must be 32 bytes aligned  and in
+	 * P2 area
+	 */
+	port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + 31);
+	if (!port_info->rx_buf_malloc) {
+		printf(SHETHER_NAME ": malloc failed\n");
+		ret = -ENOMEM;
+		goto err_buf_malloc;
 	}
+
 	tmp_addr = (u32)(((int)port_info->rx_buf_malloc + (32 - 1)) &
 			  ~(32 - 1));
 	port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr);
@@ -399,18 +400,31 @@ static int sh_eth_rx_desc_init(struct dev_info_s *dev)
 	outl(ADDR_TO_PHY(cur_rx_desc), RDFXR(port));
 	outl(RDFFR_RDLF, RDFFR(port));
 
-	return 0;
+	return ret;
+
+err_buf_malloc:
+	free(port_info->rx_desc_malloc);
+	port_info->rx_desc_malloc = NULL;
+
+err:
+	return ret;
 }
 
-static void sh_eth_desc_free(struct dev_info_s *dev)
+static void sh_eth_tx_desc_free(struct sh_eth_dev *eth)
 {
-	int port = dev->port;
-	struct port_info_s *port_info = &dev->port_info[port];
+	int port = eth->port;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 
 	if (port_info->tx_desc_malloc) {
 		free(port_info->tx_desc_malloc);
 		port_info->tx_desc_malloc = NULL;
 	}
+}
+
+static void sh_eth_rx_desc_free(struct sh_eth_dev *eth)
+{
+	int port = eth->port;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 
 	if (port_info->rx_desc_malloc) {
 		free(port_info->rx_desc_malloc);
@@ -423,36 +437,48 @@ static void sh_eth_desc_free(struct dev_info_s *dev)
 	}
 }
 
-static int sh_eth_desc_init(struct dev_info_s *dev)
+static int sh_eth_desc_init(struct sh_eth_dev *eth)
 {
-	int rc;
+	int ret = 0;
 
-	if ((rc = sh_eth_tx_desc_init(dev)) || (rc = sh_eth_rx_desc_init(dev))) {
-		sh_eth_desc_free(dev);
-		return rc;
-	}
+	ret = sh_eth_tx_desc_init(eth);
+	if (ret)
+		goto err_tx_init;
 
-	return 0;
+	ret = sh_eth_rx_desc_init(eth);
+	if (ret)
+		goto err_rx_init;
+
+	return ret;
+err_rx_init:
+	sh_eth_tx_desc_free(eth);
+
+err_tx_init:
+	return ret;
 }
 
-static int sh_eth_phy_config(struct dev_info_s *dev)
+static int sh_eth_phy_config(struct sh_eth_dev *eth)
 {
-	int port = dev->port;
-	struct port_info_s *port_info = &dev->port_info[port];
-	int timeout;
+	int port = eth->port, timeout, ret = 0;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 	u32 val;
+
 	/* Reset phy */
-	sh_eth_mii_write_phy_reg(port, port_info->phy_addr, PHY_CTRL, PHY_C_RESET);
+	sh_eth_mii_write_phy_reg
+		(port, port_info->phy_addr, PHY_CTRL, PHY_C_RESET);
 	timeout = 10;
 	while (timeout--) {
-		val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, PHY_CTRL);
+		val = sh_eth_mii_read_phy_reg(port,
+				port_info->phy_addr, PHY_CTRL);
 		if (!(val & PHY_C_RESET))
 			break;
-		udelay(50000);
+		udelay(SH_ETH_PHY_DELAY);
 	}
+
 	if (timeout < 0) {
-		printf("%s phy reset timeout\n", __func__);
-		return -1;
+		printf(SHETHER_NAME ": phy reset timeout\n");
+		ret = -EIO;
+		goto err_tout;
 	}
 
 	/* Advertise 100/10 baseT full/half duplex */
@@ -467,23 +493,27 @@ static int sh_eth_phy_config(struct dev_info_s *dev)
 		val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1);
 		if (val & PHY_S_ANEGC)
 			break;
-		udelay(50000);
+
+		udelay(SH_ETH_PHY_DELAY);
 	}
+
 	if (timeout < 0) {
-		printf("sh_eth_phy_config() phy auto-negotiation failed\n");
-		return -1;
+		printf(SHETHER_NAME ": phy auto-negotiation failed\n");
+		ret = -ETIMEDOUT;
+		goto err_tout;
 	}
 
-	return 0;
+	return ret;
+
+err_tout:
+	return ret;
 }
 
-static int sh_eth_config(struct dev_info_s *dev, bd_t * bd)
+static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
 {
-	int port = dev->port;
-	struct port_info_s *port_info = &dev->port_info[port];
-	u32 val;
-	u32 phy_status;
-	int rc;
+	int port = eth->port, ret = 0;
+	u32 val,  phy_status;
+	struct sh_eth_info *port_info = &eth->port_info[port];
 
 	/* Configure e-dmac registers */
 	outl((inl(EDMR(port)) & ~EMDR_DESC_R) | EDMR_EL, EDMR(port));
@@ -513,20 +543,20 @@ static int sh_eth_config(struct dev_info_s *dev, bd_t * bd)
 	outl(TPAUSER_TPAUSE, TPAUSER(port));
 
 	/* Configure phy */
-	if ((rc = sh_eth_phy_config(dev)))
-		return rc;
-
+	ret = sh_eth_phy_config(eth);
+	if (ret) {
+		printf(SHETHER_NAME ":i phy config timeout\n");
+		goto err_phy_cfg;
+	}
 	/* Read phy status to finish configuring the e-mac */
-	phy_status = sh_eth_mii_read_phy_reg(dev->port,
-					     dev->port_info[dev->port].phy_addr,
-					     1);
+	phy_status = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1);
 
 	/* Set the transfer speed */
 	if (phy_status & (PHY_S_100X_F|PHY_S_100X_H)) {
-		printf("100Base/");
+		printf(SHETHER_NAME ": 100Base/");
 		outl(GECMR_100B, GECMR(port));
 	} else {
-		printf("10Base/");
+		printf(SHETHER_NAME ": 10Base/");
 		outl(GECMR_10B, GECMR(port));
 	}
 
@@ -538,27 +568,34 @@ static int sh_eth_config(struct dev_info_s *dev, bd_t * bd)
 		printf("Half\n");
 		outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE),  ECMR(port));
 	}
-	return 0;
+
+	return ret;
+
+err_phy_cfg:
+	return ret;
 }
 
-static int sh_eth_start(struct dev_info_s *dev)
+static void sh_eth_start(struct sh_eth_dev *eth)
 {
 	/*
 	 * Enable the e-dmac receiver only. The transmitter will be enabled when
 	 * we have something to transmit
 	 */
-	outl(EDRRR_R, EDRRR(dev->port));
+	outl(EDRRR_R, EDRRR(eth->port));
+}
 
-	return 0;
+static void sh_eth_stop(struct sh_eth_dev *eth)
+{
+	outl(~EDRRR_R, EDRRR(eth->port));
 }
 
 static int sh_eth_get_mac(bd_t *bd)
 {
 	char *s, *e;
-	int i;
 
 	s = getenv("ethaddr");
 	if (s != NULL) {
+		int i;
 		for (i = 0; i < 6; ++i) {
 			bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
 			if (s)
@@ -570,34 +607,92 @@ static int sh_eth_get_mac(bd_t *bd)
 	return 0;
 }
 
-int eth_init(bd_t *bd)
+int sh_eth_init(struct eth_device *dev, bd_t *bd)
 {
-	int rc;
-	/* Allocate main device information structure */
-	if (!(dev = malloc(sizeof(*dev)))) {
-		printf("eth_init: malloc failed\n");
-		return -ENOMEM;
-	}
+	int ret = 0;
+	struct sh_eth_dev *eth = dev->priv;
 
-	memset(dev, 0, sizeof(*dev));
+	ret = sh_eth_reset(eth);
+	if (ret)
+		goto err;
 
-	dev->port = CONFIG_SH_ETHER_USE_PORT;
-	dev->port_info[dev->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
+	ret = sh_eth_desc_init(eth);
+	if (ret)
+		goto err;
 
-	sh_eth_get_mac(bd);
+	ret = sh_eth_config(eth, bd);
+	if (ret)
+		goto err_config;
+
+	sh_eth_start(eth);
+
+	return ret;
 
-	if ((rc = sh_eth_reset(dev)) || (rc = sh_eth_desc_init(dev)))
+err_config:
+	sh_eth_tx_desc_free(eth);
+	sh_eth_rx_desc_free(eth);
+
+err:
+	return ret;
+}
+
+void sh_eth_halt(struct eth_device *dev)
+{
+	struct sh_eth_dev *eth = dev->priv;
+
+	sh_eth_reset(eth);
+	sh_eth_stop(eth);
+}
+
+int sh_eth_initialize(bd_t *bd)
+{
+    int ret = 0;
+	struct sh_eth_dev *eth = NULL;
+    struct eth_device *dev = NULL;
+
+    eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev));
+	if (!eth) {
+		printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
+		ret = -ENOMEM;
 		goto err;
+	}
 
-	if ((rc = sh_eth_config(dev, bd)) || (rc = sh_eth_start(dev)))
-		goto err_desc;
+    dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	if (!dev) {
+		printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
+		ret = -ENOMEM;
+		goto err;
+	}
+    memset(dev, 0, sizeof(struct eth_device));
+    memset(eth, 0, sizeof(struct sh_eth_dev));
 
-	return 0;
+	eth->port = CONFIG_SH_ETHER_USE_PORT;
+	eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
+
+    dev->priv = (void *)eth;
+    dev->iobase = 0;
+    dev->init = sh_eth_init;
+    dev->halt = sh_eth_halt;
+    dev->send = sh_eth_send;
+    dev->recv = sh_eth_recv;
+    eth->port_info[eth->port].dev = dev;
+
+	sprintf(dev->name, SHETHER_NAME);
+
+    /* Register Device to EtherNet subsystem  */
+    eth_register(dev);
+
+	sh_eth_get_mac(bd);
+
+	return ret;
 
-err_desc:
-	sh_eth_desc_free(dev);
 err:
-	free(dev);
-	printf("eth_init: Failed\n");
-	return rc;
+	if (dev)
+		free(dev);
+
+	if (eth)
+		free(eth);
+
+	printf(SHETHER_NAME ": Failed\n");
+	return ret;
 }
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 9cf0ea0b9e7cd635903bd30fccdb817585025d15..a13fff02c3e64c6a7455bf4a69adfd60ad4cb0c0 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -20,6 +20,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <netdev.h>
 #include <asm/types.h>
 
 #define SHETHER_NAME "sh_eth"
@@ -48,7 +49,7 @@
 #define TX_DESC_PADDING		4
 #define TX_DESC_SIZE		(12 + TX_DESC_PADDING)
 
-/* Tx descriptor. We always use 4 bytes of padding */
+/* Tx descriptor. We always use 3 bytes of padding */
 struct tx_desc_s {
 	volatile u32 td0;
 	u32 td1;
@@ -72,7 +73,7 @@ struct rx_desc_s {
 	u32 padding;
 };
 
-struct port_info_s {
+struct sh_eth_info {
 	struct tx_desc_s *tx_desc_malloc;
 	struct tx_desc_s *tx_desc_base;
 	struct tx_desc_s *tx_desc_cur;
@@ -83,11 +84,12 @@ struct port_info_s {
 	u8 *rx_buf_base;
 	u8 mac_addr[6];
 	u8 phy_addr;
+	struct eth_device *dev;
 };
 
-struct dev_info_s {
+struct sh_eth_dev {
 	int port;
-	struct port_info_s port_info[MAX_PORT_NUM];
+	struct sh_eth_info port_info[MAX_PORT_NUM];
 };
 
 /* Register Address */
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 648c94cbbbbd8046631ad19bac80d6a54e019d2a..9cc4fce0024701bd8b0375954e04dd832ba5a22c 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -34,21 +34,24 @@
 #endif
 
 #if defined (CONFIG_DRIVER_SMC911X_32_BIT)
-static inline u32 reg_read(u32 addr)
+static inline u32 __smc911x_reg_read(u32 addr)
 {
 	return *(volatile u32*)addr;
 }
-static inline void reg_write(u32 addr, u32 val)
+u32 smc911x_reg_read(u32 addr) __attribute__((weak, alias("__smc911x_reg_read")));
+
+static inline void __smc911x_reg_write(u32 addr, u32 val)
 {
 	*(volatile u32*)addr = val;
 }
+void smc911x_reg_write(u32 addr, u32 val) __attribute__((weak, alias("__smc911x_reg_write")));
 #elif defined (CONFIG_DRIVER_SMC911X_16_BIT)
-static inline u32 reg_read(u32 addr)
+static inline u32 smc911x_reg_read(u32 addr)
 {
 	volatile u16 *addr_16 = (u16 *)addr;
 	return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16));
 }
-static inline void reg_write(u32 addr, u32 val)
+static inline void smc911x_reg_write(u32 addr, u32 val)
 {
 	*(volatile u16*)addr = (u16)val;
 	*(volatile u16*)(addr + 2) = (u16)(val >> 16);
@@ -58,9 +61,9 @@ static inline void reg_write(u32 addr, u32 val)
 #endif /* CONFIG_DRIVER_SMC911X_16_BIT */
 
 u32 pkt_data_pull(u32 addr) \
-	__attribute__ ((weak, alias ("reg_read")));
+	__attribute__ ((weak, alias ("smc911x_reg_read")));
 void pkt_data_push(u32 addr, u32 val) \
-	__attribute__ ((weak, alias ("reg_write")));
+	__attribute__ ((weak, alias ("smc911x_reg_write")));
 
 #define mdelay(n)       udelay((n)*1000)
 
@@ -381,6 +384,7 @@ void pkt_data_push(u32 addr, u32 val) \
 #define CHIP_9116	0x116
 #define CHIP_9117	0x117
 #define CHIP_9118	0x118
+#define CHIP_9211	0x9211
 #define CHIP_9215	0x115a
 #define CHIP_9216	0x116a
 #define CHIP_9217	0x117a
@@ -396,6 +400,7 @@ static const struct chip_id chip_ids[] =  {
 	{ CHIP_9116, "LAN9116" },
 	{ CHIP_9117, "LAN9117" },
 	{ CHIP_9118, "LAN9118" },
+	{ CHIP_9211, "LAN9211" },
 	{ CHIP_9215, "LAN9215" },
 	{ CHIP_9216, "LAN9216" },
 	{ CHIP_9217, "LAN9217" },
@@ -407,22 +412,22 @@ static const struct chip_id chip_ids[] =  {
 
 u32 smc911x_get_mac_csr(u8 reg)
 {
-	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 		;
-	reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
-	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+	smc911x_reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
+	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 		;
 
-	return reg_read(MAC_CSR_DATA);
+	return smc911x_reg_read(MAC_CSR_DATA);
 }
 
 void smc911x_set_mac_csr(u8 reg, u32 data)
 {
-	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 		;
-	reg_write(MAC_CSR_DATA, data);
-	reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
-	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+	smc911x_reg_write(MAC_CSR_DATA, data);
+	smc911x_reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
+	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 		;
 }
 
@@ -496,10 +501,10 @@ static int smc911x_phy_reset(void)
 {
 	u32 reg;
 
-	reg = reg_read(PMT_CTRL);
+	reg = smc911x_reg_read(PMT_CTRL);
 	reg &= ~0xfffff030;
 	reg |= PMT_CTRL_PHY_RST;
-	reg_write(PMT_CTRL, reg);
+	smc911x_reg_write(PMT_CTRL, reg);
 
 	mdelay(100);
 
@@ -541,13 +546,13 @@ static void smc911x_reset(void)
 	int timeout;
 
 	/* Take out of PM setting first */
-	if (reg_read(PMT_CTRL) & PMT_CTRL_READY) {
+	if (smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY) {
 		/* Write to the bytetest will take out of powerdown */
-		reg_write(BYTE_TEST, 0x0);
+		smc911x_reg_write(BYTE_TEST, 0x0);
 
 		timeout = 10;
 
-		while (timeout-- && !(reg_read(PMT_CTRL) & PMT_CTRL_READY))
+		while (timeout-- && !(smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY))
 			udelay(10);
 		if (!timeout) {
 			printf(DRIVERNAME
@@ -557,12 +562,12 @@ static void smc911x_reset(void)
 	}
 
 	/* Disable interrupts */
-	reg_write(INT_EN, 0);
+	smc911x_reg_write(INT_EN, 0);
 
-	reg_write(HW_CFG, HW_CFG_SRST);
+	smc911x_reg_write(HW_CFG, HW_CFG_SRST);
 
 	timeout = 1000;
-	while (timeout-- && reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY)
+	while (timeout-- && smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY)
 		udelay(10);
 
 	if (!timeout) {
@@ -572,23 +577,23 @@ static void smc911x_reset(void)
 
 	/* Reset the FIFO level and flow control settings */
 	smc911x_set_mac_csr(FLOW, FLOW_FCPT | FLOW_FCEN);
-	reg_write(AFC_CFG, 0x0050287F);
+	smc911x_reg_write(AFC_CFG, 0x0050287F);
 
 	/* Set to LED outputs */
-	reg_write(GPIO_CFG, 0x70070000);
+	smc911x_reg_write(GPIO_CFG, 0x70070000);
 }
 
 static void smc911x_enable(void)
 {
 	/* Enable TX */
-	reg_write(HW_CFG, 8 << 16 | HW_CFG_SF);
+	smc911x_reg_write(HW_CFG, 8 << 16 | HW_CFG_SF);
 
-	reg_write(GPT_CFG, GPT_CFG_TIMER_EN | 10000);
+	smc911x_reg_write(GPT_CFG, GPT_CFG_TIMER_EN | 10000);
 
-	reg_write(TX_CFG, TX_CFG_TX_ON);
+	smc911x_reg_write(TX_CFG, TX_CFG_TX_ON);
 
 	/* no padding to start of packets */
-	reg_write(RX_CFG, 0);
+	smc911x_reg_write(RX_CFG, 0);
 
 	smc911x_set_mac_csr(MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS);
 
@@ -600,13 +605,13 @@ int eth_init(bd_t *bd)
 
 	printf(DRIVERNAME ": initializing\n");
 
-	val = reg_read(BYTE_TEST);
+	val = smc911x_reg_read(BYTE_TEST);
 	if (val != 0x87654321) {
 		printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);
 		goto err_out;
 	}
 
-	val = reg_read(ID_REV) >> 16;
+	val = smc911x_reg_read(ID_REV) >> 16;
 	for (i = 0; chip_ids[i].id != 0; i++) {
 		if (chip_ids[i].id == val) break;
 	}
@@ -640,8 +645,8 @@ int eth_send(volatile void *packet, int length)
 	u32 tmplen;
 	u32 status;
 
-	reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length);
-	reg_write(TX_DATA_FIFO, length);
+	smc911x_reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length);
+	smc911x_reg_write(TX_DATA_FIFO, length);
 
 	tmplen = (length + 3) / 4;
 
@@ -649,12 +654,12 @@ int eth_send(volatile void *packet, int length)
 		pkt_data_push(TX_DATA_FIFO, *data++);
 
 	/* wait for transmission */
-	while (!((reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16));
+	while (!((smc911x_reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16));
 
 	/* get status. Ignore 'no carrier' error, it has no meaning for
 	 * full duplex operation
 	 */
-	status = reg_read(TX_STATUS_FIFO) & (TX_STS_LOC | TX_STS_LATE_COLL |
+	status = smc911x_reg_read(TX_STATUS_FIFO) & (TX_STS_LOC | TX_STS_LATE_COLL |
 		TX_STS_MANY_COLL | TX_STS_MANY_DEFER | TX_STS_UNDERRUN);
 
 	if (!status)
@@ -681,11 +686,11 @@ int eth_rx(void)
 	u32 pktlen, tmplen;
 	u32 status;
 
-	if ((reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) {
-		status = reg_read(RX_STATUS_FIFO);
+	if ((smc911x_reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) {
+		status = smc911x_reg_read(RX_STATUS_FIFO);
 		pktlen = (status & RX_STS_PKT_LEN) >> 16;
 
-		reg_write(RX_CFG, 0);
+		smc911x_reg_write(RX_CFG, 0);
 
 		tmplen = (pktlen + 2+ 3) / 4;
 		while (tmplen--)
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index fbc9a6dd05b4a3178b80168cf316c173f866ee85..dc90f23859fe6518d272c2453cf7b6ddb11704fe 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -1141,6 +1141,9 @@ struct phy_info phy_info_M88E1118 = {
 		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
 		{0x16, 0x0002, NULL}, /* Change Page Number */
 		{0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */
+		{0x16, 0x0003, NULL}, /* Change Page Number */
+		{0x10, 0x021e, NULL}, /* Adjust LED control */
+		{0x16, 0x0000, NULL}, /* Change Page Number */
 		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
 		{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
 		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
@@ -1152,6 +1155,7 @@ struct phy_info phy_info_M88E1118 = {
 		/* Status is read once to clear old link state */
 		{MIIM_STATUS, miim_read, NULL},
 		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
 		/* Read the status */
 		{MIIM_88E1011_PHY_STATUS, miim_read,
 		 &mii_parse_88E1011_psr},
diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c
index 829f0828537c308fb25036b4d8a69d2250c8c92e..d613f3e4cf21e92b882985fd533090f279dba4ae 100644
--- a/drivers/qe/uec_phy.c
+++ b/drivers/qe/uec_phy.c
@@ -603,6 +603,55 @@ static int fixed_phy_read_status (struct uec_mii_info *mii_info)
 	return 0;
 }
 
+static int smsc_config_aneg (struct uec_mii_info *mii_info)
+{
+	return 0;
+}
+
+static int smsc_read_status (struct uec_mii_info *mii_info)
+{
+	u16 status;
+	int err;
+
+	/* Update the link, but return if there
+	 * was an error */
+	err = genmii_update_link (mii_info);
+	if (err)
+		return err;
+
+	/* If the link is up, read the speed and duplex */
+	/* If we aren't autonegotiating, assume speeds
+	 * are as set */
+	if (mii_info->autoneg && mii_info->link) {
+		int	val;
+
+		status = phy_read (mii_info, 0x1f);
+		val = (status & 0x1c) >> 2;
+
+		switch (val) {
+			case 1:
+				mii_info->duplex = DUPLEX_HALF;
+				mii_info->speed = SPEED_10;
+				break;
+			case 5:
+				mii_info->duplex = DUPLEX_FULL;
+				mii_info->speed = SPEED_10;
+				break;
+			case 2:
+				mii_info->duplex = DUPLEX_HALF;
+				mii_info->speed = SPEED_100;
+				break;
+			case 6:
+				mii_info->duplex = DUPLEX_FULL;
+				mii_info->speed = SPEED_100;
+				break;
+		}
+		mii_info->pause = 0;
+	}
+
+	return 0;
+}
+
 static struct phy_info phy_info_dm9161 = {
 	.phy_id = 0x0181b880,
 	.phy_id_mask = 0x0ffffff0,
@@ -655,6 +704,15 @@ static struct phy_info phy_info_fixedphy = {
 	.read_status = fixed_phy_read_status,
 };
 
+static struct phy_info phy_info_smsclan8700 = {
+	.phy_id = 0x0007c0c0,
+	.phy_id_mask = 0xfffffff0,
+	.name = "SMSC LAN8700",
+	.features = MII_BASIC_FEATURES,
+	.config_aneg = smsc_config_aneg,
+	.read_status = smsc_read_status,
+};
+
 static struct phy_info phy_info_genmii = {
 	.phy_id = 0x00000000,
 	.phy_id_mask = 0x00000000,
@@ -669,6 +727,7 @@ static struct phy_info *phy_info[] = {
 	&phy_info_dm9161a,
 	&phy_info_marvell,
 	&phy_info_bcm5481,
+	&phy_info_smsclan8700,
 	&phy_info_fixedphy,
 	&phy_info_genmii,
 	NULL
diff --git a/include/configs/sh7763rdp.h b/include/configs/sh7763rdp.h
index 8a76dad5d93580f85cacb18cb9a9ab8aac622a6b..4ea79cf33b3be301f0d78338c68ae8099f398d32 100644
--- a/include/configs/sh7763rdp.h
+++ b/include/configs/sh7763rdp.h
@@ -118,6 +118,7 @@
 #define CONFIG_SYS_HZ				(CONFIG_SYS_CLK_FREQ / TMU_CLK_DIVIDER)
 
 /* Ether */
+#define CONFIG_NET_MULTI 1
 #define CONFIG_SH_ETHER 1
 #define CONFIG_SH_ETHER_USE_PORT (1)
 #define CONFIG_SH_ETHER_PHY_ADDR (0x01)
diff --git a/include/net.h b/include/net.h
index d2d394f0da80d0788e92dce97f740c9fe0679443..bbe0d4b5a2dfe4b001f00b3b8e62d86923372ca1 100644
--- a/include/net.h
+++ b/include/net.h
@@ -474,6 +474,22 @@ static inline int is_multicast_ether_addr(const u8 *addr)
 	return (0x01 & addr[0]);
 }
 
+/**
+ * is_valid_ether_addr - Determine if the given Ethernet address is valid
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
+ * a multicast address, and is not FF:FF:FF:FF:FF:FF.
+ *
+ * Return true if the address is valid.
+ */
+static inline int is_valid_ether_addr(const u8 * addr)
+{
+	/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
+	 * explicitly check for it here. */
+	return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
+}
+
 /* Convert an IP address to a string */
 extern void	ip_to_string (IPaddr_t x, char *s);
 
diff --git a/include/netdev.h b/include/netdev.h
index 751f0dab55d2a08c0f79f238a254eda7b3b70f41..ce1ecbd8e82b61b98ffb3e5c4009c4a685682146 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -57,6 +57,7 @@ int mcffec_initialize(bd_t *bis);
 int mpc512x_fec_initialize(bd_t *bis);
 int mpc5xxx_fec_initialize(bd_t *bis);
 int mpc8220_fec_initialize(bd_t *bis);
+int mpc82xx_scc_enet_initialize(bd_t *bis);
 int natsemi_initialize(bd_t *bis);
 int npe_initialize(bd_t *bis);
 int ns8382x_initialize(bd_t *bis);
@@ -70,6 +71,7 @@ int skge_initialize(bd_t *bis);
 int tsi108_eth_initialize(bd_t *bis);
 int uec_initialize(int index);
 int uli526x_initialize(bd_t *bis);
+int sh_eth_initialize(bd_t *bis);
 
 /* Boards with PCI network controllers can call this from their board_eth_init()
  * function to initialize whatever's on board.
diff --git a/net/net.c b/net/net.c
index e6547f9eddc860838e245483277c8d12b59ef87a..459baf4ea69da201933d0f26612381236b93d75d 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1684,7 +1684,7 @@ NetSetEther(volatile uchar * xet, uchar * addr, uint prot)
 void
 NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
 {
-	volatile IP_t *ip = (IP_t *)xip;
+	IP_t *ip = (IP_t *)xip;
 
 	/*
 	 *	If the data is an odd number of bytes, zero the