Merge branch 'master' of git://git.denx.de/u-boot-net
diff --git a/README b/README
index 263bb05..1158e24 100644
--- a/README
+++ b/README
@@ -822,6 +822,16 @@
 
 - NETWORK Support (other):
 
+		CONFIG_DRIVER_AT91EMAC
+		Support for AT91RM9200 EMAC.
+
+			CONFIG_RMII
+			Define this to use reduced MII inteface
+
+			CONFIG_DRIVER_AT91EMAC_QUIET
+			If this defined, the driver is quiet.
+			The driver doen't show link status messages.
+
 		CONFIG_DRIVER_LAN91C96
 		Support for SMSC's LAN91C96 chips.
 
diff --git a/board/atmel/at91rm9200dk/at91rm9200dk.c b/board/atmel/at91rm9200dk/at91rm9200dk.c
index c761dd7..49b5fe3 100644
--- a/board/atmel/at91rm9200dk/at91rm9200dk.c
+++ b/board/atmel/at91rm9200dk/at91rm9200dk.c
@@ -23,9 +23,15 @@
  */
 
 #include <common.h>
+#include <exports.h>
+#include <netdev.h>
 #include <asm/arch/AT91RM9200.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <dm9161.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -95,6 +101,15 @@
 #endif
 #endif	/* CONFIG_DRIVER_ETHER */
 
+#ifdef CONFIG_DRIVER_AT91EMAC
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
+
 /*
  * Disk On Chip (NAND) Millenium initialization.
  * The NAND lives in the CS2* space
diff --git a/board/atmel/at91rm9200ek/at91rm9200ek.c b/board/atmel/at91rm9200ek/at91rm9200ek.c
index ea684e9..570a09a 100644
--- a/board/atmel/at91rm9200ek/at91rm9200ek.c
+++ b/board/atmel/at91rm9200ek/at91rm9200ek.c
@@ -23,9 +23,14 @@
  */
 
 #include <common.h>
+#include <exports.h>
+#include <netdev.h>
 #include <asm/arch/AT91RM9200.h>
+#include <asm/io.h>
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <dm9161.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -84,3 +89,12 @@
 	p_phyops->AutoNegotiate = dm9161_AutoNegotiate;
 }
 #endif
+
+#ifdef CONFIG_DRIVER_AT91EMAC
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
diff --git a/board/cmc_pu2/cmc_pu2.c b/board/cmc_pu2/cmc_pu2.c
index 3ad756d..0ac851c 100644
--- a/board/cmc_pu2/cmc_pu2.c
+++ b/board/cmc_pu2/cmc_pu2.c
@@ -30,8 +30,12 @@
 #include <common.h>
 #include <asm/mach-types.h>
 #include <asm/arch/AT91RM9200.h>
+#include <asm/io.h>
+#include <netdev.h>
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <dm9161.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -177,3 +181,12 @@
 
 #endif
 #endif	/* CONFIG_DRIVER_ETHER */
+
+#ifdef CONFIG_DRIVER_AT91EMAC
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
diff --git a/board/csb637/csb637.c b/board/csb637/csb637.c
index fbc3c87..d7fdcc4 100644
--- a/board/csb637/csb637.c
+++ b/board/csb637/csb637.c
@@ -23,8 +23,12 @@
 
 #include <common.h>
 #include <asm/arch/AT91RM9200.h>
+#include <netdev.h>
+#include <asm/io.h>
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <bcm5221.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -79,3 +83,12 @@
 
 #endif
 #endif	/* CONFIG_DRIVER_ETHER */
+
+#ifdef CONFIG_DRIVER_AT91EMAC
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
diff --git a/board/eukrea/cpuat91/cpuat91.c b/board/eukrea/cpuat91/cpuat91.c
index 1a700b6..0017962 100644
--- a/board/eukrea/cpuat91/cpuat91.c
+++ b/board/eukrea/cpuat91/cpuat91.c
@@ -26,9 +26,14 @@
  */
 
 #include <common.h>
+#include <netdev.h>
 #include <asm/arch/AT91RM9200.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <ks8721.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -79,3 +84,12 @@
 
 #endif	/* CONFIG_CMD_NET */
 #endif	/* CONFIG_DRIVER_ETHER */
+#ifdef CONFIG_DRIVER_AT91EMAC
+
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
diff --git a/board/freescale/mpc8360emds/mpc8360emds.c b/board/freescale/mpc8360emds/mpc8360emds.c
index d4ba043..4f55732 100644
--- a/board/freescale/mpc8360emds/mpc8360emds.c
+++ b/board/freescale/mpc8360emds/mpc8360emds.c
@@ -159,7 +159,8 @@
 		int i;
 
 		for (i = 0; i < ARRAY_SIZE(uec_info); i++)
-			uec_info[i].enet_interface = ENET_1000_RGMII_RXID;
+			uec_info[i].enet_interface_type = RGMII_RXID;
+			uec_info[i].speed = 1000;
 	}
 	return uec_eth_init(bd, uec_info, ARRAY_SIZE(uec_info));
 }
diff --git a/board/kb9202/kb9202.c b/board/kb9202/kb9202.c
index 59ed8ff..3164cc5 100644
--- a/board/kb9202/kb9202.c
+++ b/board/kb9202/kb9202.c
@@ -28,8 +28,12 @@
 
 #include <common.h>
 #include <asm/arch/AT91RM9200.h>
+#include <asm/io.h>
+#include <netdev.h>
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <lxt971a.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -92,3 +96,12 @@
 
 #endif
 #endif	/* CONFIG_DRIVER_ETHER */
+
+#ifdef CONFIG_DRIVER_AT91EMAC
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
diff --git a/board/m501sk/m501sk.c b/board/m501sk/m501sk.c
index 1e6a605..c995768 100644
--- a/board/m501sk/m501sk.c
+++ b/board/m501sk/m501sk.c
@@ -24,8 +24,13 @@
  */
 
 #include <common.h>
+#include <asm/io.h>
+#include <netdev.h>
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <dm9161.h>
+#endif
+
 #include "m501sk.h"
 #include "net.h"
 
@@ -186,4 +191,13 @@
 }
 #endif /* CONFIG_CMD_NET */
 #endif /* CONFIG_DRIVER_ETHER */
+
+#ifdef CONFIG_DRIVER_AT91EMAC
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
 #endif /* CONFIG_M501SK */
diff --git a/board/mp2usb/mp2usb.c b/board/mp2usb/mp2usb.c
index dcda699..e5eba6b 100644
--- a/board/mp2usb/mp2usb.c
+++ b/board/mp2usb/mp2usb.c
@@ -27,8 +27,12 @@
 
 #include <common.h>
 #include <asm/arch/AT91RM9200.h>
+#include <netdev.h>
+#include <asm/io.h>
+#if defined(CONFIG_DRIVER_ETHER)
 #include <at91rm9200_net.h>
 #include <dm9161.h>
+#endif
 #include <asm/mach-types.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -83,3 +87,12 @@
 
 #endif
 #endif	/* CONFIG_DRIVER_ETHER */
+
+#ifdef CONFIG_DRIVER_AT91EMAC
+int board_eth_init(bd_t *bis)
+{
+	int rc = 0;
+	rc = at91emac_register(bis, 0);
+	return rc;
+}
+#endif
diff --git a/cpu/arm920t/at91rm9200/bcm5221.c b/cpu/arm920t/at91rm9200/bcm5221.c
index b52c615..8de3cba 100644
--- a/cpu/arm920t/at91rm9200/bcm5221.c
+++ b/cpu/arm920t/at91rm9200/bcm5221.c
@@ -28,10 +28,10 @@
 
 #include <at91rm9200_net.h>
 #include <net.h>
-#include <bcm5221.h>
-
 #ifdef CONFIG_DRIVER_ETHER
 
+#include <bcm5221.h>
+
 #if defined(CONFIG_CMD_NET)
 
 /*
diff --git a/cpu/arm920t/at91rm9200/dm9161.c b/cpu/arm920t/at91rm9200/dm9161.c
index 1beb6e8..6d4384f 100644
--- a/cpu/arm920t/at91rm9200/dm9161.c
+++ b/cpu/arm920t/at91rm9200/dm9161.c
@@ -23,9 +23,8 @@
 
 #include <at91rm9200_net.h>
 #include <net.h>
-#include <dm9161.h>
-
 #ifdef CONFIG_DRIVER_ETHER
+#include <dm9161.h>
 
 #if defined(CONFIG_CMD_NET)
 
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 904727e..1ec0ba1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -27,6 +27,7 @@
 
 COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
 COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
+COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
 COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
 COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
 COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o
@@ -37,6 +38,7 @@
 COBJS-$(CONFIG_E1000) += e1000.o
 COBJS-$(CONFIG_EEPRO100) += eepro100.o
 COBJS-$(CONFIG_ENC28J60) += enc28j60.o
+COBJS-$(CONFIG_EP93XX) += ep93xx_eth.o
 COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o
 COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
 COBJS-$(CONFIG_FTMAC100) += ftmac100.o
diff --git a/drivers/net/at91_emac.c b/drivers/net/at91_emac.c
new file mode 100644
index 0000000..2399569
--- /dev/null
+++ b/drivers/net/at91_emac.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2009 BuS Elektronik GmbH & Co. KG
+ * Jens Scharsig (esw@bus-elektronik.de)
+ *
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#ifndef CONFIG_AT91_LEGACY
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_emac.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_pio.h>
+#else
+/* remove next 5 lines, if all RM9200 boards convert to at91 arch */
+#include <asm/arch-at91/at91rm9200.h>
+#include <asm/arch-at91/hardware.h>
+#include <asm/arch-at91/at91_emac.h>
+#include <asm/arch-at91/at91_pmc.h>
+#include <asm/arch-at91/at91_pio.h>
+#endif
+#include <net.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <linux/mii.h>
+
+#undef MII_DEBUG
+#undef ET_DEBUG
+
+#if (CONFIG_SYS_RX_ETH_BUFFER > 1024)
+#error AT91 EMAC supports max 1024 RX buffers. \
+	Please decrease the CONFIG_SYS_RX_ETH_BUFFER value
+#endif
+
+/* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
+#if (AT91C_MASTER_CLOCK > 80000000)
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_64
+#elif (AT91C_MASTER_CLOCK > 40000000)
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_32
+#elif (AT91C_MASTER_CLOCK > 20000000)
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_16
+#else
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_8
+#endif
+
+#ifdef ET_DEBUG
+#define DEBUG_AT91EMAC(...)	printf(__VA_ARGS__);
+#else
+#define DEBUG_AT91EMAC(...)
+#endif
+
+#ifdef MII_DEBUG
+#define DEBUG_AT91PHY(...)	printf(__VA_ARGS__);
+#else
+#define DEBUG_AT91PHY(...)
+#endif
+
+#ifndef CONFIG_DRIVER_AT91EMAC_QUIET
+#define VERBOSEP(...)	printf(__VA_ARGS__);
+#else
+#define VERBOSEP(...)
+#endif
+
+#define RBF_ADDR      0xfffffffc
+#define RBF_OWNER     (1<<0)
+#define RBF_WRAP      (1<<1)
+#define RBF_BROADCAST (1<<31)
+#define RBF_MULTICAST (1<<30)
+#define RBF_UNICAST   (1<<29)
+#define RBF_EXTERNAL  (1<<28)
+#define RBF_UNKOWN    (1<<27)
+#define RBF_SIZE      0x07ff
+#define RBF_LOCAL4    (1<<26)
+#define RBF_LOCAL3    (1<<25)
+#define RBF_LOCAL2    (1<<24)
+#define RBF_LOCAL1    (1<<23)
+
+#define RBF_FRAMEMAX CONFIG_SYS_RX_ETH_BUFFER
+#define RBF_FRAMELEN 0x600
+
+typedef struct {
+	unsigned long addr, size;
+} rbf_t;
+
+typedef struct {
+	rbf_t 		rbfdt[RBF_FRAMEMAX];
+	unsigned long	rbindex;
+} emac_device;
+
+void at91emac_EnableMDIO(at91_emac_t *at91mac)
+{
+	/* Mac CTRL reg set for MDIO enable */
+	writel(readl(&at91mac->ctl) | AT91_EMAC_CTL_MPE, &at91mac->ctl);
+}
+
+void at91emac_DisableMDIO(at91_emac_t *at91mac)
+{
+	/* Mac CTRL reg set for MDIO disable */
+	writel(readl(&at91mac->ctl) & ~AT91_EMAC_CTL_MPE, &at91mac->ctl);
+}
+
+int  at91emac_read(at91_emac_t *at91mac, unsigned char addr,
+		unsigned char reg, unsigned short *value)
+{
+	at91emac_EnableMDIO(at91mac);
+
+	writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_R |
+		AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
+		AT91_EMAC_MAN_PHYA(addr),
+		&at91mac->man);
+	udelay(10000);
+	*value = readl(&at91mac->man) & AT91_EMAC_MAN_DATA_MASK;
+
+	at91emac_DisableMDIO(at91mac);
+
+	DEBUG_AT91PHY("AT91PHY read %x REG(%d)=%x\n", at91mac, reg, *value)
+
+	return 0;
+}
+
+int  at91emac_write(at91_emac_t *at91mac, unsigned char addr,
+		unsigned char reg, unsigned short value)
+{
+	DEBUG_AT91PHY("AT91PHY write %x REG(%d)=%x\n", at91mac, reg, &value)
+
+	at91emac_EnableMDIO(at91mac);
+
+	writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_W |
+		AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
+		AT91_EMAC_MAN_PHYA(addr) | (value & AT91_EMAC_MAN_DATA_MASK),
+		&at91mac->man);
+	udelay(10000);
+
+	at91emac_DisableMDIO(at91mac);
+	return 0;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+
+at91_emac_t *get_emacbase_by_name(char *devname)
+{
+	struct eth_device *netdev;
+
+	netdev = eth_get_dev_by_name(devname);
+	return (at91_emac_t *) netdev->iobase;
+}
+
+int  at91emac_mii_read(char *devname, unsigned char addr,
+		unsigned char reg, unsigned short *value)
+{
+	at91_emac_t *emac;
+
+	emac = get_emacbase_by_name(devname);
+	at91emac_read(emac , addr, reg, value);
+	return 0;
+}
+
+
+int  at91emac_mii_write(char *devname, unsigned char addr,
+		unsigned char reg, unsigned short value)
+{
+	at91_emac_t *emac;
+
+	emac = get_emacbase_by_name(devname);
+	at91emac_write(emac, addr, reg, value);
+	return 0;
+}
+
+#endif
+
+static int at91emac_phy_reset(struct eth_device *netdev)
+{
+	int i;
+	u16 status, adv;
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+
+	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+	at91emac_write(emac, 0, MII_ADVERTISE, adv);
+	VERBOSEP("%s: Starting autonegotiation...\n", netdev->name);
+	at91emac_write(emac, 0, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
+
+	for (i = 0; i < 100000 / 100; i++) {
+		at91emac_read(emac, 0, MII_BMSR, &status);
+		if (status & BMSR_ANEGCOMPLETE)
+			break;
+		udelay(100);
+	}
+
+	if (status & BMSR_ANEGCOMPLETE) {
+		VERBOSEP("%s: Autonegotiation complete\n", netdev->name);
+	} else {
+		printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+		       netdev->name, status);
+		return 1;
+	}
+	return 0;
+}
+
+static int at91emac_phy_init(struct eth_device *netdev)
+{
+	u16 phy_id, status, adv, lpa;
+	int media, speed, duplex;
+	int i;
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+
+	/* Check if the PHY is up to snuff... */
+	at91emac_read(emac, 0, MII_PHYSID1, &phy_id);
+	if (phy_id == 0xffff) {
+		printf("%s: No PHY present\n", netdev->name);
+		return 1;
+	}
+
+	at91emac_read(emac, 0, MII_BMSR, &status);
+
+	if (!(status & BMSR_LSTATUS)) {
+		/* Try to re-negotiate if we don't have link already. */
+		if (at91emac_phy_reset(netdev))
+			return 2;
+
+		for (i = 0; i < 100000 / 100; i++) {
+			at91emac_read(emac, 0, MII_BMSR, &status);
+			if (status & BMSR_LSTATUS)
+				break;
+			udelay(100);
+		}
+	}
+	if (!(status & BMSR_LSTATUS)) {
+		VERBOSEP("%s: link down\n", netdev->name);
+		return 3;
+	} else {
+		at91emac_read(emac, 0, MII_ADVERTISE, &adv);
+		at91emac_read(emac, 0, MII_LPA, &lpa);
+		media = mii_nway_result(lpa & adv);
+		speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+			 ? 1 : 0);
+		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+		VERBOSEP("%s: link up, %sMbps %s-duplex\n",
+		       netdev->name,
+		       speed ? "100" : "10",
+		       duplex ? "full" : "half");
+	}
+	return 0;
+}
+
+int at91emac_UpdateLinkSpeed(at91_emac_t *emac)
+{
+	unsigned short stat1;
+
+	at91emac_read(emac, 0, MII_BMSR, &stat1);
+
+	if (!(stat1 & BMSR_LSTATUS))	/* link status up? */
+		return 1;
+
+	if (stat1 & BMSR_100FULL) {
+		/*set Emac for 100BaseTX and Full Duplex  */
+		writel(readl(&emac->cfg) |
+			AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD,
+			&emac->cfg);
+		return 0;
+	}
+
+	if (stat1 & BMSR_10FULL) {
+		/*set MII for 10BaseT and Full Duplex  */
+		writel((readl(&emac->cfg) &
+			~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
+			) | AT91_EMAC_CFG_FD,
+			&emac->cfg);
+		return 0;
+	}
+
+	if (stat1 & BMSR_100HALF) {
+		/*set MII for 100BaseTX and Half Duplex  */
+		writel((readl(&emac->cfg) &
+			~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
+			) | AT91_EMAC_CFG_SPD,
+			&emac->cfg);
+		return 0;
+	}
+
+	if (stat1 & BMSR_10HALF) {
+		/*set MII for 10BaseT and Half Duplex  */
+		writel((readl(&emac->cfg) &
+			~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)),
+			&emac->cfg);
+		return 0;
+	}
+	return 1;
+}
+
+static int at91emac_init(struct eth_device *netdev, bd_t *bd)
+{
+	int i;
+	u32 value;
+	emac_device *dev;
+	at91_emac_t *emac;
+	at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
+	at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
+
+	emac = (at91_emac_t *) netdev->iobase;
+	dev = (emac_device *) netdev->priv;
+
+	/* PIO Disable Register */
+	value =	AT91_PMX_AA_EMDIO |	AT91_PMX_AA_EMDC |
+		AT91_PMX_AA_ERXER |	AT91_PMX_AA_ERX1 |
+		AT91_PMX_AA_ERX0 |	AT91_PMX_AA_ECRS |
+		AT91_PMX_AA_ETX1 |	AT91_PMX_AA_ETX0 |
+		AT91_PMX_AA_ETXEN |	AT91_PMX_AA_EREFCK;
+
+	writel(value, &pio->pioa.pdr);
+	writel(value, &pio->pioa.asr);
+
+#ifdef CONFIG_RMII
+	value = AT91_PMX_BA_ERXCK;
+#else
+	value = AT91_PMX_BA_ERXCK |	AT91_PMX_BA_ECOL |
+		AT91_PMX_BA_ERXDV |	AT91_PMX_BA_ERX3 |
+		AT91_PMX_BA_ERX2 |	AT91_PMX_BA_ETXER |
+		AT91_PMX_BA_ETX3 |	AT91_PMX_BA_ETX2;
+#endif
+	writel(value, &pio->piob.pdr);
+	writel(value, &pio->piob.bsr);
+
+	writel(1 << AT91_ID_EMAC, &pmc->pcer);
+	writel(readl(&emac->ctl) | AT91_EMAC_CTL_CSR, &emac->ctl);
+
+	DEBUG_AT91EMAC("init MAC-ADDR %x%x \n",
+		cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))),
+		cpu_to_le32(*((u32 *)netdev->enetaddr)));
+	writel(cpu_to_le32(*((u32 *)netdev->enetaddr)), &emac->sa2l);
+	writel(cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), &emac->sa2h);
+	DEBUG_AT91EMAC("init MAC-ADDR %x%x \n",
+		readl(&emac->sa2h), readl(&emac->sa2l));
+
+	/* Init Ethernet buffers */
+	for (i = 0; i < RBF_FRAMEMAX; i++) {
+		dev->rbfdt[i].addr = (unsigned long) NetRxPackets[i];
+		dev->rbfdt[i].size = 0;
+	}
+	dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
+	dev->rbindex = 0;
+	writel((u32) &(dev->rbfdt[0]), &emac->rbqp);
+
+	writel(readl(&emac->rsr) &
+		~(AT91_EMAC_RSR_OVR | AT91_EMAC_RSR_REC | AT91_EMAC_RSR_BNA),
+		&emac->rsr);
+
+	value = AT91_EMAC_CFG_CAF |	AT91_EMAC_CFG_NBC |
+		HCLK_DIV;
+#ifdef CONFIG_RMII
+	value |= AT91C_EMAC_RMII;
+#endif
+	writel(value, &emac->cfg);
+
+	writel(readl(&emac->ctl) | AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE,
+		&emac->ctl);
+
+	if (!at91emac_phy_init(netdev)) {
+		at91emac_UpdateLinkSpeed(emac);
+		return 0;
+	}
+	return 1;
+}
+
+static void at91emac_halt(struct eth_device *netdev)
+{
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+	writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE),
+		&emac->ctl);
+	DEBUG_AT91EMAC("halt MAC\n");
+}
+
+static int at91emac_send(struct eth_device *netdev, volatile void *packet,
+		     int length)
+{
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+
+	while (!(readl(&emac->tsr) & AT91_EMAC_TSR_BNQ))
+		;
+	writel((u32) packet, &emac->tar);
+	writel(AT91_EMAC_TCR_LEN(length), &emac->tcr);
+	while (AT91_EMAC_TCR_LEN(readl(&emac->tcr)))
+		;
+	DEBUG_AT91EMAC("Send %d \n", length);
+	writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr);
+	return 0;
+}
+
+static int at91emac_recv(struct eth_device *netdev)
+{
+	emac_device *dev;
+	at91_emac_t *emac;
+	rbf_t *rbfp;
+	int size;
+
+	emac = (at91_emac_t *) netdev->iobase;
+	dev = (emac_device *) netdev->priv;
+
+	rbfp = &dev->rbfdt[dev->rbindex];
+	while (rbfp->addr & RBF_OWNER)	{
+		size = rbfp->size & RBF_SIZE;
+		NetReceive(NetRxPackets[dev->rbindex], size);
+
+		DEBUG_AT91EMAC("Recv[%d]: %d bytes @ %x \n",
+			dev->rbindex, size, rbfp->addr);
+
+		rbfp->addr &= ~RBF_OWNER;
+		rbfp->size = 0;
+		if (dev->rbindex < (RBF_FRAMEMAX-1))
+			dev->rbindex++;
+		else
+			dev->rbindex = 0;
+
+		rbfp = &(dev->rbfdt[dev->rbindex]);
+		if (!(rbfp->addr & RBF_OWNER))
+			writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC,
+				&emac->rsr);
+	}
+
+	if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) {
+		/* EMAC silicon bug 41.3.1 workaround 1 */
+		writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl);
+		writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl);
+		dev->rbindex = 0;
+		printf("%s: reset receiver (EMAC dead lock bug)\n",
+			netdev->name);
+	}
+	return 0;
+}
+
+int at91emac_register(bd_t *bis, unsigned long iobase)
+{
+	emac_device *emac;
+	emac_device *emacfix;
+	struct eth_device *dev;
+
+	if (iobase == 0)
+		iobase = AT91_EMAC_BASE;
+	emac = malloc(sizeof(*emac)+512);
+	if (emac == NULL)
+		return 1;
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		free(emac);
+		return 1;
+	}
+	/* alignment as per Errata (64 bytes) is insufficient! */
+	emacfix = (emac_device *) (((unsigned long) emac + 0x1ff) & 0xFFFFFE00);
+	memset(emacfix, 0, sizeof(emac_device));
+
+	memset(dev, 0, sizeof(*dev));
+#ifndef CONFIG_RMII
+	sprintf(dev->name, "AT91 EMAC");
+#else
+	sprintf(dev->name, "AT91 EMAC RMII");
+#endif
+	dev->iobase = iobase;
+	dev->priv = emacfix;
+	dev->init = at91emac_init;
+	dev->halt = at91emac_halt;
+	dev->send = at91emac_send;
+	dev->recv = at91emac_recv;
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, at91emac_mii_read, at91emac_mii_write);
+#endif
+	return 1;
+}
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
index df36004..9424fb2 100644
--- a/drivers/net/cs8900.c
+++ b/drivers/net/cs8900.c
@@ -308,14 +308,13 @@
 
 	dev = malloc(sizeof(*dev));
 	if (!dev) {
-		free(dev);
 		return 0;
 	}
 	memset(dev, 0, sizeof(*dev));
 
 	priv = malloc(sizeof(*priv));
 	if (!priv) {
-		free(priv);
+		free(dev);
 		return 0;
 	}
 	memset(priv, 0, sizeof(*priv));
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index fa8cee4..02bbb8c 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -42,10 +42,17 @@
 #include <miiphy.h>
 #include <malloc.h>
 #include <asm/arch/emac_defs.h>
+#include <asm/io.h>
 
 unsigned int	emac_dbg = 0;
 #define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)
 
+#ifdef DAVINCI_EMAC_GIG_ENABLE
+#define emac_gigabit_enable()	davinci_eth_gigabit_enable()
+#else
+#define emac_gigabit_enable()	/* no gigabit to enable */
+#endif
+
 static void davinci_eth_mdio_enable(void);
 
 static int gen_init_phy(int phy_addr);
@@ -99,12 +106,14 @@
 
 	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
 
-	adap_mdio->CONTROL = (clkdiv & 0xff) |
-		MDIO_CONTROL_ENABLE |
-		MDIO_CONTROL_FAULT |
-		MDIO_CONTROL_FAULT_ENABLE;
+	writel((clkdiv & 0xff) |
+	       MDIO_CONTROL_ENABLE |
+	       MDIO_CONTROL_FAULT |
+	       MDIO_CONTROL_FAULT_ENABLE,
+	       &adap_mdio->CONTROL);
 
-	while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
+	while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
+		;
 }
 
 /*
@@ -119,7 +128,8 @@
 
 	active_phy_addr = 0xff;
 
-	if ((phy_act_state = adap_mdio->ALIVE) == 0)
+	phy_act_state = readl(&adap_mdio->ALIVE) & EMAC_MDIO_PHY_MASK;
+	if (phy_act_state == 0)
 		return(0);				/* No active PHYs */
 
 	debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
@@ -144,15 +154,18 @@
 {
 	int	tmp;
 
-	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
 
-	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
-				MDIO_USERACCESS0_WRITE_READ |
-				((reg_num & 0x1f) << 21) |
-				((phy_addr & 0x1f) << 16);
+	writel(MDIO_USERACCESS0_GO |
+	       MDIO_USERACCESS0_WRITE_READ |
+	       ((reg_num & 0x1f) << 21) |
+	       ((phy_addr & 0x1f) << 16),
+	       &adap_mdio->USERACCESS0);
 
 	/* Wait for command to complete */
-	while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
+	while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
+		;
 
 	if (tmp & MDIO_USERACCESS0_ACK) {
 		*data = tmp & 0xffff;
@@ -167,16 +180,19 @@
 int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
 {
 
-	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
 
-	adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
-				MDIO_USERACCESS0_WRITE_WRITE |
-				((reg_num & 0x1f) << 21) |
-				((phy_addr & 0x1f) << 16) |
-				(data & 0xffff);
+	writel(MDIO_USERACCESS0_GO |
+	       MDIO_USERACCESS0_WRITE_WRITE |
+	       ((reg_num & 0x1f) << 21) |
+	       ((phy_addr & 0x1f) << 16) |
+	       (data & 0xffff),
+	       &adap_mdio->USERACCESS0);
 
 	/* Wait for command to complete */
-	while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
 
 	return(1);
 }
@@ -245,9 +261,24 @@
 {
 	return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1);
 }
-
 #endif
 
+static void  __attribute__((unused)) davinci_eth_gigabit_enable(void)
+{
+	u_int16_t data;
+
+	if (davinci_eth_phy_read(EMAC_MDIO_PHY_NUM, 0, &data)) {
+		if (data & (1 << 6)) { /* speed selection MSB */
+			/*
+			 * Check if link detected is giga-bit
+			 * If Gigabit mode detected, enable gigbit in MAC
+			 */
+			writel(EMAC_MACCONTROL_GIGFORCE |
+			       EMAC_MACCONTROL_GIGABIT_ENABLE,
+			       &adap_emac->MACCONTROL);
+		}
+	}
+}
 
 /* Eth device open */
 static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
@@ -255,64 +286,73 @@
 	dv_reg_p		addr;
 	u_int32_t		clkdiv, cnt;
 	volatile emac_desc	*rx_desc;
+	unsigned long		mac_hi;
+	unsigned long		mac_lo;
 
 	debug_emac("+ emac_open\n");
 
 	/* Reset EMAC module and disable interrupts in wrapper */
-	adap_emac->SOFTRESET = 1;
-	while (adap_emac->SOFTRESET != 0) {;}
-	adap_ewrap->EWCTL = 0;
+	writel(1, &adap_emac->SOFTRESET);
+	while (readl(&adap_emac->SOFTRESET) != 0)
+		;
+#if defined(DAVINCI_EMAC_VERSION2)
+	writel(1, &adap_ewrap->softrst);
+	while (readl(&adap_ewrap->softrst) != 0)
+		;
+#else
+	writel(0, &adap_ewrap->EWCTL);
 	for (cnt = 0; cnt < 5; cnt++) {
-		clkdiv = adap_ewrap->EWCTL;
+		clkdiv = readl(&adap_ewrap->EWCTL);
 	}
+#endif
 
 	rx_desc = emac_rx_desc;
 
-	adap_emac->TXCONTROL = 0x01;
-	adap_emac->RXCONTROL = 0x01;
+	writel(1, &adap_emac->TXCONTROL);
+	writel(1, &adap_emac->RXCONTROL);
 
 	/* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
 	/* Using channel 0 only - other channels are disabled */
-	adap_emac->MACINDEX = 0;
-	adap_emac->MACADDRHI =
-		(davinci_eth_mac_addr[3] << 24) |
-		(davinci_eth_mac_addr[2] << 16) |
-		(davinci_eth_mac_addr[1] << 8)  |
-		(davinci_eth_mac_addr[0]);
-	adap_emac->MACADDRLO =
-		(davinci_eth_mac_addr[5] << 8) |
-		(davinci_eth_mac_addr[4]);
+	writel(0, &adap_emac->MACINDEX);
+	mac_hi = (davinci_eth_mac_addr[3] << 24) |
+		 (davinci_eth_mac_addr[2] << 16) |
+		 (davinci_eth_mac_addr[1] << 8)  |
+		 (davinci_eth_mac_addr[0]);
+	mac_lo = (davinci_eth_mac_addr[5] << 8) |
+		 (davinci_eth_mac_addr[4]);
 
-	adap_emac->MACHASH1 = 0;
-	adap_emac->MACHASH2 = 0;
+	writel(mac_hi, &adap_emac->MACADDRHI);
+#if defined(DAVINCI_EMAC_VERSION2)
+	writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH,
+	       &adap_emac->MACADDRLO);
+#else
+	writel(mac_lo, &adap_emac->MACADDRLO);
+#endif
+
+	writel(0, &adap_emac->MACHASH1);
+	writel(0, &adap_emac->MACHASH2);
 
 	/* Set source MAC address - REQUIRED */
-	adap_emac->MACSRCADDRHI =
-		(davinci_eth_mac_addr[3] << 24) |
-		(davinci_eth_mac_addr[2] << 16) |
-		(davinci_eth_mac_addr[1] << 8)  |
-		(davinci_eth_mac_addr[0]);
-	adap_emac->MACSRCADDRLO =
-		(davinci_eth_mac_addr[4] << 8) |
-		(davinci_eth_mac_addr[5]);
+	writel(mac_hi, &adap_emac->MACSRCADDRHI);
+	writel(mac_lo, &adap_emac->MACSRCADDRLO);
 
 	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
 	addr = &adap_emac->TX0HDP;
 	for(cnt = 0; cnt < 16; cnt++)
-		*addr++ = 0;
+		writel(0, addr++);
 
 	addr = &adap_emac->RX0HDP;
 	for(cnt = 0; cnt < 16; cnt++)
-		*addr++ = 0;
+		writel(0, addr++);
 
 	/* Clear Statistics (do this before setting MacControl register) */
 	addr = &adap_emac->RXGOODFRAMES;
 	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
-		*addr++ = 0;
+		writel(0, addr++);
 
 	/* No multicast addressing */
-	adap_emac->MACHASH1 = 0;
-	adap_emac->MACHASH2 = 0;
+	writel(0, &adap_emac->MACHASH1);
+	writel(0, &adap_emac->MACHASH2);
 
 	/* Create RX queue and set receive process in place */
 	emac_rx_active_head = emac_rx_desc;
@@ -324,34 +364,52 @@
 		rx_desc++;
 	}
 
-	/* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
+	/* Finalize the rx desc list */
 	rx_desc--;
 	rx_desc->next = 0;
 	emac_rx_active_tail = rx_desc;
 	emac_rx_queue_active = 1;
 
 	/* Enable TX/RX */
-	adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
-	adap_emac->RXBUFFEROFFSET = 0;
+	writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN);
+	writel(0, &adap_emac->RXBUFFEROFFSET);
 
-	/* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
-	adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
+	/*
+	 * No fancy configs - Use this for promiscous debug
+	 *   - EMAC_RXMBPENABLE_RXCAFEN_ENABLE
+	 */
+	writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE);
 
 	/* Enable ch 0 only */
-	adap_emac->RXUNICASTSET = 0x01;
+	writel(1, &adap_emac->RXUNICASTSET);
 
 	/* Enable MII interface and Full duplex mode */
-	adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE);
+#ifdef CONFIG_SOC_DA8XX
+	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+		EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
+		EMAC_MACCONTROL_RMIISPEED_100),
+	       &adap_emac->MACCONTROL);
+#else
+	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+		EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
+	       &adap_emac->MACCONTROL);
+#endif
 
 	/* Init MDIO & get link state */
 	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
-	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
+	writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
+	       &adap_mdio->CONTROL);
+
+	/* We need to wait for MDIO to start */
+	udelay(1000);
 
 	if (!phy.get_link_speed(active_phy_addr))
 		return(0);
 
+	emac_gigabit_enable();
+
 	/* Start receive process */
-	adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
+	writel((u_int32_t)emac_rx_desc, &adap_emac->RX0HDP);
 
 	debug_emac("- emac_open\n");
 
@@ -368,34 +426,42 @@
 
 	if (ch == EMAC_CH_TX) {
 		/* Init TX channel teardown */
-		adap_emac->TXTEARDOWN = 1;
-		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
-			/* Wait here for Tx teardown completion interrupt to occur
-			 * Note: A task delay can be called here to pend rather than
-			 * occupying CPU cycles - anyway it has been found that teardown
-			 * takes very few cpu cycles and does not affect functionality */
-			 dly--;
-			 udelay(1);
-			 if (dly == 0)
+		writel(1, &adap_emac->TXTEARDOWN);
+		do {
+			/*
+			 * Wait here for Tx teardown completion interrupt to
+			 * occur. Note: A task delay can be called here to pend
+			 * rather than occupying CPU cycles - anyway it has
+			 * been found that teardown takes very few cpu cycles
+			 * and does not affect functionality
+			 */
+			dly--;
+			udelay(1);
+			if (dly == 0)
 				break;
-		}
-		adap_emac->TX0CP = cnt;
-		adap_emac->TX0HDP = 0;
+			cnt = readl(&adap_emac->TX0CP);
+		} while (cnt != 0xfffffffc);
+		writel(cnt, &adap_emac->TX0CP);
+		writel(0, &adap_emac->TX0HDP);
 	} else {
 		/* Init RX channel teardown */
-		adap_emac->RXTEARDOWN = 1;
-		for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
-			/* Wait here for Rx teardown completion interrupt to occur
-			 * Note: A task delay can be called here to pend rather than
-			 * occupying CPU cycles - anyway it has been found that teardown
-			 * takes very few cpu cycles and does not affect functionality */
-			 dly--;
-			 udelay(1);
-			 if (dly == 0)
+		writel(1, &adap_emac->RXTEARDOWN);
+		do {
+			/*
+			 * Wait here for Rx teardown completion interrupt to
+			 * occur. Note: A task delay can be called here to pend
+			 * rather than occupying CPU cycles - anyway it has
+			 * been found that teardown takes very few cpu cycles
+			 * and does not affect functionality
+			 */
+			dly--;
+			udelay(1);
+			if (dly == 0)
 				break;
-		}
-		adap_emac->RX0CP = cnt;
-		adap_emac->RX0HDP = 0;
+			cnt = readl(&adap_emac->RX0CP);
+		} while (cnt != 0xfffffffc);
+		writel(cnt, &adap_emac->RX0CP);
+		writel(0, &adap_emac->RX0HDP);
 	}
 
 	debug_emac("- emac_ch_teardown\n");
@@ -410,8 +476,12 @@
 	davinci_eth_ch_teardown(EMAC_CH_RX);	/* RX Channel teardown */
 
 	/* Reset EMAC module and disable interrupts in wrapper */
-	adap_emac->SOFTRESET = 1;
-	adap_ewrap->EWCTL = 0;
+	writel(1, &adap_emac->SOFTRESET);
+#if defined(DAVINCI_EMAC_VERSION2)
+	writel(1, &adap_ewrap->softrst);
+#else
+	writel(0, &adap_ewrap->EWCTL);
+#endif
 
 	debug_emac("- emac_close\n");
 }
@@ -435,6 +505,8 @@
 		return (ret_status);
 	}
 
+	emac_gigabit_enable();
+
 	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
 	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
 		length = EMAC_MIN_ETHERNET_PKT_SIZE;
@@ -449,7 +521,7 @@
 				      EMAC_CPPI_OWNERSHIP_BIT |
 				      EMAC_CPPI_EOP_BIT);
 	/* Send the packet */
-	adap_emac->TX0HDP = (unsigned int) emac_tx_desc;
+	writel((unsigned long)emac_tx_desc, &adap_emac->TX0HDP);
 
 	/* Wait for packet to complete or link down */
 	while (1) {
@@ -457,7 +529,10 @@
 			davinci_eth_ch_teardown (EMAC_CH_TX);
 			return (ret_status);
 		}
-		if (adap_emac->TXINTSTATRAW & 0x01) {
+
+		emac_gigabit_enable();
+
+		if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
 			ret_status = length;
 			break;
 		}
@@ -490,15 +565,15 @@
 		}
 
 		/* Ack received packet descriptor */
-		adap_emac->RX0CP = (unsigned int) rx_curr_desc;
+		writel((unsigned long)rx_curr_desc, &adap_emac->RX0CP);
 		curr_desc = rx_curr_desc;
 		emac_rx_active_head =
 			(volatile emac_desc *) rx_curr_desc->next;
 
 		if (status & EMAC_CPPI_EOQ_BIT) {
 			if (emac_rx_active_head) {
-				adap_emac->RX0HDP =
-					(unsigned int) emac_rx_active_head;
+				writel((unsigned long)emac_rx_active_head,
+				       &adap_emac->RX0HDP);
 			} else {
 				emac_rx_queue_active = 0;
 				printf ("INFO:emac_rcv_packet: RX Queue not active\n");
@@ -515,8 +590,8 @@
 			emac_rx_active_head = curr_desc;
 			emac_rx_active_tail = curr_desc;
 			if (emac_rx_queue_active != 0) {
-				adap_emac->RX0HDP =
-					(unsigned int) emac_rx_active_head;
+				writel((unsigned long)emac_rx_active_head,
+				       &adap_emac->RX0HDP);
 				printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
 				emac_rx_queue_active = 1;
 			}
@@ -526,7 +601,8 @@
 			tail_desc->next = (unsigned int) curr_desc;
 			status = tail_desc->pkt_flag_len;
 			if (status & EMAC_CPPI_EOQ_BIT) {
-				adap_emac->RX0HDP = (unsigned int) curr_desc;
+				writel((unsigned long)curr_desc,
+				       &adap_emac->RX0HDP);
 				status &= ~EMAC_CPPI_EOQ_BIT;
 				tail_desc->pkt_flag_len = status;
 			}
@@ -566,7 +642,7 @@
 	davinci_eth_mdio_enable();
 
 	for (i = 0; i < 256; i++) {
-		if (adap_mdio->ALIVE)
+		if (readl(&adap_mdio->ALIVE))
 			break;
 		udelay(10);
 	}
diff --git a/drivers/net/ep93xx_eth.c b/drivers/net/ep93xx_eth.c
new file mode 100644
index 0000000..4e39948
--- /dev/null
+++ b/drivers/net/ep93xx_eth.c
@@ -0,0 +1,653 @@
+/*
+ * Cirrus Logic EP93xx ethernet MAC / MII driver.
+ *
+ * Copyright (C) 2010, 2009
+ * Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * Copyright (C) 2004, 2005
+ * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
+ *
+ * Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver,
+ * which is
+ *
+ * (C) Copyright 2002 2003
+ * Adam Bezanson, Network Audio Technologies, Inc.
+ * <bezanson@netaudiotech.com>
+ *
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <command.h>
+#include <common.h>
+#include <asm/arch/ep93xx.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <linux/types.h>
+#include "ep93xx_eth.h"
+
+#define GET_PRIV(eth_dev)	((struct ep93xx_priv *)(eth_dev)->priv)
+#define GET_REGS(eth_dev)	(GET_PRIV(eth_dev)->regs)
+
+/* ep93xx_miiphy ops forward declarations */
+static int ep93xx_miiphy_read(char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short * const value);
+static int ep93xx_miiphy_write(char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short const value);
+
+#if defined(EP93XX_MAC_DEBUG)
+/**
+ * Dump ep93xx_mac values to the terminal.
+ */
+static void dump_dev(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_dev()\n");
+	printf("  rx_dq.base	     %p\n", priv->rx_dq.base);
+	printf("  rx_dq.current	     %p\n", priv->rx_dq.current);
+	printf("  rx_dq.end	     %p\n", priv->rx_dq.end);
+	printf("  rx_sq.base	     %p\n", priv->rx_sq.base);
+	printf("  rx_sq.current	     %p\n", priv->rx_sq.current);
+	printf("  rx_sq.end	     %p\n", priv->rx_sq.end);
+
+	for (i = 0; i < NUMRXDESC; i++)
+		printf("  rx_buffer[%2.d]      %p\n", i, NetRxPackets[i]);
+
+	printf("  tx_dq.base	     %p\n", priv->tx_dq.base);
+	printf("  tx_dq.current	     %p\n", priv->tx_dq.current);
+	printf("  tx_dq.end	     %p\n", priv->tx_dq.end);
+	printf("  tx_sq.base	     %p\n", priv->tx_sq.base);
+	printf("  tx_sq.current	     %p\n", priv->tx_sq.current);
+	printf("  tx_sq.end	     %p\n", priv->tx_sq.end);
+}
+
+/**
+ * Dump all RX status queue entries to the terminal.
+ */
+static void dump_rx_status_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_rx_status_queue()\n");
+	printf("  descriptor address	 word1		 word2\n");
+	for (i = 0; i < NUMRXDESC; i++) {
+		printf("  [ %p ]	     %08X	 %08X\n",
+			priv->rx_sq.base + i,
+			(priv->rx_sq.base + i)->word1,
+			(priv->rx_sq.base + i)->word2);
+	}
+}
+
+/**
+ * Dump all RX descriptor queue entries to the terminal.
+ */
+static void dump_rx_descriptor_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_rx_descriptor_queue()\n");
+	printf("  descriptor address	 word1		 word2\n");
+	for (i = 0; i < NUMRXDESC; i++) {
+		printf("  [ %p ]	     %08X	 %08X\n",
+			priv->rx_dq.base + i,
+			(priv->rx_dq.base + i)->word1,
+			(priv->rx_dq.base + i)->word2);
+	}
+}
+
+/**
+ * Dump all TX descriptor queue entries to the terminal.
+ */
+static void dump_tx_descriptor_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_tx_descriptor_queue()\n");
+	printf("  descriptor address	 word1		 word2\n");
+	for (i = 0; i < NUMTXDESC; i++) {
+		printf("  [ %p ]	     %08X	 %08X\n",
+			priv->tx_dq.base + i,
+			(priv->tx_dq.base + i)->word1,
+			(priv->tx_dq.base + i)->word2);
+	}
+}
+
+/**
+ * Dump all TX status queue entries to the terminal.
+ */
+static void dump_tx_status_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_tx_status_queue()\n");
+	printf("  descriptor address	 word1\n");
+	for (i = 0; i < NUMTXDESC; i++) {
+		printf("  [ %p ]	     %08X\n",
+			priv->rx_sq.base + i,
+			(priv->rx_sq.base + i)->word1);
+	}
+}
+#else
+#define dump_dev(x)
+#define dump_rx_descriptor_queue(x)
+#define dump_rx_status_queue(x)
+#define dump_tx_descriptor_queue(x)
+#define dump_tx_status_queue(x)
+#endif	/* defined(EP93XX_MAC_DEBUG) */
+
+/**
+ * Reset the EP93xx MAC by twiddling the soft reset bit and spinning until
+ * it's cleared.
+ */
+static void ep93xx_mac_reset(struct eth_device *dev)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+	uint32_t value;
+
+	debug("+ep93xx_mac_reset");
+
+	value = readl(&mac->selfctl);
+	value |= SELFCTL_RESET;
+	writel(value, &mac->selfctl);
+
+	while (readl(&mac->selfctl) & SELFCTL_RESET)
+		; /* noop */
+
+	debug("-ep93xx_mac_reset");
+}
+
+/* Eth device open */
+static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	struct mac_regs *mac = GET_REGS(dev);
+	uchar *mac_addr = dev->enetaddr;
+	int i;
+
+	debug("+ep93xx_eth_open");
+
+	/* Reset the MAC */
+	ep93xx_mac_reset(dev);
+
+	/* Reset the descriptor queues' current and end address values */
+	priv->tx_dq.current = priv->tx_dq.base;
+	priv->tx_dq.end = (priv->tx_dq.base + NUMTXDESC);
+
+	priv->tx_sq.current = priv->tx_sq.base;
+	priv->tx_sq.end = (priv->tx_sq.base + NUMTXDESC);
+
+	priv->rx_dq.current = priv->rx_dq.base;
+	priv->rx_dq.end = (priv->rx_dq.base + NUMRXDESC);
+
+	priv->rx_sq.current = priv->rx_sq.base;
+	priv->rx_sq.end = (priv->rx_sq.base + NUMRXDESC);
+
+	/*
+	 * Set the transmit descriptor and status queues' base address,
+	 * current address, and length registers.  Set the maximum frame
+	 * length and threshold. Enable the transmit descriptor processor.
+	 */
+	writel((uint32_t)priv->tx_dq.base, &mac->txdq.badd);
+	writel((uint32_t)priv->tx_dq.base, &mac->txdq.curadd);
+	writel(sizeof(struct tx_descriptor) * NUMTXDESC, &mac->txdq.blen);
+
+	writel((uint32_t)priv->tx_sq.base, &mac->txstsq.badd);
+	writel((uint32_t)priv->tx_sq.base, &mac->txstsq.curadd);
+	writel(sizeof(struct tx_status) * NUMTXDESC, &mac->txstsq.blen);
+
+	writel(0x00040000, &mac->txdthrshld);
+	writel(0x00040000, &mac->txststhrshld);
+
+	writel((TXSTARTMAX << 0) | (PKTSIZE_ALIGN << 16), &mac->maxfrmlen);
+	writel(BMCTL_TXEN, &mac->bmctl);
+
+	/*
+	 * Set the receive descriptor and status queues' base address,
+	 * current address, and length registers.  Enable the receive
+	 * descriptor processor.
+	 */
+	writel((uint32_t)priv->rx_dq.base, &mac->rxdq.badd);
+	writel((uint32_t)priv->rx_dq.base, &mac->rxdq.curadd);
+	writel(sizeof(struct rx_descriptor) * NUMRXDESC, &mac->rxdq.blen);
+
+	writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.badd);
+	writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.curadd);
+	writel(sizeof(struct rx_status) * NUMRXDESC, &mac->rxstsq.blen);
+
+	writel(0x00040000, &mac->rxdthrshld);
+
+	writel(BMCTL_RXEN, &mac->bmctl);
+
+	writel(0x00040000, &mac->rxststhrshld);
+
+	/* Wait until the receive descriptor processor is active */
+	while (!(readl(&mac->bmsts) & BMSTS_RXACT))
+		; /* noop */
+
+	/*
+	 * Initialize the RX descriptor queue. Clear the TX descriptor queue.
+	 * Clear the RX and TX status queues. Enqueue the RX descriptor and
+	 * status entries to the MAC.
+	 */
+	for (i = 0; i < NUMRXDESC; i++) {
+		/* set buffer address */
+		(priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i];
+
+		/* set buffer length, clear buffer index and NSOF */
+		(priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN;
+	}
+
+	memset(priv->tx_dq.base, 0,
+		(sizeof(struct tx_descriptor) * NUMTXDESC));
+	memset(priv->rx_sq.base, 0,
+		(sizeof(struct rx_status) * NUMRXDESC));
+	memset(priv->tx_sq.base, 0,
+		(sizeof(struct tx_status) * NUMTXDESC));
+
+	writel(NUMRXDESC, &mac->rxdqenq);
+	writel(NUMRXDESC, &mac->rxstsqenq);
+
+	/* Set the primary MAC address */
+	writel(AFP_IAPRIMARY, &mac->afp);
+	writel(mac_addr[0] | (mac_addr[1] << 8) |
+		(mac_addr[2] << 16) | (mac_addr[3] << 24),
+		&mac->indad);
+	writel(mac_addr[4] | (mac_addr[5] << 8), &mac->indad_upper);
+
+	/* Turn on RX and TX */
+	writel(RXCTL_IA0 | RXCTL_BA | RXCTL_SRXON |
+		RXCTL_RCRCA | RXCTL_MA, &mac->rxctl);
+	writel(TXCTL_STXON, &mac->txctl);
+
+	/* Dump data structures if we're debugging */
+	dump_dev(dev);
+	dump_rx_descriptor_queue(dev);
+	dump_rx_status_queue(dev);
+	dump_tx_descriptor_queue(dev);
+	dump_tx_status_queue(dev);
+
+	debug("-ep93xx_eth_open");
+
+	return 1;
+}
+
+/**
+ * Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL
+ * registers.
+ */
+static void ep93xx_eth_close(struct eth_device *dev)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+
+	debug("+ep93xx_eth_close");
+
+	writel(0x00000000, &mac->rxctl);
+	writel(0x00000000, &mac->txctl);
+
+	debug("-ep93xx_eth_close");
+}
+
+/**
+ * Copy a frame of data from the MAC into the protocol layer for further
+ * processing.
+ */
+static int ep93xx_eth_rcv_packet(struct eth_device *dev)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int len = -1;
+
+	debug("+ep93xx_eth_rcv_packet");
+
+	if (RX_STATUS_RFP(priv->rx_sq.current)) {
+		if (RX_STATUS_RWE(priv->rx_sq.current)) {
+			/*
+			 * We have a good frame. Extract the frame's length
+			 * from the current rx_status_queue entry, and copy
+			 * the frame's data into NetRxPackets[] of the
+			 * protocol stack. We track the total number of
+			 * bytes in the frame (nbytes_frame) which will be
+			 * used when we pass the data off to the protocol
+			 * layer via NetReceive().
+			 */
+			len = RX_STATUS_FRAME_LEN(priv->rx_sq.current);
+
+			NetReceive((uchar *)priv->rx_dq.current->word1,	len);
+
+			debug("reporting %d bytes...\n", len);
+		} else {
+			/* Do we have an erroneous packet? */
+			error("packet rx error, status %08X %08X",
+				priv->rx_sq.current->word1,
+				priv->rx_sq.current->word2);
+			dump_rx_descriptor_queue(dev);
+			dump_rx_status_queue(dev);
+		}
+
+		/*
+		 * Clear the associated status queue entry, and
+		 * increment our current pointers to the next RX
+		 * descriptor and status queue entries (making sure
+		 * we wrap properly).
+		 */
+		memset((void *)priv->rx_sq.current, 0,
+			sizeof(struct rx_status));
+
+		priv->rx_sq.current++;
+		if (priv->rx_sq.current >= priv->rx_sq.end)
+			priv->rx_sq.current = priv->rx_sq.base;
+
+		priv->rx_dq.current++;
+		if (priv->rx_dq.current >= priv->rx_dq.end)
+			priv->rx_dq.current = priv->rx_dq.base;
+
+		/*
+		 * Finally, return the RX descriptor and status entries
+		 * back to the MAC engine, and loop again, checking for
+		 * more descriptors to process.
+		 */
+		writel(1, &mac->rxdqenq);
+		writel(1, &mac->rxstsqenq);
+	} else {
+		len = 0;
+	}
+
+	debug("-ep93xx_eth_rcv_packet %d", len);
+	return len;
+}
+
+/**
+ * Send a block of data via ethernet.
+ */
+static int ep93xx_eth_send_packet(struct eth_device *dev,
+				volatile void * const packet, int const length)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int ret = -1;
+
+	debug("+ep93xx_eth_send_packet");
+
+	/* Parameter check */
+	BUG_ON(packet == NULL);
+
+	/*
+	 * Initialize the TX descriptor queue with the new packet's info.
+	 * Clear the associated status queue entry. Enqueue the packet
+	 * to the MAC for transmission.
+	 */
+
+	/* set buffer address */
+	priv->tx_dq.current->word1 = (uint32_t)packet;
+
+	/* set buffer length and EOF bit */
+	priv->tx_dq.current->word2 = length | TX_DESC_EOF;
+
+	/* clear tx status */
+	priv->tx_sq.current->word1 = 0;
+
+	/* enqueue the TX descriptor */
+	writel(1, &mac->txdqenq);
+
+	/* wait for the frame to become processed */
+	while (!TX_STATUS_TXFP(priv->tx_sq.current))
+		; /* noop */
+
+	if (!TX_STATUS_TXWE(priv->tx_sq.current)) {
+		error("packet tx error, status %08X",
+			priv->tx_sq.current->word1);
+		dump_tx_descriptor_queue(dev);
+		dump_tx_status_queue(dev);
+
+		/* TODO: Add better error handling? */
+		goto eth_send_out;
+	}
+
+	ret = 0;
+	/* Fall through */
+
+eth_send_out:
+	debug("-ep93xx_eth_send_packet %d", ret);
+	return ret;
+}
+
+#if defined(CONFIG_MII)
+int ep93xx_miiphy_initialize(bd_t * const bd)
+{
+	miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write);
+	return 0;
+}
+#endif
+
+/**
+ * Initialize the EP93xx MAC.  The MAC hardware is reset.  Buffers are
+ * allocated, if necessary, for the TX and RX descriptor and status queues,
+ * as well as for received packets.  The EP93XX MAC hardware is initialized.
+ * Transmit and receive operations are enabled.
+ */
+int ep93xx_eth_initialize(u8 dev_num, int base_addr)
+{
+	int ret = -1;
+	struct eth_device *dev;
+	struct ep93xx_priv *priv;
+
+	debug("+ep93xx_eth_initialize");
+
+	priv = malloc(sizeof(*priv));
+	if (!priv) {
+		error("malloc() failed");
+		goto eth_init_failed_0;
+	}
+	memset(priv, 0, sizeof(*priv));
+
+	priv->regs = (struct mac_regs *)base_addr;
+
+	priv->tx_dq.base = calloc(NUMTXDESC,
+				sizeof(struct tx_descriptor));
+	if (priv->tx_dq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_1;
+	}
+
+	priv->tx_sq.base = calloc(NUMTXDESC,
+				sizeof(struct tx_status));
+	if (priv->tx_sq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_2;
+	}
+
+	priv->rx_dq.base = calloc(NUMRXDESC,
+				sizeof(struct rx_descriptor));
+	if (priv->rx_dq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_3;
+	}
+
+	priv->rx_sq.base = calloc(NUMRXDESC,
+				sizeof(struct rx_status));
+	if (priv->rx_sq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_4;
+	}
+
+	dev = malloc(sizeof *dev);
+	if (dev == NULL) {
+		error("malloc() failed");
+		goto eth_init_failed_5;
+	}
+	memset(dev, 0, sizeof *dev);
+
+	dev->iobase = base_addr;
+	dev->priv = priv;
+	dev->init = ep93xx_eth_open;
+	dev->halt = ep93xx_eth_close;
+	dev->send = ep93xx_eth_send_packet;
+	dev->recv = ep93xx_eth_rcv_packet;
+
+	sprintf(dev->name, "ep93xx_eth-%hu", dev_num);
+
+	eth_register(dev);
+
+	/* Done! */
+	ret = 1;
+	goto eth_init_done;
+
+eth_init_failed_5:
+	free(priv->rx_sq.base);
+	/* Fall through */
+
+eth_init_failed_4:
+	free(priv->rx_dq.base);
+	/* Fall through */
+
+eth_init_failed_3:
+	free(priv->tx_sq.base);
+	/* Fall through */
+
+eth_init_failed_2:
+	free(priv->tx_dq.base);
+	/* Fall through */
+
+eth_init_failed_1:
+	free(priv);
+	/* Fall through */
+
+eth_init_failed_0:
+	/* Fall through */
+
+eth_init_done:
+	debug("-ep93xx_eth_initialize %d", ret);
+	return ret;
+}
+
+#if defined(CONFIG_MII)
+
+/**
+ * Maximum MII address we support
+ */
+#define MII_ADDRESS_MAX			31
+
+/**
+ * Maximum MII register address we support
+ */
+#define MII_REGISTER_MAX		31
+
+/**
+ * Read a 16-bit value from an MII register.
+ */
+static int ep93xx_miiphy_read(char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short * const value)
+{
+	struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
+	int ret = -1;
+	uint32_t self_ctl;
+
+	debug("+ep93xx_miiphy_read");
+
+	/* Parameter checks */
+	BUG_ON(dev == NULL);
+	BUG_ON(addr > MII_ADDRESS_MAX);
+	BUG_ON(reg > MII_REGISTER_MAX);
+	BUG_ON(value == NULL);
+
+	/*
+	 * Save the current SelfCTL register value.  Set MAC to suppress
+	 * preamble bits.  Wait for any previous MII command to complete
+	 * before issuing the new command.
+	 */
+	self_ctl = readl(&mac->selfctl);
+#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
+	writel(self_ctl & ~(1 << 8), &mac->selfctl);
+#endif	/* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
+
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	/*
+	 * Issue the MII 'read' command.  Wait for the command to complete.
+	 * Read the MII data value.
+	 */
+	writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg,
+		&mac->miicmd);
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	*value = (unsigned short)readl(&mac->miidata);
+
+	/* Restore the saved SelfCTL value and return. */
+	writel(self_ctl, &mac->selfctl);
+
+	ret = 0;
+	/* Fall through */
+
+	debug("-ep93xx_miiphy_read");
+	return ret;
+}
+
+/**
+ * Write a 16-bit value to an MII register.
+ */
+static int ep93xx_miiphy_write(char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short const value)
+{
+	struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
+	int ret = -1;
+	uint32_t self_ctl;
+
+	debug("+ep93xx_miiphy_write");
+
+	/* Parameter checks */
+	BUG_ON(dev == NULL);
+	BUG_ON(addr > MII_ADDRESS_MAX);
+	BUG_ON(reg > MII_REGISTER_MAX);
+
+	/*
+	 * Save the current SelfCTL register value.  Set MAC to suppress
+	 * preamble bits.  Wait for any previous MII command to complete
+	 * before issuing the new command.
+	 */
+	self_ctl = readl(&mac->selfctl);
+#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
+	writel(self_ctl & ~(1 << 8), &mac->selfctl);
+#endif	/* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
+
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	/* Issue the MII 'write' command.  Wait for the command to complete. */
+	writel((uint32_t)value, &mac->miidata);
+	writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg,
+		&mac->miicmd);
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	/* Restore the saved SelfCTL value and return. */
+	writel(self_ctl, &mac->selfctl);
+
+	ret = 0;
+	/* Fall through */
+
+	debug("-ep93xx_miiphy_write");
+	return ret;
+}
+#endif	/* defined(CONFIG_MII) */
diff --git a/drivers/net/ep93xx_eth.h b/drivers/net/ep93xx_eth.h
new file mode 100644
index 0000000..4654b2f
--- /dev/null
+++ b/drivers/net/ep93xx_eth.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * Copyright (C) 2004, 2005
+ * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _EP93XX_ETH_H
+#define _EP93XX_ETH_H
+
+#include <net.h>
+
+/**
+ * #define this to dump device status and queue info during initialization and
+ * following errors.
+ */
+#undef EP93XX_MAC_DEBUG
+
+/**
+ * Number of descriptor and status entries in our RX queues.
+ * It must be power of 2 !
+ */
+#define NUMRXDESC		PKTBUFSRX
+
+/**
+ * Number of descriptor and status entries in our TX queues.
+ */
+#define NUMTXDESC		1
+
+/**
+ * 944 = (1024 - 64) - 16, Fifo size - Minframesize - 16 (Chip FACT)
+ */
+#define TXSTARTMAX		944
+
+/**
+ * Receive descriptor queue entry
+ */
+struct rx_descriptor {
+	uint32_t word1;
+	uint32_t word2;
+};
+
+/**
+ * Receive status queue entry
+ */
+struct rx_status {
+	uint32_t word1;
+	uint32_t word2;
+};
+
+#define RX_STATUS_RWE(rx_status) ((rx_status->word1 >> 30) & 0x01)
+#define RX_STATUS_RFP(rx_status) ((rx_status->word1 >> 31) & 0x01)
+#define RX_STATUS_FRAME_LEN(rx_status) (rx_status->word2 & 0xFFFF)
+
+/**
+ * Transmit descriptor queue entry
+ */
+struct tx_descriptor {
+	uint32_t word1;
+	uint32_t word2;
+};
+
+#define TX_DESC_EOF (1 << 31)
+
+/**
+ * Transmit status queue entry
+ */
+struct tx_status {
+	uint32_t word1;
+};
+
+#define TX_STATUS_TXWE(tx_status) (((tx_status)->word1 >> 30) & 0x01)
+#define TX_STATUS_TXFP(tx_status) (((tx_status)->word1 >> 31) & 0x01)
+
+/**
+ * Transmit descriptor queue
+ */
+struct tx_descriptor_queue {
+	struct tx_descriptor *base;
+	struct tx_descriptor *current;
+	struct tx_descriptor *end;
+};
+
+/**
+ * Transmit status queue
+ */
+struct tx_status_queue {
+	struct tx_status *base;
+	volatile struct tx_status *current;
+	struct tx_status *end;
+};
+
+/**
+ * Receive descriptor queue
+ */
+struct rx_descriptor_queue {
+	struct rx_descriptor *base;
+	struct rx_descriptor *current;
+	struct rx_descriptor *end;
+};
+
+/**
+ * Receive status queue
+ */
+struct rx_status_queue {
+	struct rx_status *base;
+	volatile struct rx_status *current;
+	struct rx_status *end;
+};
+
+/**
+ * EP93xx MAC private data structure
+ */
+struct ep93xx_priv {
+	struct rx_descriptor_queue	rx_dq;
+	struct rx_status_queue		rx_sq;
+	void				*rx_buffer[NUMRXDESC];
+
+	struct tx_descriptor_queue	tx_dq;
+	struct tx_status_queue		tx_sq;
+
+	struct mac_regs			*regs;
+};
+
+#endif
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index c184353..dcb8850 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -42,6 +42,7 @@
 #include <net.h>
 #include <netdev.h>
 #include <malloc.h>
+#include <miiphy.h>
 
 #include <linux/mii.h>
 #include <asm/io.h>
@@ -164,6 +165,36 @@
 	return MACB_BFEXT(DATA, frame);
 }
 
+#if defined(CONFIG_CMD_MII)
+
+int macb_miiphy_read(char *devname, u8 phy_adr, u8 reg, u16 *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct macb_device *macb = to_macb(dev);
+
+	if ( macb->phy_addr != phy_adr )
+		return -1;
+
+	*value = macb_mdio_read(macb, reg);
+
+	return 0;
+}
+
+int macb_miiphy_write(char *devname, u8 phy_adr, u8 reg, u16 value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct macb_device *macb = to_macb(dev);
+
+	if ( macb->phy_addr != phy_adr )
+		return -1;
+
+	macb_mdio_write(macb, reg, value);
+
+	return 0;
+}
+#endif
+
+
 #if defined(CONFIG_CMD_NET)
 
 static int macb_send(struct eth_device *netdev, volatile void *packet,
@@ -542,84 +573,9 @@
 
 	eth_register(netdev);
 
-	return 0;
-}
-
-#endif
-
 #if defined(CONFIG_CMD_MII)
-
-int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
-{
-	unsigned long netctl;
-	unsigned long netstat;
-	unsigned long frame;
-	int iflag;
-
-	iflag = disable_interrupts();
-	netctl = macb_readl(&macb, EMACB_NCR);
-	netctl |= MACB_BIT(MPE);
-	macb_writel(&macb, EMACB_NCR, netctl);
-	if (iflag)
-		enable_interrupts();
-
-	frame = (MACB_BF(SOF, 1)
-		 | MACB_BF(RW, 2)
-		 | MACB_BF(PHYA, addr)
-		 | MACB_BF(REGA, reg)
-		 | MACB_BF(CODE, 2));
-	macb_writel(&macb, EMACB_MAN, frame);
-
-	do {
-		netstat = macb_readl(&macb, EMACB_NSR);
-	} while (!(netstat & MACB_BIT(IDLE)));
-
-	frame = macb_readl(&macb, EMACB_MAN);
-	*value = MACB_BFEXT(DATA, frame);
-
-	iflag = disable_interrupts();
-	netctl = macb_readl(&macb, EMACB_NCR);
-	netctl &= ~MACB_BIT(MPE);
-	macb_writel(&macb, EMACB_NCR, netctl);
-	if (iflag)
-		enable_interrupts();
-
-	return 0;
-}
-
-int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
-{
-	unsigned long netctl;
-	unsigned long netstat;
-	unsigned long frame;
-	int iflag;
-
-	iflag = disable_interrupts();
-	netctl = macb_readl(&macb, EMACB_NCR);
-	netctl |= MACB_BIT(MPE);
-	macb_writel(&macb, EMACB_NCR, netctl);
-	if (iflag)
-		enable_interrupts();
-
-	frame = (MACB_BF(SOF, 1)
-		 | MACB_BF(RW, 1)
-		 | MACB_BF(PHYA, addr)
-		 | MACB_BF(REGA, reg)
-		 | MACB_BF(CODE, 2)
-		 | MACB_BF(DATA, value));
-	macb_writel(&macb, EMACB_MAN, frame);
-
-	do {
-		netstat = macb_readl(&macb, EMACB_NSR);
-	} while (!(netstat & MACB_BIT(IDLE)));
-
-	iflag = disable_interrupts();
-	netctl = macb_readl(&macb, EMACB_NCR);
-	netctl &= ~MACB_BIT(MPE);
-	macb_writel(&macb, EMACB_NCR, netctl);
-	if (iflag)
-		enable_interrupts();
-
+	miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write);
+#endif
 	return 0;
 }
 
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 5d51406..cac08d0 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -257,12 +257,15 @@
 
 	addrh = smc911x_get_mac_csr(dev, ADDRH);
 	addrl = smc911x_get_mac_csr(dev, ADDRL);
-	dev->enetaddr[0] = addrl;
-	dev->enetaddr[1] = addrl >>  8;
-	dev->enetaddr[2] = addrl >> 16;
-	dev->enetaddr[3] = addrl >> 24;
-	dev->enetaddr[4] = addrh;
-	dev->enetaddr[5] = addrh >> 8;
+	if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) {
+		/* address is obtained from optional eeprom */
+		dev->enetaddr[0] = addrl;
+		dev->enetaddr[1] = addrl >>  8;
+		dev->enetaddr[2] = addrl >> 16;
+		dev->enetaddr[3] = addrl >> 24;
+		dev->enetaddr[4] = addrh;
+		dev->enetaddr[5] = addrh >> 8;
+	}
 
 	dev->init = smc911x_init;
 	dev->halt = smc911x_halt;
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index d8b6619..fd49eff 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -48,14 +48,15 @@
 		     volatile void *packet, int length);
 static int tsec_recv(struct eth_device *dev);
 static int tsec_init(struct eth_device *dev, bd_t * bd);
+static int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info);
 static void tsec_halt(struct eth_device *dev);
 static void init_registers(volatile tsec_t * regs);
 static void startup_tsec(struct eth_device *dev);
 static int init_phy(struct eth_device *dev);
 void write_phy_reg(struct tsec_private *priv, uint regnum, uint value);
 uint read_phy_reg(struct tsec_private *priv, uint regnum);
-struct phy_info *get_phy_info(struct eth_device *dev);
-void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd);
+static struct phy_info *get_phy_info(struct eth_device *dev);
+static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd);
 static void adjust_link(struct eth_device *dev);
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
 	&& !defined(BITBANGMII)
@@ -112,7 +113,7 @@
 /* Initialize device structure. Returns success if PHY
  * initialization succeeded (i.e. if it recognizes the PHY)
  */
-int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info)
+static int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info)
 {
 	struct eth_device *dev;
 	int i;
@@ -174,7 +175,7 @@
  * that it returns success if the link is up, failure otherwise.
  * This allows u-boot to find the first active controller.
  */
-int tsec_init(struct eth_device *dev, bd_t * bd)
+static int tsec_init(struct eth_device *dev, bd_t * bd)
 {
 	uint tempval;
 	char tmpbuf[MAC_ADDR_LEN];
@@ -235,7 +236,8 @@
 
 
 /* Provide the default behavior of writing the PHY of this ethernet device */
-#define write_phy_reg(priv, regnum, value) tsec_local_mdio_write(priv->phyregs,priv->phyaddr,regnum,value)
+#define write_phy_reg(priv, regnum, value) \
+	tsec_local_mdio_write(priv->phyregs,priv->phyaddr,regnum,value)
 
 /* Reads register regnum on the device's PHY through the
  * specified registers.	 It lowers and raises the read
@@ -243,7 +245,8 @@
  * notvalid bit cleared), and the bus to cease activity (miimind
  * busy bit cleared), and then returns the value
  */
-uint tsec_local_mdio_read(volatile tsec_mdio_t *phyregs, uint phyid, uint regnum)
+static uint tsec_local_mdio_read(volatile tsec_mdio_t *phyregs,
+				uint phyid, uint regnum)
 {
 	uint value;
 
@@ -269,7 +272,8 @@
 }
 
 /* #define to provide old read_phy_reg functionality without duplicating code */
-#define read_phy_reg(priv,regnum) tsec_local_mdio_read(priv->phyregs,priv->phyaddr,regnum)
+#define read_phy_reg(priv,regnum) \
+	tsec_local_mdio_read(priv->phyregs,priv->phyaddr,regnum)
 
 #define TBIANA_SETTINGS ( \
 		TBIANA_ASYMMETRIC_PAUSE \
@@ -277,17 +281,18 @@
 		| TBIANA_FULL_DUPLEX \
 		)
 
+/* Force the TBI PHY into 1000Mbps full duplex when in SGMII mode */
 #define TBICR_SETTINGS ( \
 		TBICR_PHY_RESET \
-		| TBICR_ANEG_ENABLE \
 		| TBICR_FULL_DUPLEX \
 		| TBICR_SPEED1_SET \
 		)
+
 /* Configure the TBI for SGMII operation */
 static void tsec_configure_serdes(struct tsec_private *priv)
 {
-	/* Access TBI PHY registers at given TSEC register offset as opposed to the
-	 * register offset used for external PHY accesses */
+	/* Access TBI PHY registers at given TSEC register offset as opposed
+	 * to the register offset used for external PHY accesses */
 	tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_ANA,
 			TBIANA_SETTINGS);
 	tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_TBICON,
@@ -342,7 +347,7 @@
  * Returns which value to write to the control register.
  * For 10/100, the value is slightly different
  */
-uint mii_cr_init(uint mii_reg, struct tsec_private * priv)
+static uint mii_cr_init(uint mii_reg, struct tsec_private * priv)
 {
 	if (priv->flags & TSEC_GIGABIT)
 		return MIIM_CONTROL_INIT;
@@ -353,7 +358,7 @@
 /*
  * Wait for auto-negotiation to complete, then determine link
  */
-uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
+static uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
 {
 	/*
 	 * Wait if the link is up, and autonegotiation is in progress
@@ -407,7 +412,7 @@
  *
  * Stolen from Linux's mii.c and phy_device.c
  */
-uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
+static uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
 {
 	/* We're using autonegotiation */
 	if (mii_reg & PHY_BMSR_AUTN_ABLE) {
@@ -476,7 +481,7 @@
  * link.  "Ethernet@Wirespeed" reduces advertised speed until link
  * can be achieved.
  */
-uint mii_BCM54xx_wirespeed(uint mii_reg, struct tsec_private *priv)
+static uint mii_BCM54xx_wirespeed(uint mii_reg, struct tsec_private *priv)
 {
 	return (read_phy_reg(priv, mii_reg) & 0x8FFF) | 0x8010;
 }
@@ -485,61 +490,150 @@
  * Parse the BCM54xx status register for speed and duplex information.
  * The linux sungem_phy has this information, but in a table format.
  */
-uint mii_parse_BCM54xx_sr(uint mii_reg, struct tsec_private *priv)
+static uint mii_parse_BCM54xx_sr(uint mii_reg, struct tsec_private *priv)
 {
+	/* If there is no link, speed and duplex don't matter */
+	if (!priv->link)
+		return 0;
 
-	switch((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >> MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT){
-
-		case 1:
-			printf("Enet starting in 10BT/HD\n");
-			priv->duplexity = 0;
-			priv->speed = 10;
-			break;
-
-		case 2:
-			printf("Enet starting in 10BT/FD\n");
-			priv->duplexity = 1;
-			priv->speed = 10;
-			break;
-
-		case 3:
-			printf("Enet starting in 100BT/HD\n");
-			priv->duplexity = 0;
-			priv->speed = 100;
-			break;
-
-		case 5:
-			printf("Enet starting in 100BT/FD\n");
-			priv->duplexity = 1;
-			priv->speed = 100;
-			break;
-
-		case 6:
-			printf("Enet starting in 1000BT/HD\n");
-			priv->duplexity = 0;
-			priv->speed = 1000;
-			break;
-
-		case 7:
-			printf("Enet starting in 1000BT/FD\n");
-			priv->duplexity = 1;
-			priv->speed = 1000;
-			break;
-
-		default:
-			printf("Auto-neg error, defaulting to 10BT/HD\n");
-			priv->duplexity = 0;
-			priv->speed = 10;
-			break;
+	switch ((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >>
+		MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT) {
+	case 1:
+		priv->duplexity = 0;
+		priv->speed = 10;
+		break;
+	case 2:
+		priv->duplexity = 1;
+		priv->speed = 10;
+		break;
+	case 3:
+		priv->duplexity = 0;
+		priv->speed = 100;
+		break;
+	case 5:
+		priv->duplexity = 1;
+		priv->speed = 100;
+		break;
+	case 6:
+		priv->duplexity = 0;
+		priv->speed = 1000;
+		break;
+	case 7:
+		priv->duplexity = 1;
+		priv->speed = 1000;
+		break;
+	default:
+		printf("Auto-neg error, defaulting to 10BT/HD\n");
+		priv->duplexity = 0;
+		priv->speed = 10;
+		break;
 	}
 
 	return 0;
-
 }
+
+/*
+ * Find out if PHY is in copper or serdes mode by looking at Expansion Reg
+ * 0x42 - "Operating Mode Status Register"
+ */
+static int BCM8482_is_serdes(struct tsec_private *priv)
+{
+	u16 val;
+	int serdes = 0;
+
+	write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_ER | 0x42);
+	val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA);
+
+	switch (val & 0x1f) {
+	case 0x0d:	/* RGMII-to-100Base-FX */
+	case 0x0e:	/* RGMII-to-SGMII */
+	case 0x0f:	/* RGMII-to-SerDes */
+	case 0x12:	/* SGMII-to-SerDes */
+	case 0x13:	/* SGMII-to-100Base-FX */
+	case 0x16:	/* SerDes-to-Serdes */
+		serdes = 1;
+		break;
+	case 0x6:	/* RGMII-to-Copper */
+	case 0x14:	/* SGMII-to-Copper */
+	case 0x17:	/* SerDes-to-Copper */
+		break;
+	default:
+		printf("ERROR, invalid PHY mode (0x%x\n)", val);
+		break;
+	}
+
+	return serdes;
+}
+
+/*
+ * Determine SerDes link speed and duplex from Expansion reg 0x42 "Operating
+ * Mode Status Register"
+ */
+uint mii_parse_BCM5482_serdes_sr(struct tsec_private *priv)
+{
+	u16 val;
+	int i = 0;
+
+	/* Wait 1s for link - Clause 37 autonegotiation happens very fast */
+	while (1) {
+		write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL,
+				MIIM_BCM54XX_EXP_SEL_ER | 0x42);
+		val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA);
+
+		if (val & 0x8000)
+			break;
+
+		if (i++ > 1000) {
+			priv->link = 0;
+			return 1;
+		}
+
+		udelay(1000);	/* 1 ms */
+	}
+
+	priv->link = 1;
+	switch ((val >> 13) & 0x3) {
+	case (0x00):
+		priv->speed = 10;
+		break;
+	case (0x01):
+		priv->speed = 100;
+		break;
+	case (0x02):
+		priv->speed = 1000;
+		break;
+	}
+
+	priv->duplexity = (val & 0x1000) == 0x1000;
+
+	return 0;
+}
+
+/*
+ * Figure out if BCM5482 is in serdes or copper mode and determine link
+ * configuration accordingly
+ */
+static uint mii_parse_BCM5482_sr(uint mii_reg, struct tsec_private *priv)
+{
+	if (BCM8482_is_serdes(priv)) {
+		mii_parse_BCM5482_serdes_sr(priv);
+		priv->flags |= TSEC_FIBER;
+	} else {
+		/* Wait for auto-negotiation to complete or fail */
+		mii_parse_sr(mii_reg, priv);
+
+		/* Parse BCM54xx copper aux status register */
+		mii_reg = read_phy_reg(priv, MIIM_BCM54xx_AUXSTATUS);
+		mii_parse_BCM54xx_sr(mii_reg, priv);
+	}
+
+	return 0;
+}
+
 /* Parse the 88E1011's status register for speed and duplex
  * information
  */
-uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv)
+static uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv)
 {
 	uint speed;
 
@@ -597,7 +691,7 @@
 /* Parse the RTL8211B's status register for speed and duplex
  * information
  */
-uint mii_parse_RTL8211B_sr(uint mii_reg, struct tsec_private * priv)
+static uint mii_parse_RTL8211B_sr(uint mii_reg, struct tsec_private * priv)
 {
 	uint speed;
 
@@ -655,7 +749,7 @@
 /* Parse the cis8201's status register for speed and duplex
  * information
  */
-uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv)
+static uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv)
 {
 	uint speed;
 
@@ -683,7 +777,7 @@
 /* Parse the vsc8244's status register for speed and duplex
  * information
  */
-uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv)
+static uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv)
 {
 	uint speed;
 
@@ -711,7 +805,7 @@
 /* Parse the DM9161's status register for speed and duplex
  * information
  */
-uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv)
+static uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv)
 {
 	if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
 		priv->speed = 100;
@@ -729,7 +823,7 @@
 /*
  * Hack to write all 4 PHYs with the LED values
  */
-uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv)
+static uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv)
 {
 	uint phyid;
 	volatile tsec_mdio_t *regbase = priv->phyregs;
@@ -747,7 +841,7 @@
 	return MIIM_CIS8204_SLEDCON_INIT;
 }
 
-uint mii_cis8204_setmode(uint mii_reg, struct tsec_private * priv)
+static uint mii_cis8204_setmode(uint mii_reg, struct tsec_private * priv)
 {
 	if (priv->flags & TSEC_REDUCED)
 		return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII;
@@ -755,7 +849,7 @@
 		return MIIM_CIS8204_EPHYCON_INIT;
 }
 
-uint mii_m88e1111s_setmode(uint mii_reg, struct tsec_private *priv)
+static uint mii_m88e1111s_setmode(uint mii_reg, struct tsec_private *priv)
 {
 	uint mii_data = read_phy_reg(priv, mii_reg);
 
@@ -847,8 +941,9 @@
 			break;
 		}
 
-		printf("Speed: %d, %s duplex\n", priv->speed,
-		       (priv->duplexity) ? "full" : "half");
+		printf("Speed: %d, %s duplex%s\n", priv->speed,
+		       (priv->duplexity) ? "full" : "half",
+		       (priv->flags & TSEC_FIBER) ? ", fiber mode" : "");
 
 	} else {
 		printf("%s: No link.\n", dev->name);
@@ -996,11 +1091,11 @@
 		phy_run_commands(priv, priv->phyinfo->shutdown);
 }
 
-struct phy_info phy_info_M88E1149S = {
+static struct phy_info phy_info_M88E1149S = {
 	0x1410ca,
 	"Marvell 88E1149S",
 	4,
-	(struct phy_cmd[]){     /* config */
+	(struct phy_cmd[]) {     /* config */
 		/* Reset and configure the PHY */
 		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
 		{0x1d, 0x1f, NULL},
@@ -1014,23 +1109,22 @@
 		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
 		{miim_end,}
 	},
-	(struct phy_cmd[]){     /* startup */
+	(struct phy_cmd[]) {     /* startup */
 		/* 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},
+		{MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
 		{miim_end,}
 	},
-	(struct phy_cmd[]){     /* shutdown */
+	(struct phy_cmd[]) {     /* shutdown */
 		{miim_end,}
 	},
 };
 
 /* The 5411 id is 0x206070, the 5421 is 0x2060e0 */
-struct phy_info phy_info_BCM5461S = {
+static struct phy_info phy_info_BCM5461S = {
 	0x02060c1,	/* 5461 ID */
 	"Broadcom BCM5461S",
 	0, /* not clear to me what minor revisions we can shift away */
@@ -1057,7 +1151,7 @@
 	},
 };
 
-struct phy_info phy_info_BCM5464S = {
+static struct phy_info phy_info_BCM5464S = {
 	0x02060b1,	/* 5464 ID */
 	"Broadcom BCM5464S",
 	0, /* not clear to me what minor revisions we can shift away */
@@ -1084,7 +1178,7 @@
 	},
 };
 
-struct phy_info phy_info_BCM5482S =  {
+static struct phy_info phy_info_BCM5482S =  {
 	0x0143bcb,
 	"Broadcom BCM5482S",
 	4,
@@ -1096,15 +1190,20 @@
 		/* Read Misc Control register and or in Ethernet@Wirespeed */
 		{MIIM_BCM54xx_AUXCNTL, 0, &mii_BCM54xx_wirespeed},
 		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		/* Initial config/enable of secondary SerDes interface */
+		{MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x14, 0xf), NULL},
+		/* Write intial value to secondary SerDes Contol */
+		{MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_SSD | 0, NULL},
+		{MIIM_BCM54XX_EXP_DATA, MIIM_CONTROL_RESTART, NULL},
+		/* Enable copper/fiber auto-detect */
+		{MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x1e, 0x201)},
 		{miim_end,}
 	},
 	(struct phy_cmd[]) { /* startup */
 		/* 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_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
+		/* Determine copper/fiber, auto-negotiate, and read the result */
+		{MIIM_STATUS, miim_read, &mii_parse_BCM5482_sr},
 		{miim_end,}
 	},
 	(struct phy_cmd[]) { /* shutdown */
@@ -1112,74 +1211,72 @@
 	},
 };
 
-struct phy_info phy_info_M88E1011S = {
+static struct phy_info phy_info_M88E1011S = {
 	0x01410c6,
 	"Marvell 88E1011S",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   /* Reset and configure the PHY */
-			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-			   {0x1d, 0x1f, NULL},
-			   {0x1e, 0x200c, NULL},
-			   {0x1d, 0x5, NULL},
-			   {0x1e, 0x0, NULL},
-			   {0x1e, 0x100, NULL},
-			   {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-			   {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* 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},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Reset and configure the PHY */
+		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+		{0x1d, 0x1f, NULL},
+		{0x1e, 0x200c, NULL},
+		{0x1d, 0x5, NULL},
+		{0x1e, 0x0, NULL},
+		{0x1e, 0x100, NULL},
+		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+		{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* 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},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
-struct phy_info phy_info_M88E1111S = {
+static struct phy_info phy_info_M88E1111S = {
 	0x01410cc,
 	"Marvell 88E1111S",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   /* Reset and configure the PHY */
-			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-			   {0x1b, 0x848f, &mii_m88e1111s_setmode},
-			   {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */
-			   {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-			   {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* 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},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Reset and configure the PHY */
+		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+		{0x1b, 0x848f, &mii_m88e1111s_setmode},
+		{0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */
+		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+		{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* 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},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
-struct phy_info phy_info_M88E1118 = {
+static struct phy_info phy_info_M88E1118 = {
 	0x01410e1,
 	"Marvell 88E1118",
 	4,
-	(struct phy_cmd[]){	/* config */
+	(struct phy_cmd[]) {	/* config */
 		/* Reset and configure the PHY */
 		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
 		{0x16, 0x0002, NULL}, /* Change Page Number */
@@ -1192,8 +1289,8 @@
 		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
 		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
 		{miim_end,}
-		},
-	(struct phy_cmd[]){	/* startup */
+	},
+	(struct phy_cmd[]) {	/* startup */
 		{0x16, 0x0000, NULL}, /* Change Page Number */
 		/* Status is read once to clear old link state */
 		{MIIM_STATUS, miim_read, NULL},
@@ -1203,17 +1300,17 @@
 		{MIIM_88E1011_PHY_STATUS, miim_read,
 		 &mii_parse_88E1011_psr},
 		{miim_end,}
-		},
-	(struct phy_cmd[]){	/* shutdown */
+	},
+	(struct phy_cmd[]) {	/* shutdown */
 		{miim_end,}
-		},
+	},
 };
 
 /*
  *  Since to access LED register we need do switch the page, we
  * do LED configuring in the miim_read-like function as follows
  */
-uint mii_88E1121_set_led (uint mii_reg, struct tsec_private *priv)
+static uint mii_88E1121_set_led (uint mii_reg, struct tsec_private *priv)
 {
 	uint pg;
 
@@ -1230,34 +1327,33 @@
 	return 0;
 }
 
-struct phy_info phy_info_M88E1121R = {
+static struct phy_info phy_info_M88E1121R = {
 	0x01410cb,
 	"Marvell 88E1121R",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   /* Reset and configure the PHY */
-			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-			   {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-			   {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-			   /* Configure leds */
-			   {MIIM_88E1121_PHY_LED_CTRL, miim_read,
-			    &mii_88E1121_set_led},
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   /* Disable IRQs and de-assert interrupt */
-			   {MIIM_88E1121_PHY_IRQ_EN, 0, NULL},
-			   {MIIM_88E1121_PHY_IRQ_STATUS, miim_read, NULL},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* Status is read once to clear old link state */
-			   {MIIM_STATUS, miim_read, NULL},
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   {MIIM_STATUS, miim_read, &mii_parse_link},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Reset and configure the PHY */
+		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+		{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+		/* Configure leds */
+		{MIIM_88E1121_PHY_LED_CTRL, miim_read, &mii_88E1121_set_led},
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		/* Disable IRQs and de-assert interrupt */
+		{MIIM_88E1121_PHY_IRQ_EN, 0, NULL},
+		{MIIM_88E1121_PHY_IRQ_STATUS, miim_read, NULL},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* Status is read once to clear old link state */
+		{MIIM_STATUS, miim_read, NULL},
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		{MIIM_STATUS, miim_read, &mii_parse_link},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
 static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv)
@@ -1276,276 +1372,262 @@
 	0x01410cd,
 	"Marvell 88E1145",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   /* Reset the PHY */
-			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+	(struct phy_cmd[]) {	/* config */
+		/* Reset the PHY */
+		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
 
-			   /* Errata E0, E1 */
-			   {29, 0x001b, NULL},
-			   {30, 0x418f, NULL},
-			   {29, 0x0016, NULL},
-			   {30, 0xa2da, NULL},
+		/* Errata E0, E1 */
+		{29, 0x001b, NULL},
+		{30, 0x418f, NULL},
+		{29, 0x0016, NULL},
+		{30, 0xa2da, NULL},
 
-			   /* Configure the PHY */
-			   {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
-			   {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-			   {MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO,
-			    NULL},
-			   {MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode},
-			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* Status is read once to clear old link state */
-			   {MIIM_STATUS, miim_read, NULL},
-			   /* Auto-negotiate */
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   {MIIM_88E1111_PHY_LED_CONTROL,
-			    MIIM_88E1111_PHY_LED_DIRECT, NULL},
-			   /* Read the Status */
-			   {MIIM_88E1011_PHY_STATUS, miim_read,
-			    &mii_parse_88E1011_psr},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+		/* Configure the PHY */
+		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+		{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+		{MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO, NULL},
+		{MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode},
+		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, NULL},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* Status is read once to clear old link state */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		{MIIM_88E1111_PHY_LED_CONTROL, MIIM_88E1111_PHY_LED_DIRECT, NULL},
+		/* Read the Status */
+		{MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
-struct phy_info phy_info_cis8204 = {
+static struct phy_info phy_info_cis8204 = {
 	0x3f11,
 	"Cicada Cis8204",
 	6,
-	(struct phy_cmd[]){	/* config */
-			   /* Override PHY config settings */
-			   {MIIM_CIS8201_AUX_CONSTAT,
-			    MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
-			   /* Configure some basic stuff */
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT,
-			    &mii_cis8204_fixled},
-			   {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT,
-			    &mii_cis8204_setmode},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* Read the Status (2x to make sure link is right) */
-			   {MIIM_STATUS, miim_read, NULL},
-			   /* Auto-negotiate */
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   /* Read the status */
-			   {MIIM_CIS8201_AUX_CONSTAT, miim_read,
-			    &mii_parse_cis8201},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Override PHY config settings */
+		{MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT,
+		 &mii_cis8204_fixled},
+		{MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT,
+		 &mii_cis8204_setmode},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* Read the Status (2x to make sure link is right) */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		/* Read the status */
+		{MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
 /* Cicada 8201 */
-struct phy_info phy_info_cis8201 = {
+static struct phy_info phy_info_cis8201 = {
 	0xfc41,
 	"CIS8201",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   /* Override PHY config settings */
-			   {MIIM_CIS8201_AUX_CONSTAT,
-			    MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
-			   /* Set up the interface mode */
-			   {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT,
-			    NULL},
-			   /* Configure some basic stuff */
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* Read the Status (2x to make sure link is right) */
-			   {MIIM_STATUS, miim_read, NULL},
-			   /* Auto-negotiate */
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   /* Read the status */
-			   {MIIM_CIS8201_AUX_CONSTAT, miim_read,
-			    &mii_parse_cis8201},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Override PHY config settings */
+		{MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
+		/* Set up the interface mode */
+		{MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* Read the Status (2x to make sure link is right) */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		/* Read the status */
+		{MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
-struct phy_info phy_info_VSC8211 = {
+
+static struct phy_info phy_info_VSC8211 = {
 	0xfc4b,
 	"Vitesse VSC8211",
 	4,
 	(struct phy_cmd[]) { /* config */
-			   /* Override PHY config settings */
-			   {MIIM_CIS8201_AUX_CONSTAT,
-			    MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
-			   /* Set up the interface mode */
-			   {MIIM_CIS8201_EXT_CON1,
-			    MIIM_CIS8201_EXTCON1_INIT, NULL},
-			   /* Configure some basic stuff */
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {miim_end,}
-			   },
+		/* Override PHY config settings */
+		{MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
+		/* Set up the interface mode */
+		{MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{miim_end,}
+	},
 	(struct phy_cmd[]) { /* startup */
-			   /* Read the Status (2x to make sure link is right) */
-			   {MIIM_STATUS, miim_read, NULL},
-			   /* Auto-negotiate */
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   /* Read the status */
-			   {MIIM_CIS8201_AUX_CONSTAT, miim_read,
-			    &mii_parse_cis8201},
-			   {miim_end,}
-			   },
+		/* Read the Status (2x to make sure link is right) */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		/* Read the status */
+		{MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
+		{miim_end,}
+	},
 	(struct phy_cmd[]) { /* shutdown */
-			   {miim_end,}
+		{miim_end,}
 	},
 };
-struct phy_info phy_info_VSC8244 = {
+
+static struct phy_info phy_info_VSC8244 = {
 	0x3f1b,
 	"Vitesse VSC8244",
 	6,
-	(struct phy_cmd[]){	/* config */
-			   /* Override PHY config settings */
-			   /* Configure some basic stuff */
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* Read the Status (2x to make sure link is right) */
-			   {MIIM_STATUS, miim_read, NULL},
-			   /* Auto-negotiate */
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   /* Read the status */
-			   {MIIM_VSC8244_AUX_CONSTAT, miim_read,
-			    &mii_parse_vsc8244},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Override PHY config settings */
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* Read the Status (2x to make sure link is right) */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		/* Read the status */
+		{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
-struct phy_info phy_info_VSC8641 = {
+static struct phy_info phy_info_VSC8641 = {
 	0x7043,
 	"Vitesse VSC8641",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   /* Configure some basic stuff */
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* Read the Status (2x to make sure link is right) */
-			   {MIIM_STATUS, miim_read, NULL},
-			   /* Auto-negotiate */
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   /* Read the status */
-			   {MIIM_VSC8244_AUX_CONSTAT, miim_read,
-			    &mii_parse_vsc8244},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* Read the Status (2x to make sure link is right) */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		/* Read the status */
+		{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
-struct phy_info phy_info_VSC8221 = {
+static struct phy_info phy_info_VSC8221 = {
 	0xfc55,
 	"Vitesse VSC8221",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   /* Configure some basic stuff */
-			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* Read the Status (2x to make sure link is right) */
-			   {MIIM_STATUS, miim_read, NULL},
-			   /* Auto-negotiate */
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   /* Read the status */
-			   {MIIM_VSC8244_AUX_CONSTAT, miim_read,
-			    &mii_parse_vsc8244},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* Read the Status (2x to make sure link is right) */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		/* Read the status */
+		{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
-struct phy_info phy_info_VSC8601 = {
-		0x00007042,
-		"Vitesse VSC8601",
-		4,
-		(struct phy_cmd[]){     /* config */
-				/* Override PHY config settings */
-				/* Configure some basic stuff */
-				{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+static struct phy_info phy_info_VSC8601 = {
+	0x00007042,
+	"Vitesse VSC8601",
+	4,
+	(struct phy_cmd[]) {     /* config */
+		/* Override PHY config settings */
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
 #ifdef CONFIG_SYS_VSC8601_SKEWFIX
-				{MIIM_VSC8601_EPHY_CON,MIIM_VSC8601_EPHY_CON_INIT_SKEW,NULL},
+		{MIIM_VSC8601_EPHY_CON,MIIM_VSC8601_EPHY_CON_INIT_SKEW,NULL},
 #if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX)
-				{MIIM_EXT_PAGE_ACCESS,1,NULL},
-#define VSC8101_SKEW	(CONFIG_SYS_VSC8601_SKEW_TX<<14)|(CONFIG_SYS_VSC8601_SKEW_RX<<12)
-				{MIIM_VSC8601_SKEW_CTRL,VSC8101_SKEW,NULL},
-				{MIIM_EXT_PAGE_ACCESS,0,NULL},
+		{MIIM_EXT_PAGE_ACCESS,1,NULL},
+#define VSC8101_SKEW \
+	(CONFIG_SYS_VSC8601_SKEW_TX << 14) | (CONFIG_SYS_VSC8601_SKEW_RX << 12)
+		{MIIM_VSC8601_SKEW_CTRL,VSC8101_SKEW,NULL},
+		{MIIM_EXT_PAGE_ACCESS,0,NULL},
 #endif
 #endif
-				{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
-				{MIIM_CONTROL, MIIM_CONTROL_RESTART, &mii_cr_init},
-				{miim_end,}
-				 },
-		(struct phy_cmd[]){     /* startup */
-				/* Read the Status (2x to make sure link is right) */
-				{MIIM_STATUS, miim_read, NULL},
-				/* Auto-negotiate */
-				{MIIM_STATUS, miim_read, &mii_parse_sr},
-				/* Read the status */
-				{MIIM_VSC8244_AUX_CONSTAT, miim_read,
-						&mii_parse_vsc8244},
-				{miim_end,}
-				},
-		(struct phy_cmd[]){     /* shutdown */
-				{miim_end,}
-				},
+		{MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+		{MIIM_CONTROL, MIIM_CONTROL_RESTART, &mii_cr_init},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {     /* startup */
+		/* Read the Status (2x to make sure link is right) */
+		{MIIM_STATUS, miim_read, NULL},
+		/* Auto-negotiate */
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		/* Read the status */
+		{MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {     /* shutdown */
+		{miim_end,}
+	},
 };
 
-
-struct phy_info phy_info_dm9161 = {
+static struct phy_info phy_info_dm9161 = {
 	0x0181b88,
 	"Davicom DM9161E",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL},
-			   /* Do not bypass the scrambler/descrambler */
-			   {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL},
-			   /* Clear 10BTCSR to default */
-			   {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT,
-			    NULL},
-			   /* Configure some basic stuff */
-			   {MIIM_CONTROL, MIIM_CR_INIT, NULL},
-			   /* Restart Auto Negotiation */
-			   {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* 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_DM9161_SCSR, miim_read,
-			    &mii_parse_dm9161_scsr},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		{MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL},
+		/* Do not bypass the scrambler/descrambler */
+		{MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL},
+		/* Clear 10BTCSR to default */
+		{MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL},
+		/* Configure some basic stuff */
+		{MIIM_CONTROL, MIIM_CR_INIT, NULL},
+		/* Restart Auto Negotiation */
+		{MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* 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_DM9161_SCSR, miim_read, &mii_parse_dm9161_scsr},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
+
 /* a generic flavor.  */
-struct phy_info phy_info_generic =  {
+static struct phy_info phy_info_generic =  {
 	0,
 	"Unknown/Generic PHY",
 	32,
@@ -1565,8 +1647,7 @@
 	}
 };
 
-
-uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
+static uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
 {
 	unsigned int speed;
 	if (priv->link) {
@@ -1601,26 +1682,26 @@
 	0x0001378e,
 	"LXT971",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   {MIIM_CR, MIIM_CR_INIT, mii_cr_init},	/* autonegotiate */
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup - enable interrupts */
-			   /* { 0x12, 0x00f2, NULL }, */
-			   {MIIM_STATUS, miim_read, NULL},
-			   {MIIM_STATUS, miim_read, &mii_parse_sr},
-			   {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown - disable interrupts */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		{MIIM_CR, MIIM_CR_INIT, mii_cr_init},	/* autonegotiate */
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup - enable interrupts */
+		/* { 0x12, 0x00f2, NULL }, */
+		{MIIM_STATUS, miim_read, NULL},
+		{MIIM_STATUS, miim_read, &mii_parse_sr},
+		{MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown - disable interrupts */
+		{miim_end,}
+	},
 };
 
 /* Parse the DP83865's link and auto-neg status register for speed and duplex
  * information
  */
-uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv)
+static uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv)
 {
 	switch (mii_reg & MIIM_DP83865_SPD_MASK) {
 
@@ -1646,34 +1727,33 @@
 	return 0;
 }
 
-struct phy_info phy_info_dp83865 = {
+static struct phy_info phy_info_dp83865 = {
 	0x20005c7,
 	"NatSemi DP83865",
 	4,
-	(struct phy_cmd[]){	/* config */
-			   {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* startup */
-			   /* 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 link and auto-neg status */
-			   {MIIM_DP83865_LANR, miim_read,
-			    &mii_parse_dp83865_lanr},
-			   {miim_end,}
-			   },
-	(struct phy_cmd[]){	/* shutdown */
-			   {miim_end,}
-			   },
+	(struct phy_cmd[]) {	/* config */
+		{MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* startup */
+		/* 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 link and auto-neg status */
+		{MIIM_DP83865_LANR, miim_read, &mii_parse_dp83865_lanr},
+		{miim_end,}
+	},
+	(struct phy_cmd[]) {	/* shutdown */
+		{miim_end,}
+	},
 };
 
-struct phy_info phy_info_rtl8211b = {
+static struct phy_info phy_info_rtl8211b = {
 	0x001cc91,
 	"RealTek RTL8211B",
 	4,
-	(struct phy_cmd[]){	/* config */
+	(struct phy_cmd[]) {	/* config */
 		/* Reset and configure the PHY */
 		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
 		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
@@ -1682,7 +1762,7 @@
 		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
 		{miim_end,}
 	},
-	(struct phy_cmd[]){	/* startup */
+	(struct phy_cmd[]) {	/* startup */
 		/* Status is read once to clear old link state */
 		{MIIM_STATUS, miim_read, NULL},
 		/* Auto-negotiate */
@@ -1691,12 +1771,12 @@
 		{MIIM_RTL8211B_PHY_STATUS, miim_read, &mii_parse_RTL8211B_sr},
 		{miim_end,}
 	},
-	(struct phy_cmd[]){	/* shutdown */
+	(struct phy_cmd[]) {	/* shutdown */
 		{miim_end,}
 	},
 };
 
-struct phy_info *phy_info[] = {
+static struct phy_info *phy_info[] = {
 	&phy_info_cis8204,
 	&phy_info_cis8201,
 	&phy_info_BCM5461S,
@@ -1725,7 +1805,7 @@
  * all of the known PHYs to see if one matches.	 If so, return
  * it, if not, return NULL
  */
-struct phy_info *get_phy_info(struct eth_device *dev)
+static struct phy_info *get_phy_info(struct eth_device *dev)
 {
 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
 	uint phy_reg, phy_ID;
@@ -1750,7 +1830,8 @@
 	}
 
 	if (theInfo == &phy_info_generic) {
-		printf("%s: No support for PHY id %x; assuming generic\n", dev->name, phy_ID);
+		printf("%s: No support for PHY id %x; assuming generic\n",
+			dev->name, phy_ID);
 	} else {
 		debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID);
 	}
@@ -1761,7 +1842,7 @@
 /* Execute the given series of commands on the given device's
  * PHY, running functions as necessary
  */
-void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd)
+static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd)
 {
 	int i;
 	uint result;
@@ -1863,10 +1944,10 @@
 static int
 tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set)
 {
- struct tsec_private *priv = privlist[1];
- volatile tsec_t *regs = priv->regs;
- volatile u32  *reg_array, value;
- u8 result, whichbit, whichreg;
+	struct tsec_private *priv = privlist[1];
+	volatile tsec_t *regs = priv->regs;
+	volatile u32  *reg_array, value;
+	u8 result, whichbit, whichreg;
 
 	result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff);
 	whichbit = result & 0x1f;	/* the 5 LSB = which bit to set */
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c
index db95ada..27dc500 100644
--- a/drivers/qe/uec.c
+++ b/drivers/qe/uec.c
@@ -323,9 +323,10 @@
 	return 0;
 }
 
-static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode)
+static int uec_set_mac_if_mode(uec_private_t *uec,
+		enet_interface_type_e if_mode, int speed)
 {
-	enet_interface_e	enet_if_mode;
+	enet_interface_type_e	enet_if_mode;
 	uec_info_t		*uec_info;
 	uec_t			*uec_regs;
 	u32			upsmr;
@@ -346,52 +347,68 @@
 	upsmr = in_be32(&uec->uccf->uf_regs->upsmr);
 	upsmr &= ~(UPSMR_RPM | UPSMR_TBIM | UPSMR_R10M | UPSMR_RMM);
 
-	switch (enet_if_mode) {
-		case ENET_100_MII:
-		case ENET_10_MII:
+	switch (speed) {
+		case 10:
 			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
+			switch (enet_if_mode) {
+				case MII:
+					break;
+				case RGMII:
+					upsmr |= (UPSMR_RPM | UPSMR_R10M);
+					break;
+				case RMII:
+					upsmr |= (UPSMR_R10M | UPSMR_RMM);
+					break;
+				default:
+					return -EINVAL;
+					break;
+			}
 			break;
-		case ENET_1000_GMII:
-			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
-			break;
-		case ENET_1000_TBI:
-			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
-			upsmr |= UPSMR_TBIM;
-			break;
-		case ENET_1000_RTBI:
-			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
-			upsmr |= (UPSMR_RPM | UPSMR_TBIM);
-			break;
-		case ENET_1000_RGMII_RXID:
-		case ENET_1000_RGMII_ID:
-		case ENET_1000_RGMII:
-			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
-			upsmr |= UPSMR_RPM;
-			break;
-		case ENET_100_RGMII:
+		case 100:
 			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
-			upsmr |= UPSMR_RPM;
+			switch (enet_if_mode) {
+				case MII:
+					break;
+				case RGMII:
+					upsmr |= UPSMR_RPM;
+					break;
+				case RMII:
+					upsmr |= UPSMR_RMM;
+					break;
+				default:
+					return -EINVAL;
+					break;
+			}
 			break;
-		case ENET_10_RGMII:
-			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
-			upsmr |= (UPSMR_RPM | UPSMR_R10M);
-			break;
-		case ENET_100_RMII:
-			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
-			upsmr |= UPSMR_RMM;
-			break;
-		case ENET_10_RMII:
-			maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
-			upsmr |= (UPSMR_R10M | UPSMR_RMM);
-			break;
-		case ENET_1000_SGMII:
+		case 1000:
 			maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
-			upsmr |= UPSMR_SGMM;
+			switch (enet_if_mode) {
+				case GMII:
+					break;
+				case TBI:
+					upsmr |= UPSMR_TBIM;
+					break;
+				case RTBI:
+					upsmr |= (UPSMR_RPM | UPSMR_TBIM);
+					break;
+				case RGMII_RXID:
+				case RGMII_ID:
+				case RGMII:
+					upsmr |= UPSMR_RPM;
+					break;
+				case SGMII:
+					upsmr |= UPSMR_SGMM;
+					break;
+				default:
+					return -EINVAL;
+					break;
+			}
 			break;
 		default:
 			return -EINVAL;
 			break;
 	}
+
 	out_be32(&uec_regs->maccfg2, maccfg2);
 	out_be32(&uec->uccf->uf_regs->upsmr, upsmr);
 
@@ -504,7 +521,7 @@
 	struct uec_mii_info	*mii_info = uec->mii_info;
 
 	extern void change_phy_interface_mode(struct eth_device *dev,
-					 enet_interface_e mode);
+				 enet_interface_type_e mode, int speed);
 	uec_regs = uec->uec_regs;
 
 	if (mii_info->link) {
@@ -522,25 +539,19 @@
 		}
 
 		if (mii_info->speed != uec->oldspeed) {
+			enet_interface_type_e	mode = \
+				uec->uec_info->enet_interface_type;
 			if (uec->uec_info->uf_info.eth_type == GIGA_ETH) {
 				switch (mii_info->speed) {
 				case 1000:
 					break;
 				case 100:
 					printf ("switching to rgmii 100\n");
-					/* change phy to rgmii 100 */
-					change_phy_interface_mode(dev,
-								ENET_100_RGMII);
-					/* change the MAC interface mode */
-					uec_set_mac_if_mode(uec,ENET_100_RGMII);
+					mode = RGMII;
 					break;
 				case 10:
 					printf ("switching to rgmii 10\n");
-					/* change phy to rgmii 10 */
-					change_phy_interface_mode(dev,
-								ENET_10_RGMII);
-					/* change the MAC interface mode */
-					uec_set_mac_if_mode(uec,ENET_10_RGMII);
+					mode = RGMII;
 					break;
 				default:
 					printf("%s: Ack,Speed(%d)is illegal\n",
@@ -549,6 +560,11 @@
 				}
 			}
 
+			/* change phy */
+			change_phy_interface_mode(dev, mode, mii_info->speed);
+			/* change the MAC interface mode */
+			uec_set_mac_if_mode(uec, mode, mii_info->speed);
+
 			printf("%s: Speed %dBT\n", dev->name, mii_info->speed);
 			uec->oldspeed = mii_info->speed;
 		}
@@ -980,7 +996,6 @@
 	int				num_threads_tx;
 	int				num_threads_rx;
 	u32				utbipar;
-	enet_interface_e		enet_interface;
 	u32				length;
 	u32				align;
 	qe_bd_t				*bd;
@@ -1060,7 +1075,7 @@
 	out_be32(&uec_regs->maccfg2, MACCFG2_INIT_VALUE);
 
 	/* Setup MAC interface mode */
-	uec_set_mac_if_mode(uec, uec_info->enet_interface);
+	uec_set_mac_if_mode(uec, uec_info->enet_interface_type, uec_info->speed);
 
 	/* Setup MII management base */
 #ifndef CONFIG_eTSEC_MDIO_BUS
@@ -1075,7 +1090,6 @@
 	/* Setup UTBIPAR */
 	utbipar = in_be32(&uec_regs->utbipar);
 	utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;
-	enet_interface = uec->uec_info->enet_interface;
 
 	/* Initialize UTBIPAR address to CONFIG_UTBIPAR_INIT_TBIPA for ALL UEC.
 	 * This frees up the remaining SMI addresses for use.
@@ -1084,7 +1098,8 @@
 	out_be32(&uec_regs->utbipar, utbipar);
 
 	/* Configure the TBI for SGMII operation */
-	if (uec->uec_info->enet_interface == ENET_1000_SGMII) {
+	if ((uec->uec_info->enet_interface_type == SGMII) &&
+	   (uec->uec_info->speed == 1000)) {
 		uec_write_phy_reg(uec->dev, uec_regs->utbipar,
 			ENET_TBI_MII_ANA, TBIANA_SETTINGS);
 
@@ -1215,6 +1230,7 @@
 		if (err || i <= 0)
 			printf("warning: %s: timeout on PHY link\n", dev->name);
 
+		adjust_link(dev);
 		uec->the_first_run = 1;
 	}
 
diff --git a/drivers/qe/uec.h b/drivers/qe/uec.h
index febfbce..2a9e2dc 100644
--- a/drivers/qe/uec.h
+++ b/drivers/qe/uec.h
@@ -662,22 +662,18 @@
 
 /* UEC ethernet interface type
 */
-typedef enum enet_interface {
-	ENET_10_MII,
-	ENET_10_RMII,
-	ENET_10_RGMII,
-	ENET_100_MII,
-	ENET_100_RMII,
-	ENET_100_RGMII,
-	ENET_1000_GMII,
-	ENET_1000_RGMII,
-	ENET_1000_RGMII_ID,
-	ENET_1000_RGMII_RXID,
-	ENET_1000_RGMII_TXID,
-	ENET_1000_TBI,
-	ENET_1000_RTBI,
-	ENET_1000_SGMII
-} enet_interface_e;
+typedef enum enet_interface_type {
+	MII,
+	RMII,
+	RGMII,
+	GMII,
+	RGMII_ID,
+	RGMII_RXID,
+	RGMII_TXID,
+	TBI,
+	RTBI,
+	SGMII
+} enet_interface_type_e;
 
 /* UEC initialization info struct
 */
@@ -696,7 +692,8 @@
 	.tx_bd_ring_len		= 16,	\
 	.rx_bd_ring_len		= 16,	\
 	.phy_address		= CONFIG_SYS_UEC##num##_PHY_ADDR, \
-	.enet_interface		= CONFIG_SYS_UEC##num##_INTERFACE_MODE, \
+	.enet_interface_type	= CONFIG_SYS_UEC##num##_INTERFACE_TYPE, \
+	.speed			= CONFIG_SYS_UEC##num##_INTERFACE_SPEED, \
 }
 
 typedef struct uec_info {
@@ -708,7 +705,8 @@
 	u16				rx_bd_ring_len;
 	u16				tx_bd_ring_len;
 	u8				phy_address;
-	enet_interface_e		enet_interface;
+	enet_interface_type_e		enet_interface_type;
+	int				speed;
 } uec_info_t;
 
 /* UEC driver initialized info
diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c
index 9715183..c4214d9 100644
--- a/drivers/qe/uec_phy.c
+++ b/drivers/qe/uec_phy.c
@@ -401,7 +401,8 @@
 
 	gbit_config_aneg(mii_info);
 
-	if (uec->uec_info->enet_interface == ENET_1000_RGMII_RXID) {
+	if ((uec->uec_info->enet_interface_type == RGMII_RXID) &&
+	   (uec->uec_info->speed == 1000)) {
 		u16 val;
 		int cnt = 50;
 
@@ -429,20 +430,22 @@
 {
 	struct eth_device *edev = mii_info->dev;
 	uec_private_t *uec = edev->priv;
-	enum enet_interface iface = uec->uec_info->enet_interface;
+	enum enet_interface_type iface = uec->uec_info->enet_interface_type;
+	int	speed = uec->uec_info->speed;
 
-	if (iface == ENET_1000_RGMII_ID ||
-			iface == ENET_1000_RGMII_RXID ||
-			iface == ENET_1000_RGMII_TXID) {
+	if ((speed == 1000) &&
+	   (iface == RGMII_ID ||
+	    iface == RGMII_RXID ||
+	    iface == RGMII_TXID)) {
 		int temp;
 
 		temp = phy_read(mii_info, MII_M1111_PHY_EXT_CR);
-		if (iface == ENET_1000_RGMII_ID) {
+		if (iface == RGMII_ID) {
 			temp |= MII_M1111_RX_DELAY | MII_M1111_TX_DELAY;
-		} else if (iface == ENET_1000_RGMII_RXID) {
+		} else if (iface == RGMII_RXID) {
 			temp &= ~MII_M1111_TX_DELAY;
 			temp |= MII_M1111_RX_DELAY;
-		} else if (iface == ENET_1000_RGMII_TXID) {
+		} else if (iface == RGMII_TXID) {
 			temp &= ~MII_M1111_RX_DELAY;
 			temp |= MII_M1111_TX_DELAY;
 		}
@@ -795,7 +798,9 @@
 }
 
 void marvell_phy_interface_mode (struct eth_device *dev,
-				 enet_interface_e mode)
+				 enet_interface_type_e type,
+				 int speed
+				)
 {
 	uec_private_t *uec = (uec_private_t *) dev->priv;
 	struct uec_mii_info *mii_info;
@@ -807,33 +812,35 @@
 	}
 	mii_info = uec->mii_info;
 
-	if (mode == ENET_100_RGMII) {
-		phy_write (mii_info, 0x00, 0x9140);
-		phy_write (mii_info, 0x1d, 0x001f);
-		phy_write (mii_info, 0x1e, 0x200c);
-		phy_write (mii_info, 0x1d, 0x0005);
-		phy_write (mii_info, 0x1e, 0x0000);
-		phy_write (mii_info, 0x1e, 0x0100);
-		phy_write (mii_info, 0x09, 0x0e00);
-		phy_write (mii_info, 0x04, 0x01e1);
-		phy_write (mii_info, 0x00, 0x9140);
-		phy_write (mii_info, 0x00, 0x1000);
-		udelay (100000);
-		phy_write (mii_info, 0x00, 0x2900);
-		phy_write (mii_info, 0x14, 0x0cd2);
-		phy_write (mii_info, 0x00, 0xa100);
-		phy_write (mii_info, 0x09, 0x0000);
-		phy_write (mii_info, 0x1b, 0x800b);
-		phy_write (mii_info, 0x04, 0x05e1);
-		phy_write (mii_info, 0x00, 0xa100);
-		phy_write (mii_info, 0x00, 0x2100);
-		udelay (1000000);
-	} else if (mode == ENET_10_RGMII) {
-		phy_write (mii_info, 0x14, 0x8e40);
-		phy_write (mii_info, 0x1b, 0x800b);
-		phy_write (mii_info, 0x14, 0x0c82);
-		phy_write (mii_info, 0x00, 0x8100);
-		udelay (1000000);
+	if (type == RGMII) {
+		if (speed == 100) {
+			phy_write (mii_info, 0x00, 0x9140);
+			phy_write (mii_info, 0x1d, 0x001f);
+			phy_write (mii_info, 0x1e, 0x200c);
+			phy_write (mii_info, 0x1d, 0x0005);
+			phy_write (mii_info, 0x1e, 0x0000);
+			phy_write (mii_info, 0x1e, 0x0100);
+			phy_write (mii_info, 0x09, 0x0e00);
+			phy_write (mii_info, 0x04, 0x01e1);
+			phy_write (mii_info, 0x00, 0x9140);
+			phy_write (mii_info, 0x00, 0x1000);
+			udelay (100000);
+			phy_write (mii_info, 0x00, 0x2900);
+			phy_write (mii_info, 0x14, 0x0cd2);
+			phy_write (mii_info, 0x00, 0xa100);
+			phy_write (mii_info, 0x09, 0x0000);
+			phy_write (mii_info, 0x1b, 0x800b);
+			phy_write (mii_info, 0x04, 0x05e1);
+			phy_write (mii_info, 0x00, 0xa100);
+			phy_write (mii_info, 0x00, 0x2100);
+			udelay (1000000);
+		} else if (speed == 10) {
+			phy_write (mii_info, 0x14, 0x8e40);
+			phy_write (mii_info, 0x1b, 0x800b);
+			phy_write (mii_info, 0x14, 0x0c82);
+			phy_write (mii_info, 0x00, 0x8100);
+			udelay (1000000);
+		}
 	}
 
 	/* handle 88e1111 rev.B2 erratum 5.6 */
@@ -844,9 +851,10 @@
 	/* now the B2 will correctly report autoneg completion status */
 }
 
-void change_phy_interface_mode (struct eth_device *dev, enet_interface_e mode)
+void change_phy_interface_mode (struct eth_device *dev,
+				enet_interface_type_e type, int speed)
 {
 #ifdef CONFIG_PHY_MODE_NEED_CHANGE
-	marvell_phy_interface_mode (dev, mode);
+	marvell_phy_interface_mode (dev, type, speed);
 #endif
 }
diff --git a/examples/standalone/smc91111_eeprom.c b/examples/standalone/smc91111_eeprom.c
index 9145763..b91f34c 100644
--- a/examples/standalone/smc91111_eeprom.c
+++ b/examples/standalone/smc91111_eeprom.c
@@ -53,9 +53,8 @@
 	int c, i, j, done, line, reg, value, start, what;
 	char input[50];
 
-	struct eth_device dev = {
-		.iobase = CONFIG_SMC91111_BASE
-	};
+	struct eth_device dev;
+	dev.iobase = CONFIG_SMC91111_BASE;
 
 	/* Print the ABI version */
 	app_startup (argv);
diff --git a/include/asm-arm/arch-at91/at91_emac.h b/include/asm-arm/arch-at91/at91_emac.h
new file mode 100644
index 0000000..4b96f04
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91_emac.h
@@ -0,0 +1,145 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
+ *
+ * based on AT91RM9200 datasheet revision I (36. Ethernet MAC (EMAC))
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef AT91_H
+#define AT91_H
+
+typedef struct at91_emac {
+	u32	 ctl;
+	u32	 cfg;
+	u32	 sr;
+	u32	 tar;
+	u32	 tcr;
+	u32	 tsr;
+	u32	 rbqp;
+	u32	 reserved0;
+	u32	 rsr;
+	u32	 isr;
+	u32	 ier;
+	u32	 idr;
+	u32	 imr;
+	u32	 man;
+	u32	 reserved1[2];
+	u32	 fra;
+	u32	 scol;
+	u32	 mocl;
+	u32	 ok;
+	u32	 seqe;
+	u32	 ale;
+	u32	 dte;
+	u32	 lcol;
+	u32	 ecol;
+	u32	 cse;
+	u32	 tue;
+	u32	 cde;
+	u32	 elr;
+	u32	 rjb;
+	u32	 usf;
+	u32	 sqee;
+	u32	 drfc;
+	u32	 reserved2[3];
+	u32	 hsh;
+	u32	 hsl;
+	u32	 sh1l;
+	u32	 sa1h;
+	u32	 sa2l;
+	u32	 sa2h;
+	u32	 sa3l;
+	u32	 sa3h;
+	u32	 sa4l;
+	u32	 sa4h;
+} at91_emac_t;
+
+#define AT91_EMAC_CTL_LB	0x0001
+#define AT91_EMAC_CTL_LBL	0x0002
+#define AT91_EMAC_CTL_RE	0x0004
+#define AT91_EMAC_CTL_TE	0x0008
+#define AT91_EMAC_CTL_MPE	0x0010
+#define AT91_EMAC_CTL_CSR	0x0020
+#define AT91_EMAC_CTL_ISR	0x0040
+#define AT91_EMAC_CTL_WES	0x0080
+#define AT91_EMAC_CTL_BP	0x1000
+
+#define AT91_EMAC_CFG_SPD	0x0001
+#define AT91_EMAC_CFG_FD	0x0002
+#define AT91_EMAC_CFG_BR	0x0004
+#define AT91_EMAC_CFG_CAF	0x0010
+#define AT91_EMAC_CFG_NBC	0x0020
+#define AT91_EMAC_CFG_MTI	0x0040
+#define AT91_EMAC_CFG_UNI	0x0080
+#define AT91_EMAC_CFG_BIG	0x0100
+#define AT91_EMAC_CFG_EAE	0x0200
+#define AT91_EMAC_CFG_CLK_MASK	0xFFFFF3FF
+#define AT91_EMAC_CFG_MCLK_8	0x0000
+#define AT91_EMAC_CFG_MCLK_16	0x0400
+#define AT91_EMAC_CFG_MCLK_32	0x0800
+#define AT91_EMAC_CFG_MCLK_64	0x0C00
+#define AT91_EMAC_CFG_RTY	0x1000
+#define AT91_EMAC_CFG_RMII	0x2000
+
+#define AT91_EMAC_SR_LINK	0x0001
+#define AT91_EMAC_SR_MDIO	0x0002
+#define AT91_EMAC_SR_IDLE	0x0004
+
+#define AT91_EMAC_TCR_LEN(x)	(x & 0x7FF)
+#define AT91_EMAC_TCR_NCRC	0x8000
+
+#define AT91_EMAC_TSR_OVR	0x0001
+#define AT91_EMAC_TSR_COL	0x0002
+#define AT91_EMAC_TSR_RLE	0x0004
+#define AT91_EMAC_TSR_TXIDLE	0x0008
+#define AT91_EMAC_TSR_BNQ	0x0010
+#define AT91_EMAC_TSR_COMP	0x0020
+#define AT91_EMAC_TSR_UND	0x0040
+
+#define AT91_EMAC_RSR_BNA	0x0001
+#define AT91_EMAC_RSR_REC	0x0002
+#define AT91_EMAC_RSR_OVR	0x0004
+
+/*  ISR, IER, IDR, IMR use the same bits */
+#define AT91_EMAC_IxR_DONE	0x0001
+#define AT91_EMAC_IxR_RCOM	0x0002
+#define AT91_EMAC_IxR_RBNA	0x0004
+#define AT91_EMAC_IxR_TOVR	0x0008
+#define AT91_EMAC_IxR_TUND	0x0010
+#define AT91_EMAC_IxR_RTRY	0x0020
+#define AT91_EMAC_IxR_TBRE	0x0040
+#define AT91_EMAC_IxR_TCOM	0x0080
+#define AT91_EMAC_IxR_TIDLE	0x0100
+#define AT91_EMAC_IxR_LINK	0x0200
+#define AT91_EMAC_IxR_ROVR	0x0400
+#define AT91_EMAC_IxR_HRESP	0x0800
+
+#define AT91_EMAC_MAN_DATA_MASK		0xFFFF
+#define AT91_EMAC_MAN_CODE_802_3	0x00020000
+#define AT91_EMAC_MAN_REGA(reg)		((reg & 0x1F) << 18)
+#define AT91_EMAC_MAN_PHYA(phy)		((phy & 0x1F) << 23)
+#define AT91_EMAC_MAN_RW_R		0x20000000
+#define AT91_EMAC_MAN_RW_W		0x10000000
+#define AT91_EMAC_MAN_HIGH		0x40000000
+#define AT91_EMAC_MAN_LOW		0x80000000
+
+#endif
diff --git a/include/asm-arm/arch-davinci/emac_defs.h b/include/asm-arm/arch-davinci/emac_defs.h
index 96bc80e..e313263 100644
--- a/include/asm-arm/arch-davinci/emac_defs.h
+++ b/include/asm-arm/arch-davinci/emac_defs.h
@@ -43,6 +43,13 @@
 #define EMAC_WRAPPER_BASE_ADDR		(0x01d0a000)
 #define EMAC_WRAPPER_RAM_ADDR		(0x01d08000)
 #define EMAC_MDIO_BASE_ADDR		(0x01d0b000)
+#define DAVINCI_EMAC_VERSION2
+#elif defined(CONFIG_SOC_DA8XX)
+#define EMAC_BASE_ADDR			DAVINCI_EMAC_CNTRL_REGS_BASE
+#define EMAC_WRAPPER_BASE_ADDR		DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE
+#define EMAC_WRAPPER_RAM_ADDR		DAVINCI_EMAC_WRAPPER_RAM_BASE
+#define EMAC_MDIO_BASE_ADDR		DAVINCI_MDIO_CNTRL_REGS_BASE
+#define DAVINCI_EMAC_VERSION2
 #else
 #define EMAC_BASE_ADDR			(0x01c80000)
 #define EMAC_WRAPPER_BASE_ADDR		(0x01c81000)
@@ -51,6 +58,11 @@
 #endif
 
 #ifdef CONFIG_SOC_DM646X
+#define DAVINCI_EMAC_VERSION2
+#define DAVINCI_EMAC_GIG_ENABLE
+#endif
+
+#ifdef CONFIG_SOC_DM646X
 /* MDIO module input frequency */
 #define EMAC_MDIO_BUS_FREQ		76500000
 /* MDIO clock output frequency */
@@ -60,6 +72,11 @@
 #define EMAC_MDIO_BUS_FREQ		121500000
 /* MDIO clock output frequency */
 #define EMAC_MDIO_CLOCK_FREQ		2200000		/* 2.2 MHz */
+#elif defined(CONFIG_SOC_DA8XX)
+/* MDIO module input frequency */
+#define EMAC_MDIO_BUS_FREQ		clk_get(DAVINCI_MDIO_CLKID)
+/* MDIO clock output frequency */
+#define EMAC_MDIO_CLOCK_FREQ		2000000		/* 2.0 MHz */
 #else
 /* MDIO module input frequency */
 #define EMAC_MDIO_BUS_FREQ		99000000	/* PLL/6 - 99 MHz */
@@ -128,6 +145,10 @@
 #define EMAC_MACCONTROL_FULLDUPLEX_ENABLE	(0x1)
 #define EMAC_MACCONTROL_GIGABIT_ENABLE		(1 << 7)
 #define EMAC_MACCONTROL_GIGFORCE		(1 << 17)
+#define EMAC_MACCONTROL_RMIISPEED_100		(1 << 15)
+
+#define EMAC_MAC_ADDR_MATCH		(1 << 19)
+#define EMAC_MAC_ADDR_IS_VALID		(1 << 20)
 
 #define EMAC_RXMBPENABLE_RXCAFEN_ENABLE	(0x200000)
 #define EMAC_RXMBPENABLE_RXBROADEN	(0x2000)
@@ -283,10 +304,40 @@
 
 /* EMAC Wrapper Registers Structure */
 typedef struct  {
-#if defined(CONFIG_SOC_DM646X) || defined(CONFIG_SOC_DM365)
-	dv_reg		IDVER;
-	dv_reg		SOFTRST;
-	dv_reg		EMCTRL;
+#ifdef DAVINCI_EMAC_VERSION2
+	dv_reg		idver;
+	dv_reg		softrst;
+	dv_reg		emctrl;
+	dv_reg		c0rxthreshen;
+	dv_reg		c0rxen;
+	dv_reg		c0txen;
+	dv_reg		c0miscen;
+	dv_reg		c1rxthreshen;
+	dv_reg		c1rxen;
+	dv_reg		c1txen;
+	dv_reg		c1miscen;
+	dv_reg		c2rxthreshen;
+	dv_reg		c2rxen;
+	dv_reg		c2txen;
+	dv_reg		c2miscen;
+	dv_reg		c0rxthreshstat;
+	dv_reg		c0rxstat;
+	dv_reg		c0txstat;
+	dv_reg		c0miscstat;
+	dv_reg		c1rxthreshstat;
+	dv_reg		c1rxstat;
+	dv_reg		c1txstat;
+	dv_reg		c1miscstat;
+	dv_reg		c2rxthreshstat;
+	dv_reg		c2rxstat;
+	dv_reg		c2txstat;
+	dv_reg		c2miscstat;
+	dv_reg		c0rximax;
+	dv_reg		c0tximax;
+	dv_reg		c1rximax;
+	dv_reg		c1tximax;
+	dv_reg		c2rximax;
+	dv_reg		c2tximax;
 #else
 	u_int8_t	RSVD0[4100];
 	dv_reg		EWCTL;
diff --git a/include/common.h b/include/common.h
index 81f2b59..0ae5abc 100644
--- a/include/common.h
+++ b/include/common.h
@@ -123,6 +123,11 @@
 #define debugX(level,fmt,args...)
 #endif	/* DEBUG */
 
+#define error(fmt, args...) do {					\
+		printf("ERROR: " fmt "\nat %s:%d/%s()\n",		\
+			##args, __FILE__, __LINE__, __func__);		\
+} while (0)
+
 #ifndef BUG
 #define BUG() do { \
 	printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
diff --git a/include/configs/MPC8323ERDB.h b/include/configs/MPC8323ERDB.h
index 356586c..8e6f7ce 100644
--- a/include/configs/MPC8323ERDB.h
+++ b/include/configs/MPC8323ERDB.h
@@ -347,7 +347,8 @@
 #define CONFIG_SYS_UEC1_TX_CLK		QE_CLK10
 #define CONFIG_SYS_UEC1_ETH_TYPE	FAST_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR	4
-#define CONFIG_SYS_UEC1_INTERFACE_MODE	ENET_100_MII
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE	MII
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED	100
 #endif
 
 #define CONFIG_UEC_ETH2		/* ETH4 */
@@ -358,7 +359,8 @@
 #define CONFIG_SYS_UEC2_TX_CLK		QE_CLK3
 #define CONFIG_SYS_UEC2_ETH_TYPE	FAST_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR	0
-#define CONFIG_SYS_UEC2_INTERFACE_MODE	ENET_100_MII
+#define CONFIG_SYS_UEC2_INTERFACE_TYPE	MII
+#define CONFIG_SYS_UEC2_INTERFACE_SPEED	100
 #endif
 
 /*
diff --git a/include/configs/MPC832XEMDS.h b/include/configs/MPC832XEMDS.h
index f17f9c7..1adac64 100644
--- a/include/configs/MPC832XEMDS.h
+++ b/include/configs/MPC832XEMDS.h
@@ -362,7 +362,8 @@
 #define CONFIG_SYS_UEC1_TX_CLK		QE_CLK10
 #define CONFIG_SYS_UEC1_ETH_TYPE	FAST_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR	3
-#define CONFIG_SYS_UEC1_INTERFACE_MODE	ENET_100_MII
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE	MII
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED	100
 #endif
 
 #define CONFIG_UEC_ETH2		/* ETH4 */
@@ -373,7 +374,8 @@
 #define CONFIG_SYS_UEC2_TX_CLK		QE_CLK8
 #define CONFIG_SYS_UEC2_ETH_TYPE	FAST_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR	4
-#define CONFIG_SYS_UEC2_INTERFACE_MODE	ENET_100_MII
+#define CONFIG_SYS_UEC2_INTERFACE_TYPE	MII
+#define CONFIG_SYS_UEC2_INTERFACE_SPEED	100
 #endif
 
 /*
diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h
index 8520155..6fa7287 100644
--- a/include/configs/MPC8360EMDS.h
+++ b/include/configs/MPC8360EMDS.h
@@ -400,7 +400,8 @@
 #define CONFIG_SYS_UEC1_TX_CLK		QE_CLK9
 #define CONFIG_SYS_UEC1_ETH_TYPE	GIGA_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR	0
-#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
 #endif
 
 #define CONFIG_UEC_ETH2		/* GETH2 */
@@ -411,7 +412,8 @@
 #define CONFIG_SYS_UEC2_TX_CLK		QE_CLK4
 #define CONFIG_SYS_UEC2_ETH_TYPE	GIGA_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR	1
-#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
 #endif
 
 /*
diff --git a/include/configs/MPC8360ERDK.h b/include/configs/MPC8360ERDK.h
index 1d1f94f..c6f1409 100644
--- a/include/configs/MPC8360ERDK.h
+++ b/include/configs/MPC8360ERDK.h
@@ -318,7 +318,8 @@
 #define CONFIG_SYS_UEC1_TX_CLK		QE_CLK9
 #define CONFIG_SYS_UEC1_ETH_TYPE	GIGA_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR	2
-#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_RXID
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_RXID
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
 #endif
 
 #define CONFIG_UEC_ETH2		/* GETH2 */
@@ -329,7 +330,8 @@
 #define CONFIG_SYS_UEC2_TX_CLK		QE_CLK4
 #define CONFIG_SYS_UEC2_ETH_TYPE	GIGA_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR	4
-#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_RXID
+#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_RXID
+#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
 #endif
 
 /*
diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h
index 128a7e1..6973538 100644
--- a/include/configs/MPC8568MDS.h
+++ b/include/configs/MPC8568MDS.h
@@ -333,7 +333,8 @@
 #define CONFIG_SYS_UEC1_TX_CLK         QE_CLK16
 #define CONFIG_SYS_UEC1_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR       7
-#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
 #endif
 
 #define CONFIG_UEC_ETH2         /* GETH2 */
@@ -344,7 +345,8 @@
 #define CONFIG_SYS_UEC2_TX_CLK         QE_CLK16
 #define CONFIG_SYS_UEC2_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR       1
-#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
 #endif
 #endif /* CONFIG_QE */
 
diff --git a/include/configs/MPC8569MDS.h b/include/configs/MPC8569MDS.h
index 6cf807b..9b81703 100644
--- a/include/configs/MPC8569MDS.h
+++ b/include/configs/MPC8569MDS.h
@@ -376,12 +376,14 @@
 #define CONFIG_SYS_UEC1_TX_CLK         QE_CLK12
 #define CONFIG_SYS_UEC1_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR       7
-#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
 #elif defined(CONFIG_SYS_UCC_RMII_MODE)
 #define CONFIG_SYS_UEC1_TX_CLK         QE_CLK16	/* CLK16 for RMII */
 #define CONFIG_SYS_UEC1_ETH_TYPE       FAST_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR       8	/* 0x8 for RMII */
-#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_100_RMII
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE RMII
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED 100
 #endif /* CONFIG_SYS_UCC_RGMII_MODE */
 #endif /* CONFIG_UEC_ETH1 */
 
@@ -395,12 +397,14 @@
 #define CONFIG_SYS_UEC2_TX_CLK         QE_CLK17
 #define CONFIG_SYS_UEC2_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR       1
-#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
 #elif defined(CONFIG_SYS_UCC_RMII_MODE)
 #define CONFIG_SYS_UEC2_TX_CLK         QE_CLK16	/* CLK 16 for RMII */
 #define CONFIG_SYS_UEC2_ETH_TYPE       FAST_ETH
 #define CONFIG_SYS_UEC2_PHY_ADDR       0x9	/* 0x9 for RMII */
-#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_100_RMII
+#define CONFIG_SYS_UEC2_INTERFACE_TYPE RMII
+#define CONFIG_SYS_UEC2_INTERFACE_SPEED 100
 #endif /* CONFIG_SYS_UCC_RGMII_MODE */
 #endif /* CONFIG_UEC_ETH2 */
 
@@ -414,12 +418,14 @@
 #define CONFIG_SYS_UEC3_TX_CLK         QE_CLK12
 #define CONFIG_SYS_UEC3_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC3_PHY_ADDR       2
-#define CONFIG_SYS_UEC3_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC3_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC3_INTERFACE_SPEED 1000
 #elif defined(CONFIG_SYS_UCC_RMII_MODE)
 #define CONFIG_SYS_UEC3_TX_CLK		QE_CLK16 /* CLK_16 for RMII */
 #define CONFIG_SYS_UEC3_ETH_TYPE	FAST_ETH
 #define CONFIG_SYS_UEC3_PHY_ADDR	0xA     /* 0xA for RMII */
-#define CONFIG_SYS_UEC3_INTERFACE_MODE ENET_100_RMII
+#define CONFIG_SYS_UEC3_INTERFACE_TYPE RMII
+#define CONFIG_SYS_UEC3_INTERFACE_SPEED 100
 #endif /* CONFIG_SYS_UCC_RGMII_MODE */
 #endif /* CONFIG_UEC_ETH3 */
 
@@ -433,12 +439,14 @@
 #define CONFIG_SYS_UEC4_TX_CLK         QE_CLK17
 #define CONFIG_SYS_UEC4_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC4_PHY_ADDR       3
-#define CONFIG_SYS_UEC4_INTERFACE_MODE ENET_1000_RGMII_ID
+#define CONFIG_SYS_UEC4_INTERFACE_TYPE RGMII_ID
+#define CONFIG_SYS_UEC4_INTERFACE_SPEED 1000
 #elif defined(CONFIG_SYS_UCC_RMII_MODE)
 #define CONFIG_SYS_UEC4_TX_CLK		QE_CLK16 /* CLK16 for RMII */
 #define CONFIG_SYS_UEC4_ETH_TYPE	FAST_ETH
 #define CONFIG_SYS_UEC4_PHY_ADDR	0xB     /* 0xB for RMII */
-#define CONFIG_SYS_UEC4_INTERFACE_MODE ENET_100_RMII
+#define CONFIG_SYS_UEC4_INTERFACE_TYPE RMII
+#define CONFIG_SYS_UEC4_INTERFACE_SPEED 100
 #endif /* CONFIG_SYS_UCC_RGMII_MODE */
 #endif /* CONFIG_UEC_ETH4 */
 
@@ -451,7 +459,8 @@
 #define CONFIG_SYS_UEC6_TX_CLK         QE_CLK_NONE
 #define CONFIG_SYS_UEC6_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC6_PHY_ADDR       4
-#define CONFIG_SYS_UEC6_INTERFACE_MODE ENET_1000_SGMII
+#define CONFIG_SYS_UEC6_INTERFACE_TYPE SGMII
+#define CONFIG_SYS_UEC6_INTERFACE_SPEED 1000
 #endif /* CONFIG_UEC_ETH6 */
 
 #undef CONFIG_UEC_ETH8         /* GETH8 */
@@ -463,7 +472,8 @@
 #define CONFIG_SYS_UEC8_TX_CLK         QE_CLK_NONE
 #define CONFIG_SYS_UEC8_ETH_TYPE       GIGA_ETH
 #define CONFIG_SYS_UEC8_PHY_ADDR       6
-#define CONFIG_SYS_UEC8_INTERFACE_MODE ENET_1000_SGMII
+#define CONFIG_SYS_UEC8_INTERFACE_TYPE SGMII
+#define CONFIG_SYS_UEC8_INTERFACE_SPEED 1000
 #endif /* CONFIG_UEC_ETH8 */
 
 #endif /* CONFIG_QE */
diff --git a/include/configs/at91rm9200dk.h b/include/configs/at91rm9200dk.h
index 590c69a..5de70cb 100644
--- a/include/configs/at91rm9200dk.h
+++ b/include/configs/at91rm9200dk.h
@@ -122,7 +122,14 @@
 #define CONFIG_SYS_MEMTEST_START		PHYS_SDRAM
 #define CONFIG_SYS_MEMTEST_END			CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
 
-#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
+
 #define CONFIG_NET_RETRY_COUNT		20
 #define CONFIG_AT91C_USE_RMII
 
diff --git a/include/configs/at91rm9200ek.h b/include/configs/at91rm9200ek.h
index b4f075e..4750855 100644
--- a/include/configs/at91rm9200ek.h
+++ b/include/configs/at91rm9200ek.h
@@ -145,7 +145,13 @@
 /*
  * Network Driver Setting
  */
-#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
 #define CONFIG_NET_RETRY_COUNT		20
 #define CONFIG_AT91C_USE_RMII
 
diff --git a/include/configs/cmc_pu2.h b/include/configs/cmc_pu2.h
index be478b2..00d0cec 100644
--- a/include/configs/cmc_pu2.h
+++ b/include/configs/cmc_pu2.h
@@ -152,7 +152,13 @@
 #define CONFIG_SYS_MEMTEST_START	PHYS_SDRAM
 #define CONFIG_SYS_MEMTEST_END		CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
 
-#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
 #define CONFIG_NET_RETRY_COUNT		20
 #define CONFIG_AT91C_USE_RMII
 
diff --git a/include/configs/cpuat91.h b/include/configs/cpuat91.h
index 8746f70..e872fe9 100644
--- a/include/configs/cpuat91.h
+++ b/include/configs/cpuat91.h
@@ -128,7 +128,13 @@
 #define CONFIG_SYS_MEMTEST_END			\
 	(CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 512 * 1024)
 
-#define CONFIG_DRIVER_ETHER			1
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
 #define CONFIG_NET_RETRY_COUNT			20
 #define CONFIG_AT91C_USE_RMII			1
 #define CONFIG_PHY_ADDRESS			(1 << 5)
diff --git a/include/configs/csb637.h b/include/configs/csb637.h
index f4fd808..689e7f0 100644
--- a/include/configs/csb637.h
+++ b/include/configs/csb637.h
@@ -126,7 +126,13 @@
 #define CONFIG_SYS_ALT_MEMTEST			1
 #define CONFIG_SYS_MEMTEST_SCRATCH		CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 4
 
-#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
 #define CONFIG_NET_RETRY_COUNT		20
 #undef CONFIG_AT91C_USE_RMII
 
diff --git a/include/configs/kb9202.h b/include/configs/kb9202.h
index 7dd81e6..3fe88fe 100644
--- a/include/configs/kb9202.h
+++ b/include/configs/kb9202.h
@@ -115,7 +115,13 @@
 #define CONFIG_SYS_MEMTEST_START		PHYS_SDRAM
 #define CONFIG_SYS_MEMTEST_END			CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - (512*1024)
 
-#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
 #define CONFIG_NET_RETRY_COUNT		20
 
 #define CONFIG_SYS_FLASH_BASE			0x10000000
diff --git a/include/configs/kmeter1.h b/include/configs/kmeter1.h
index 0327b97..d27b75b 100644
--- a/include/configs/kmeter1.h
+++ b/include/configs/kmeter1.h
@@ -295,7 +295,8 @@
 #define CONFIG_SYS_UEC1_TX_CLK		QE_CLK17
 #define CONFIG_SYS_UEC1_ETH_TYPE	FAST_ETH
 #define CONFIG_SYS_UEC1_PHY_ADDR	0
-#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_100_RMII
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE RMII
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED 100
 #endif
 
 /*
diff --git a/include/configs/m501sk.h b/include/configs/m501sk.h
index 5c06642..a28fd27 100644
--- a/include/configs/m501sk.h
+++ b/include/configs/m501sk.h
@@ -34,6 +34,7 @@
 #define AT91C_MASTER_CLOCK	59904000
 #define AT91_SLOW_CLOCK	32768 /* slow clock */
 
+#define CONFIG_AT91RM9200	1	/* It's an Atmel AT91RM9200 SoC	*/
 #define CONFIG_AT91RM9200DK	1 /* on an AT91RM9200DK Board    */
 #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
 #define CONFIG_CMDLINE_TAG	1 /* enable passing of ATAGs    */
@@ -166,7 +167,13 @@
 /* CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144 */
 #define CONFIG_SYS_MEMTEST_END	0x00100000
 
-#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
 #define CONFIG_NET_RETRY_COUNT	20
 #define CONFIG_AT91C_USE_RMII
 
diff --git a/include/configs/mp2usb.h b/include/configs/mp2usb.h
index 0c2ee60..31eb1b6 100644
--- a/include/configs/mp2usb.h
+++ b/include/configs/mp2usb.h
@@ -181,7 +181,13 @@
 #define CONFIG_SYS_MEMTEST_START	PHYS_SDRAM
 #define CONFIG_SYS_MEMTEST_END		CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
 
-#define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_MULTI		1
+#ifdef CONFIG_NET_MULTI
+#define CONFIG_DRIVER_AT91EMAC		1
+#define CONFIG_SYS_RX_ETH_BUFFER	8
+#else
+#define CONFIG_DRIVER_ETHER		1
+#endif
 #define CONFIG_NET_RETRY_COUNT		20
 #undef CONFIG_AT91C_USE_RMII
 
diff --git a/include/netdev.h b/include/netdev.h
index a9d5ec9..1dd80f0 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -42,6 +42,7 @@
 
 /* Driver initialization prototypes */
 int au1x00_enet_initialize(bd_t*);
+int at91emac_register(bd_t *bis, unsigned long iobase);
 int bfin_EMAC_initialize(bd_t *bis);
 int cs8900_initialize(u8 dev_num, int base_addr);
 int dc21x4x_initialize(bd_t *bis);
@@ -49,6 +50,7 @@
 int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr);
 int e1000_initialize(bd_t *bis);
 int eepro100_initialize(bd_t *bis);
+int ep93xx_eth_initialize(u8 dev_num, int base_addr);
 int eth_3com_initialize (bd_t * bis);
 int fec_initialize (bd_t *bis);
 int fecmxc_initialize (bd_t *bis);
diff --git a/include/tsec.h b/include/tsec.h
index f56723a..1e90365 100644
--- a/include/tsec.h
+++ b/include/tsec.h
@@ -153,6 +153,19 @@
 #define MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK	0x0700
 #define MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT	8
 
+#define MIIM_BCM54XX_SHD	0x1c	/* 0x1c shadow registers */
+#define MIIM_BCM54XX_SHD_WRITE	0x8000
+#define MIIM_BCM54XX_SHD_VAL(x)	((x & 0x1f) << 10)
+#define MIIM_BCM54XX_SHD_DATA(x)	((x & 0x3ff) << 0)
+#define MIIM_BCM54XX_SHD_WR_ENCODE(val, data)	\
+	(MIIM_BCM54XX_SHD_WRITE | MIIM_BCM54XX_SHD_VAL(val) | \
+	 MIIM_BCM54XX_SHD_DATA(data))
+
+#define MIIM_BCM54XX_EXP_DATA	0x15	/* Expansion register data */
+#define MIIM_BCM54XX_EXP_SEL	0x17	/* Expansion register select */
+#define MIIM_BCM54XX_EXP_SEL_SSD	0x0e00	/* Secondary SerDes select */
+#define MIIM_BCM54XX_EXP_SEL_ER	0x0f00	/* Expansion register select */
+
 /* Cicada Auxiliary Control/Status Register */
 #define MIIM_CIS8201_AUX_CONSTAT	0x1c
 #define MIIM_CIS8201_AUXCONSTAT_INIT	0x0004
@@ -571,9 +584,9 @@
 
 /* This flag currently only has
  * meaning if we're using the eTSEC */
-#define TSEC_REDUCED	(1 << 1)
-
-#define TSEC_SGMII	(1 << 2)
+#define TSEC_REDUCED	(1 << 1)	/* MAC-PHY interface uses RGMII */
+#define TSEC_SGMII	(1 << 2)	/* MAC-PHY interface uses SGMII */
+#define TSEC_FIBER	(1 << 3)	/* PHY uses fiber, eg 1000 Base-X */
 
 struct tsec_private {
 	volatile tsec_t *regs;
@@ -644,7 +657,6 @@
 	u32 flags;
 };
 
-int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info);
 int tsec_standard_init(bd_t *bis);
 int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsec_info, int num);