[U-Boot] [RFC PATCH 1/3] net: rework the mii support

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Wed Aug 26 22:13:01 CEST 2009


this rework is done in order to add a phylib and reduce and simplify
the implementation of multi net_device support for the same driver

precedently we pass the device name to the miiphy_read/write & co

now we pass the mii_device instance of the mii bus
all network driver are switch to this way

we currently keep the old miiphy api by wrapping it to the new mii_device
api until we have the phylib implementation and all the network driver
using it

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 board/Marvell/rd6281a/rd6281a.c                 |   18 +-
 board/Marvell/sheevaplug/sheevaplug.c           |   16 +-
 board/actux1/actux1.c                           |   15 +-
 board/actux2/actux2.c                           |    4 +-
 board/actux3/actux3.c                           |    9 +-
 board/actux4/actux4.c                           |    2 +-
 board/amcc/taishan/lcd.c                        |   52 +++--
 board/atum8548/atum8548.c                       |    2 +-
 board/csb272/csb272.c                           |   10 +-
 board/csb472/csb472.c                           |   10 +-
 board/ep82xxm/ep82xxm.c                         |    2 +-
 board/esd/common/misc.c                         |    7 +-
 board/esd/pmc440/pmc440.c                       |   24 +-
 board/evb64260/eth.c                            |   48 ++--
 board/freescale/mpc8260ads/mpc8260ads.c         |    2 +-
 board/freescale/mpc8323erdb/mpc8323erdb.c       |    2 +-
 board/freescale/mpc832xemds/mpc832xemds.c       |    2 +-
 board/freescale/mpc8349emds/mpc8349emds.c       |    2 +-
 board/freescale/mpc8349itx/mpc8349itx.c         |    2 +-
 board/freescale/mpc8360emds/mpc8360emds.c       |    2 +-
 board/freescale/mpc8360erdk/mpc8360erdk.c       |    2 +-
 board/freescale/mpc8536ds/mpc8536ds.c           |    2 +-
 board/freescale/mpc8544ds/mpc8544ds.c           |    2 +-
 board/freescale/mpc8548cds/mpc8548cds.c         |   23 +-
 board/freescale/mpc8560ads/mpc8560ads.c         |    2 +-
 board/freescale/mpc8572ds/mpc8572ds.c           |    2 +-
 board/freescale/p2020ds/p2020ds.c               |    2 +-
 board/funkwerk/vovpn-gw/m88e6060.c              |    2 +-
 board/funkwerk/vovpn-gw/vovpn-gw.c              |    5 +-
 board/keymile/kmeter1/kmeter1.c                 |    2 +-
 board/motionpro/motionpro.c                     |    7 +-
 board/mpl/mip405/mip405.c                       |    8 +-
 board/netphone/netphone.c                       |    6 +-
 board/netta/netta.c                             |    6 +-
 board/netta2/netta2.c                           |    6 +-
 board/pm856/pm856.c                             |    2 +-
 board/prodrive/alpr/alpr.c                      |   12 +-
 board/prodrive/p3mx/mv_eth.c                    |   62 +++--
 board/sbc8349/sbc8349.c                         |    2 +-
 board/sbc8548/sbc8548.c                         |    2 +-
 board/sbc8560/sbc8560.c                         |    2 +-
 board/stxgp3/stxgp3.c                           |    2 +-
 board/stxssa/stxssa.c                           |    2 +-
 board/stxxtc/stxxtc.c                           |   13 +-
 board/tqc/tqm834x/tqm834x.c                     |    2 +-
 board/tqc/tqm8xx/tqm8xx.c                       |   12 +-
 board/uc100/uc100.c                             |    2 +-
 board/zpc1900/zpc1900.c                         |    2 +-
 common/Makefile                                 |    2 -
 common/cmd_mii.c                                |   28 +-
 cpu/arm920t/at91rm9200/ether.c                  |   29 ++-
 cpu/arm920t/at91rm9200/lxt972.c                 |    2 +-
 cpu/arm926ejs/davinci/lxt972.c                  |    2 +-
 cpu/ixp/npe/include/npe.h                       |    8 +-
 cpu/ixp/npe/miiphy.c                            |   25 +-
 cpu/ixp/npe/npe.c                               |   29 ++-
 cpu/mips/au1x00_eth.c                           |   29 ++-
 cpu/mpc8220/fec.c                               |   65 +++--
 cpu/mpc8260/ether_fcc.c                         |   16 +-
 cpu/mpc85xx/ether_fcc.c                         |   16 +-
 cpu/mpc8xx/fec.c                                |   42 ++-
 cpu/ppc4xx/miiphy.c                             |   45 ++--
 drivers/net/4xx_enet.c                          |  109 +++++---
 drivers/net/bfin_mac.c                          |   39 ++-
 drivers/net/davinci_emac.c                      |   29 ++-
 drivers/net/dnet.c                              |    2 +-
 drivers/net/eepro100.c                          |   34 ++-
 drivers/net/fec_mxc.c                           |   55 +++--
 drivers/net/fsl_mcdmafec.c                      |   23 ++-
 drivers/net/kirkwood_egiga.c                    |   36 ++-
 drivers/net/kirkwood_egiga.h                    |    1 +
 drivers/net/mcffec.c                            |   23 ++-
 drivers/net/mcfmii.c                            |   29 +-
 drivers/net/mpc512x_fec.c                       |   56 ++--
 drivers/net/mpc5xxx_fec.c                       |   85 +++---
 drivers/net/ns7520_eth.c                        |   36 +--
 drivers/net/ns9750_eth.c                        |    2 +-
 drivers/net/phy/Makefile                        |    4 +-
 common/miiphyutil.c => drivers/net/phy/miidev.c |  352 ++++++++++-------------
 drivers/net/phy/miiphybb.c                      |   35 ++-
 drivers/net/phy/mv88e61xx.c                     |  123 ++++----
 drivers/net/phy/mv88e61xx.h                     |   10 +-
 drivers/net/smc911x.c                           |    2 +-
 drivers/net/tsec.c                              |   46 ++--
 drivers/net/uli526x.c                           |    2 +-
 drivers/qe/uec.c                                |   42 ++-
 drivers/qe/uec_phy.c                            |   10 +-
 include/linux/mii.h                             |    2 +
 include/miidev.h                                |   91 ++++++
 include/miiphy.h                                |   36 ---
 include/ns7520_eth.h                            |    2 +-
 include/ns9750_eth.h                            |    2 +-
 net/eth.c                                       |    6 +-
 net/net.c                                       |    2 +-
 94 files changed, 1198 insertions(+), 891 deletions(-)
 rename common/miiphyutil.c => drivers/net/phy/miidev.c (50%)
 create mode 100644 include/miidev.h

diff --git a/board/Marvell/rd6281a/rd6281a.c b/board/Marvell/rd6281a/rd6281a.c
index 8713a3c..2db116d 100644
--- a/board/Marvell/rd6281a/rd6281a.c
+++ b/board/Marvell/rd6281a/rd6281a.c
@@ -23,7 +23,7 @@
  */
 
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <netdev.h>
 #include <asm/arch/kirkwood.h>
 #include <asm/arch/mpp.h>
@@ -122,14 +122,16 @@ int dram_init(void)
 
 void mv_phy_88e1116_init(char *name)
 {
+	struct mii_device *dev;
 	u16 reg;
 	u16 devadr;
 
 	if (miiphy_set_current_dev(name))
 		return;
 
+	dev = mii_get_current_dev();
 	/* command to read PHY dev address */
-	if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
+	if (miiphy_read(dev, 0xEE, 0xEE, (u16 *) &devadr)) {
 		printf("Err..%s could not read PHY dev address\n",
 			__FUNCTION__);
 		return;
@@ -139,18 +141,18 @@ void mv_phy_88e1116_init(char *name)
 	 * Enable RGMII delay on Tx and Rx for CPU port
 	 * Ref: sec 4.7.2 of chip datasheet
 	 */
-	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
-	miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
+	miiphy_write(dev, devadr, MV88E1116_PGADR_REG, 2);
+	miiphy_read(dev, devadr, MV88E1116_MAC_CTRL_REG, &reg);
 	reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
-	miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
-	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+	miiphy_write(dev, devadr, MV88E1116_MAC_CTRL_REG, reg);
+	miiphy_write(dev, devadr, MV88E1116_PGADR_REG, 0);
 
 	/* reset the phy */
-	if (miiphy_read (name, devadr, PHY_BMCR, &reg) != 0) {
+	if (miiphy_read (dev, devadr, PHY_BMCR, &reg) != 0) {
 		printf("Err..(%s) PHY status read failed\n", __FUNCTION__);
 		return;
 	}
-	if (miiphy_write (name, devadr, PHY_BMCR, reg | 0x8000) != 0) {
+	if (miiphy_write (dev, devadr, PHY_BMCR, reg | 0x8000) != 0) {
 		printf("Err..(%s) PHY reset failed\n", __FUNCTION__);
 		return;
 	}
diff --git a/board/Marvell/sheevaplug/sheevaplug.c b/board/Marvell/sheevaplug/sheevaplug.c
index 547126a..b2865ff 100644
--- a/board/Marvell/sheevaplug/sheevaplug.c
+++ b/board/Marvell/sheevaplug/sheevaplug.c
@@ -23,7 +23,7 @@
  */
 
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm/arch/kirkwood.h>
 #include <asm/arch/mpp.h>
 #include "sheevaplug.h"
@@ -126,12 +126,14 @@ void reset_phy(void)
 	u16 reg;
 	u16 devadr;
 	char *name = "egiga0";
+	struct mii_device *dev;
 
 	if (miiphy_set_current_dev(name))
 		return;
 
+	dev = mii_get_current_dev();
 	/* command to read PHY dev address */
-	if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
+	if (miiphy_read(dev, 0xEE, 0xEE, (u16 *) &devadr)) {
 		printf("Err..%s could not read PHY dev address\n",
 			__FUNCTION__);
 		return;
@@ -141,14 +143,14 @@ void reset_phy(void)
 	 * Enable RGMII delay on Tx and Rx for CPU port
 	 * Ref: sec 4.7.2 of chip datasheet
 	 */
-	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
-	miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
+	miiphy_write(dev, devadr, MV88E1116_PGADR_REG, 2);
+	miiphy_read(dev, devadr, MV88E1116_MAC_CTRL_REG, &reg);
 	reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
-	miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
-	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+	miiphy_write(dev, devadr, MV88E1116_MAC_CTRL_REG, reg);
+	miiphy_write(dev, devadr, MV88E1116_PGADR_REG, 0);
 
 	/* reset the phy */
-	miiphy_reset(name, devadr);
+	miiphy_reset(dev, devadr);
 
 	printf("88E1116 Initialized on %s\n", name);
 }
diff --git a/board/actux1/actux1.c b/board/actux1/actux1.c
index 399be23..655fe04 100644
--- a/board/actux1/actux1.c
+++ b/board/actux1/actux1.c
@@ -36,7 +36,7 @@
 #include <malloc.h>
 #include <asm/arch/ixp425.h>
 #include <asm/io.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "actux1_hw.h"
 
@@ -136,12 +136,17 @@ void pci_init_board (void)
 void reset_phy (void)
 {
 	u16 id1, id2;
+	struct mii_device *dev;
+
+	dev = mii_get_by_name("NPE0");
+	if (!dev)
+		return;
 
 	/* initialize the PHY */
-	miiphy_reset ("NPE0", CONFIG_PHY_ADDR);
+	miiphy_reset (dev, CONFIG_PHY_ADDR);
 
-	miiphy_read ("NPE0", CONFIG_PHY_ADDR, PHY_PHYIDR1, &id1);
-	miiphy_read ("NPE0", CONFIG_PHY_ADDR, PHY_PHYIDR2, &id2);
+	miiphy_read (dev, CONFIG_PHY_ADDR, PHY_PHYIDR1, &id1);
+	miiphy_read (dev, CONFIG_PHY_ADDR, PHY_PHYIDR2, &id2);
 
 	id2 &= 0xFFF0;		/* mask out revision bits */
 
@@ -152,7 +157,7 @@ void reset_phy (void)
 		 * LED2 (unused) = LINK,
 		 * LED3(red) = Coll
 		 */
-		miiphy_write ("NPE0", CONFIG_PHY_ADDR, 20, 0xD432);
+		miiphy_write (dev, CONFIG_PHY_ADDR, 20, 0xD432);
 	} else if (id1 == 0x143 && id2 == 0xbc30) {
 		/* BCM5241: default values are OK */
 	} else
diff --git a/board/actux2/actux2.c b/board/actux2/actux2.c
index d6aaad6..94f8ebc 100644
--- a/board/actux2/actux2.c
+++ b/board/actux2/actux2.c
@@ -37,7 +37,7 @@
 #include <asm/arch/ixp425.h>
 #include <asm/io.h>
 
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "actux2_hw.h"
 
@@ -132,5 +132,5 @@ u32 get_board_rev (void)
 void reset_phy (void)
 {
 	/* init IcPlus IP175C ethernet switch to native IP175C mode */
-	miiphy_write ("NPE0", 29, 31, 0x175C);
+	miiphy_write (mii_get_by_name("NPE0"), 29, 31, 0x175C);
 }
diff --git a/board/actux3/actux3.c b/board/actux3/actux3.c
index 63bf365..e7fd0ac 100644
--- a/board/actux3/actux3.c
+++ b/board/actux3/actux3.c
@@ -37,7 +37,7 @@
 #include <asm/arch/ixp425.h>
 #include <asm/io.h>
 
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "actux3_hw.h"
 
@@ -147,18 +147,19 @@ int dram_init (void)
 void reset_phy (void)
 {
 	int i;
+	struct mii_device *dev = mii_get_by_name("NPE0");
 
 	/* initialize the PHY */
-	miiphy_reset ("NPE0", CONFIG_PHY_ADDR);
+	miiphy_reset (dev, CONFIG_PHY_ADDR);
 
 	/* all LED outputs = Link/Act */
-	miiphy_write ("NPE0", CONFIG_PHY_ADDR, 0x16, 0x0AAA);
+	miiphy_write (dev, CONFIG_PHY_ADDR, 0x16, 0x0AAA);
 
 	/*
 	 * The Marvell 88E6060 switch comes up with all ports disabled.
 	 * set all ethernet switch ports to forwarding state
 	*/
 	for (i = 1; i <= 5; i++)
-		miiphy_write ("NPE0", CONFIG_PHY_ADDR + 8 + i, 0x04, 0x03);
+		miiphy_write (dev, CONFIG_PHY_ADDR + 8 + i, 0x04, 0x03);
 
 }
diff --git a/board/actux4/actux4.c b/board/actux4/actux4.c
index f373b58..9821d32 100644
--- a/board/actux4/actux4.c
+++ b/board/actux4/actux4.c
@@ -36,7 +36,7 @@
 #include <malloc.h>
 #include <asm/arch/ixp425.h>
 
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "actux4_hw.h"
 
diff --git a/board/amcc/taishan/lcd.c b/board/amcc/taishan/lcd.c
index d432cc3..644d3ee 100644
--- a/board/amcc/taishan/lcd.c
+++ b/board/amcc/taishan/lcd.c
@@ -25,7 +25,7 @@
 #include <common.h>
 #include <command.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #ifdef CONFIG_TAISHAN
 
@@ -272,23 +272,30 @@ void set_phy_loopback_mode(void)
 {
 	char devemac2[32];
 	char devemac3[32];
+	struct mii_device *dev2;
+	struct mii_device *dev3;
 
 	sprintf(devemac2, "%s2", CONFIG_EMAC_DEV_NAME);
 	sprintf(devemac3, "%s3", CONFIG_EMAC_DEV_NAME);
+	dev2 = mii_get_by_name(devemac2);
+	dev3 = mii_get_by_name(devemac2);
+
+	if (!dev2 || !dev3)
+		return;
 
 #if 0
 	unsigned short reg_short;
 
-	miiphy_read(devemac2, 0x1, 1, &reg_short);
+	miiphy_read(dev2, 0x1, 1, &reg_short);
 	if (reg_short & 0x04) {
 		/*
 		 * printf("EMAC2 link up,do nothing\n");
 		 */
 	} else {
 		udelay(1000);
-		miiphy_write(devemac2, 0x1, 0, 0x6000);
+		miiphy_write(dev2, 0x1, 0, 0x6000);
 		udelay(1000);
-		miiphy_read(devemac2, 0x1, 0, &reg_short);
+		miiphy_read(dev2, 0x1, 0, &reg_short);
 		if (reg_short != 0x6000) {
 			printf
 			    ("\nEMAC2 error set LOOPBACK mode error,reg2[0]=%x\n",
@@ -296,16 +303,16 @@ void set_phy_loopback_mode(void)
 		}
 	}
 
-	miiphy_read(devemac3, 0x3, 1, &reg_short);
+	miiphy_read(dev3, 0x3, 1, &reg_short);
 	if (reg_short & 0x04) {
 		/*
 		 * printf("EMAC3 link up,do nothing\n");
 		 */
 	} else {
 		udelay(1000);
-		miiphy_write(devemac3, 0x3, 0, 0x6000);
+		miiphy_write(dev3, 0x3, 0, 0x6000);
 		udelay(1000);
-		miiphy_read(devemac3, 0x3, 0, &reg_short);
+		miiphy_read(dev3, 0x3, 0, &reg_short);
 		if (reg_short != 0x6000) {
 			printf
 			    ("\nEMAC3 error set LOOPBACK mode error,reg2[0]=%x\n",
@@ -314,9 +321,9 @@ void set_phy_loopback_mode(void)
 	}
 #else
 	/* Set PHY as LOOPBACK MODE, for Linux emac initializing */
-	miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0, 0x6000);
+	miiphy_write(dev2, CONFIG_PHY2_ADDR, 0, 0x6000);
 	udelay(1000);
-	miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0, 0x6000);
+	miiphy_write(dev3, CONFIG_PHY3_ADDR, 0, 0x6000);
 	udelay(1000);
 #endif	/* 0 */
 }
@@ -325,34 +332,41 @@ void set_phy_normal_mode(void)
 {
 	char devemac2[32];
 	char devemac3[32];
+	struct mii_device *dev2;
+	struct mii_device *dev3;
 	unsigned short reg_short;
 
 	sprintf(devemac2, "%s2", CONFIG_EMAC_DEV_NAME);
 	sprintf(devemac3, "%s3", CONFIG_EMAC_DEV_NAME);
+	dev2 = mii_get_by_name(devemac2);
+	dev3 = mii_get_by_name(devemac2);
+
+	if (!dev2 || !dev3)
+		return;
 
 	/* Set phy of EMAC2 */
-	miiphy_read(devemac2, CONFIG_PHY2_ADDR, 0x16, &reg_short);
+	miiphy_read(dev2, CONFIG_PHY2_ADDR, 0x16, &reg_short);
 	reg_short &= ~(0x7);
 	reg_short |= 0x6;	/* RGMII DLL Delay */
-	miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x16, reg_short);
+	miiphy_write(dev2, CONFIG_PHY2_ADDR, 0x16, reg_short);
 
-	miiphy_read(devemac2, CONFIG_PHY2_ADDR, 0x17, &reg_short);
+	miiphy_read(dev2, CONFIG_PHY2_ADDR, 0x17, &reg_short);
 	reg_short &= ~(0x40);
-	miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x17, reg_short);
+	miiphy_write(dev2, CONFIG_PHY2_ADDR, 0x17, reg_short);
 
-	miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x1c, 0x74f0);
+	miiphy_write(dev2, CONFIG_PHY2_ADDR, 0x1c, 0x74f0);
 
 	/* Set phy of EMAC3 */
-	miiphy_read(devemac3, CONFIG_PHY3_ADDR, 0x16, &reg_short);
+	miiphy_read(dev3, CONFIG_PHY3_ADDR, 0x16, &reg_short);
 	reg_short &= ~(0x7);
 	reg_short |= 0x6;	/* RGMII DLL Delay */
-	miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x16, reg_short);
+	miiphy_write(dev3, CONFIG_PHY3_ADDR, 0x16, reg_short);
 
-	miiphy_read(devemac3, CONFIG_PHY3_ADDR, 0x17, &reg_short);
+	miiphy_read(dev3, CONFIG_PHY3_ADDR, 0x17, &reg_short);
 	reg_short &= ~(0x40);
-	miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x17, reg_short);
+	miiphy_write(dev3, CONFIG_PHY3_ADDR, 0x17, reg_short);
 
-	miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x1c, 0x74f0);
+	miiphy_write(dev3, CONFIG_PHY3_ADDR, 0x1c, 0x74f0);
 }
 #endif	/* 0 - test only */
 
diff --git a/board/atum8548/atum8548.c b/board/atum8548/atum8548.c
index c8085c7..f536429 100644
--- a/board/atum8548/atum8548.c
+++ b/board/atum8548/atum8548.c
@@ -33,7 +33,7 @@
 #include <asm/io.h>
 #include <asm/mmu.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 
diff --git a/board/csb272/csb272.c b/board/csb272/csb272.c
index 11596d2..d3a830a 100644
--- a/board/csb272/csb272.c
+++ b/board/csb272/csb272.c
@@ -24,7 +24,7 @@
 #include <common.h>
 #include <asm/processor.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <ppc4xx_enet.h>
 
 void sdram_init(void);
@@ -172,15 +172,17 @@ phys_size_t initdram (int board_type)
  */
 int last_stage_init(void)
 {
+	struct mii_device *dev = mii_get_by_name("ppc_4xx_eth0");
+
 	/* initialize the PHY */
-	miiphy_reset("ppc_4xx_eth0", CONFIG_PHY_ADDR);
+	miiphy_reset(dev, CONFIG_PHY_ADDR);
 
 	/* AUTO neg */
-	miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, PHY_BMCR,
+	miiphy_write(dev, CONFIG_PHY_ADDR, PHY_BMCR,
 			PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
 
 	/* LEDs     */
-	miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, PHY_FCSCR, 0x0d08);
+	miiphy_write(dev, CONFIG_PHY_ADDR, PHY_FCSCR, 0x0d08);
 
 
 	return 0; /* success */
diff --git a/board/csb472/csb472.c b/board/csb472/csb472.c
index 9dc130e..9aaf3c5 100644
--- a/board/csb472/csb472.c
+++ b/board/csb472/csb472.c
@@ -24,7 +24,7 @@
 #include <common.h>
 #include <asm/processor.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <ppc4xx_enet.h>
 
 void sdram_init(void);
@@ -140,15 +140,17 @@ phys_size_t initdram (int board_type)
  */
 int last_stage_init(void)
 {
+	struct mii_device *dev = mii_get_by_name("ppc_4xx_eth0");
+
 	/* initialize the PHY */
-	miiphy_reset("ppc_4xx_eth0", CONFIG_PHY_ADDR);
+	miiphy_reset(dev, CONFIG_PHY_ADDR);
 
 	/* AUTO neg */
-	miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, PHY_BMCR,
+	miiphy_write(dev, CONFIG_PHY_ADDR, PHY_BMCR,
 			PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
 
 	/* LEDs     */
-	miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, PHY_FCSCR, 0x0d08);
+	miiphy_write(dev, CONFIG_PHY_ADDR, PHY_FCSCR, 0x0d08);
 
 	return 0; /* success */
 }
diff --git a/board/ep82xxm/ep82xxm.c b/board/ep82xxm/ep82xxm.c
index c1d6e91..9b0449a 100644
--- a/board/ep82xxm/ep82xxm.c
+++ b/board/ep82xxm/ep82xxm.c
@@ -30,7 +30,7 @@
 #ifdef CONFIG_PCI
 #include <pci.h>
 #endif
-#include <miiphy.h>
+#include <miidev.h>
 
 /*
  * I/O Port configuration table
diff --git a/board/esd/common/misc.c b/board/esd/common/misc.c
index 48b4b7c..20b2271 100644
--- a/board/esd/common/misc.c
+++ b/board/esd/common/misc.c
@@ -24,7 +24,7 @@
 #include <common.h>
 
 #ifdef CONFIG_LXT971_NO_SLEEP
-#include <miiphy.h>
+#include <miidev.h>
 #endif
 
 
@@ -32,9 +32,10 @@
 void lxt971_no_sleep(void)
 {
 	unsigned short reg;
+	struct mii_device *dev = mii_get_by_name("ppc_4xx_eth0");
 
-	miiphy_read("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, &reg);
+	miiphy_read(dev, CONFIG_PHY_ADDR, 0x10, &reg);
 	reg &= ~0x0040;                  /* disable sleep mode */
-	miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, reg);
+	miiphy_write(dev, CONFIG_PHY_ADDR, 0x10, reg);
 }
 #endif /* CONFIG_LXT971_NO_SLEEP */
diff --git a/board/esd/pmc440/pmc440.c b/board/esd/pmc440/pmc440.c
index f22a1c2..9ffb08e 100644
--- a/board/esd/pmc440/pmc440.c
+++ b/board/esd/pmc440/pmc440.c
@@ -36,7 +36,7 @@
 #include <command.h>
 #include <i2c.h>
 #ifdef CONFIG_RESET_PHY_R
-#include <miiphy.h>
+#include <miidev.h>
 #endif
 #include <serial.h>
 #include "fpga.h"
@@ -757,6 +757,8 @@ void reset_phy(void)
 {
 	char *s;
 	unsigned short val_method, val_behavior;
+	struct mii_device *dev0 = mii_get_by_name("ppc_4xx_eth0");
+	struct mii_device *dev1 = mii_get_by_name("ppc_4xx_eth1");
 
 	/* special LED setup for NGCC/CANDES */
 	if ((s = getenv("bd_type")) &&
@@ -769,18 +771,18 @@ void reset_phy(void)
 		val_behavior = 0x0cf0;
 	}
 
-	if (miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0001) == 0) {
-		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, 0x0010);
-		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, val_behavior);
-		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, val_method);
-		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0000);
+	if (miiphy_write(dev0, CONFIG_PHY_ADDR, 0x1f, 0x0001) == 0) {
+		miiphy_write(dev0, CONFIG_PHY_ADDR, 0x11, 0x0010);
+		miiphy_write(dev0, CONFIG_PHY_ADDR, 0x11, val_behavior);
+		miiphy_write(dev0, CONFIG_PHY_ADDR, 0x10, val_method);
+		miiphy_write(dev0, CONFIG_PHY_ADDR, 0x1f, 0x0000);
 	}
 
-	if (miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0001) == 0) {
-		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, 0x0010);
-		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, val_behavior);
-		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x10, val_method);
-		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0000);
+	if (miiphy_write(dev1, CONFIG_PHY1_ADDR, 0x1f, 0x0001) == 0) {
+		miiphy_write(dev1, CONFIG_PHY1_ADDR, 0x11, 0x0010);
+		miiphy_write(dev1, CONFIG_PHY1_ADDR, 0x11, val_behavior);
+		miiphy_write(dev1, CONFIG_PHY1_ADDR, 0x10, val_method);
+		miiphy_write(dev1, CONFIG_PHY1_ADDR, 0x1f, 0x0000);
 	}
 }
 #endif
diff --git a/board/evb64260/eth.c b/board/evb64260/eth.c
index ca8bab5..444ef78 100644
--- a/board/evb64260/eth.c
+++ b/board/evb64260/eth.c
@@ -25,7 +25,7 @@ Skeleton NIC driver for Etherboot
 #include <galileo/gt64260R.h>
 #include <galileo/core.h>
 #include <asm/cache.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <net.h>
 #include <netdev.h>
 
@@ -89,15 +89,12 @@ static const char ether_port_phy_addr[3]={4,5,6};
 /* MII PHY access routines are common for all i/f, use gal_ent0 */
 #define GT6426x_MII_DEVNAME	"gal_enet0"
 
-int gt6426x_miiphy_read(char *devname, unsigned char phy,
-		unsigned char reg, unsigned short *val);
+int gt6426x_miiphy_read(struct mii_device *dev, int phy, int reg);
 
-static inline unsigned short
-miiphy_read_ret(unsigned short phy, unsigned short reg)
+static inline unsigned short miiphy_read_ret(int phy, int reg)
 {
-    unsigned short val;
-    gt6426x_miiphy_read(GT6426x_MII_DEVNAME,phy,reg,&val);
-    return val;
+	return gt6426x_miiphy_read(mii_get_by_name(GT6426x_MII_DEVNAME),
+				   phy, reg);
 }
 
 
@@ -345,8 +342,7 @@ gt6426x_eth_disable(void *v)
 MII utilities - write: write to an MII register via SMI
 ***************************************************************************/
 int
-gt6426x_miiphy_write(char *devname, unsigned char phy,
-		unsigned char reg, unsigned short data)
+gt6426x_miiphy_write(struct mii_device *dev, int phy, int reg, int data)
 {
     unsigned int temp= (reg<<21) | (phy<<16) | data;
 
@@ -360,8 +356,7 @@ gt6426x_miiphy_write(char *devname, unsigned char phy,
 MII utilities - read: read from an MII register via SMI
 ***************************************************************************/
 int
-gt6426x_miiphy_read(char *devname, unsigned char phy,
-		unsigned char reg, unsigned short *val)
+gt6426x_miiphy_read(struct mii_device *dev, int phy, int reg)
 {
     unsigned int temp= (reg<<21) | (phy<<16) | 1<<26;
 
@@ -373,9 +368,7 @@ gt6426x_miiphy_read(char *devname, unsigned char phy,
 	temp=GTREGREAD(ETHERNET_SMI_REGISTER);
 	if(temp & (1<<27)) break;		/* wait for ReadValid */
     }
-    *val = temp & 0xffff;
-
-    return 0;
+    return temp & 0xffff;
 }
 
 #ifdef DEBUG
@@ -424,6 +417,7 @@ check_phy_state(struct eth_dev_s *p)
 {
 	int bmsr = miiphy_read_ret(ether_port_phy_addr[p->dev], PHY_BMSR);
 	int psr = GTREGREAD(ETHERNET0_PORT_STATUS_REGISTER + p->reg_base);
+	struct mii_device *mii_dev = mii_get_by_name(GT6426x_MII_DEVNAME);
 
 	if ((psr & 1<<3) && (bmsr & PHY_BMSR_LS)) {
 		int nego = miiphy_read_ret(ether_port_phy_addr[p->dev], PHY_ANAR) &
@@ -450,7 +444,7 @@ check_phy_state(struct eth_dev_s *p)
 		if ((psr & 0x3) != want) {
 			printf("MII: GT thinks %x, PHY thinks %x, restarting autoneg..\n",
 					psr & 0x3, want);
-			miiphy_write(GT6426x_MII_DEVNAME,ether_port_phy_addr[p->dev],0,
+			miiphy_write(mii_dev,ether_port_phy_addr[p->dev],0,
 					miiphy_read_ret(ether_port_phy_addr[p->dev],0) | (1<<9));
 			udelay(10000);	/* the EVB's GT takes a while to notice phy
 					   went down and up */
@@ -467,6 +461,7 @@ gt6426x_eth_probe(void *v, bd_t *bis)
 {
 	struct eth_device *wp = (struct eth_device *)v;
 	struct eth_dev_s *p = (struct eth_dev_s *)wp->priv;
+	struct mii_device *mii_dev = mii_get_by_name(GT6426x_MII_DEVNAME);
 	int dev = p->dev;
 	unsigned int reg_base = p->reg_base;
 	unsigned long temp;
@@ -496,7 +491,7 @@ gt6426x_eth_probe(void *v, bd_t *bis)
 	   led 2: 0xc=link/rxact
 	   led 3: 0x2=rxact (N/C)
 	   strch: 0,2=30 ms, enable */
-	miiphy_write(GT6426x_MII_DEVNAME,ether_port_phy_addr[p->dev], 20, 0x1c22);
+	miiphy_write(mii_dev,ether_port_phy_addr[p->dev], 20, 0x1c22);
 
 	/* 2.7ns port rise time */
 	/*miiphy_write(ether_port_phy_addr[p->dev], 30, 0x0<<10); */
@@ -669,6 +664,9 @@ void
 gt6426x_eth_initialize(bd_t *bis)
 {
 	struct eth_device *dev;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
 	struct eth_dev_s *p;
 	int devnum, x, temp;
 	char *s, *e, buf[64];
@@ -685,6 +683,15 @@ gt6426x_eth_initialize(bd_t *bis)
 			return;
 		}
 
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		mii_dev = calloc(sizeof(*mii_dev), 1);
+		if (!mii_dev) {
+			printf( "%s: gal_enet%d allocation failure, %s\n",
+					__FUNCTION__, devnum, "mii_device structure");
+			return;
+		}
+#endif
+
 		/* must be less than NAMESIZE (16) */
 		sprintf(dev->name, "gal_enet%d", devnum);
 
@@ -798,9 +805,12 @@ gt6426x_eth_initialize(bd_t *bis)
 
 
 		eth_register(dev);
+
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-		miiphy_register(dev->name,
-				gt6426x_miiphy_read, gt6426x_miiphy_write);
+		mii_dev->name = dev->name;
+		mii_dev->read = gt6426x_miiphy_read;
+		mii_dev->write = gt6426x_miiphy_write;
+		mii_register(mii_dev);
 #endif
 	}
 
diff --git a/board/freescale/mpc8260ads/mpc8260ads.c b/board/freescale/mpc8260ads/mpc8260ads.c
index 49a88bb..ed00a9b 100644
--- a/board/freescale/mpc8260ads/mpc8260ads.c
+++ b/board/freescale/mpc8260ads/mpc8260ads.c
@@ -42,7 +42,7 @@
 #include <asm/m8260_pci.h>
 #include <i2c.h>
 #include <spd.h>
-#include <miiphy.h>
+#include <miidev.h>
 #ifdef CONFIG_PCI
 #include <pci.h>
 #endif
diff --git a/board/freescale/mpc8323erdb/mpc8323erdb.c b/board/freescale/mpc8323erdb/mpc8323erdb.c
index 8680a19..bc396b9 100644
--- a/board/freescale/mpc8323erdb/mpc8323erdb.c
+++ b/board/freescale/mpc8323erdb/mpc8323erdb.c
@@ -13,7 +13,7 @@
 #include <ioports.h>
 #include <mpc83xx.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <command.h>
 #include <libfdt.h>
 #if defined(CONFIG_PCI)
diff --git a/board/freescale/mpc832xemds/mpc832xemds.c b/board/freescale/mpc832xemds/mpc832xemds.c
index d4d4479..ecc9e8a 100644
--- a/board/freescale/mpc832xemds/mpc832xemds.c
+++ b/board/freescale/mpc832xemds/mpc832xemds.c
@@ -16,7 +16,7 @@
 #include <ioports.h>
 #include <mpc83xx.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <command.h>
 #if defined(CONFIG_PCI)
 #include <pci.h>
diff --git a/board/freescale/mpc8349emds/mpc8349emds.c b/board/freescale/mpc8349emds/mpc8349emds.c
index 61d1249..ec0324e 100644
--- a/board/freescale/mpc8349emds/mpc8349emds.c
+++ b/board/freescale/mpc8349emds/mpc8349emds.c
@@ -28,7 +28,7 @@
 #include <asm/mpc8349_pci.h>
 #include <i2c.h>
 #include <spi.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <spd_sdram.h>
 
 #if defined(CONFIG_OF_LIBFDT)
diff --git a/board/freescale/mpc8349itx/mpc8349itx.c b/board/freescale/mpc8349itx/mpc8349itx.c
index 7da39f1..8b60441 100644
--- a/board/freescale/mpc8349itx/mpc8349itx.c
+++ b/board/freescale/mpc8349itx/mpc8349itx.c
@@ -24,7 +24,7 @@
 #include <ioports.h>
 #include <mpc83xx.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <vsc7385.h>
 #ifdef CONFIG_PCI
 #include <asm/mpc8349_pci.h>
diff --git a/board/freescale/mpc8360emds/mpc8360emds.c b/board/freescale/mpc8360emds/mpc8360emds.c
index dc4dbd3..0c6ef00 100644
--- a/board/freescale/mpc8360emds/mpc8360emds.c
+++ b/board/freescale/mpc8360emds/mpc8360emds.c
@@ -15,7 +15,7 @@
 #include <ioports.h>
 #include <mpc83xx.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #if defined(CONFIG_PCI)
 #include <pci.h>
 #endif
diff --git a/board/freescale/mpc8360erdk/mpc8360erdk.c b/board/freescale/mpc8360erdk/mpc8360erdk.c
index 3771878..293b2d7 100644
--- a/board/freescale/mpc8360erdk/mpc8360erdk.c
+++ b/board/freescale/mpc8360erdk/mpc8360erdk.c
@@ -18,7 +18,7 @@
 #include <ioports.h>
 #include <mpc83xx.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm/io.h>
 #include <asm/mmu.h>
 #include <pci.h>
diff --git a/board/freescale/mpc8536ds/mpc8536ds.c b/board/freescale/mpc8536ds/mpc8536ds.c
index 8c5984b..cda03ea 100644
--- a/board/freescale/mpc8536ds/mpc8536ds.c
+++ b/board/freescale/mpc8536ds/mpc8536ds.c
@@ -31,7 +31,7 @@
 #include <asm/fsl_ddr_sdram.h>
 #include <asm/io.h>
 #include <spd.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <spd_sdram.h>
 #include <fdt_support.h>
diff --git a/board/freescale/mpc8544ds/mpc8544ds.c b/board/freescale/mpc8544ds/mpc8544ds.c
index fd59839..1d0ddbb 100644
--- a/board/freescale/mpc8544ds/mpc8544ds.c
+++ b/board/freescale/mpc8544ds/mpc8544ds.c
@@ -29,7 +29,7 @@
 #include <asm/fsl_pci.h>
 #include <asm/fsl_ddr_sdram.h>
 #include <asm/io.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <tsec.h>
diff --git a/board/freescale/mpc8548cds/mpc8548cds.c b/board/freescale/mpc8548cds/mpc8548cds.c
index ac1c9b4..400c92d 100644
--- a/board/freescale/mpc8548cds/mpc8548cds.c
+++ b/board/freescale/mpc8548cds/mpc8548cds.c
@@ -30,7 +30,7 @@
 #include <asm/fsl_pci.h>
 #include <asm/fsl_ddr_sdram.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 
@@ -427,24 +427,25 @@ int last_stage_init(void)
 	/* This is needed to get the RGMII working for the 1.3+
 	 * CDS cards */
 	if (get_board_version() ==  0x13) {
-		miiphy_write(CONFIG_TSEC1_NAME,
-				TSEC1_PHY_ADDR, 29, 18);
+		struct mii_device *dev;
 
-		miiphy_read(CONFIG_TSEC1_NAME,
-				TSEC1_PHY_ADDR, 30, &temp);
+		dev = mii_get_by_name(CONFIG_TSEC1_NAME);
+		if (!dev)
+			return;
+
+		miiphy_write(dev, TSEC1_PHY_ADDR, 29, 18);
+
+		miiphy_read(dev, TSEC1_PHY_ADDR, 30, &temp);
 
 		temp = (temp & 0xf03f);
 		temp |= 2 << 9;		/* 36 ohm */
 		temp |= 2 << 6;		/* 39 ohm */
 
-		miiphy_write(CONFIG_TSEC1_NAME,
-				TSEC1_PHY_ADDR, 30, temp);
+		miiphy_write(dev, TSEC1_PHY_ADDR, 30, temp);
 
-		miiphy_write(CONFIG_TSEC1_NAME,
-				TSEC1_PHY_ADDR, 29, 3);
+		miiphy_write(dev, TSEC1_PHY_ADDR, 29, 3);
 
-		miiphy_write(CONFIG_TSEC1_NAME,
-				TSEC1_PHY_ADDR, 30, 0x8000);
+		miiphy_write(dev, TSEC1_PHY_ADDR, 30, 0x8000);
 	}
 
 	return 0;
diff --git a/board/freescale/mpc8560ads/mpc8560ads.c b/board/freescale/mpc8560ads/mpc8560ads.c
index 2bca0f2..d55d5f8 100644
--- a/board/freescale/mpc8560ads/mpc8560ads.c
+++ b/board/freescale/mpc8560ads/mpc8560ads.c
@@ -33,7 +33,7 @@
 #include <asm/fsl_ddr_sdram.h>
 #include <ioports.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <asm/fsl_lbc.h>
diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c
index 7c86134..a912f6c 100644
--- a/board/freescale/mpc8572ds/mpc8572ds.c
+++ b/board/freescale/mpc8572ds/mpc8572ds.c
@@ -30,7 +30,7 @@
 #include <asm/fsl_pci.h>
 #include <asm/fsl_ddr_sdram.h>
 #include <asm/io.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <tsec.h>
diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c
index 14de7e7..d090b53 100644
--- a/board/freescale/p2020ds/p2020ds.c
+++ b/board/freescale/p2020ds/p2020ds.c
@@ -30,7 +30,7 @@
 #include <asm/fsl_pci.h>
 #include <asm/fsl_ddr_sdram.h>
 #include <asm/io.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <tsec.h>
diff --git a/board/funkwerk/vovpn-gw/m88e6060.c b/board/funkwerk/vovpn-gw/m88e6060.c
index 58b5b6e..fac7e99 100644
--- a/board/funkwerk/vovpn-gw/m88e6060.c
+++ b/board/funkwerk/vovpn-gw/m88e6060.c
@@ -27,7 +27,7 @@
 #include <mpc8260.h>
 #include <asm/m8260_pci.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "m88e6060.h"
 
diff --git a/board/funkwerk/vovpn-gw/vovpn-gw.c b/board/funkwerk/vovpn-gw/vovpn-gw.c
index 8c4abdd..380a4dd 100644
--- a/board/funkwerk/vovpn-gw/vovpn-gw.c
+++ b/board/funkwerk/vovpn-gw/vovpn-gw.c
@@ -24,7 +24,7 @@
 #include <ioports.h>
 #include <mpc8260.h>
 #include <asm/m8260_pci.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "m88e6060.h"
 
@@ -187,6 +187,7 @@ void reset_phy (void)
 #if defined(CONFIG_CMD_NET)
 	int i;
 	unsigned short val;
+	struct mii_device *dev = mii_get_by_name("FCC1 ETHERNET");
 #endif
 
 	iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 0);
@@ -198,7 +199,7 @@ void reset_phy (void)
 	iop->pdat |= 0x00080000;
 	for (i=0; i<100; i++) {
 		udelay(20000);
-		if (bb_miiphy_read("FCC1 ETHERNET", CONFIG_SYS_PHY_ADDR,2,&val ) == 0) {
+		if (bb_miiphy_read(dev, CONFIG_SYS_PHY_ADDR,2,&val ) == 0) {
 			break;
 		}
 	}
diff --git a/board/keymile/kmeter1/kmeter1.c b/board/keymile/kmeter1/kmeter1.c
index fa2f1cf..03b3777 100644
--- a/board/keymile/kmeter1/kmeter1.c
+++ b/board/keymile/kmeter1/kmeter1.c
@@ -21,7 +21,7 @@
 #include <ioports.h>
 #include <mpc83xx.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm/io.h>
 #include <asm/mmu.h>
 #include <asm/processor.h>
diff --git a/board/motionpro/motionpro.c b/board/motionpro/motionpro.c
index b369219..01a36ed 100644
--- a/board/motionpro/motionpro.c
+++ b/board/motionpro/motionpro.c
@@ -28,7 +28,7 @@
 
 #include <common.h>
 #include <mpc5xxx.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 
 #if defined(CONFIG_STATUS_LED)
@@ -89,9 +89,10 @@ int board_early_init_r(void)
 void reset_phy(void)
 {
 	unsigned short mode_control;
+	struct mii_device *dev = mii_get_by_name("FEC ETHERNET");
 
-	miiphy_read("FEC ETHERNET", CONFIG_PHY_ADDR, 0x15, &mode_control);
-	miiphy_write("FEC ETHERNET", CONFIG_PHY_ADDR, 0x15,
+	miiphy_read(dev, CONFIG_PHY_ADDR, 0x15, &mode_control);
+	miiphy_write(dev, CONFIG_PHY_ADDR, 0x15,
 			mode_control & 0xfffe);
 	return;
 }
diff --git a/board/mpl/mip405/mip405.c b/board/mpl/mip405/mip405.c
index 1738f54..b94c8ce 100644
--- a/board/mpl/mip405/mip405.c
+++ b/board/mpl/mip405/mip405.c
@@ -66,7 +66,7 @@
 #include "mip405.h"
 #include <asm/processor.h>
 #include <4xx_i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include "../common/common_util.h"
 #include <stdio_dev.h>
 #include <i2c.h>
@@ -725,14 +725,16 @@ int last_stage_init (void)
 	unsigned long stop;
 	struct rtc_time newtm;
 	char *s;
+	struct mii_device *dev = mii_get_by_name("ppc_4xx_eth0");
+
 	mem_test_reloc();
 	/* write correct LED configuration */
-	if (miiphy_write("ppc_4xx_eth0", 0x1, 0x14, 0x2402) != 0) {
+	if (miiphy_write(dev, 0x1, 0x14, 0x2402) != 0) {
 		printf ("Error writing to the PHY\n");
 	}
 	/* since LED/CFG2 is not connected on the -2,
 	 * write to correct capability information */
-	if (miiphy_write("ppc_4xx_eth0", 0x1, 0x4, 0x01E1) != 0) {
+	if (miiphy_write(dev, 0x1, 0x4, 0x01E1) != 0) {
 		printf ("Error writing to the PHY\n");
 	}
 	print_mip405_rev ();
diff --git a/board/netphone/netphone.c b/board/netphone/netphone.c
index ce5f051..60770fd 100644
--- a/board/netphone/netphone.c
+++ b/board/netphone/netphone.c
@@ -28,7 +28,7 @@
  */
 
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <sed156x.h>
 #include <status_led.h>
 
@@ -38,9 +38,9 @@
 #include <watchdog.h>
 #endif
 
-int fec8xx_miiphy_read(char *devname, unsigned char addr,
+int fec8xx_miiphy_read(struct mii_device *dev, unsigned char addr,
 		unsigned char  reg, unsigned short *value);
-int fec8xx_miiphy_write(char *devname, unsigned char  addr,
+int fec8xx_miiphy_write(struct mii_device *dev, unsigned char  addr,
 		unsigned char  reg, unsigned short value);
 
 /****************************************************************/
diff --git a/board/netta/netta.c b/board/netta/netta.c
index 38c9d89..e52c8f6 100644
--- a/board/netta/netta.c
+++ b/board/netta/netta.c
@@ -27,7 +27,7 @@
  */
 
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "mpc8xx.h"
 
@@ -35,9 +35,9 @@
 #include <watchdog.h>
 #endif
 
-int fec8xx_miiphy_read(char *devname, unsigned char addr,
+int fec8xx_miiphy_read(struct mii_device *dev, unsigned char addr,
 		unsigned char  reg, unsigned short *value);
-int fec8xx_miiphy_write(char *devname, unsigned char  addr,
+int fec8xx_miiphy_write(struct mii_device *dev, unsigned char  addr,
 		unsigned char  reg, unsigned short value);
 
 /****************************************************************/
diff --git a/board/netta2/netta2.c b/board/netta2/netta2.c
index 3b0191d..d19cfb3 100644
--- a/board/netta2/netta2.c
+++ b/board/netta2/netta2.c
@@ -28,7 +28,7 @@
  */
 
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "mpc8xx.h"
 
@@ -36,9 +36,9 @@
 #include <watchdog.h>
 #endif
 
-int fec8xx_miiphy_read(char *devname, unsigned char addr,
+int fec8xx_miiphy_read(struct mii_device *dev, unsigned char addr,
 		unsigned char  reg, unsigned short *value);
-int fec8xx_miiphy_write(char *devname, unsigned char  addr,
+int fec8xx_miiphy_write(struct mii_device *dev, unsigned char  addr,
 		unsigned char  reg, unsigned short value);
 
 /****************************************************************/
diff --git a/board/pm856/pm856.c b/board/pm856/pm856.c
index b14a3d3..8e5bc3b 100644
--- a/board/pm856/pm856.c
+++ b/board/pm856/pm856.c
@@ -33,7 +33,7 @@
 #include <asm/fsl_ddr_sdram.h>
 #include <ioports.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <netdev.h>
 
 #if defined(CONFIG_DDR_ECC)
diff --git a/board/prodrive/alpr/alpr.c b/board/prodrive/alpr/alpr.c
index dc34319..83e50fa 100644
--- a/board/prodrive/alpr/alpr.c
+++ b/board/prodrive/alpr/alpr.c
@@ -27,7 +27,7 @@
 #include <fdt_support.h>
 #include <spd_sdram.h>
 #include <ppc4xx_enet.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm/processor.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -104,6 +104,8 @@ int board_early_init_f (void)
 int last_stage_init(void)
 {
 	unsigned short reg;
+	struct mii_device *dev_eth2 = mii_get_by_name("ppc_4xx_eth2");
+	struct mii_device *dev_eth3 = mii_get_by_name("ppc_4xx_eth3");
 
 	/*
 	 * Configure LED's of both Marvell 88E1111 PHY's
@@ -111,12 +113,12 @@ int last_stage_init(void)
 	 * This has to be done after the 4xx ethernet driver is loaded,
 	 * so "last_stage_init()" is the right place.
 	 */
-	miiphy_read("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, &reg);
+	miiphy_read(dev_eth2, CONFIG_PHY2_ADDR, 0x18, &reg);
 	reg |= 0x0001;
-	miiphy_write("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, reg);
-	miiphy_read("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, &reg);
+	miiphy_write(dev_eth2, CONFIG_PHY2_ADDR, 0x18, reg);
+	miiphy_read(dev_eth3, CONFIG_PHY3_ADDR, 0x18, &reg);
 	reg |= 0x0001;
-	miiphy_write("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, reg);
+	miiphy_write(dev_eth3, CONFIG_PHY3_ADDR, 0x18, reg);
 
 	return 0;
 }
diff --git a/board/prodrive/p3mx/mv_eth.c b/board/prodrive/p3mx/mv_eth.c
index 8203b3c..5385d91 100644
--- a/board/prodrive/p3mx/mv_eth.c
+++ b/board/prodrive/p3mx/mv_eth.c
@@ -30,7 +30,7 @@
 #include <common.h>
 #include <net.h>
 #include <malloc.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "mv_eth.h"
 
@@ -99,12 +99,10 @@ int mv64460_eth_receive (struct eth_device *dev);
 
 int mv64460_eth_xmit (struct eth_device *, volatile void *packet, int length);
 
-int mv_miiphy_read(char *devname, unsigned char phy_addr,
-		   unsigned char phy_reg, unsigned short *value);
-int mv_miiphy_write(char *devname, unsigned char phy_addr,
-		    unsigned char phy_reg, unsigned short value);
+int mv_miiphy_read(struct mii_device *dev, int phy_addr, int phy_reg);
+int mv_miiphy_write(struct mii_device *dev, int phy_addr, int phy_reg, int value);
 
-int phy_setup_aneg (char *devname, unsigned char addr);
+int phy_setup_aneg (struct mii_device *dev, unsigned char addr);
 
 #ifndef	 UPDATE_STATS_BY_SOFTWARE
 static void mv64460_eth_print_stat (struct eth_device *dev);
@@ -252,6 +250,7 @@ void mv_eth_phy_init (void)
 void mv6446x_eth_initialize (bd_t * bis)
 {
 	struct eth_device *dev;
+	struct mii_device *mii_dev;
 	ETH_PORT_INFO *ethernet_private;
 	struct mv64460_eth_priv *port_private;
 	int devnum, x, temp;
@@ -274,6 +273,13 @@ void mv6446x_eth_initialize (bd_t * bis)
 			return;
 		}
 
+		mii_dev = calloc (sizeof (*mii_dev), 1);
+		if (!mii_dev) {
+			printf ("%s: mv_enet%d allocation failure, %s\n",
+				__FUNCTION__, devnum, "mii_device structure");
+			return;
+		}
+
 		/* must be less than NAMESIZE (16) */
 		sprintf (dev->name, "mv_enet%d", devnum);
 
@@ -435,7 +441,10 @@ void mv6446x_eth_initialize (bd_t * bis)
 #endif
 		eth_register (dev);
 
-		miiphy_register(dev->name, mv_miiphy_read, mv_miiphy_write);
+		mii_dev->name = dev->name;
+		mii_dev->read = mv_miiphy_read;
+		mii_dev->write = mv_miiphy_write;
+		mii_register(mii_dev);
 	}
 	DP (printf ("%s: exit\n", __FUNCTION__));
 
@@ -474,6 +483,7 @@ static int mv64460_eth_real_open (struct eth_device *dev)
 	int duplex;
 	int i;
 	int reg;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 	ethernet_private = (ETH_PORT_INFO *) dev->priv;
 	/* ronen - when we update the MAC env params we only update dev->enetaddr
@@ -581,12 +591,12 @@ static int mv64460_eth_real_open (struct eth_device *dev)
 		ethernet_phy_reset (port_num);
 
 		/* Start/Restart autonegotiation */
-		phy_setup_aneg (dev->name, reg);
+		phy_setup_aneg (mii_dev, reg);
 		udelay (1000);
 	}
 #endif /* defined(CONFIG_PHY_RESET) */
 
-	miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);
+	miiphy_read (mii_dev, reg, PHY_BMSR, &reg_short);
 
 	/*
 	 * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
@@ -608,15 +618,15 @@ static int mv64460_eth_real_open (struct eth_device *dev)
 				putc ('.');
 			}
 			udelay (1000);	/* 1 ms */
-			miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);
+			miiphy_read (mii_dev, reg, PHY_BMSR, &reg_short);
 
 		}
 		puts (" done\n");
 		udelay (500000);	/* another 500 ms (results in faster booting) */
 	}
 
-	speed = miiphy_speed (dev->name, reg);
-	duplex = miiphy_duplex (dev->name, reg);
+	speed = miiphy_speed (mii_dev, reg);
+	duplex = miiphy_duplex (mii_dev, reg);
 
 	printf ("ENET Speed is %d Mbps - %s duplex connection\n",
 		(int) speed, (duplex == HALF) ? "HALF" : "FULL");
@@ -2236,25 +2246,25 @@ static int ethernet_phy_get (ETH_PORT eth_port_num)
 /***********************************************************/
 /* (Re)start autonegotiation				   */
 /***********************************************************/
-int phy_setup_aneg (char *devname, unsigned char addr)
+int phy_setup_aneg (struct mii_device *dev, unsigned char addr)
 {
 	unsigned short ctl, adv;
 
 	/* Setup standard advertise */
-	miiphy_read (devname, addr, PHY_ANAR, &adv);
+	miiphy_read (dev, addr, PHY_ANAR, &adv);
 	adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 |
 		PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
 		PHY_ANLPAR_10);
-	miiphy_write (devname, addr, PHY_ANAR, adv);
+	miiphy_write (dev, addr, PHY_ANAR, adv);
 
-	miiphy_read (devname, addr, PHY_1000BTCR, &adv);
+	miiphy_read (dev, addr, PHY_1000BTCR, &adv);
 	adv |= (0x0300);
-	miiphy_write (devname, addr, PHY_1000BTCR, adv);
+	miiphy_write (dev, addr, PHY_1000BTCR, adv);
 
 	/* Start/Restart aneg */
-	miiphy_read (devname, addr, PHY_BMCR, &ctl);
+	miiphy_read (dev, addr, PHY_BMCR, &ctl);
 	ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
-	miiphy_write (devname, addr, PHY_BMCR, ctl);
+	miiphy_write (dev, addr, PHY_BMCR, ctl);
 
 	return 0;
 }
@@ -2544,8 +2554,7 @@ static bool eth_port_read_smi_reg (ETH_PORT eth_port_num,
 	return true;
 }
 
-int mv_miiphy_read(char *devname, unsigned char phy_addr,
-		   unsigned char phy_reg, unsigned short *value)
+int mv_miiphy_read(struct mii_device *dev, int phy_addr, int phy_reg)
 {
 	unsigned int reg_value;
 	unsigned int time_out = PHY_BUSY_TIMEOUT;
@@ -2554,7 +2563,7 @@ int mv_miiphy_read(char *devname, unsigned char phy_addr,
 	do {
 		reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
 		if (time_out-- == 0) {
-			return false;
+			return -1;
 		}
 	}
 	while (reg_value & ETH_SMI_BUSY);
@@ -2569,7 +2578,7 @@ int mv_miiphy_read(char *devname, unsigned char phy_addr,
 	do {
 		reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
 		if (time_out-- == 0) {
-			return false;
+			return -1;
 		}
 	}
 	while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
@@ -2579,9 +2588,7 @@ int mv_miiphy_read(char *devname, unsigned char phy_addr,
 
 	reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
 
-	*value = reg_value & 0xffff;
-
-	return 0;
+	return reg_value & 0xffff;
 }
 
 /*******************************************************************************
@@ -2629,8 +2636,7 @@ static bool eth_port_write_smi_reg (ETH_PORT eth_port_num,
 	return true;
 }
 
-int mv_miiphy_write(char *devname, unsigned char phy_addr,
-		    unsigned char phy_reg, unsigned short value)
+int mv_miiphy_write(struct mii_device *dev, int phy_addr,int phy_reg, int value)
 {
 	unsigned int reg_value;
 	unsigned int time_out = PHY_BUSY_TIMEOUT;
diff --git a/board/sbc8349/sbc8349.c b/board/sbc8349/sbc8349.c
index 34861d4..fca3bf5 100644
--- a/board/sbc8349/sbc8349.c
+++ b/board/sbc8349/sbc8349.c
@@ -31,7 +31,7 @@
 #include <asm/mpc8349_pci.h>
 #include <i2c.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #if defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
 #endif
diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c
index 9c05c2f..3b0df99 100644
--- a/board/sbc8548/sbc8548.c
+++ b/board/sbc8548/sbc8548.c
@@ -32,7 +32,7 @@
 #include <asm/fsl_pci.h>
 #include <asm/fsl_ddr_sdram.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 
diff --git a/board/sbc8560/sbc8560.c b/board/sbc8560/sbc8560.c
index c40b5e3..87a0205 100644
--- a/board/sbc8560/sbc8560.c
+++ b/board/sbc8560/sbc8560.c
@@ -34,7 +34,7 @@
 #include <asm/fsl_ddr_sdram.h>
 #include <ioports.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 
diff --git a/board/stxgp3/stxgp3.c b/board/stxgp3/stxgp3.c
index 3804fe0..2eff40d 100644
--- a/board/stxgp3/stxgp3.c
+++ b/board/stxgp3/stxgp3.c
@@ -38,7 +38,7 @@
 #include <ioports.h>
 #include <asm/io.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 long int fixed_sdram (void);
 
diff --git a/board/stxssa/stxssa.c b/board/stxssa/stxssa.c
index 73dddf3..43984cb 100644
--- a/board/stxssa/stxssa.c
+++ b/board/stxssa/stxssa.c
@@ -38,7 +38,7 @@
 #include <ioports.h>
 #include <asm/io.h>
 #include <spd_sdram.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <netdev.h>
 
 long int fixed_sdram (void);
diff --git a/board/stxxtc/stxxtc.c b/board/stxxtc/stxxtc.c
index 717dbe2..4448675 100644
--- a/board/stxxtc/stxxtc.c
+++ b/board/stxxtc/stxxtc.c
@@ -30,7 +30,7 @@
  */
 
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "mpc8xx.h"
 
@@ -475,18 +475,23 @@ void reset_phys(void)
 {
 	int phyno;
 	unsigned short v;
+	struct mii_device *dev;
 
 	udelay(10000);
 	/* reset the damn phys */
 	mii_init();
 
+	dev = mii_get_by_name("FEC ETHERNET");
+	if (!dev)
+		return;
+
 	for (phyno = 0; phyno < 32; ++phyno) {
-		miiphy_read("FEC ETHERNET", phyno, PHY_PHYIDR1, &v);
+		miiphy_read(dev, phyno, PHY_PHYIDR1, &v);
 		if (v == 0xFFFF)
 			continue;
-		miiphy_write("FEC ETHERNET", phyno, PHY_BMCR, PHY_BMCR_POWD);
+		miiphy_write(dev, phyno, PHY_BMCR, PHY_BMCR_POWD);
 		udelay(10000);
-		miiphy_write("FEC ETHERNET", phyno, PHY_BMCR, PHY_BMCR_RESET | PHY_BMCR_AUTON);
+		miiphy_write(dev, phyno, PHY_BMCR, PHY_BMCR_RESET | PHY_BMCR_AUTON);
 		udelay(10000);
 	}
 }
diff --git a/board/tqc/tqm834x/tqm834x.c b/board/tqc/tqm834x/tqm834x.c
index 4fd8cd6..cfd32a4 100644
--- a/board/tqc/tqm834x/tqm834x.c
+++ b/board/tqc/tqm834x/tqm834x.c
@@ -27,7 +27,7 @@
 #include <mpc83xx.h>
 #include <asm/mpc8349_pci.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm-ppc/mmu.h>
 #include <pci.h>
 
diff --git a/board/tqc/tqm8xx/tqm8xx.c b/board/tqc/tqm8xx/tqm8xx.c
index f92c598..d8835fe 100644
--- a/board/tqc/tqm8xx/tqm8xx.c
+++ b/board/tqc/tqm8xx/tqm8xx.c
@@ -603,15 +603,21 @@ void lcd_show_board_info(void)
 /* TK885D specific initializaion						*/
 /* ---------------------------------------------------------------------------- */
 #ifdef CONFIG_TK885D
-#include <miiphy.h>
+#include <miidev.h>
 int last_stage_init(void)
 {
 	const unsigned char phy[] = {CONFIG_FEC1_PHY, CONFIG_FEC2_PHY};
 	unsigned short reg;
 	int ret, i = 100;
 	char *s;
+	struct mii_device *dev;
 
 	mii_init();
+
+	dev = mii_get_by_name("FEC ETHERNET");
+	if (!dev)
+		return;
+
 	/* Without this delay 0xff is read from the UART buffer later in
 	 * abortboot() and autoboot is aborted */
 	udelay(10000);
@@ -626,13 +632,13 @@ int last_stage_init(void)
 		return 0;
 
 	for (i = 0; i < 2; i++) {
-		ret = miiphy_read("FEC ETHERNET", phy[i], PHY_BMCR, &reg);
+		ret = miiphy_read(dev, phy[i], PHY_BMCR, &reg);
 		if (ret) {
 			printf("Cannot read BMCR on PHY %d\n", phy[i]);
 			return 0;
 		}
 		/* Auto-negotiation off, hard set full duplex, 100Mbps */
-		ret = miiphy_write("FEC ETHERNET", phy[i],
+		ret = miiphy_write(dev, phy[i],
 				   PHY_BMCR, (reg | PHY_BMCR_100MB |
 					      PHY_BMCR_DPLX) & ~PHY_BMCR_AUTON);
 		if (ret) {
diff --git a/board/uc100/uc100.c b/board/uc100/uc100.c
index 38c7be6..d80f1ef 100644
--- a/board/uc100/uc100.c
+++ b/board/uc100/uc100.c
@@ -28,7 +28,7 @@
 #include <common.h>
 #include <mpc8xx.h>
 #include <i2c.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 int fec8xx_miiphy_write(char *devname, unsigned char  addr,
 		unsigned char  reg, unsigned short value);
diff --git a/board/zpc1900/zpc1900.c b/board/zpc1900/zpc1900.c
index 027d566..be85abd 100644
--- a/board/zpc1900/zpc1900.c
+++ b/board/zpc1900/zpc1900.c
@@ -27,7 +27,7 @@
 #include <common.h>
 #include <ioports.h>
 #include <mpc8260.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 /*
  * I/O Port configuration table
diff --git a/common/Makefile b/common/Makefile
index 3781738..810ebc4 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -109,8 +109,6 @@ COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o
 COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o
 COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
 COBJS-$(CONFIG_CMD_MG_DISK) += cmd_mgdisk.o
-COBJS-$(CONFIG_MII) += miiphyutil.o
-COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
diff --git a/common/cmd_mii.c b/common/cmd_mii.c
index 65e13c3..b1f07ae 100644
--- a/common/cmd_mii.c
+++ b/common/cmd_mii.c
@@ -27,7 +27,7 @@
 
 #include <common.h>
 #include <command.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 typedef struct _MII_reg_desc_t {
 	ushort regno;
@@ -221,14 +221,14 @@ static int special_field(
 	ushort regval)
 {
 	if ((regno == 0) && (pdesc->lo == 6)) {
-		ushort speed_bits = regval & PHY_BMCR_SPEED_MASK;
+		ushort speed_bits = regval & BMCR_SPEED_MASK;
 		printf("%2u,%2u =   b%u%u    speed selection = %s Mbps",
 			6, 13,
 			(regval >>  6) & 1,
 			(regval >> 13) & 1,
-			speed_bits == PHY_BMCR_1000_MBPS ? "1000" :
-			speed_bits == PHY_BMCR_100_MBPS  ? "100" :
-			speed_bits == PHY_BMCR_10_MBPS   ? "10" :
+			speed_bits == BMCR_SPEED1000 ? "1000" :
+			speed_bits == BMCR_SPEED100  ? "100" :
+			speed_bits == BMCR_SPEED10   ? "10" :
 			"???");
 		return 1;
 	}
@@ -299,7 +299,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	unsigned char	addr, reg;
 	unsigned short	data;
 	int		rcode = 0;
-	char		*devname;
+	struct mii_device *dev;
 
 	if (argc < 2) {
 		cmd_usage(cmdtp);
@@ -338,7 +338,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	}
 
 	/* use current device */
-	devname = miiphy_get_current_dev();
+	dev = mii_get_current_dev();
 
 	/*
 	 * check info/read/write.
@@ -359,17 +359,17 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		}
 
 		for (j = start; j <= end; j++) {
-			if (miiphy_info (devname, j, &oui, &model, &rev) == 0) {
+			if (miiphy_info (dev, j, &oui, &model, &rev) == 0) {
 				printf("PHY 0x%02X: "
 					"OUI = 0x%04X, "
 					"Model = 0x%02X, "
 					"Rev = 0x%02X, "
 					"%3dbase%s, %s\n",
 					j, oui, model, rev,
-					miiphy_speed (devname, j),
-					miiphy_is_1000base_x (devname, j)
+					miiphy_speed (dev, j),
+					miiphy_is_1000base_x (dev, j)
 						? "X" : "T",
-					(miiphy_duplex (devname, j) == FULL)
+					(miiphy_duplex (dev, j) == FULL)
 						? "FDX" : "HDX");
 			}
 		}
@@ -377,7 +377,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		for (addr = addrlo; addr <= addrhi; addr++) {
 			for (reg = reglo; reg <= reghi; reg++) {
 				data = 0xffff;
-				if (miiphy_read (devname, addr, reg, &data) != 0) {
+				if (miiphy_read (dev, addr, reg, &data) != 0) {
 					printf(
 					"Error reading from the PHY addr=%02x reg=%02x\n",
 						addr, reg);
@@ -395,7 +395,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	} else if (op[0] == 'w') {
 		for (addr = addrlo; addr <= addrhi; addr++) {
 			for (reg = reglo; reg <= reghi; reg++) {
-				if (miiphy_write (devname, addr, reg, data) != 0) {
+				if (miiphy_write (dev, addr, reg, data) != 0) {
 					printf("Error writing to the PHY addr=%02x reg=%02x\n",
 						addr, reg);
 					rcode = 1;
@@ -413,7 +413,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		}
 		for (addr = addrlo; addr <= addrhi; addr++) {
 			for (reg = reglo; reg < reghi + 1; reg++) {
-				if (miiphy_read(devname, addr, reg, &regs[reg]) != 0) {
+				if (miiphy_read(dev, addr, reg, &regs[reg]) != 0) {
 					ok = 0;
 					printf(
 					"Error reading from the PHY addr=%02x reg=%02x\n",
diff --git a/cpu/arm920t/at91rm9200/ether.c b/cpu/arm920t/at91rm9200/ether.c
index 91eab95..5500758 100644
--- a/cpu/arm920t/at91rm9200/ether.c
+++ b/cpu/arm920t/at91rm9200/ether.c
@@ -23,7 +23,8 @@
 
 #include <at91rm9200_net.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
+#include <malloc.h>
 #include <asm/mach-types.h>
 
 /* ----- Ethernet Buffer definitions ----- */
@@ -283,30 +284,40 @@ void eth_halt (void)
 };
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-int  at91rm9200_miiphy_read(char *devname, unsigned char addr,
-		unsigned char reg, unsigned short * value)
+int at91rm9200_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
+	unsigned short value;
+
 	at91rm9200_EmacEnableMDIO (p_mac);
-	at91rm9200_EmacReadPhy (p_mac, reg, value);
+	at91rm9200_EmacReadPhy (p_mac, reg, &value);
 	at91rm9200_EmacDisableMDIO (p_mac);
-	return 0;
+
+	return value;
 }
 
-int  at91rm9200_miiphy_write(char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value)
+int at91rm9200_miiphy_write(struct mii_device *dev, int addr, int reg, int val)
 {
+	unsigned short value = val;
+
 	at91rm9200_EmacEnableMDIO (p_mac);
 	at91rm9200_EmacWritePhy (p_mac, reg, &value);
 	at91rm9200_EmacDisableMDIO (p_mac);
 	return 0;
 }
-
 #endif
 
 int at91rm9200_miiphy_initialize(bd_t *bis)
 {
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	miiphy_register("at91rm9200phy", at91rm9200_miiphy_read, at91rm9200_miiphy_write);
+	struct mii_device *mii_dev;
+
+	mii_dev = calloc(1, sizeof (struct mii_device));
+
+	mii_dev->name = "at91rm9200phy";
+	mii_dev->read = at91rm9200_miiphy_read;
+	mii_dev->write = at91rm9200_miiphy_write;
+
+	mii_register(mii_dev);
 #endif
 	return 0;
 }
diff --git a/cpu/arm920t/at91rm9200/lxt972.c b/cpu/arm920t/at91rm9200/lxt972.c
index 260d393..a9f66f6 100644
--- a/cpu/arm920t/at91rm9200/lxt972.c
+++ b/cpu/arm920t/at91rm9200/lxt972.c
@@ -29,7 +29,7 @@
 #include <common.h>
 #include <at91rm9200_net.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <lxt971a.h>
 
 #ifdef CONFIG_DRIVER_ETHER
diff --git a/cpu/arm926ejs/davinci/lxt972.c b/cpu/arm926ejs/davinci/lxt972.c
index ce3e41c..9e3a3eb 100644
--- a/cpu/arm926ejs/davinci/lxt972.c
+++ b/cpu/arm926ejs/davinci/lxt972.c
@@ -27,7 +27,7 @@
 
 #include <common.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <lxt971a.h>
 #include <asm/arch/emac_defs.h>
 
diff --git a/cpu/ixp/npe/include/npe.h b/cpu/ixp/npe/include/npe.h
index 3d6f727..0f046e8 100644
--- a/cpu/ixp/npe/include/npe.h
+++ b/cpu/ixp/npe/include/npe.h
@@ -24,6 +24,8 @@
 #ifndef NPE_H
 #define NPE_H
 
+#include <miidev.h>
+
 /*
  * defines...
  */
@@ -82,9 +84,7 @@ struct npe {
 /*
  * prototypes...
  */
-extern int npe_miiphy_read (char *devname, unsigned char addr,
-			    unsigned char reg, unsigned short *value);
-extern int npe_miiphy_write (char *devname, unsigned char addr,
-			     unsigned char reg, unsigned short value);
+extern int npe_miiphy_read (struct mii_device *dev, int addr, int reg);
+extern int npe_miiphy_write (struct mii_device *dev, int addr, int reg, int value);
 
 #endif /* ifndef NPE_H */
diff --git a/cpu/ixp/npe/miiphy.c b/cpu/ixp/npe/miiphy.c
index b208c51..b8459ac 100644
--- a/cpu/ixp/npe/miiphy.c
+++ b/cpu/ixp/npe/miiphy.c
@@ -45,7 +45,7 @@
   +-----------------------------------------------------------------------------*/
 
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include "IxOsal.h"
 #include "IxEthAcc.h"
 #include "IxEthAcc_p.h"
@@ -56,14 +56,14 @@
 /* Dump out to the screen PHY regs			   */
 /***********************************************************/
 
-void miiphy_dump (char *devname, unsigned char addr)
+void miiphy_dump (struct mii_device *dev, unsigned char addr)
 {
 	unsigned long i;
 	unsigned short data;
 
 
 	for (i = 0; i < 0x1A; i++) {
-		if (miiphy_read (devname, addr, i, &data)) {
+		if (miiphy_read (dev, addr, i, &data)) {
 			printf ("read error for reg %lx\n", i);
 			return;
 		}
@@ -80,40 +80,37 @@ void miiphy_dump (char *devname, unsigned char addr)
 /***********************************************************/
 /* (Re)start autonegotiation				   */
 /***********************************************************/
-int phy_setup_aneg (char *devname, unsigned char addr)
+int phy_setup_aneg (struct mii_device *dev, unsigned char addr)
 {
 	unsigned short ctl, adv;
 
 	/* Setup standard advertise */
-	miiphy_read (devname, addr, PHY_ANAR, &adv);
+	miiphy_read (dev, addr, PHY_ANAR, &adv);
 	adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 |
 		PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
 		PHY_ANLPAR_10);
-	miiphy_write (devname, addr, PHY_ANAR, adv);
+	miiphy_write (dev, addr, PHY_ANAR, adv);
 
 	/* Start/Restart aneg */
-	miiphy_read (devname, addr, PHY_BMCR, &ctl);
+	miiphy_read (dev, addr, PHY_BMCR, &ctl);
 	ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
-	miiphy_write (devname, addr, PHY_BMCR, ctl);
+	miiphy_write (dev, addr, PHY_BMCR, ctl);
 
 	return 0;
 }
 
 
-int npe_miiphy_read (char *devname, unsigned char addr,
-		     unsigned char reg, unsigned short *value)
+int npe_miiphy_read (struct mii_device *dev, int addr, int reg)
 {
 	u16 val;
 
 	ixEthAccMiiReadRtn(addr, reg, &val);
-	*value = val;
 
-	return 0;
+	return val;
 }				/* phy_read */
 
 
-int npe_miiphy_write (char *devname, unsigned char addr,
-		      unsigned char reg, unsigned short value)
+int npe_miiphy_write (struct mii_device *dev, int addr, int reg, int value)
 {
 	ixEthAccMiiWriteRtn(addr, reg, value);
 	return 0;
diff --git a/cpu/ixp/npe/npe.c b/cpu/ixp/npe/npe.c
index 2e68689..de56da7 100644
--- a/cpu/ixp/npe/npe.c
+++ b/cpu/ixp/npe/npe.c
@@ -28,7 +28,7 @@
 #include <config.h>
 #include <common.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <malloc.h>
 #include <asm/processor.h>
 #include <asm/arch-ixp/ixp425.h>
@@ -356,10 +356,11 @@ static int npe_init(struct eth_device *dev, bd_t * bis)
 	u16 reg_short;
 	int speed;
 	int duplex;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 	debug("%s: 1\n", __FUNCTION__);
 
-	miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, &reg_short);
+	miiphy_read (mii_dev, p_npe->phy_no, PHY_BMSR, &reg_short);
 
 	/*
 	 * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
@@ -378,7 +379,7 @@ static int npe_init(struct eth_device *dev, bd_t * bis)
 
 			if ((i++ % 1000) == 0) {
 				putc ('.');
-				miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, &reg_short);
+				miiphy_read (mii_dev, p_npe->phy_no, PHY_BMSR, &reg_short);
 			}
 			udelay (1000);	/* 1 ms */
 		}
@@ -386,8 +387,8 @@ static int npe_init(struct eth_device *dev, bd_t * bis)
 		udelay (500000);	/* another 500 ms (results in faster booting) */
 	}
 
-	speed = miiphy_speed (dev->name, p_npe->phy_no);
-	duplex = miiphy_duplex (dev->name, p_npe->phy_no);
+	speed = miiphy_speed (mii_dev, p_npe->phy_no);
+	duplex = miiphy_duplex (mii_dev, p_npe->phy_no);
 
 	if (p_npe->print_speed) {
 		p_npe->print_speed = 0;
@@ -563,6 +564,9 @@ int npe_initialize(bd_t * bis)
 {
 	static int virgin = 0;
 	struct eth_device *dev;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
 	int eth_num = 0;
 	struct npe *p_npe = NULL;
 	uchar enetaddr[6];
@@ -587,6 +591,16 @@ int npe_initialize(bd_t * bis)
 		}
 		memset(dev, 0, sizeof(*dev));
 
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		/* Allocate device structure */
+		mii_dev = (struct mii_device *)malloc(sizeof(*mii_dev));
+		if (mii_dev == NULL) {
+			printf ("%s: Cannot allocate mii_device %d\n", __FUNCTION__, eth_num);
+			return -1;
+		}
+		memset(mii_dev, 0, sizeof(*mii_dev));
+#endif
+
 		/* Allocate our private use data */
 		p_npe = (struct npe *)malloc(sizeof(struct npe));
 		if (p_npe == NULL) {
@@ -667,7 +681,10 @@ int npe_initialize(bd_t * bis)
 		eth_register(dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-		miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write);
+		mii_dev->name = dev->name;
+		mii_dev->read = npe_miiphy_read;
+		mii_dev->write = npe_miiphy_write;
+		mii_register(mii_dev);
 #endif
 
 	}			/* end for each supported device */
diff --git a/cpu/mips/au1x00_eth.c b/cpu/mips/au1x00_eth.c
index 5074997..37f00de 100644
--- a/cpu/mips/au1x00_eth.c
+++ b/cpu/mips/au1x00_eth.c
@@ -62,7 +62,7 @@
 #include <asm/au1x00.h>
 
 #if defined(CONFIG_CMD_MII)
-#include <miiphy.h>
+#include <miidev.h>
 #endif
 
 /* Ethernet Transmit and Receive Buffers */
@@ -89,8 +89,7 @@ mac_fifo_t mac_fifo[NO_OF_FIFOS];
 #define MAX_WAIT 1000
 
 #if defined(CONFIG_CMD_MII)
-int  au1x00_miiphy_read(char *devname, unsigned char addr,
-		unsigned char reg, unsigned short * value)
+int  au1x00_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
 	volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
 	volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
@@ -118,12 +117,10 @@ int  au1x00_miiphy_read(char *devname, unsigned char addr,
 			return -1;
 		}
 	}
-	*value = *mii_data_reg;
-	return 0;
+	return *mii_data_reg;
 }
 
-int  au1x00_miiphy_write(char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value)
+int  au1x00_miiphy_write(struct mii_device *dev, int addr, int reg, int value)
 {
 	volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
 	volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
@@ -284,6 +281,9 @@ static void au1x00_halt(struct eth_device* dev){
 
 int au1x00_enet_initialize(bd_t *bis){
 	struct eth_device* dev;
+#if defined(CONFIG_CMD_MII)
+	struct mii_device* mii_dev;
+#endif
 
 	if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) {
 		puts ("malloc failed\n");
@@ -292,6 +292,15 @@ int au1x00_enet_initialize(bd_t *bis){
 
 	memset(dev, 0, sizeof *dev);
 
+#if defined(CONFIG_CMD_MII)
+	if ((mii_dev = (struct mii_device*)malloc(sizeof *mii_dev)) == NULL) {
+		puts ("malloc failed\n");
+		return -1;
+	}
+
+	memset(mii_dev, 0, sizeof *mii_dev);
+#endif
+
 	sprintf(dev->name, "Au1X00 ethernet");
 	dev->iobase = 0;
 	dev->priv   = 0;
@@ -303,8 +312,10 @@ int au1x00_enet_initialize(bd_t *bis){
 	eth_register(dev);
 
 #if defined(CONFIG_CMD_MII)
-	miiphy_register(dev->name,
-		au1x00_miiphy_read, au1x00_miiphy_write);
+	mii_dev->name = dev->name;
+	mii_dev->read = au1x00_miiphy_read;
+	mii_dev->write = au1x00_miiphy_write;
+	mii_register(mii_dev);
 #endif
 
 	return 1;
diff --git a/cpu/mpc8220/fec.c b/cpu/mpc8220/fec.c
index 992e0ff..c1b71a6 100644
--- a/cpu/mpc8220/fec.c
+++ b/cpu/mpc8220/fec.c
@@ -10,7 +10,7 @@
 #include <mpc8220.h>
 #include <malloc.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include "dma.h"
 #include "fec.h"
 
@@ -38,12 +38,12 @@ typedef struct {
 	u8 head[16];		/* MAC header(6 + 6 + 2) + 2(aligned) */
 } NBUF;
 
-int fec8220_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal);
-int fec8220_miiphy_write (char *devname, u8 phyAddr, u8 regAddr, u16 data);
+int fec8220_miiphy_read (struct mii_device *dev, int phyAddr, int regAddr);
+int fec8220_miiphy_write (struct mii_device *dev, int phyAddr, int regAddr, int data);
 
 /********************************************************************/
 #ifdef DEBUG
-static void mpc8220_fec_phydump (char *devname)
+static void mpc8220_fec_phydump (struct mii_device *dev)
 {
 	u16 phyStatus, i;
 	u8 phyAddr = CONFIG_PHY_ADDR;
@@ -61,7 +61,7 @@ static void mpc8220_fec_phydump (char *devname)
 
 	for (i = 0; i < 32; i++) {
 		if (reg_mask[i]) {
-			miiphy_read (devname, phyAddr, i, &phyStatus);
+			miiphy_read (dev, phyAddr, i, &phyStatus);
 			printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
 		}
 	}
@@ -401,11 +401,12 @@ static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
 		 */
 		int timeout = 1;
 		u16 phyStatus;
+		struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 		/*
 		 * Reset PHY, then delay 300ns
 		 */
-		miiphy_write (dev->name, phyAddr, 0x0, 0x8000);
+		miiphy_write (mii_dev, phyAddr, 0x0, 0x8000);
 		udelay (1000);
 
 		if (fec->xcv_type == MII10) {
@@ -415,11 +416,11 @@ static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
 #ifdef DEBUG
 			printf ("Forcing 10 Mbps ethernet link... ");
 #endif
-			miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+			miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus);
 			/*
 			   miiphy_write(fec, phyAddr, 0x0, 0x0100);
 			 */
-			miiphy_write (dev->name, phyAddr, 0x0, 0x0180);
+			miiphy_write (mii_dev, phyAddr, 0x0, 0x0180);
 
 			timeout = 20;
 			do {	/* wait for link status to go down */
@@ -430,7 +431,7 @@ static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
 #endif
 					break;
 				}
-				miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+				miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus);
 #ifdef DEBUG
 				printf ("=");
 #endif
@@ -443,7 +444,7 @@ static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
 					printf ("failed. Link is down.\n");
 					break;
 				}
-				miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+				miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus);
 #ifdef DEBUG
 				printf ("+");
 #endif
@@ -456,12 +457,12 @@ static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
 			/*
 			 * Set the auto-negotiation advertisement register bits
 			 */
-			miiphy_write (dev->name, phyAddr, 0x4, 0x01e1);
+			miiphy_write (mii_dev, phyAddr, 0x4, 0x01e1);
 
 			/*
 			 * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
 			 */
-			miiphy_write (dev->name, phyAddr, 0x0, 0x1200);
+			miiphy_write (mii_dev, phyAddr, 0x0, 0x1200);
 
 			/*
 			 * Wait for AN completion
@@ -477,7 +478,7 @@ static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
 					return -1;
 				}
 
-				if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) !=
+				if (miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus) !=
 				    0) {
 #ifdef DEBUG
 					printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
@@ -578,7 +579,7 @@ static void mpc8220_fec_halt (struct eth_device *dev)
 #ifdef DEBUG
 /********************************************************************/
 
-static void tfifo_print (char *devname, mpc8220_fec_priv * fec)
+static void tfifo_print (struct mii_device *dev, mpc8220_fec_priv * fec)
 {
 	u16 phyAddr = CONFIG_PHY_ADDR;
 	u16 phyStatus;
@@ -586,7 +587,7 @@ static void tfifo_print (char *devname, mpc8220_fec_priv * fec)
 	if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
 	    || (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
 
-		miiphy_read (devname, phyAddr, 0x1, &phyStatus);
+		miiphy_read (dev, phyAddr, 0x1, &phyStatus);
 		printf ("\nphyStatus: 0x%04x\n", phyStatus);
 		printf ("ecntrl:   0x%08x\n", fec->eth->ecntrl);
 		printf ("ievent:   0x%08x\n", fec->eth->ievent);
@@ -602,7 +603,7 @@ static void tfifo_print (char *devname, mpc8220_fec_priv * fec)
 	}
 }
 
-static void rfifo_print (char *devname, mpc8220_fec_priv * fec)
+static void rfifo_print (struct mii_device *dev, mpc8220_fec_priv * fec)
 {
 	u16 phyAddr = CONFIG_PHY_ADDR;
 	u16 phyStatus;
@@ -610,7 +611,7 @@ static void rfifo_print (char *devname, mpc8220_fec_priv * fec)
 	if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
 	    || (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
 
-		miiphy_read (devname, phyAddr, 0x1, &phyStatus);
+		miiphy_read (dev, phyAddr, 0x1, &phyStatus);
 		printf ("\nphyStatus: 0x%04x\n", phyStatus);
 		printf ("ecntrl:   0x%08x\n", fec->eth->ecntrl);
 		printf ("ievent:   0x%08x\n", fec->eth->ievent);
@@ -638,10 +639,11 @@ static int mpc8220_fec_send (struct eth_device *dev, volatile void *eth_data,
 	 */
 	mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
 	FEC_TBD *pTbd;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 #ifdef DEBUG
 	printf ("tbd status: 0x%04x\n", fec->tbdBase[0].status);
-	tfifo_print (dev->name, fec);
+	tfifo_print (mii_dev, fec);
 #endif
 
 	/*
@@ -685,7 +687,7 @@ static int mpc8220_fec_send (struct eth_device *dev, volatile void *eth_data,
 	if (fec->xcv_type != SEVENWIRE) {
 		u16 phyStatus;
 
-		miiphy_read (dev->name, 0, 0x1, &phyStatus);
+		miiphy_read (mii_dev, 0, 0x1, &phyStatus);
 	}
 
 	/*
@@ -693,13 +695,13 @@ static int mpc8220_fec_send (struct eth_device *dev, volatile void *eth_data,
 	 */
 
 #ifdef DEBUG
-	tfifo_print (dev->name, fec);
+	tfifo_print (mii_dev, fec);
 #endif
 
 	DMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
 
 #ifdef DEBUG
-	tfifo_print (dev->name, fec);
+	tfifo_print (mii_dev, fec);
 #endif
 
 #ifdef DEBUG
@@ -815,6 +817,7 @@ int mpc8220_fec_initialize (bd_t * bis)
 	mpc8220_fec_priv *fec2;
 #endif
 	struct eth_device *dev;
+	struct mii_device *mii_dev;
 	char *tmp, *end;
 	char env_enetaddr[6];
 
@@ -847,10 +850,14 @@ int mpc8220_fec_initialize (bd_t * bis)
 	sprintf (dev->name, "FEC ETHERNET");
 	eth_register (dev);
 
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	miiphy_register (dev->name,
-			fec8220_miiphy_read, fec8220_miiphy_write);
-#endif
+	mii_dev = (struct mii_device *) malloc (sizeof (*mii_dev));
+	memset (mii_dev, 0, sizeof *mii_dev);
+
+	mii_dev->name = dev->name;
+	mii_dev->read = fec8220_miiphy_read;
+	mii_dev->write = fec8220_miiphy_write;
+
+	mii_register (mii_dev);
 
 	/*
 	 * Try to set the mac address now. The fec mac address is
@@ -885,7 +892,7 @@ int mpc8220_fec_initialize (bd_t * bis)
 
 /* MII-interface related functions */
 /********************************************************************/
-int fec8220_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal)
+int fec8220_miiphy_read (struct mii_device *dev, int phyAddr, int regAddr)
 {
 	ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1;
 	u32 reg;		/* convenient holder for the PHY register */
@@ -923,13 +930,11 @@ int fec8220_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal)
 	/*
 	 * it's now safe to read the PHY's register
 	 */
-	*retVal = (u16) eth->mii_data;
-
-	return 0;
+	return eth->mii_data;
 }
 
 /********************************************************************/
-int fec8220_miiphy_write (char *devname, u8 phyAddr, u8 regAddr, u16 data)
+int fec8220_miiphy_write (struct mii_device *dev, int phyAddr, int regAddr, int data)
 {
 	ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1;
 	u32 reg;		/* convenient holder for the PHY register */
diff --git a/cpu/mpc8260/ether_fcc.c b/cpu/mpc8260/ether_fcc.c
index 5ac02a0..620ac64 100644
--- a/cpu/mpc8260/ether_fcc.c
+++ b/cpu/mpc8260/ether_fcc.c
@@ -48,7 +48,7 @@
 #include <net.h>
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-#include <miiphy.h>
+#include <miidev.h>
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -376,6 +376,10 @@ static void fec_halt(struct eth_device* dev)
 int fec_initialize(bd_t *bis)
 {
 	struct eth_device* dev;
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \
+		&& defined(CONFIG_BITBANGMII)
+	struct mii_device* mii_dev;
+#endif
 	int i;
 
 	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
@@ -395,8 +399,14 @@ int fec_initialize(bd_t *bis)
 
 #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \
 		&& defined(CONFIG_BITBANGMII)
-		miiphy_register(dev->name,
-				bb_miiphy_read,	bb_miiphy_write);
+		mii_dev = (struct mii_device*) malloc(sizeof *mii_dev);
+		memset(mii_dev, 0, sizeof *mii_dev);
+
+		mii_dev->name = dev->name;
+		mii_dev->read = mii_bitbang_read;
+		mii_dev->write = mii_bitbang_write;
+
+		mii_register(mii_dev);
 #endif
 	}
 
diff --git a/cpu/mpc85xx/ether_fcc.c b/cpu/mpc85xx/ether_fcc.c
index 32ad469..980b3f0 100644
--- a/cpu/mpc85xx/ether_fcc.c
+++ b/cpu/mpc85xx/ether_fcc.c
@@ -49,7 +49,7 @@
 #include <net.h>
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-#include <miiphy.h>
+#include <miidev.h>
 #endif
 
 #if defined(CONFIG_CPM2)
@@ -441,6 +441,10 @@ static void fec_halt(struct eth_device* dev)
 int fec_initialize(bd_t *bis)
 {
 	struct eth_device* dev;
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \
+		&& defined(CONFIG_BITBANGMII)
+	struct mii__device* mii_dev;
+#endif
 	int i;
 
 	for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
@@ -460,8 +464,14 @@ int fec_initialize(bd_t *bis)
 
 #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \
 		&& defined(CONFIG_BITBANGMII)
-		miiphy_register(dev->name,
-				bb_miiphy_read,	bb_miiphy_write);
+		mii_dev = (struct mii_device*) malloc(sizeof *mii_dev);
+		memset(mii_dev, 0, sizeof *mii_dev);
+
+		mii_dev->name = dev->name;
+		mii_dev->read = mii_bitbang_read;
+		mii_dev->write = mii_bitbang_write;
+
+		mii_register(mii_dev);
 #endif
 	}
 
diff --git a/cpu/mpc8xx/fec.c b/cpu/mpc8xx/fec.c
index 89c1ff9..d0bf193 100644
--- a/cpu/mpc8xx/fec.c
+++ b/cpu/mpc8xx/fec.c
@@ -25,6 +25,7 @@
 #include <malloc.h>
 #include <commproc.h>
 #include <net.h>
+#include <miidev.h>
 #include <command.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -47,7 +48,6 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif
 
 #if defined(WANT_MII)
-#include <miiphy.h>
 
 #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
 #error "CONFIG_MII has to be defined!"
@@ -63,10 +63,8 @@ DECLARE_GLOBAL_DATA_PTR;
 static int mii_discover_phy(struct eth_device *dev);
 #endif
 
-int fec8xx_miiphy_read(char *devname, unsigned char addr,
-		unsigned char  reg, unsigned short *value);
-int fec8xx_miiphy_write(char *devname, unsigned char  addr,
-		unsigned char  reg, unsigned short value);
+int fec8xx_miiphy_read(struct mii_device *dev, int addr, int reg);
+int fec8xx_miiphy_write(struct mii_device *dev, int addr, int reg, int value);
 
 static struct ether_fcc_info_s
 {
@@ -150,6 +148,9 @@ static void __mii_init(void);
 int fec_initialize(bd_t *bis)
 {
 	struct eth_device* dev;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device* mii_dev;
+#endif
 	struct ether_fcc_info_s *efis;
 	int             i;
 
@@ -186,8 +187,17 @@ int fec_initialize(bd_t *bis)
 		eth_register(dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-		miiphy_register(dev->name,
-			fec8xx_miiphy_read, fec8xx_miiphy_write);
+		mii_dev = malloc(sizeof(*mii_dev));
+		if (mii_dev == NULL)
+			hang();
+
+		memset(mii_dev, 0, sizeof(*mii_dev));
+
+		mii_dev->name = dev->name;
+		mii_dev->read = fec8xx_miiphy_read;
+		mii_dev->write = fec8xx_miiphy_write;
+
+		mii_register(mii_dev);
 #endif
 	}
 	return 1;
@@ -573,6 +583,9 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
 	volatile fec_t *fecp =
 		(volatile fec_t *) (CONFIG_SYS_IMMR + efis->fecp_offset);
 	int i;
+#if defined(CONFIG_MII)
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
+#endif
 
 	if (efis->ether_index == 0) {
 #if defined(CONFIG_FADS)	/* FADS family uses FPGA (BCSR) to control PHYs */
@@ -742,7 +755,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
 	/*
 	 * adapt the RMII speed to the speed of the phy
 	 */
-	if (miiphy_speed (dev->name, efis->actual_phy_addr) == _100BASET) {
+	if (miiphy_speed (mii_dev, efis->actual_phy_addr) == _100BASET) {
 		fec_100Mbps (dev);
 	} else {
 		fec_10Mbps (dev);
@@ -753,7 +766,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
 	/*
 	 * adapt to the half/full speed settings
 	 */
-	if (miiphy_duplex (dev->name, efis->actual_phy_addr) == FULL) {
+	if (miiphy_duplex (mii_dev, efis->actual_phy_addr) == FULL) {
 		fec_full_duplex (dev);
 	} else {
 		fec_half_duplex (dev);
@@ -990,8 +1003,7 @@ void mii_init (void)
  *	  Otherwise they hang in mii_send() !!! Sorry!
  *****************************************************************************/
 
-int fec8xx_miiphy_read(char *devname, unsigned char addr,
-		unsigned char  reg, unsigned short *value)
+int fec8xx_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
 	short rdreg;    /* register working value */
 
@@ -1000,15 +1012,13 @@ int fec8xx_miiphy_read(char *devname, unsigned char addr,
 #endif
 	rdreg = mii_send(mk_mii_read(addr, reg));
 
-	*value = rdreg;
 #ifdef MII_DEBUG
-	printf ("0x%04x\n", *value);
+	printf ("0x%04x\n", rdreg);
 #endif
-	return 0;
+	return rdreg;
 }
 
-int fec8xx_miiphy_write(char *devname, unsigned char  addr,
-		unsigned char  reg, unsigned short value)
+int fec8xx_miiphy_write(struct mii_device *dev, int addr, int reg, int value)
 {
 	short rdreg;    /* register working value */
 #ifdef MII_DEBUG
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index 6a92bf8..086cc9e 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -43,7 +43,7 @@
 #include <commproc.h>
 #include <ppc4xx_enet.h>
 #include <405_mal.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #if !defined(CONFIG_PHY_CLK_FREQ)
 #define CONFIG_PHY_CLK_FREQ	0
@@ -53,13 +53,13 @@
 /* Dump out to the screen PHY regs			   */
 /***********************************************************/
 
-void miiphy_dump (char *devname, unsigned char addr)
+void miiphy_dump (struct mii_device *dev, unsigned char addr)
 {
 	unsigned long i;
 	unsigned short data;
 
 	for (i = 0; i < 0x1A; i++) {
-		if (miiphy_read (devname, addr, i, &data)) {
+		if (miiphy_read (dev, addr, i, &data)) {
 			printf ("read error for reg %lx\n", i);
 			return;
 		}
@@ -75,7 +75,7 @@ void miiphy_dump (char *devname, unsigned char addr)
 /***********************************************************/
 /* (Re)start autonegotiation				   */
 /***********************************************************/
-int phy_setup_aneg (char *devname, unsigned char addr)
+int phy_setup_aneg (struct mii_device *dev, unsigned char addr)
 {
 	u16 bmcr;
 
@@ -89,11 +89,11 @@ int phy_setup_aneg (char *devname, unsigned char addr)
 	u16 exsr = 0x0000;
 #endif
 
-	miiphy_read (devname, addr, PHY_BMSR, &bmsr);
+	miiphy_read (dev, addr, PHY_BMSR, &bmsr);
 
 #if defined(CONFIG_PHY_GIGE)
 	if (bmsr & PHY_BMSR_EXT_STAT)
-		miiphy_read (devname, addr, PHY_EXSR, &exsr);
+		miiphy_read (dev, addr, PHY_EXSR, &exsr);
 
 	if (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)) {
 		/* 1000BASE-X */
@@ -105,17 +105,17 @@ int phy_setup_aneg (char *devname, unsigned char addr)
 		if (exsr & PHY_EXSR_1000XH)
 			anar |= PHY_X_ANLPAR_HD;
 
-		miiphy_write (devname, addr, PHY_ANAR, anar);
+		miiphy_write (dev, addr, PHY_ANAR, anar);
 	} else
 #endif
 	{
 		u16 anar, btcr;
 
-		miiphy_read (devname, addr, PHY_ANAR, &anar);
+		miiphy_read (dev, addr, PHY_ANAR, &anar);
 		anar &= ~(0x5000 | PHY_ANLPAR_T4 | PHY_ANLPAR_TXFD |
 			  PHY_ANLPAR_TX | PHY_ANLPAR_10FD | PHY_ANLPAR_10);
 
-		miiphy_read (devname, addr, PHY_1000BTCR, &btcr);
+		miiphy_read (dev, addr, PHY_1000BTCR, &btcr);
 		btcr &= ~(0x00FF | PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD);
 
 		if (bmsr & PHY_BMSR_100T4)
@@ -133,7 +133,7 @@ int phy_setup_aneg (char *devname, unsigned char addr)
 		if (bmsr & PHY_BMSR_10TH)
 			anar |= PHY_ANLPAR_10;
 
-		miiphy_write (devname, addr, PHY_ANAR, anar);
+		miiphy_write (dev, addr, PHY_ANAR, anar);
 
 #if defined(CONFIG_PHY_GIGE)
 		if (exsr & PHY_EXSR_1000TF)
@@ -142,7 +142,7 @@ int phy_setup_aneg (char *devname, unsigned char addr)
 		if (exsr & PHY_EXSR_1000TH)
 			btcr |= PHY_1000BTCR_1000HD;
 
-		miiphy_write (devname, addr, PHY_1000BTCR, btcr);
+		miiphy_write (dev, addr, PHY_1000BTCR, btcr);
 #endif
 	}
 
@@ -152,21 +152,21 @@ int phy_setup_aneg (char *devname, unsigned char addr)
 	 */
 	u16 adv;
 
-	miiphy_read (devname, addr, PHY_ANAR, &adv);
+	miiphy_read (dev, addr, PHY_ANAR, &adv);
 	adv |= (PHY_ANLPAR_ACK  | PHY_ANLPAR_TXFD | PHY_ANLPAR_TX |
 		PHY_ANLPAR_10FD | PHY_ANLPAR_10);
-	miiphy_write (devname, addr, PHY_ANAR, adv);
+	miiphy_write (dev, addr, PHY_ANAR, adv);
 
-	miiphy_read (devname, addr, PHY_1000BTCR, &adv);
+	miiphy_read (dev, addr, PHY_1000BTCR, &adv);
 	adv |= (0x0300);
-	miiphy_write (devname, addr, PHY_1000BTCR, adv);
+	miiphy_write (dev, addr, PHY_1000BTCR, adv);
 
 #endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
 
 	/* Start/Restart aneg */
-	miiphy_read (devname, addr, PHY_BMCR, &bmcr);
+	miiphy_read (dev, addr, PHY_BMCR, &bmcr);
 	bmcr |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
-	miiphy_write (devname, addr, PHY_BMCR, bmcr);
+	miiphy_write (dev, addr, PHY_BMCR, bmcr);
 
 	return 0;
 }
@@ -338,8 +338,7 @@ static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value)
 	return 0;
 }
 
-int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
-			 unsigned short *value)
+int emac4xx_miiphy_read (struct mii_device *dev, int addr, int reg)
 {
 	unsigned long sta_reg;
 	unsigned long emac_reg;
@@ -350,17 +349,15 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
 		return -1;
 
 	sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
-	*value = *(u16 *)(&sta_reg);
-
-	return 0;
+	return *(u16 *)(&sta_reg);
 }
 
 /***********************************************************/
 /* write a phy reg and return the value with a rc	    */
 /***********************************************************/
 
-int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg,
-			  unsigned short value)
+extern int emac4xx_miiphy_write (struct mii_device *dev, int addr, int reg,
+				  int value)
 {
 	return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
 }
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index 329eef0..82d3a60 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -90,7 +90,7 @@
 #include <ppc4xx.h>
 #include <ppc4xx_enet.h>
 #include <405_mal.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <malloc.h>
 
 #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
@@ -304,11 +304,10 @@ static void mal_err (struct eth_device *dev, unsigned long isr,
 		     unsigned long mal_errr);
 static void emac_err (struct eth_device *dev, unsigned long isr);
 
-extern int phy_setup_aneg (char *devname, unsigned char addr);
-extern int emac4xx_miiphy_read (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short *value);
-extern int emac4xx_miiphy_write (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value);
+extern int phy_setup_aneg (struct mii_device *dev, unsigned char addr);
+extern int emac4xx_miiphy_read (struct mii_device *dev, int addr, int reg);
+extern int emac4xx_miiphy_write (struct mii_device *dev, int addr, int reg,
+				  int value);
 
 int board_emac_count(void);
 
@@ -891,6 +890,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 #endif
 
 	EMAC_4XX_HW_PST hw_p = dev->priv;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 	/* before doing anything, figure out if we have a MAC address */
 	/* if not, bail */
@@ -1046,10 +1046,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 		out_be32((void *)EMAC_M1 + hw_p->hw_addr, mode_reg);
 
 		/* Configure GPCS interface to recommended setting for SGMII */
-		miiphy_reset(dev->name, reg);
-		miiphy_write(dev->name, reg, 0x04, 0x8120); /* AsymPause, FDX */
-		miiphy_write(dev->name, reg, 0x07, 0x2801); /* msg_pg, toggle */
-		miiphy_write(dev->name, reg, 0x00, 0x0140); /* 1Gbps, FDX     */
+		miiphy_reset(mii_dev, reg);
+		miiphy_write(mii_dev, reg, 0x04, 0x8120); /* AsymPause, FDX */
+		miiphy_write(mii_dev, reg, 0x07, 0x2801); /* msg_pg, toggle */
+		miiphy_write(mii_dev, reg, 0x00, 0x0140); /* 1Gbps, FDX     */
 	}
 #endif /* defined(CONFIG_GPCS_PHY_ADDR) */
 
@@ -1091,10 +1091,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 	 */
 	if (hw_p->first_init == 0) {
 #if defined(CONFIG_M88E1111_PHY)
-		miiphy_write (dev->name, reg, 0x14, 0x0ce3);
-		miiphy_write (dev->name, reg, 0x18, 0x4101);
-		miiphy_write (dev->name, reg, 0x09, 0x0e00);
-		miiphy_write (dev->name, reg, 0x04, 0x01e1);
+		miiphy_write (mii_dev, reg, 0x14, 0x0ce3);
+		miiphy_write (mii_dev, reg, 0x18, 0x4101);
+		miiphy_write (mii_dev, reg, 0x09, 0x0e00);
+		miiphy_write (mii_dev, reg, 0x04, 0x01e1);
 #endif
 #if defined(CONFIG_M88E1112_PHY)
 		if (bis->bi_phymode[devnum] == BI_PHYMODE_SGMII) {
@@ -1105,19 +1105,19 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 			 */
 
 			/* Set access to Page 2 */
-			miiphy_write(dev->name, reg, 0x16, 0x0002);
+			miiphy_write(mii_dev, reg, 0x16, 0x0002);
 
-			miiphy_write(dev->name, reg, 0x00, 0x0040); /* 1Gbps */
-			miiphy_read(dev->name, reg, 0x1a, &reg_short);
+			miiphy_write(mii_dev, reg, 0x00, 0x0040); /* 1Gbps */
+			miiphy_read(mii_dev, reg, 0x1a, &reg_short);
 			reg_short |= 0x8000; /* bypass Auto-Negotiation */
-			miiphy_write(dev->name, reg, 0x1a, reg_short);
-			miiphy_reset(dev->name, reg); /* reset MAC interface */
+			miiphy_write(mii_dev, reg, 0x1a, reg_short);
+			miiphy_reset(mii_dev, reg); /* reset MAC interface */
 
 			/* Reset access to Page 0 */
-			miiphy_write(dev->name, reg, 0x16, 0x0000);
+			miiphy_write(mii_dev, reg, 0x16, 0x0000);
 		}
 #endif /* defined(CONFIG_M88E1112_PHY) */
-		miiphy_reset (dev->name, reg);
+		miiphy_reset (mii_dev, reg);
 
 #if defined(CONFIG_440GX) || \
     defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
@@ -1131,9 +1131,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 		 */
 		if (((devnum == 2) || (devnum == 3)) && (4 == ethgroup)) {
 #if defined(CONFIG_CIS8201_SHORT_ETCH)
-			miiphy_write (dev->name, reg, 23, 0x1300);
+			miiphy_write (mii_dev, reg, 23, 0x1300);
 #else
-			miiphy_write (dev->name, reg, 23, 0x1000);
+			miiphy_write (mii_dev, reg, 23, 0x1000);
 #endif
 			/*
 			 * Vitesse VSC8201/Cicada CIS8201 errata:
@@ -1141,15 +1141,15 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 			 * This work around (provided by Vitesse) changes
 			 * the default timer convergence from 8ms to 12ms
 			 */
-			miiphy_write (dev->name, reg, 0x1f, 0x2a30);
-			miiphy_write (dev->name, reg, 0x08, 0x0200);
-			miiphy_write (dev->name, reg, 0x1f, 0x52b5);
-			miiphy_write (dev->name, reg, 0x02, 0x0004);
-			miiphy_write (dev->name, reg, 0x01, 0x0671);
-			miiphy_write (dev->name, reg, 0x00, 0x8fae);
-			miiphy_write (dev->name, reg, 0x1f, 0x2a30);
-			miiphy_write (dev->name, reg, 0x08, 0x0000);
-			miiphy_write (dev->name, reg, 0x1f, 0x0000);
+			miiphy_write (mii_dev, reg, 0x1f, 0x2a30);
+			miiphy_write (mii_dev, reg, 0x08, 0x0200);
+			miiphy_write (mii_dev, reg, 0x1f, 0x52b5);
+			miiphy_write (mii_dev, reg, 0x02, 0x0004);
+			miiphy_write (mii_dev, reg, 0x01, 0x0671);
+			miiphy_write (mii_dev, reg, 0x00, 0x8fae);
+			miiphy_write (mii_dev, reg, 0x1f, 0x2a30);
+			miiphy_write (mii_dev, reg, 0x08, 0x0000);
+			miiphy_write (mii_dev, reg, 0x1f, 0x0000);
 			/* end Vitesse/Cicada errata */
 		}
 #endif /* defined(CONFIG_CIS8201_PHY) */
@@ -1160,27 +1160,27 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 		 * for RGMII mode.
 		 */
 		if (((devnum == 2) || (devnum ==3)) && (4 == ethgroup)) {
-			miiphy_read (dev->name, reg, 0x16, &reg_short);
+			miiphy_read (mii_dev, reg, 0x16, &reg_short);
 			reg_short &= ~(0x7);
 			reg_short |= 0x6;	/* RGMII DLL Delay*/
-			miiphy_write (dev->name, reg, 0x16, reg_short);
+			miiphy_write (mii_dev, reg, 0x16, reg_short);
 
-			miiphy_read (dev->name, reg, 0x17, &reg_short);
+			miiphy_read (mii_dev, reg, 0x17, &reg_short);
 			reg_short &= ~(0x40);
-			miiphy_write (dev->name, reg, 0x17, reg_short);
+			miiphy_write (mii_dev, reg, 0x17, reg_short);
 
-			miiphy_write(dev->name, reg, 0x1c, 0x74f0);
+			miiphy_write(mii_dev, reg, 0x1c, 0x74f0);
 		}
 #endif /* defined(CONFIG_ET1011C_PHY) */
 
 #endif /* defined(CONFIG_440GX) ... */
 		/* Start/Restart autonegotiation */
-		phy_setup_aneg (dev->name, reg);
+		phy_setup_aneg (mii_dev, reg);
 		udelay (1000);
 	}
 #endif /* defined(CONFIG_PHY_RESET) */
 
-	miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);
+	miiphy_read (mii_dev, reg, PHY_BMSR, &reg_short);
 
 	/*
 	 * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
@@ -1202,7 +1202,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 				putc ('.');
 			}
 			udelay (1000);	/* 1 ms */
-			miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);
+			miiphy_read (mii_dev, reg, PHY_BMSR, &reg_short);
 		}
 		puts (" done\n");
 		udelay (500000);	/* another 500 ms (results in faster booting) */
@@ -1224,8 +1224,8 @@ get_speed:
 			return -1;
 		}
 	} else {
-		speed = miiphy_speed(dev->name, reg);
-		duplex = miiphy_duplex(dev->name, reg);
+		speed = miiphy_speed(mii_dev, reg);
+		duplex = miiphy_duplex(mii_dev, reg);
 	}
 
 	if (hw_p->print_speed) {
@@ -1908,6 +1908,9 @@ int ppc_4xx_eth_initialize (bd_t * bis)
 	u8 ethaddr[4 + CONFIG_EMAC_NR_START][6];
 	u32 hw_addr[4];
 	u32 mal_ier;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
 
 #if defined(CONFIG_440GX)
 	unsigned long pfc1;
@@ -1999,6 +2002,18 @@ int ppc_4xx_eth_initialize (bd_t * bis)
 		}
 		memset(dev, 0, sizeof(*dev));
 
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		/* Allocate device structure */
+		mii_dev = (struct mii_device *) malloc (sizeof (*mii_dev));
+		if (mii_dev == NULL) {
+			printf ("ppc_4xx_eth_initialize: "
+				"Cannot allocate mii_device %d\n", eth_num);
+			free (dev);
+			return (-1);
+		}
+		memset(mii_dev, 0, sizeof(*mii_dev));
+#endif
+
 		/* Allocate our private use data */
 		hw = (EMAC_4XX_HW_PST) malloc (sizeof (*hw));
 		if (hw == NULL) {
@@ -2006,6 +2021,9 @@ int ppc_4xx_eth_initialize (bd_t * bis)
 				"Cannot allocate private hw data for eth_device %d",
 				eth_num);
 			free (dev);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+			free (mii_dev);
+#endif
 			return (-1);
 		}
 		memset(hw, 0, sizeof(*hw));
@@ -2063,8 +2081,11 @@ int ppc_4xx_eth_initialize (bd_t * bis)
 		eth_register (dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-		miiphy_register (dev->name,
-				 emac4xx_miiphy_read, emac4xx_miiphy_write);
+		mii_dev->name = dev->name;
+		mii_dev->read = emac4xx_miiphy_read;
+		mii_dev->write = emac4xx_miiphy_write;
+
+		mii_register (mii_dev);
 #endif
 	}			/* end for each supported device */
 
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 12d98c2..1f6b6aa 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -12,7 +12,7 @@
 #include <netdev.h>
 #include <command.h>
 #include <malloc.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <linux/mii.h>
 
 #include <asm/blackfin.h>
@@ -70,18 +70,17 @@ static int bfin_miiphy_wait(void)
 	return 0;
 }
 
-static int bfin_miiphy_read(char *devname, uchar addr, uchar reg, ushort *val)
+static int bfin_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
 	if (bfin_miiphy_wait())
-		return 1;
+		return -1;
 	bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY);
 	if (bfin_miiphy_wait())
-		return 1;
-	*val = bfin_read_EMAC_STADAT();
-	return 0;
+		return -1;
+	return bfin_read_EMAC_STADAT();
 }
 
-static int bfin_miiphy_write(char *devname, uchar addr, uchar reg, ushort val)
+static int bfin_miiphy_write(struct mii_device *dev, int addr, int reg, int val)
 {
 	if (bfin_miiphy_wait())
 		return 1;
@@ -93,11 +92,24 @@ static int bfin_miiphy_write(char *devname, uchar addr, uchar reg, ushort val)
 int bfin_EMAC_initialize(bd_t *bis)
 {
 	struct eth_device *dev;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
+
 	dev = malloc(sizeof(*dev));
 	if (dev == NULL)
 		hang();
 
 	memset(dev, 0, sizeof(*dev));
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	mii_dev = malloc(sizeof(*mii_dev));
+	if (mii_dev == NULL)
+		hang();
+
+	memset(mii_dev, 0, sizeof(*mii_dev));
+#endif
+
 	sprintf(dev->name, "Blackfin EMAC");
 
 	dev->iobase = 0;
@@ -110,7 +122,11 @@ int bfin_EMAC_initialize(bd_t *bis)
 	eth_register(dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	miiphy_register(dev->name, bfin_miiphy_read, bfin_miiphy_write);
+	mii_dev->name = dev->name;
+	mii_dev->read = bfin_miiphy_read;
+	mii_dev->write = bfin_miiphy_write;
+
+	mii_register(mii_dev);
 #endif
 
 	return 0;
@@ -213,6 +229,7 @@ static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
 {
 	u16 phydat;
 	size_t count;
+	struct mii_device *mii_dev = mii_get_by_name(name);
 
 	/* Enable PHY output */
 	*pVR_CTL |= CLKBUFOE;
@@ -260,11 +277,11 @@ static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
 	bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ)));
 
 	/* turn on auto-negotiation and wait for link to come up */
-	bfin_miiphy_write(dev->name, CONFIG_PHY_ADDR, MII_BMCR, BMCR_ANENABLE);
+	bfin_miiphy_write(mii_dev, CONFIG_PHY_ADDR, MII_BMCR, BMCR_ANENABLE);
 	count = 0;
 	while (1) {
 		++count;
-		if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_BMSR, &phydat))
+		if (bfin_miiphy_read(mii_dev, CONFIG_PHY_ADDR, MII_BMSR, &phydat))
 			return -1;
 		if (phydat & BMSR_LSTATUS)
 			break;
@@ -276,7 +293,7 @@ static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
 	}
 
 	/* see what kind of link we have */
-	if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_LPA, &phydat))
+	if (bfin_miiphy_read(mii_dev, CONFIG_PHY_ADDR, MII_LPA, &phydat))
 		return -1;
 	if (phydat & LPA_DUPLEX)
 		*opmode = FDMODE;
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index fa8cee4..34d96d6 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -39,7 +39,7 @@
 #include <common.h>
 #include <command.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <malloc.h>
 #include <asm/arch/emac_defs.h>
 
@@ -236,16 +236,20 @@ static int gen_auto_negotiate(int phy_addr)
 
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-static int davinci_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
+static int davinci_mii_phy_read(struct mii_device *dev, int addr, int reg)
 {
-	return(davinci_eth_phy_read(addr, reg, value) ? 0 : 1);
+	unsigned short value;
+
+	davinci_eth_phy_read(addr, reg, &value);
+
+	return value;
 }
 
-static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
+static int davinci_mii_phy_write(struct mii_device *dev, int addr, int reg,
+				  int value)
 {
 	return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1);
 }
-
 #endif
 
 
@@ -547,6 +551,7 @@ int davinci_emac_initialize(void)
 	u_int16_t	tmp;
 	int		i;
 	struct eth_device *dev;
+	struct mii_device *mii_dev;
 
 	dev = malloc(sizeof *dev);
 
@@ -555,6 +560,13 @@ int davinci_emac_initialize(void)
 
 	memset(dev, 0, sizeof *dev);
 
+	mii_dev = malloc(sizeof *mii_dev);
+
+	if (mii_dev == NULL)
+		return -1;
+
+	memset(mii_dev, 0, sizeof *mii_dev);
+
 	dev->iobase = 0;
 	dev->init = davinci_eth_open;
 	dev->halt = davinci_eth_close;
@@ -620,6 +632,11 @@ int davinci_emac_initialize(void)
 
 	printf("Ethernet PHY: %s\n", phy.name);
 
-	miiphy_register(phy.name, davinci_mii_phy_read, davinci_mii_phy_write);
+	mii_dev->name = phy.name;
+	mii_dev->read = davinci_mii_phy_read;
+	mii_dev->write = davinci_mii_phy_write;
+
+	mii_register(mii_dev);
+
 	return(1);
 }
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index bfe87fa..85129ec 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -18,7 +18,7 @@
 #include <malloc.h>
 #include <linux/mii.h>
 
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm/io.h>
 
 #include "dnet.h"
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 9c06b25..2b94d53 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -27,7 +27,7 @@
 #include <netdev.h>
 #include <asm/io.h>
 #include <pci.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #undef DEBUG
 
@@ -350,34 +350,34 @@ static struct eth_device* verify_phyaddr (char *devname, unsigned char addr)
 	return dev;
 }
 
-static int eepro100_miiphy_read (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short *value)
+static int eepro100_miiphy_read (struct mii_device *mii_dev, int addr, int reg)
 {
 	struct eth_device *dev;
+	unsigned short value;
 
-	dev = verify_phyaddr(devname, addr);
+	dev = verify_phyaddr(mii_dev->name, addr);
 	if (dev == NULL)
 		return -1;
 
-	if (get_phyreg(dev, addr, reg, value) != 0) {
-		printf("%s: mii read timeout!\n", devname);
+	if (get_phyreg(dev, addr, reg, &value) != 0) {
+		printf("%s: mii read timeout!\n", dev->name);
 		return -1;
 	}
 
-	return 0;
+	return value;
 }
 
-static int eepro100_miiphy_write (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value)
+static int eepro100_miiphy_write (struct mii_device *mii_dev, int addr, int reg,
+				   int value)
 {
 	struct eth_device *dev;
 
-	dev = verify_phyaddr(devname, addr);
+	dev = verify_phyaddr(mii_dev->name, addr);
 	if (dev == NULL)
 		return -1;
 
 	if (set_phyreg(dev, addr, reg, value) != 0) {
-		printf("%s: mii write timeout!\n", devname);
+		printf("%s: mii write timeout!\n", dev->name);
 		return -1;
 	}
 
@@ -413,6 +413,9 @@ int eepro100_initialize (bd_t * bis)
 	pci_dev_t devno;
 	int card_number = 0;
 	struct eth_device *dev;
+#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
 	u32 iobase, status;
 	int idx = 0;
 
@@ -461,9 +464,14 @@ int eepro100_initialize (bd_t * bis)
 		eth_register (dev);
 
 #if defined (CONFIG_MII) || defined(CONFIG_CMD_MII)
+		mii_dev = (struct mii_device *) malloc (sizeof *mii_dev);
+
+		mii_dev->name = dev->name;
+		mii_dev->read = eepro100_miiphy_read;
+		mii_dev->write = eepro100_miiphy_write;
+
 		/* register mii command access routines */
-		miiphy_register(dev->name,
-				eepro100_miiphy_read, eepro100_miiphy_write);
+		mii_register(mii_dev);
 #endif
 
 		card_number++;
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index bd83a24..9635bf7 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -24,7 +24,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include "fec_mxc.h"
 
 #include <asm/arch/clock.h>
@@ -60,15 +60,15 @@ struct fec_priv gfec = {
 /*
  * MII-interface related functions
  */
-static int fec_miiphy_read(char *dev, uint8_t phyAddr, uint8_t regAddr,
-		uint16_t *retVal)
+static int fec_miiphy_read(struct mii_device *dev, int phyAddr, int regAddr)
 {
-	struct eth_device *edev = eth_get_dev_by_name(dev);
+	struct eth_device *edev = eth_get_dev_by_name(dev->name);
 	struct fec_priv *fec = (struct fec_priv *)edev->priv;
 
 	uint32_t reg;		/* convenient holder for the PHY register */
 	uint32_t phy;		/* convenient holder for the PHY */
 	uint32_t start;
+	int val;
 
 	/*
 	 * reading from any PHY's register is done by properly
@@ -100,16 +100,16 @@ static int fec_miiphy_read(char *dev, uint8_t phyAddr, uint8_t regAddr,
 	/*
 	 * it's now safe to read the PHY's register
 	 */
-	*retVal = readl(&fec->eth->mii_data);
+	val = readl(&fec->eth->mii_data);
 	debug("fec_miiphy_read: phy: %02x reg:%02x val:%#x\n", phyAddr,
-			regAddr, *retVal);
-	return 0;
+			regAddr, val);
+	return val;
 }
 
-static int fec_miiphy_write(char *dev, uint8_t phyAddr, uint8_t regAddr,
-		uint16_t data)
+static int fec_miiphy_write(struct mii_device *dev, int phyAddr, int regAddr,
+			     int data)
 {
-	struct eth_device *edev = eth_get_dev_by_name(dev);
+	struct eth_device *edev = eth_get_dev_by_name(dev->name);
 	struct fec_priv *fec = (struct fec_priv *)edev->priv;
 
 	uint32_t reg;		/* convenient holder for the PHY register */
@@ -143,28 +143,28 @@ static int fec_miiphy_write(char *dev, uint8_t phyAddr, uint8_t regAddr,
 	return 0;
 }
 
-static int miiphy_restart_aneg(struct eth_device *dev)
+static int miiphy_restart_aneg(struct mii_device *dev)
 {
 	/*
 	 * Wake up from sleep if necessary
 	 * Reset PHY, then delay 300ns
 	 */
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, PHY_MIPGSR, 0x00FF);
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, PHY_BMCR,
+	miiphy_write(dev, CONFIG_FEC_MXC_PHYADDR, PHY_MIPGSR, 0x00FF);
+	miiphy_write(dev, CONFIG_FEC_MXC_PHYADDR, PHY_BMCR,
 			PHY_BMCR_RESET);
 	udelay(1000);
 
 	/*
 	 * Set the auto-negotiation advertisement register bits
 	 */
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, PHY_ANAR, 0x1e0);
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, PHY_BMCR,
+	miiphy_write(dev, CONFIG_FEC_MXC_PHYADDR, PHY_ANAR, 0x1e0);
+	miiphy_write(dev, CONFIG_FEC_MXC_PHYADDR, PHY_BMCR,
 			PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
 
 	return 0;
 }
 
-static int miiphy_wait_aneg(struct eth_device *dev)
+static int miiphy_wait_aneg(struct mii_device *dev)
 {
 	uint32_t start;
 	uint16_t status;
@@ -179,7 +179,7 @@ static int miiphy_wait_aneg(struct eth_device *dev)
 			return -1;
 		}
 
-		if (miiphy_read(dev->name, CONFIG_FEC_MXC_PHYADDR,
+		if (miiphy_read(dev, CONFIG_FEC_MXC_PHYADDR,
 					PHY_BMSR, &status)) {
 			printf("%s: Autonegotiation failed. status: 0x%04x\n",
 					dev->name, status);
@@ -329,6 +329,7 @@ static int fec_set_hwaddr(struct eth_device *dev, unsigned char *mac)
 static int fec_open(struct eth_device *edev)
 {
 	struct fec_priv *fec = (struct fec_priv *)edev->priv;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 	debug("fec_open: fec_open(dev)\n");
 	/* full-duplex, heartbeat disabled */
@@ -340,9 +341,9 @@ static int fec_open(struct eth_device *edev)
 	 */
 	writel(FEC_ECNTRL_ETHER_EN, &fec->eth->ecntrl);
 
-	miiphy_wait_aneg(edev);
-	miiphy_speed(edev->name, 0);
-	miiphy_duplex(edev->name, 0);
+	miiphy_wait_aneg(mii_dev);
+	miiphy_speed(mii_dev, 0);
+	miiphy_duplex(mii_dev, 0);
 
 	/*
 	 * Enable SmartDMA receive task
@@ -357,6 +358,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 {
 	uint32_t base;
 	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 	/*
 	 * reserve memory for both buffer descriptor chains at once
@@ -450,7 +452,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 
 
 	if (fec->xcv_type != SEVENWIRE)
-		miiphy_restart_aneg(dev);
+		miiphy_restart_aneg(mii_dev);
 
 	fec_open(dev);
 	return 0;
@@ -648,6 +650,7 @@ static int fec_probe(bd_t *bd)
 {
 	struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
 	struct eth_device *edev;
+	struct mii_device *mii_dev;
 	struct fec_priv *fec = &gfec;
 	unsigned char ethaddr_str[20];
 	unsigned char ethaddr[6];
@@ -664,6 +667,11 @@ static int fec_probe(bd_t *bd)
 		puts("fec_imx27: not enough malloc memory!\n");
 		return -ENOMEM;
 	}
+	mii_dev = (struct mii_device *)malloc(sizeof(struct mii_device));
+	if (!mii_dev) {
+		puts("fec_imx27: not enough malloc memory!\n");
+		return -ENOMEM;
+	}
 	edev->priv = fec;
 	edev->init = fec_init;
 	edev->send = fec_send;
@@ -708,7 +716,10 @@ static int fec_probe(bd_t *bd)
 
 	sprintf(edev->name, "FEC_MXC");
 
-	miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write);
+	mii_dev->name = edev->name;
+	mii_dev->read = fec_miiphy_read;
+	mii_dev->write = fec_miiphy_write;
+	mii_register(mii_dev);
 
 	eth_register(edev);
 
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
index 35a6dfb..90ca618 100644
--- a/drivers/net/fsl_mcdmafec.c
+++ b/drivers/net/fsl_mcdmafec.c
@@ -29,7 +29,7 @@
 #include <command.h>
 #include <config.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #undef	ET_DEBUG
 #undef	MII_DEBUG
@@ -197,10 +197,11 @@ static void set_fec_duplex_speed(volatile fecdma_t * fecp, bd_t * bd,
 static int fec_send(struct eth_device *dev, volatile void *packet, int length)
 {
 	struct fec_info_dma *info = dev->priv;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 	cbd_t *pTbd, *pUsedTbd;
 	u16 phyStatus;
 
-	miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &phyStatus);
+	miiphy_read(mii_dev, info->phy_addr, PHY_BMSR, &phyStatus);
 
 	/* process all the consumed TBDs */
 	while (info->cleanTbdNum < CONFIG_SYS_TX_ETH_BUFFER) {
@@ -516,6 +517,9 @@ static void fec_halt(struct eth_device *dev)
 int mcdmafec_initialize(bd_t * bis)
 {
 	struct eth_device *dev;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
 	int i;
 #ifdef CONFIG_SYS_DMA_USE_INTSRAM
 	u32 tmp = CONFIG_SYS_INTSRAM + 0x2000;
@@ -572,8 +576,19 @@ int mcdmafec_initialize(bd_t * bis)
 		eth_register(dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-		miiphy_register(dev->name,
-				mcffec_miiphy_read, mcffec_miiphy_write);
+		mii_dev =
+		    (struct mii_device *)memalign(CONFIG_SYS_CACHELINE_SIZE,
+						  sizeof *mii_dev);
+		if (mii_dev == NULL)
+			hang();
+
+		memset(mii_dev, 0, sizeof(*mii_dev));
+		
+		mii_dev->name = dev->name;
+		mii_dev->read = mcffec_miiphy_read;
+		mii_dev->write = mcffec_miiphy_write;
+
+		mii_register(mii_dev);
 #endif
 
 		if (i > 0)
diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c
index 479035d..647c5d2 100644
--- a/drivers/net/kirkwood_egiga.c
+++ b/drivers/net/kirkwood_egiga.c
@@ -31,7 +31,7 @@
 #include <common.h>
 #include <net.h>
 #include <malloc.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm/errno.h>
 #include <asm/types.h>
 #include <asm/byteorder.h>
@@ -45,19 +45,20 @@
  *
  * Returns 16bit phy register value, or 0xffff on error
  */
-static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
+static int smi_reg_read(struct mii_device *mii_dev, int phy_adr, int reg_ofs)
 {
-	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct eth_device *dev = eth_get_dev_by_name(mii_dev->name);
 	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 	struct kwgbe_registers *regs = dkwgbe->regs;
 	u32 smi_reg;
 	u32 timeout;
+	int data;
 
 	/* Phyadr read request */
 	if (phy_adr == KIRKWOOD_PHY_ADR_REQUEST &&
 			reg_ofs == KIRKWOOD_PHY_ADR_REQUEST) {
 		/* */
-		*data = (u16) (KWGBEREG_RD(regs->phyadr) & PHYADR_MASK);
+		data = (KWGBEREG_RD(regs->phyadr) & PHYADR_MASK);
 		return 0;
 	}
 	/* check parameters */
@@ -107,12 +108,12 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
 	/* Wait for the data to update in the SMI register */
 	for (timeout = 0; timeout < KWGBE_PHY_SMI_TIMEOUT; timeout++) ;
 
-	*data = (u16) (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK);
+	data = (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK);
 
 	debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr,
 		reg_ofs, *data);
 
-	return 0;
+	return data;
 }
 
 /*
@@ -121,9 +122,10 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
  * Returns 0 if write succeed, -EINVAL on bad parameters
  * -ETIME on timeout
  */
-static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
+static int smi_reg_write(struct mii_device *mii_dev, int phy_adr, int reg_ofs,
+			  int data)
 {
-	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct eth_device *dev = eth_get_dev_by_name(mii_dev->name);
 	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 	struct kwgbe_registers *regs = dkwgbe->regs;
 	u32 smi_reg;
@@ -401,6 +403,10 @@ static int kwgbe_init(struct eth_device *dev)
 	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 	struct kwgbe_registers *regs = dkwgbe->regs;
 	int i;
+#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
+	 && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
+	struct mii_device *mii_dev = &dkwgbe->mii_dev;
+#endif
 
 	/* setup RX rings */
 	kwgbe_init_rx_desc_ring(dkwgbe);
@@ -452,7 +458,7 @@ static int kwgbe_init(struct eth_device *dev)
 	for (i = 0; i < 5; i++) {
 		u16 phyadr;
 
-		miiphy_read(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
+		miiphy_read(mii_dev, KIRKWOOD_PHY_ADR_REQUEST,
 				KIRKWOOD_PHY_ADR_REQUEST, &phyadr);
 		/* Return if we get link up */
 		if (miiphy_link(dev->name, phyadr))
@@ -612,6 +618,9 @@ int kirkwood_egiga_initialize(bd_t * bis)
 {
 	struct kwgbe_device *dkwgbe;
 	struct eth_device *dev;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
 	int devnum;
 	char *s;
 	u8 used_ports[MAX_KWGBE_DEVS] = CONFIG_KIRKWOOD_EGIGA_PORTS;
@@ -694,9 +703,14 @@ int kirkwood_egiga_initialize(bd_t * bis)
 		eth_register(dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-		miiphy_register(dev->name, smi_reg_read, smi_reg_write);
+		mii_dev = &dkwgbe->mii_dev;
+		mii_dev->name = dev->name;
+		mii_dev->read = smi_reg_read;
+		mii_dev->write = smi_reg_write;
+
+		mii_register(mii_dev);
 		/* Set phy address of the port */
-		miiphy_write(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
+		miiphy_write(mii_dev, KIRKWOOD_PHY_ADR_REQUEST,
 				KIRKWOOD_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
 #endif
 	}
diff --git a/drivers/net/kirkwood_egiga.h b/drivers/net/kirkwood_egiga.h
index 16d5214..8d03613 100644
--- a/drivers/net/kirkwood_egiga.h
+++ b/drivers/net/kirkwood_egiga.h
@@ -494,6 +494,7 @@ struct kwgbe_txdesc {
 /* port device data struct */
 struct kwgbe_device {
 	struct eth_device dev;
+	struct mii_device mii_dev;
 	struct kwgbe_registers *regs;
 	struct kwgbe_txdesc *p_txdesc;
 	struct kwgbe_rxdesc *p_rxdesc;
diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c
index 64be5de..356ed43 100644
--- a/drivers/net/mcffec.c
+++ b/drivers/net/mcffec.c
@@ -30,7 +30,7 @@
 #include <command.h>
 #include <net.h>
 #include <netdev.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include <asm/fec.h>
 #include <asm/immap.h>
@@ -138,10 +138,11 @@ int fec_send(struct eth_device *dev, volatile void *packet, int length)
 {
 	struct fec_info_s *info = dev->priv;
 	volatile fec_t *fecp = (fec_t *) (info->iobase);
+	struct mii_device* mii_dev = mii_get_by_name(dev->name);
 	int j, rc;
 	u16 phyStatus;
 
-	miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &phyStatus);
+	miiphy_read(mii_dev, info->phy_addr, PHY_BMSR, &phyStatus);
 
 	/* section 16.9.23.3
 	 * Wait for ready
@@ -559,6 +560,9 @@ int mcffec_initialize(bd_t * bis)
 #ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
 	u32 tmp = CONFIG_SYS_INIT_RAM_ADDR + 0x1000;
 #endif
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	struct mii_device *mii_dev;
+#endif
 
 	for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); i++) {
 
@@ -611,8 +615,19 @@ int mcffec_initialize(bd_t * bis)
 		eth_register(dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-		miiphy_register(dev->name,
-				mcffec_miiphy_read, mcffec_miiphy_write);
+		mii_dev =
+		    (struct mii_device *)memalign(CONFIG_SYS_CACHELINE_SIZE,
+						  sizeof *mii_dev);
+		if (mii_dev == NULL)
+			hang();
+
+		memset(mii_dev, 0, sizeof(*mii_dev));
+
+		mii_dev->name = dev->name;
+		mii_dev->read = mcffec_miiphy_read;
+		mii_dev->write = mcffec_miiphy_write;
+
+		mii_register(mii_dev);
 #endif
 		if (i > 0)
 			fec_info[i - 1].next = &fec_info[i];
diff --git a/drivers/net/mcfmii.c b/drivers/net/mcfmii.c
index 4acc29e..804563f 100644
--- a/drivers/net/mcfmii.c
+++ b/drivers/net/mcfmii.c
@@ -42,7 +42,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /*extern int fecpin_setclear(struct eth_device *dev, int setclear);*/
 
 #if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_CMD_MII)
-#include <miiphy.h>
+#include <miidev.h>
 
 /* Make MII read/write commands for the FEC. */
 #define mk_mii_read(ADDR, REG)		(0x60020000 | ((ADDR << 23) | \
@@ -225,12 +225,14 @@ void __mii_init(void)
 	FEC_INFO_T *info;
 	volatile FEC_T *fecp;
 	struct eth_device *dev;
+	struct mii_device *mii_dev;
 	int miispd = 0, i = 0;
 	u16 status = 0;
 	u16 linkgood = 0;
 
 	/* retrieve from register structure */
 	dev = eth_get_dev();
+	mii_dev = mii_get_by_name(dev->name);
 	info = dev->priv;
 
 	fecp = (FEC_T *) info->miibase;
@@ -255,7 +257,7 @@ void __mii_init(void)
 		status = 0;
 		i++;
 		/* Read PHY control register */
-		miiphy_read(dev->name, info->phy_addr, PHY_BMCR, &status);
+		miiphy_read(mii_dev, info->phy_addr, PHY_BMCR, &status);
 
 		/* If phy set to autonegotiate, wait for autonegotiation done,
 		 * if phy is not autonegotiating, just wait for link up.
@@ -266,7 +268,7 @@ void __mii_init(void)
 			linkgood = PHY_BMSR_LS;
 		}
 		/* Read PHY status register */
-		miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &status);
+		miiphy_read(mii_dev, info->phy_addr, PHY_BMSR, &status);
 		if ((status & linkgood) == linkgood)
 			break;
 
@@ -277,42 +279,37 @@ void __mii_init(void)
 	}
 
 	/* adapt to the duplex and speed settings of the phy */
-	info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
-	info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
+	info->dup_spd = miiphy_duplex(mii_dev, info->phy_addr) << 16;
+	info->dup_spd |= miiphy_speed(mii_dev, info->phy_addr);
 }
 
 /*
  * Read and write a MII PHY register, routines used by MII Utilities
  *
- * FIXME: These routines are expected to return 0 on success, but mii_send
- *	  does _not_ return an error code. Maybe 0xFFFF means error, i.e.
- *	  no PHY connected...
- *	  For now always return 0.
  * FIXME: These routines only work after calling eth_init() at least once!
  *	  Otherwise they hang in mii_send() !!! Sorry!
  */
 
-int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg,
-		       unsigned short *value)
+int mcffec_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
 	short rdreg;		/* register working value */
+	int value;
 
 #ifdef MII_DEBUG
 	printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
 #endif
 	rdreg = mii_send(mk_mii_read(addr, reg));
 
-	*value = rdreg;
+	value = rdreg;
 
 #ifdef MII_DEBUG
-	printf("0x%04x\n", *value);
+	printf("0x%04x\n", value);
 #endif
 
-	return 0;
+	return value;
 }
 
-int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg,
-			unsigned short value)
+int mcffec_miiphy_write(struct mii_device *dev, int addr, int reg, int value)
 {
 	short rdreg;		/* register working value */
 
diff --git a/drivers/net/mpc512x_fec.c b/drivers/net/mpc512x_fec.c
index fb2c19a..a64d0d8 100644
--- a/drivers/net/mpc512x_fec.c
+++ b/drivers/net/mpc512x_fec.c
@@ -10,7 +10,7 @@
 #include <malloc.h>
 #include <net.h>
 #include <netdev.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include <asm/io.h>
 #include "mpc512x_fec.h"
 
@@ -29,8 +29,9 @@ DECLARE_GLOBAL_DATA_PTR;
 static u32 local_crc32(char *string, unsigned int crc_value, int len);
 #endif
 
-int fec512x_miiphy_read(char *devname, u8 phyAddr, u8 regAddr, u16 * retVal);
-int fec512x_miiphy_write(char *devname, u8 phyAddr, u8 regAddr, u16 data);
+int fec512x_miiphy_read(struct mii_device *dev, int phyAddr, int regAddr);
+int fec512x_miiphy_write(struct mii_device *dev, int phyAddr, int regAddr,
+			  int data);
 int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
 
 static uchar rx_buff[FEC_BUFFER_SIZE];
@@ -38,7 +39,7 @@ static int rx_buff_idx = 0;
 
 /********************************************************************/
 #if (DEBUG & 0x2)
-static void mpc512x_fec_phydump (char *devname)
+static void mpc512x_fec_phydump (struct mii_device *dev)
 {
 	u16 phyStatus, i;
 	u8 phyAddr = CONFIG_PHY_ADDR;
@@ -50,7 +51,7 @@ static void mpc512x_fec_phydump (char *devname)
 
 	for (i = 0; i < 32; i++) {
 		if (reg_mask[i]) {
-			miiphy_read (devname, phyAddr, i, &phyStatus);
+			miiphy_read (dev, phyAddr, i, &phyStatus);
 			printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
 		}
 	}
@@ -281,6 +282,7 @@ static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis)
 int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 {
 	mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 	const u8 phyAddr = CONFIG_PHY_ADDR;	/* Only one PHY */
 	int timeout = 1;
 	u16 phyStatus;
@@ -310,7 +312,7 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 		/*
 		 * Reset PHY, then delay 300ns
 		 */
-		miiphy_write (dev->name, phyAddr, 0x0, 0x8000);
+		miiphy_write (mii_dev, phyAddr, 0x0, 0x8000);
 		udelay (1000);
 
 		if (fec->xcv_type == MII10) {
@@ -320,9 +322,9 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 #if (DEBUG & 0x2)
 			printf ("Forcing 10 Mbps ethernet link... ");
 #endif
-			miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+			miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus);
 
-			miiphy_write (dev->name, phyAddr, 0x0, 0x0180);
+			miiphy_write (mii_dev, phyAddr, 0x0, 0x0180);
 
 			timeout = 20;
 			do {    /* wait for link status to go down */
@@ -333,7 +335,7 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 #endif
 					break;
 				}
-				miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+				miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus);
 #if (DEBUG & 0x2)
 				printf ("=");
 #endif
@@ -346,7 +348,7 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 					printf ("failed. Link is down.\n");
 					break;
 				}
-				miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+				miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus);
 #if (DEBUG & 0x2)
 				printf ("+");
 #endif
@@ -359,12 +361,12 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 			/*
 			 * Set the auto-negotiation advertisement register bits
 			 */
-			miiphy_write (dev->name, phyAddr, 0x4, 0x01e1);
+			miiphy_write (mii_dev, phyAddr, 0x4, 0x01e1);
 
 			/*
 			 * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
 			 */
-			miiphy_write (dev->name, phyAddr, 0x0, 0x1200);
+			miiphy_write (mii_dev, phyAddr, 0x0, 0x1200);
 
 			/*
 			 * Wait for AN completion
@@ -380,7 +382,7 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 					return -1;
 				}
 
-				if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) {
+				if (miiphy_read (mii_dev, phyAddr, 0x1, &phyStatus) != 0) {
 #if (DEBUG & 0x2)
 					printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
 #endif
@@ -396,7 +398,7 @@ int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
 
 #if (DEBUG & 0x2)
 	if (fec->xcv_type != SEVENWIRE)
-		mpc512x_fec_phydump (dev->name);
+		mpc512x_fec_phydump (mii_dev);
 #endif
 
 #if (DEBUG & 0x1)
@@ -412,8 +414,10 @@ static void mpc512x_fec_halt (struct eth_device *dev)
 	int counter = 0xffff;
 
 #if (DEBUG & 0x2)
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
+
 	if (fec->xcv_type != SEVENWIRE)
-		mpc512x_fec_phydump (dev->name);
+		mpc512x_fec_phydump (mii_dev);
 #endif
 
 	/*
@@ -615,6 +619,7 @@ int mpc512x_fec_initialize (bd_t * bis)
 	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 	mpc512x_fec_priv *fec;
 	struct eth_device *dev;
+	struct mii_device *mii_dev;
 	int i;
 	char *tmp, *end, env_enetaddr[6];
 	void * bd;
@@ -640,10 +645,14 @@ int mpc512x_fec_initialize (bd_t * bis)
 	sprintf (dev->name, "FEC ETHERNET");
 	eth_register (dev);
 
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	miiphy_register (dev->name,
-			fec512x_miiphy_read, fec512x_miiphy_write);
-#endif
+	mii_dev = (struct mii_device *) malloc (sizeof(*mii_dev));
+	memset (mii_dev, 0, sizeof *mii_dev);
+
+	mii_dev->name = dev->name;
+	mii_dev->read = fec512x_miiphy_read;
+	mii_dev->write = fec512x_miiphy_write;
+
+	mii_register (mii_dev);
 
 	/* Clean up space FEC's MIB and FIFO RAM ...*/
 	memset ((void *)&im->fec.mib,  0x00, sizeof(im->fec.mib));
@@ -691,7 +700,7 @@ int mpc512x_fec_initialize (bd_t * bis)
 
 /* MII-interface related functions */
 /********************************************************************/
-int fec512x_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal)
+int fec512x_miiphy_read(struct mii_device *dev, int phyAddr, int regAddr)
 {
 	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 	volatile fec512x_t *eth = &im->fec;
@@ -732,13 +741,12 @@ int fec512x_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal)
 	/*
 	 * it's now safe to read the PHY's register
 	 */
-	*retVal = (u16) in_be32(&eth->mii_data);
-
-	return 0;
+	return in_be32(&eth->mii_data);
 }
 
 /********************************************************************/
-int fec512x_miiphy_write (char *devname, u8 phyAddr, u8 regAddr, u16 data)
+int fec512x_miiphy_write(struct mii_device *dev, int phyAddr, int regAddr,
+			  int data)
 {
 	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 	volatile fec512x_t *eth = &im->fec;
diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c
index 1876b76..ad1538a 100644
--- a/drivers/net/mpc5xxx_fec.c
+++ b/drivers/net/mpc5xxx_fec.c
@@ -12,7 +12,7 @@
 #include <malloc.h>
 #include <net.h>
 #include <netdev.h>
-#include <miiphy.h>
+#include <miidev.h>
 #include "mpc5xxx_fec.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -24,8 +24,8 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif
 
 #if (DEBUG & 0x60)
-static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec);
-static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec);
+static void tfifo_print(struct mii_device *dev, mpc5xxx_fec_priv *fec);
+static void rfifo_print(struct mii_device *dev, mpc5xxx_fec_priv *fec);
 #endif /* DEBUG */
 
 #if (DEBUG & 0x40)
@@ -39,14 +39,14 @@ typedef struct {
     uint8 head[16];             /* MAC header(6 + 6 + 2) + 2(aligned) */
 } NBUF;
 
-int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal);
-int fec5xxx_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
+int fec5xxx_miiphy_read(struct mii_device *dev, int phyAddr, int regAddr);
+int fec5xxx_miiphy_write(struct mii_device *dev, int phyAddr, int regAddr, int data);
 
 static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis);
 
 /********************************************************************/
 #if (DEBUG & 0x2)
-static void mpc5xxx_fec_phydump (char *devname)
+static void mpc5xxx_fec_phydump (struct mii_device *dev)
 {
 	uint16 phyStatus, i;
 	uint8 phyAddr = CONFIG_PHY_ADDR;
@@ -64,7 +64,7 @@ static void mpc5xxx_fec_phydump (char *devname)
 
 	for (i = 0; i < 32; i++) {
 		if (reg_mask[i]) {
-			miiphy_read(devname, phyAddr, i, &phyStatus);
+			miiphy_read(dev, phyAddr, i, &phyStatus);
 			printf("Mii reg %d: 0x%04x\n", i, phyStatus);
 		}
 	}
@@ -246,6 +246,9 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
 {
 	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
 	struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
+#if (DEBUG & 0x2)
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
+#endif
 
 #if (DEBUG & 0x1)
 	printf ("mpc5xxx_fec_init... Begin\n");
@@ -371,7 +374,7 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
 
 #if (DEBUG & 0x2)
 	if (fec->xcv_type != SEVENWIRE)
-		mpc5xxx_fec_phydump (dev->name);
+		mpc5xxx_fec_phydump (mii_dev);
 #endif
 
 	/*
@@ -392,6 +395,7 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
 	const uint8 phyAddr = CONFIG_PHY_ADDR;	/* Only one PHY */
 	static int initialized = 0;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 	if(initialized)
 		return 0;
@@ -471,13 +475,13 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 		/*
 		 * Reset PHY, then delay 300ns
 		 */
-		miiphy_write(dev->name, phyAddr, 0x0, 0x8000);
+		miiphy_write(mii_dev, phyAddr, 0x0, 0x8000);
 		udelay(1000);
 
 #if defined(CONFIG_UC101) || defined(CONFIG_MUCMC52)
 		/* Set the LED configuration Register for the UC101
 		   and MUCMC52 Board */
-		miiphy_write(dev->name, phyAddr, 0x14, 0x4122);
+		miiphy_write(mii_dev, phyAddr, 0x14, 0x4122);
 #endif
 		if (fec->xcv_type == MII10) {
 			/*
@@ -486,11 +490,11 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 #if (DEBUG & 0x2)
 			printf("Forcing 10 Mbps ethernet link... ");
 #endif
-			miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
+			miiphy_read(mii_dev, phyAddr, 0x1, &phyStatus);
 			/*
-			miiphy_write(dev->name, fec, phyAddr, 0x0, 0x0100);
+			miiphy_write(mii_dev, fec, phyAddr, 0x0, 0x0100);
 			*/
-			miiphy_write(dev->name, phyAddr, 0x0, 0x0180);
+			miiphy_write(mii_dev, phyAddr, 0x0, 0x0180);
 
 			timeout = 20;
 			do {	/* wait for link status to go down */
@@ -501,7 +505,7 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 #endif
 					break;
 				}
-				miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
+				miiphy_read(mii_dev, phyAddr, 0x1, &phyStatus);
 #if (DEBUG & 0x2)
 				printf("=");
 #endif
@@ -514,7 +518,7 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 					printf("failed. Link is down.\n");
 					break;
 				}
-				miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
+				miiphy_read(mii_dev, phyAddr, 0x1, &phyStatus);
 #if (DEBUG & 0x2)
 				printf("+");
 #endif
@@ -527,12 +531,12 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 			/*
 			 * Set the auto-negotiation advertisement register bits
 			 */
-			miiphy_write(dev->name, phyAddr, 0x4, 0x01e1);
+			miiphy_write(mii_dev, phyAddr, 0x4, 0x01e1);
 
 			/*
 			 * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
 			 */
-			miiphy_write(dev->name, phyAddr, 0x0, 0x1200);
+			miiphy_write(mii_dev, phyAddr, 0x0, 0x1200);
 
 			/*
 			 * Wait for AN completion
@@ -548,7 +552,7 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 					return -1;
 				}
 
-				if (miiphy_read(dev->name, phyAddr, 0x1, &phyStatus) != 0) {
+				if (miiphy_read(mii_dev, phyAddr, 0x1, &phyStatus) != 0) {
 #if (DEBUG & 0x2)
 					printf("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
 #endif
@@ -565,7 +569,7 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
 
 #if (DEBUG & 0x2)
 	if (fec->xcv_type != SEVENWIRE)
-		mpc5xxx_fec_phydump (dev->name);
+		mpc5xxx_fec_phydump (mii_dev);
 #endif
 
 
@@ -586,8 +590,10 @@ static void mpc5xxx_fec_halt(struct eth_device *dev)
 	int counter = 0xffff;
 
 #if (DEBUG & 0x2)
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
+
 	if (fec->xcv_type != SEVENWIRE)
-		mpc5xxx_fec_phydump (dev->name);
+		mpc5xxx_fec_phydump (mii_dev);
 #endif
 
 	/*
@@ -659,7 +665,7 @@ static void mpc5xxx_fec_halt(struct eth_device *dev)
 #if (DEBUG & 0x60)
 /********************************************************************/
 
-static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec)
+static void tfifo_print(struct mii_device *dev, mpc5xxx_fec_priv *fec)
 {
 	uint16 phyAddr = CONFIG_PHY_ADDR;
 	uint16 phyStatus;
@@ -667,7 +673,7 @@ static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec)
 	if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
 		|| (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
 
-		miiphy_read(devname, phyAddr, 0x1, &phyStatus);
+		miiphy_read(dev, phyAddr, 0x1, &phyStatus);
 		printf("\nphyStatus: 0x%04x\n", phyStatus);
 		printf("ecntrl:   0x%08x\n", fec->eth->ecntrl);
 		printf("ievent:   0x%08x\n", fec->eth->ievent);
@@ -683,7 +689,7 @@ static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec)
 	}
 }
 
-static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec)
+static void rfifo_print(struct mii_device *dev, mpc5xxx_fec_priv *fec)
 {
 	uint16 phyAddr = CONFIG_PHY_ADDR;
 	uint16 phyStatus;
@@ -691,7 +697,7 @@ static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec)
 	if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
 		|| (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
 
-		miiphy_read(devname, phyAddr, 0x1, &phyStatus);
+		miiphy_read(dev, phyAddr, 0x1, &phyStatus);
 		printf("\nphyStatus: 0x%04x\n", phyStatus);
 		printf("ecntrl:   0x%08x\n", fec->eth->ecntrl);
 		printf("ievent:   0x%08x\n", fec->eth->ievent);
@@ -719,10 +725,12 @@ static int mpc5xxx_fec_send(struct eth_device *dev, volatile void *eth_data,
 	 */
 	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
 	volatile FEC_TBD *pTbd;
+	struct mii_device *mii_dev = mii_get_by_name(dev->name);
 
 #if (DEBUG & 0x20)
+
 	printf("tbd status: 0x%04x\n", fec->tbdBase[0].status);
-	tfifo_print(dev->name, fec);
+	tfifo_print(mii_dev, fec);
 #endif
 
 	/*
@@ -765,7 +773,7 @@ static int mpc5xxx_fec_send(struct eth_device *dev, volatile void *eth_data,
 	 */
 	if (fec->xcv_type != SEVENWIRE) {
 		uint16 phyStatus;
-		miiphy_read(dev->name, 0, 0x1, &phyStatus);
+		miiphy_read(mii_dev, 0, 0x1, &phyStatus);
 	}
 
 	/*
@@ -773,11 +781,11 @@ static int mpc5xxx_fec_send(struct eth_device *dev, volatile void *eth_data,
 	 */
 
 #if (DEBUG & 0x20)
-	tfifo_print(dev->name, fec);
+	tfifo_print(mii_dev, fec);
 #endif
 	SDMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
 #if (DEBUG & 0x20)
-	tfifo_print(dev->name, fec);
+	tfifo_print(mii_dev, fec);
 #endif
 #if (DEBUG & 0x8)
 	printf( "+" );
@@ -888,6 +896,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
 {
 	mpc5xxx_fec_priv *fec;
 	struct eth_device *dev;
+	struct mii_device *mii_dev;
 	char *tmp, *end;
 	char env_enetaddr[6];
 	int i;
@@ -926,10 +935,14 @@ int mpc5xxx_fec_initialize(bd_t * bis)
 	sprintf(dev->name, "FEC ETHERNET");
 	eth_register(dev);
 
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	miiphy_register (dev->name,
-			fec5xxx_miiphy_read, fec5xxx_miiphy_write);
-#endif
+	mii_dev = (struct mii_device *)malloc(sizeof(*mii_dev));
+	memset(mii_dev, 0, sizeof *mii_dev);
+
+	mii_dev->name = dev->name;
+	mii_dev->read = fec5xxx_miiphy_read;
+	mii_dev->write = fec5xxx_miiphy_write;
+
+	mii_register (mii_dev);
 
 	/*
 	 * Try to set the mac address now. The fec mac address is
@@ -951,7 +964,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
 
 /* MII-interface related functions */
 /********************************************************************/
-int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal)
+int fec5xxx_miiphy_read(struct mii_device *dev, int phyAddr, int regAddr)
 {
 	ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
 	uint32 reg;		/* convenient holder for the PHY register */
@@ -987,13 +1000,11 @@ int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * re
 	/*
 	 * it's now safe to read the PHY's register
 	 */
-	*retVal = (uint16) eth->mii_data;
-
-	return 0;
+	return eth->mii_data;
 }
 
 /********************************************************************/
-int fec5xxx_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data)
+int fec5xxx_miiphy_write(struct mii_device *dev, int phyAddr, int regAddr, int data)
 {
 	ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
 	uint32 reg;		/* convenient holder for the PHY register */
diff --git a/drivers/net/ns7520_eth.c b/drivers/net/ns7520_eth.c
index c28726e..535199a 100644
--- a/drivers/net/ns7520_eth.c
+++ b/drivers/net/ns7520_eth.c
@@ -761,25 +761,17 @@ enum mii_status {
 /**
  * Read a 16-bit value from an MII register.
  */
-extern int ns7520_miiphy_read(char *devname, unsigned char const addr,
-		unsigned char const reg, unsigned short *const value)
+extern int ns7520_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
-	int ret = MII_STATUS_FAILURE;
-
 	/* Parameter checks */
 	if (addr > MII_ADDRESS_MAX) {
 		ERROR(("invalid addr, 0x%02X", addr));
-		goto miiphy_read_failed_0;
+		return -1;
 	}
 
 	if (reg > MII_REGISTER_MAX) {
 		ERROR(("invalid reg, 0x%02X", reg));
-		goto miiphy_read_failed_0;
-	}
-
-	if (value == NULL) {
-		ERROR(("NULL value"));
-		goto miiphy_read_failed_0;
+		return -1;
 	}
 
 	DEBUG_FN(DEBUG_MII_LOW);
@@ -796,19 +788,14 @@ extern int ns7520_miiphy_read(char *devname, unsigned char const addr,
 
 	*get_eth_reg_addr(NS7520_ETH_MCMD) = 0;
 
-	*value = (*get_eth_reg_addr(NS7520_ETH_MRDD));
-	ret = MII_STATUS_SUCCESS;
-	/* Fall through */
-
-      miiphy_read_failed_0:
-	return (ret);
+	return (*get_eth_reg_addr(NS7520_ETH_MRDD));
 }
 
 /**
  * Write a 16-bit value to an MII register.
  */
-extern int ns7520_miiphy_write(char *devname, unsigned char const addr,
-		unsigned char const reg, unsigned short const value)
+extern int ns7520_miiphy_write(struct mii_device *dev, int addr, int reg,
+			       int value)
 {
 	int ret = MII_STATUS_FAILURE;
 
@@ -844,7 +831,16 @@ extern int ns7520_miiphy_write(char *devname, unsigned char const addr,
 int ns7520_miiphy_initialize(bd_t *bis)
 {
 #if defined(CONFIG_MII)
-	miiphy_register("ns7520phy", ns7520_miiphy_read, ns7520_miiphy_write);
+	struct mii_device *dev = calloc(1, sizeof(struct mii_device));
+
+	if (!dev)
+		return -1;
+
+	dev->name = "ns7520phy";
+	dev->read = ns7520_miiphy_read;
+	dev->write = ns7520_miiphy_write;
+
+	mii_register(dev);
 #endif
 	return 0;
 }
diff --git a/drivers/net/ns9750_eth.c b/drivers/net/ns9750_eth.c
index d4901b4..031c8f8 100644
--- a/drivers/net/ns9750_eth.c
+++ b/drivers/net/ns9750_eth.c
@@ -466,7 +466,7 @@ static void ns9750_link_force (void)
 		uiControl |= PHY_BMCR_100MB;
 		uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX;
 	} else
-		uiControl |= PHY_BMCR_10_MBPS;
+		uiControl |= BMCR_SPEED10;
 
 	if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) ==
 	    FS_EEPROM_AUTONEG_DUPLEX_FULL) {
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 3b92614..6775e44 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -27,8 +27,10 @@ LIB	:= $(obj)libphy.a
 
 COBJS-$(CONFIG_BITBANGMII) += miiphybb.o
 COBJS-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o
+COBJS-$(CONFIG_MII) += miidev.o
+COBJS-$(CONFIG_CMD_MII) += miidev.o
 
-COBJS	:= $(COBJS-y)
+COBJS	:= $(sort $(COBJS-y))
 SRCS	:= $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/common/miiphyutil.c b/drivers/net/phy/miidev.c
similarity index 50%
rename from common/miiphyutil.c
rename to drivers/net/phy/miidev.c
index 66fd9ca..8a7ece6 100644
--- a/common/miiphyutil.c
+++ b/drivers/net/phy/miidev.c
@@ -2,6 +2,8 @@
  * (C) Copyright 2001
  * Gerald Van Baren, Custom IDEAS, vanbaren at cideas.com.
  *
+ * (C) Copyright 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -21,125 +23,94 @@
  * MA 02111-1307 USA
  */
 
-/*
- * This provides a bit-banged interface to the ethernet MII management
- * channel.
- */
-
 #include <common.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include <asm/types.h>
 #include <linux/list.h>
 #include <malloc.h>
 #include <net.h>
 
-/* local debug macro */
-#undef MII_DEBUG
-
-#undef debug
-#ifdef MII_DEBUG
-#define debug(fmt,args...)	printf (fmt ,##args)
-#else
-#define debug(fmt,args...)
-#endif /* MII_DEBUG */
-
-struct mii_dev {
-	struct list_head link;
-	char *name;
-	int (*read) (char *devname, unsigned char addr,
-		     unsigned char reg, unsigned short *value);
-	int (*write) (char *devname, unsigned char addr,
-		      unsigned char reg, unsigned short value);
-};
-
-static struct list_head mii_devs;
-static struct mii_dev *current_mii;
+static struct mii_device mii_devs;
+static struct mii_device *current_mii;
 
 /*****************************************************************************
  *
  * Initialize global data. Need to be called before any other miiphy routine.
  */
-void miiphy_init ()
+void mii_dev_init(void)
 {
-	INIT_LIST_HEAD (&mii_devs);
+	INIT_LIST_HEAD(&mii_devs.list);
 	current_mii = NULL;
 }
 
+struct mii_device* mii_get_current_dev(void)
+{
+	return current_mii;
+}
+
+struct mii_device* mii_get_by_name(char* name)
+{
+	struct list_head *pos;
+	struct mii_device *dev;
+
+	if(!name)
+		return NULL;
+
+	list_for_each(pos, &(mii_devs.list)) {
+		dev = list_entry(pos, struct mii_device, list);
+		if(strcmp(dev->name, name) == 0)
+			return dev;
+	}
+
+	return NULL;
+}
+
 /*****************************************************************************
  *
  * Register read and write MII access routines for the device <name>.
  */
-void miiphy_register (char *name,
-		      int (*read) (char *devname, unsigned char addr,
-				   unsigned char reg, unsigned short *value),
-		      int (*write) (char *devname, unsigned char addr,
-				    unsigned char reg, unsigned short value))
+int mii_register(struct mii_device *dev)
 {
-	struct list_head *entry;
-	struct mii_dev *new_dev;
-	struct mii_dev *miidev;
-	unsigned int name_len;
+	if(!dev || !dev->read || !dev->write)
+		return -1;
 
 	/* check if we have unique name */
-	list_for_each (entry, &mii_devs) {
-		miidev = list_entry (entry, struct mii_dev, link);
-		if (strcmp (miidev->name, name) == 0) {
-			printf ("miiphy_register: non unique device name "
-				"'%s'\n", name);
-			return;
-		}
+	if (mii_get_by_name(dev->name)) {
+		printf ("mii_register: non unique device name "
+			"'%s'\n", dev->name);
+		return -1;
 	}
 
-	/* allocate memory */
-	name_len = strlen (name);
-	new_dev =
-	    (struct mii_dev *)malloc (sizeof (struct mii_dev) + name_len + 1);
-
-	if (new_dev == NULL) {
-		printf ("miiphy_register: cannot allocate memory for '%s'\n",
-			name);
-		return;
-	}
-	memset (new_dev, 0, sizeof (struct mii_dev) + name_len);
-
-	/* initalize mii_dev struct fields */
-	INIT_LIST_HEAD (&new_dev->link);
-	new_dev->read = read;
-	new_dev->write = write;
-	new_dev->name = (char *)(new_dev + 1);
-	strncpy (new_dev->name, name, name_len);
-	new_dev->name[name_len] = '\0';
-
-	debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
-	       new_dev->name, new_dev->read, new_dev->write);
+	debug ("mii_register: added '%s', read=0x%08lx, write=0x%08lx\n",
+	       dev->name, dev->read, dev->write);
 
 	/* add it to the list */
-	list_add_tail (&new_dev->link, &mii_devs);
+	list_add_tail(&dev->list, &mii_devs.list);
 
 	if (!current_mii)
-		current_mii = new_dev;
+		current_mii = dev;
+
+	return 0;
 }
 
-int miiphy_set_current_dev (char *devname)
+int miiphy_set_current_dev(char *devname)
 {
-	struct list_head *entry;
-	struct mii_dev *dev;
+	struct mii_device *dev;
 
-	list_for_each (entry, &mii_devs) {
-		dev = list_entry (entry, struct mii_dev, link);
+	dev = mii_get_by_name(devname);
 
-		if (strcmp (devname, dev->name) == 0) {
-			current_mii = dev;
-			return 0;
-		}
+	if (!dev) {
+		printf ("No such device: %s\n", devname);
+		return 1;
 	}
 
-	printf ("No such device: %s\n", devname);
-	return 1;
+	current_mii = dev;
+
+	return 0;
 }
 
-char *miiphy_get_current_dev ()
+char* miiphy_get_current_dev(void)
 {
 	if (current_mii)
 		return current_mii->name;
@@ -147,98 +118,75 @@ char *miiphy_get_current_dev ()
 	return NULL;
 }
 
+
 /*****************************************************************************
  *
- * Read to variable <value> from the PHY attached to device <devname>,
- * use PHY address <addr> and register <reg>.
- *
- * Returns:
- *   0 on success
+ * Print out list of registered MII capable devices.
  */
-int miiphy_read (char *devname, unsigned char addr, unsigned char reg,
-		 unsigned short *value)
+void miiphy_listdev(void)
 {
-	struct list_head *entry;
-	struct mii_dev *dev;
-	int found_dev = 0;
-	int read_ret = 0;
+	struct list_head *pos;
+	struct mii_device *dev;
 
-	if (!devname) {
-		printf ("NULL device name!\n");
-		return 1;
-	}
-
-	list_for_each (entry, &mii_devs) {
-		dev = list_entry (entry, struct mii_dev, link);
-
-		if (strcmp (devname, dev->name) == 0) {
-			found_dev = 1;
-			read_ret = dev->read (devname, addr, reg, value);
-			break;
-		}
+	puts ("MII devices: ");
+	list_for_each(pos, &(mii_devs.list)) {
+		dev = list_entry(pos, struct mii_device, list);
+		printf ("'%s' ", dev->name);
 	}
 
-	if (found_dev == 0)
-		printf ("No such device: %s\n", devname);
+	puts ("\n");
 
-	return ((found_dev) ? read_ret : 1);
+	if (current_mii)
+		printf ("Current device: '%s'\n", current_mii->name);
 }
 
+/*
+ * Old Compatible API
+ */
+
 /*****************************************************************************
  *
- * Write <value> to the PHY attached to device <devname>,
+ * Read to variable <value> from the PHY attached to device <devname>,
  * use PHY address <addr> and register <reg>.
  *
  * Returns:
  *   0 on success
  */
-int miiphy_write (char *devname, unsigned char addr, unsigned char reg,
-		  unsigned short value)
+int miiphy_read(struct mii_device *dev, unsigned char addr, unsigned char reg,
+		unsigned short *value)
 {
-	struct list_head *entry;
-	struct mii_dev *dev;
-	int found_dev = 0;
-	int write_ret = 0;
+	int val;
 
-	if (!devname) {
-		printf ("NULL device name!\n");
+	if (!dev || !value)
 		return 1;
-	}
 
-	list_for_each (entry, &mii_devs) {
-		dev = list_entry (entry, struct mii_dev, link);
+	val = mii_read(dev, addr, reg);
 
-		if (strcmp (devname, dev->name) == 0) {
-			found_dev = 1;
-			write_ret = dev->write (devname, addr, reg, value);
-			break;
-		}
+	if (val < 0) {
+		*value = 0xffff;
+		return val;
 	}
 
-	if (found_dev == 0)
-		printf ("No such device: %s\n", devname);
+	*value = val;
 
-	return ((found_dev) ? write_ret : 1);
+	 return 0;
 }
 
 /*****************************************************************************
  *
- * Print out list of registered MII capable devices.
+ * Write <value> to the PHY attached to device <devname>,
+ * use PHY address <addr> and register <reg>.
+ *
+ * Returns:
+ *   0 on success
  */
-void miiphy_listdev (void)
+int miiphy_write(struct mii_device *dev, unsigned char addr, unsigned char reg,
+		 unsigned short value)
 {
-	struct list_head *entry;
-	struct mii_dev *dev;
-
-	puts ("MII devices: ");
-	list_for_each (entry, &mii_devs) {
-		dev = list_entry (entry, struct mii_dev, link);
-		printf ("'%s' ", dev->name);
-	}
-	puts ("\n");
+	if (!dev)
+		return 1;
 
-	if (current_mii)
-		printf ("Current device: '%s'\n", current_mii->name);
+	return mii_write(dev, addr, reg, value);
 }
 
 /*****************************************************************************
@@ -252,36 +200,36 @@ void miiphy_listdev (void)
  * Returns:
  *   0 on success
  */
-int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
-		 unsigned char *model, unsigned char *rev)
+int miiphy_info(struct mii_device *dev, unsigned char addr, unsigned int *oui,
+		unsigned char *model, unsigned char *rev)
 {
 	unsigned int reg = 0;
 	unsigned short tmp;
 
-	if (miiphy_read (devname, addr, PHY_PHYIDR2, &tmp) != 0) {
-		debug ("PHY ID register 2 read failed\n");
-		return (-1);
+	if (miiphy_read(dev, addr, PHY_PHYIDR2, &tmp) != 0) {
+		debug("PHY ID register 2 read failed\n");
+		return -1;
 	}
 	reg = tmp;
 
-	debug ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg);
+	debug("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg);
 
 	if (reg == 0xFFFF) {
 		/* No physical device present at this address */
-		return (-1);
+		return -1;
 	}
 
-	if (miiphy_read (devname, addr, PHY_PHYIDR1, &tmp) != 0) {
-		debug ("PHY ID register 1 read failed\n");
-		return (-1);
+	if (miiphy_read(dev, addr, PHY_PHYIDR1, &tmp) != 0) {
+		debug("PHY ID register 1 read failed\n");
+		return -1;
 	}
 	reg |= tmp << 16;
-	debug ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
+	debug("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
 
 	*oui = (reg >> 10);
 	*model = (unsigned char)((reg >> 4) & 0x0000003F);
 	*rev = (unsigned char)(reg & 0x0000000F);
-	return (0);
+	return 0;
 }
 
 /*****************************************************************************
@@ -290,21 +238,21 @@ int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
  * Returns:
  *   0 on success
  */
-int miiphy_reset (char *devname, unsigned char addr)
+int miiphy_reset(struct mii_device *dev, unsigned char addr)
 {
 	unsigned short reg;
 	int loop_cnt;
 
-	if (miiphy_read (devname, addr, PHY_BMCR, &reg) != 0) {
-		debug ("PHY status read failed\n");
-		return (-1);
+	if (miiphy_read(dev, addr, PHY_BMCR, &reg) != 0) {
+		debug("PHY status read failed\n");
+		return -1;
 	}
-	if (miiphy_write (devname, addr, PHY_BMCR, reg | 0x8000) != 0) {
-		debug ("PHY reset failed\n");
-		return (-1);
+	if (miiphy_write(dev, addr, PHY_BMCR, reg | 0x8000) != 0) {
+		debug("PHY reset failed\n");
+		return -1;
 	}
 #ifdef CONFIG_PHY_RESET_DELAY
-	udelay (CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
+	udelay(CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
 #endif
 	/*
 	 * Poll the control register for the reset bit to go to 0 (it is
@@ -314,25 +262,25 @@ int miiphy_reset (char *devname, unsigned char addr)
 	loop_cnt = 0;
 	reg = 0x8000;
 	while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) {
-		if (miiphy_read (devname, addr, PHY_BMCR, &reg) != 0) {
-			debug ("PHY status read failed\n");
-			return (-1);
+		if (miiphy_read(dev, addr, PHY_BMCR, &reg) != 0) {
+			debug("PHY status read failed\n");
+			return -1;
 		}
 	}
 	if ((reg & 0x8000) == 0) {
-		return (0);
+		return 0;
 	} else {
-		puts ("PHY reset timed out\n");
-		return (-1);
+		puts("PHY reset timed out\n");
+		return -1;
 	}
-	return (0);
+	return 0;
 }
 
 /*****************************************************************************
  *
  * Determine the ethernet speed (10/100/1000).  Return 10 on error.
  */
-int miiphy_speed (char *devname, unsigned char addr)
+int miiphy_speed(struct mii_device *dev, unsigned char addr)
 {
 	u16 bmcr, anlpar;
 
@@ -343,15 +291,15 @@ int miiphy_speed (char *devname, unsigned char addr)
 	 * Check for 1000BASE-X.  If it is supported, then assume that the speed
 	 * is 1000.
 	 */
-	if (miiphy_is_1000base_x (devname, addr)) {
+	if (miiphy_is_1000base_x(dev, addr)) {
 		return _1000BASET;
 	}
 	/*
 	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
 	 */
 	/* Check for 1000BASE-T. */
-	if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
-		printf ("PHY 1000BT status");
+	if (miiphy_read(dev, addr, PHY_1000BTSR, &btsr)) {
+		printf("PHY 1000BT status");
 		goto miiphy_read_failed;
 	}
 	if (btsr != 0xFFFF &&
@@ -361,15 +309,15 @@ int miiphy_speed (char *devname, unsigned char addr)
 #endif /* CONFIG_PHY_GIGE */
 
 	/* Check Basic Management Control Register first. */
-	if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
-		printf ("PHY speed");
+	if (miiphy_read(dev, addr, PHY_BMCR, &bmcr)) {
+		printf("PHY speed");
 		goto miiphy_read_failed;
 	}
 	/* Check if auto-negotiation is on. */
 	if (bmcr & PHY_BMCR_AUTON) {
 		/* Get auto-negotiation results. */
-		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
-			printf ("PHY AN speed");
+		if (miiphy_read(dev, addr, PHY_ANLPAR, &anlpar)) {
+			printf("PHY AN speed");
 			goto miiphy_read_failed;
 		}
 		return (anlpar & PHY_ANLPAR_100) ? _100BASET : _10BASET;
@@ -377,8 +325,8 @@ int miiphy_speed (char *devname, unsigned char addr)
 	/* Get speed from basic control settings. */
 	return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET;
 
-      miiphy_read_failed:
-	printf (" read failed, assuming 10BASE-T\n");
+miiphy_read_failed:
+	printf(" read failed, assuming 10BASE-T\n");
 	return _10BASET;
 }
 
@@ -386,7 +334,7 @@ int miiphy_speed (char *devname, unsigned char addr)
  *
  * Determine full/half duplex.  Return half on error.
  */
-int miiphy_duplex (char *devname, unsigned char addr)
+int miiphy_duplex(struct mii_device *dev, unsigned char addr)
 {
 	u16 bmcr, anlpar;
 
@@ -394,10 +342,10 @@ int miiphy_duplex (char *devname, unsigned char addr)
 	u16 btsr;
 
 	/* Check for 1000BASE-X. */
-	if (miiphy_is_1000base_x (devname, addr)) {
+	if (miiphy_is_1000base_x(dev, addr)) {
 		/* 1000BASE-X */
-		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
-			printf ("1000BASE-X PHY AN duplex");
+		if (miiphy_read(dev, addr, PHY_ANLPAR, &anlpar)) {
+			printf("1000BASE-X PHY AN duplex");
 			goto miiphy_read_failed;
 		}
 	}
@@ -405,8 +353,8 @@ int miiphy_duplex (char *devname, unsigned char addr)
 	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
 	 */
 	/* Check for 1000BASE-T. */
-	if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
-		printf ("PHY 1000BT status");
+	if (miiphy_read(dev, addr, PHY_1000BTSR, &btsr)) {
+		printf("PHY 1000BT status");
 		goto miiphy_read_failed;
 	}
 	if (btsr != 0xFFFF) {
@@ -419,25 +367,25 @@ int miiphy_duplex (char *devname, unsigned char addr)
 #endif /* CONFIG_PHY_GIGE */
 
 	/* Check Basic Management Control Register first. */
-	if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
-		puts ("PHY duplex");
+	if (miiphy_read(dev, addr, PHY_BMCR, &bmcr)) {
+		puts("PHY duplex");
 		goto miiphy_read_failed;
 	}
 	/* Check if auto-negotiation is on. */
 	if (bmcr & PHY_BMCR_AUTON) {
 		/* Get auto-negotiation results. */
-		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
-			puts ("PHY AN duplex");
+		if (miiphy_read(dev, addr, PHY_ANLPAR, &anlpar)) {
+			puts("PHY AN duplex");
 			goto miiphy_read_failed;
 		}
 		return (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) ?
-		    FULL : HALF;
+			FULL : HALF;
 	}
 	/* Get speed from basic control settings. */
 	return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF;
 
-      miiphy_read_failed:
-	printf (" read failed, assuming half duplex\n");
+miiphy_read_failed:
+	printf(" read failed, assuming half duplex\n");
 	return HALF;
 }
 
@@ -446,14 +394,14 @@ int miiphy_duplex (char *devname, unsigned char addr)
  * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
  * 1000BASE-T, or on error.
  */
-int miiphy_is_1000base_x (char *devname, unsigned char addr)
+int miiphy_is_1000base_x(struct mii_device *dev, unsigned char addr)
 {
 #if defined(CONFIG_PHY_GIGE)
 	u16 exsr;
 
-	if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) {
-		printf ("PHY extended status read failed, assuming no "
-			"1000BASE-X\n");
+	if (miiphy_read(dev, addr, PHY_EXSR, &exsr)) {
+		printf("PHY extended status read failed, assuming no "
+		       "1000BASE-X\n");
 		return 0;
 	}
 	return 0 != (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH));
@@ -467,22 +415,22 @@ int miiphy_is_1000base_x (char *devname, unsigned char addr)
  *
  * Determine link status
  */
-int miiphy_link (char *devname, unsigned char addr)
+int miiphy_link(struct mii_device *dev, unsigned char addr)
 {
 	unsigned short reg;
 
 	/* dummy read; needed to latch some phys */
-	(void)miiphy_read (devname, addr, PHY_BMSR, &reg);
-	if (miiphy_read (devname, addr, PHY_BMSR, &reg)) {
-		puts ("PHY_BMSR read failed, assuming no link\n");
-		return (0);
+	miiphy_read(dev, addr, PHY_BMSR, &reg);
+	if (miiphy_read(dev, addr, PHY_BMSR, &reg)) {
+		puts("PHY_BMSR read failed, assuming no link\n");
+		return 0;
 	}
 
 	/* Determine if a link is active */
 	if ((reg & PHY_BMSR_LS) != 0) {
-		return (1);
+		return 1;
 	} else {
-		return (0);
+		return 0;
 	}
 }
 #endif
diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c
index b77c917..23bd998 100644
--- a/drivers/net/phy/miiphybb.c
+++ b/drivers/net/phy/miiphybb.c
@@ -27,6 +27,7 @@
  */
 
 #include <common.h>
+#include <miidev.h>
 #include <ioports.h>
 #include <ppc_asm.tmpl>
 
@@ -118,8 +119,15 @@ static void miiphy_pre (char read, unsigned char addr, unsigned char reg)
  * Returns:
  *   0 on success
  */
-int bb_miiphy_read (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short *value)
+int bb_miiphy_read(struct mii_device *dev, unsigned char addr,
+		   unsigned char reg, unsigned short *value)
+{
+	*value = dev->read (dev, addr, reg);
+
+	 return 0;
+}
+
+int mii_bitbang_read(struct mii_device *dev, int addr, int reg)
 {
 	short rdreg;		/* register working value */
 	int j;			/* counter */
@@ -127,11 +135,6 @@ int bb_miiphy_read (char *devname, unsigned char addr,
 	volatile ioport_t *iop = ioport_addr ((immap_t *) CONFIG_SYS_IMMR, MDIO_PORT);
 #endif
 
-	if (value == NULL) {
-		puts("NULL value pointer\n");
-		return (-1);
-	}
-
 	miiphy_pre (1, addr, reg);
 
 	/* tri-state our MDIO I/O pin so we can read */
@@ -151,8 +154,7 @@ int bb_miiphy_read (char *devname, unsigned char addr,
 			MIIDELAY;
 		}
 		/* There is no PHY, set value to 0xFFFF and return */
-		*value = 0xFFFF;
-		return (-1);
+		return 0xFFFF;
 	}
 
 	MDC (0);
@@ -176,13 +178,11 @@ int bb_miiphy_read (char *devname, unsigned char addr,
 	MDC (1);
 	MIIDELAY;
 
-	*value = rdreg;
-
 #ifdef DEBUG
-	printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
+	printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, rdreg);
 #endif
 
-	return 0;
+	return rdreg;
 }
 
 
@@ -193,8 +193,13 @@ int bb_miiphy_read (char *devname, unsigned char addr,
  * Returns:
  *   0 on success
  */
-int bb_miiphy_write (char *devname, unsigned char addr,
-		unsigned char reg, unsigned short value)
+int bb_miiphy_write(struct mii_device *dev, unsigned char addr,
+		    unsigned char reg, unsigned short value)
+{
+	return dev->write (dev, addr, reg, value);
+}
+
+int mii_bitbang_write(struct mii_device *dev, int addr, int reg, int value)
 {
 	int j;			/* counter */
 #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c
index 3754e8b..ca32adb 100644
--- a/drivers/net/phy/mv88e61xx.c
+++ b/drivers/net/phy/mv88e61xx.c
@@ -36,14 +36,14 @@
  * By default single chip mode is configured
  * multichip mode operation can be configured in board header
  */
-static int mv88e61xx_busychk_multic(char *name, u32 devaddr)
+static int mv88e61xx_busychk_multic(struct mii_device *dev, u32 devaddr)
 {
 	u16 reg = 0;
 	u32 timeout = MV88E61XX_PHY_TIMEOUT;
 
 	/* Poll till SMIBusy bit is clear */
 	do {
-		miiphy_read(name, devaddr, 0x0, &reg);
+		miiphy_read(dev, devaddr, 0x0, &reg);
 		if (timeout-- == 0) {
 			printf("SMI busy timeout\n");
 			return -1;
@@ -52,41 +52,41 @@ static int mv88e61xx_busychk_multic(char *name, u32 devaddr)
 	return 0;
 }
 
-static void mv88e61xx_wr_phy(char *name, u32 phy_adr, u32 reg_ofs, u16 data)
+static void mv88e61xx_wr_phy(struct mii_device *dev, u32 phy_adr, u32 reg_ofs, u16 data)
 {
 	u16 mii_dev_addr;
 
 	/* command to read PHY dev address */
-	if (miiphy_read(name, 0xEE, 0xEE, &mii_dev_addr)) {
+	if (miiphy_read(dev, 0xEE, 0xEE, &mii_dev_addr)) {
 		printf("Error..could not read PHY dev address\n");
 		return;
 	}
-	mv88e61xx_busychk_multic(name, mii_dev_addr);
+	mv88e61xx_busychk_multic(dev, mii_dev_addr);
 	/* Write data to Switch indirect data register */
-	miiphy_write(name, mii_dev_addr, 0x1, data);
+	miiphy_write(dev, mii_dev_addr, 0x1, data);
 	/* Write command to Switch indirect command register (write) */
-	miiphy_write(name, mii_dev_addr, 0x0,
+	miiphy_write(dev, mii_dev_addr, 0x0,
 		     reg_ofs | (phy_adr << 5) | (1 << 10) | (1 << 12) | (1 <<
 									 15));
 }
 
-static void mv88e61xx_rd_phy(char *name, u32 phy_adr, u32 reg_ofs, u16 * data)
+static void mv88e61xx_rd_phy(struct mii_device *dev, u32 phy_adr, u32 reg_ofs, u16 * data)
 {
 	u16 mii_dev_addr;
 
 	/* command to read PHY dev address */
-	if (miiphy_read(name, 0xEE, 0xEE, &mii_dev_addr)) {
+	if (miiphy_read(dev, 0xEE, 0xEE, &mii_dev_addr)) {
 		printf("Error..could not read PHY dev address\n");
 		return;
 	}
-	mv88e61xx_busychk_multic(name, mii_dev_addr);
+	mv88e61xx_busychk_multic(dev, mii_dev_addr);
 	/* Write command to Switch indirect command register (read) */
-	miiphy_write(name, mii_dev_addr, 0x0,
+	miiphy_write(dev, mii_dev_addr, 0x0,
 		     reg_ofs | (phy_adr << 5) | (1 << 11) | (1 << 12) | (1 <<
 									 15));
-	mv88e61xx_busychk_multic(name, mii_dev_addr);
+	mv88e61xx_busychk_multic(dev, mii_dev_addr);
 	/* Read data from Switch indirect data register */
-	miiphy_read(name, mii_dev_addr, 0x1, data);
+	miiphy_read(dev, mii_dev_addr, 0x1, data);
 }
 #endif /* CONFIG_MV88E61XX_MULTICHIP_ADRMODE */
 
@@ -95,31 +95,31 @@ static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig,
 {
 	u32 prt;
 	u16 reg;
-	char *name = swconfig->name;
 	u32 cpu_port = swconfig->cpuport;
 	u32 port_mask = swconfig->ports_enabled;
 	enum mv88e61xx_cfg_vlan vlancfg = swconfig->vlancfg;
+	struct mii_device *mii_dev = mii_get_by_name(swconfig->name);
 
 	/* be sure all ports are disabled */
 	for (prt = 0; prt < max_prtnum; prt++) {
-		RD_PHY(name, ports_ofs + prt, MV88E61XX_PRT_CTRL_REG, &reg);
+		RD_PHY(mii_dev, ports_ofs + prt, MV88E61XX_PRT_CTRL_REG, &reg);
 		reg &= ~0x3;
-		WR_PHY(name, ports_ofs + prt, MV88E61XX_PRT_CTRL_REG, reg);
+		WR_PHY(mii_dev, ports_ofs + prt, MV88E61XX_PRT_CTRL_REG, reg);
 
 		if (!(cpu_port & (1 << prt)))
 			continue;
 		/* Set CPU port VID to 0x1 */
-		RD_PHY(name, (ports_ofs + prt), MV88E61XX_PRT_VID_REG, &reg);
+		RD_PHY(mii_dev, (ports_ofs + prt), MV88E61XX_PRT_VID_REG, &reg);
 		reg &= ~0xfff;
 		reg |= 0x1;
-		WR_PHY(name, (ports_ofs + prt), MV88E61XX_PRT_VID_REG, reg);
+		WR_PHY(mii_dev, (ports_ofs + prt), MV88E61XX_PRT_VID_REG, reg);
 	}
 
 	/* Setting  Port default priority for all ports to zero */
 	for (prt = 0; prt < max_prtnum; prt++) {
-		RD_PHY(name, ports_ofs + prt, MV88E61XX_PRT_VID_REG, &reg);
+		RD_PHY(mii_dev, ports_ofs + prt, MV88E61XX_PRT_VID_REG, &reg);
 		reg &= ~0xc000;
-		WR_PHY(name, ports_ofs + prt, MV88E61XX_PRT_VID_REG, reg);
+		WR_PHY(mii_dev, ports_ofs + prt, MV88E61XX_PRT_VID_REG, reg);
 	}
 	/* Setting VID and VID map for all ports except CPU port */
 	for (prt = 0; prt < max_prtnum; prt++) {
@@ -131,11 +131,11 @@ static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig,
 				 * Set Vlan map table for cpu_port to see
 				 * all ports
 				 */
-				RD_PHY(name, (ports_ofs + prt),
+				RD_PHY(mii_dev, (ports_ofs + prt),
 				       MV88E61XX_PRT_VMAP_REG, &reg);
 				reg &= ~((1 << max_prtnum) - 1);
 				reg |= port_mask & ~(1 << prt);
-				WR_PHY(name, (ports_ofs + prt),
+				WR_PHY(mii_dev, (ports_ofs + prt),
 				       MV88E61XX_PRT_VMAP_REG, reg);
 			} else {
 
@@ -143,14 +143,14 @@ static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig,
 				 *  set Ports VLAN Mapping.
 				 *      port prt <--> cpu_port VLAN #prt+1.
 				 */
-				RD_PHY(name, ports_ofs + prt,
+				RD_PHY(mii_dev, ports_ofs + prt,
 				       MV88E61XX_PRT_VID_REG, &reg);
 				reg &= ~0x0fff;
 				reg |= (prt + 1);
-				WR_PHY(name, ports_ofs + prt,
+				WR_PHY(mii_dev, ports_ofs + prt,
 				       MV88E61XX_PRT_VID_REG, reg);
 
-				RD_PHY(name, ports_ofs + prt,
+				RD_PHY(mii_dev, ports_ofs + prt,
 				       MV88E61XX_PRT_VMAP_REG, &reg);
 				if (vlancfg == MV88E61XX_VLANCFG_DEFAULT) {
 					/*
@@ -167,7 +167,7 @@ static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig,
 					reg &= ~((1 << max_prtnum) - 1);
 					reg |= cpu_port;
 				}
-				WR_PHY(name, ports_ofs + prt,
+				WR_PHY(mii_dev, ports_ofs + prt,
 				       MV88E61XX_PRT_VMAP_REG, reg);
 			}
 		}
@@ -179,17 +179,17 @@ static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig,
 	 */
 	for (prt = 0; prt < max_prtnum; prt++) {
 		if ((1 << prt) & port_mask) {
-			RD_PHY(name, ports_ofs + prt,
+			RD_PHY(mii_dev, ports_ofs + prt,
 			       MV88E61XX_PRT_CTRL_REG, &reg);
 			reg |= 0x3;
-			WR_PHY(name, ports_ofs + prt,
+			WR_PHY(mii_dev, ports_ofs + prt,
 			       MV88E61XX_PRT_CTRL_REG, reg);
 		} else {
 			/* Disable port */
-			RD_PHY(name, ports_ofs + prt,
+			RD_PHY(mii_dev, ports_ofs + prt,
 			       MV88E61XX_PRT_CTRL_REG, &reg);
 			reg &= ~0x3;
-			WR_PHY(name, ports_ofs + prt,
+			WR_PHY(mii_dev, ports_ofs + prt,
 			       MV88E61XX_PRT_CTRL_REG, reg);
 		}
 	}
@@ -199,12 +199,13 @@ static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig,
  * Make sure SMIBusy bit cleared before another
  * SMI operation can take place
  */
-static int mv88e61xx_busychk(char *name)
+static int mv88e61xx_busychk(struct mii_device *mii_dev)
 {
 	u32 reg = 0;
 	u32 timeout = MV88E61XX_PHY_TIMEOUT;
+
 	do {
-		RD_PHY(name, MV88E61XX_GLB2REG_DEVADR,
+		RD_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR,
 		       MV88E61XX_PHY_CMD, (u16 *) & reg);
 		if (timeout-- == 0) {
 			printf("SMI busy timeout\n");
@@ -219,29 +220,29 @@ static int mv88e61xx_busychk(char *name)
  */
 static int mv88361xx_powerup(struct mv88e61xx_config *swconfig, u32 prt)
 {
-	char *name = swconfig->name;
+	struct mii_device *mii_dev = mii_get_by_name(swconfig->name);
 
 	/* Write Copper Specific control reg1 (0x14) for-
 	 * Enable Phy power up
 	 * Energy Detect on (sense&Xmit NLP Periodically
 	 * reset other settings default
 	 */
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, 0x3360);
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR,
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, 0x3360);
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR,
 	       MV88E61XX_PHY_CMD, (0x9410 | (prt << 5)));
 
-	if (mv88e61xx_busychk(name))
+	if (mv88e61xx_busychk(mii_dev))
 		return -1;
 
 	/* Write PHY ctrl reg (0x0) to apply
 	 * Phy reset (set bit 15 low)
 	 * reset other default values
 	 */
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, 0x1140);
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR,
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, 0x1140);
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR,
 	       MV88E61XX_PHY_CMD, (0x9400 | (prt << 5)));
 
-	if (mv88e61xx_busychk(name))
+	if (mv88e61xx_busychk(mii_dev))
 		return -1;
 
 	return 0;
@@ -258,7 +259,7 @@ static int mv88361xx_powerup(struct mv88e61xx_config *swconfig, u32 prt)
  */
 static int mv88361xx_led_init(struct mv88e61xx_config *swconfig, u32 prt)
 {
-	char *name = swconfig->name;
+	struct mii_device *mii_dev = mii_get_by_name(swconfig->name);
 	u16 reg;
 
 	if (swconfig->led_init != MV88E61XX_LED_INIT_EN)
@@ -266,38 +267,38 @@ static int mv88361xx_led_init(struct mv88e61xx_config *swconfig, u32 prt)
 
 	/* set page address to 3 */
 	reg = 3;
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR,
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR,
 	       MV88E61XX_PHY_CMD, (1 << MV88E61XX_BUSY_OFST |
 				   1 << MV88E61XX_MODE_OFST |
 				   1 << MV88E61XX_OP_OFST |
 				   prt << MV88E61XX_ADDR_OFST | 22));
 
-	if (mv88e61xx_busychk(name))
+	if (mv88e61xx_busychk(mii_dev))
 		return -1;
 
 	/* set LED Func Ctrl reg */
 	reg = 1;	/* LED[0] On-Link, Blink-Activity, Off-NoLink */
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR,
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR,
 	       MV88E61XX_PHY_CMD, (1 << MV88E61XX_BUSY_OFST |
 				   1 << MV88E61XX_MODE_OFST |
 				   1 << MV88E61XX_OP_OFST |
 				   prt << MV88E61XX_ADDR_OFST | 16));
 
-	if (mv88e61xx_busychk(name))
+	if (mv88e61xx_busychk(mii_dev))
 		return -1;
 
 	/* set page address to 0 */
 	reg = 0;
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR,
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR,
 	       MV88E61XX_PHY_CMD, (1 << MV88E61XX_BUSY_OFST |
 				   1 << MV88E61XX_MODE_OFST |
 				   1 << MV88E61XX_OP_OFST |
 				   prt << MV88E61XX_ADDR_OFST | 22));
 
-	if (mv88e61xx_busychk(name))
+	if (mv88e61xx_busychk(mii_dev))
 		return -1;
 
 	return 0;
@@ -314,21 +315,21 @@ static int mv88361xx_led_init(struct mv88e61xx_config *swconfig, u32 prt)
  */
 static int mv88361xx_reverse_mdipn(struct mv88e61xx_config *swconfig, u32 prt)
 {
-	char *name = swconfig->name;
+	struct mii_device *mii_dev = mii_get_by_name(swconfig->name);
 	u16 reg;
 
 	if (swconfig->mdip != MV88E61XX_MDIP_REVERSE)
 		return 0;
 
 	reg = 0x0f;		/*Reverse MDIP/N[3:0] bits */
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
-	WR_PHY(name, MV88E61XX_GLB2REG_DEVADR,
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, reg);
+	WR_PHY(mii_dev, MV88E61XX_GLB2REG_DEVADR,
 	       MV88E61XX_PHY_CMD, (1 << MV88E61XX_BUSY_OFST |
 				   1 << MV88E61XX_MODE_OFST |
 				   1 << MV88E61XX_OP_OFST |
 				   prt << MV88E61XX_ADDR_OFST | 20));
 
-	if (mv88e61xx_busychk(name))
+	if (mv88e61xx_busychk(mii_dev))
 		return -1;
 
 	return 0;
@@ -342,9 +343,9 @@ int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig)
 	u32 prt;
 	u16 reg;
 	char *idstr;
-	char *name = swconfig->name;
+	struct mii_device *mii_dev = mii_get_by_name(swconfig->name);
 
-	if (miiphy_set_current_dev(name)) {
+	if (miiphy_set_current_dev(swconfig->name)) {
 		printf("%s failed\n", __FUNCTION__);
 		return -1;
 	}
@@ -354,7 +355,7 @@ int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig)
 		printf("Invalid cpu port config, using default port5\n");
 	}
 
-	RD_PHY(name, MV88E61XX_PRT_OFST, PHY_PHYIDR2, &reg);
+	RD_PHY(mii_dev, MV88E61XX_PRT_OFST, PHY_PHYIDR2, &reg);
 	switch (reg &= 0xfff0) {
 	case 0x1610:
 		idstr = "88E6161";
@@ -388,9 +389,9 @@ int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig)
 		 * Enable RGMII delay on Tx and Rx for CPU port
 		 * Ref: sec 9.5 of chip datasheet-02
 		 */
-		WR_PHY(name, MV88E61XX_PRT_OFST + 5,
+		WR_PHY(mii_dev, MV88E61XX_PRT_OFST + 5,
 		       MV88E61XX_RGMII_TIMECTRL_REG, 0x18);
-		WR_PHY(name, MV88E61XX_PRT_OFST + 4,
+		WR_PHY(mii_dev, MV88E61XX_PRT_OFST + 4,
 		       MV88E61XX_RGMII_TIMECTRL_REG, 0xc1e7);
 	}
 
@@ -406,13 +407,13 @@ int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig)
 		}
 
 		/*Program port state */
-		RD_PHY(name, MV88E61XX_PRT_OFST + prt,
+		RD_PHY(mii_dev, MV88E61XX_PRT_OFST + prt,
 		       MV88E61XX_PRT_CTRL_REG, &reg);
-		WR_PHY(name, MV88E61XX_PRT_OFST + prt,
+		WR_PHY(mii_dev, MV88E61XX_PRT_OFST + prt,
 		       MV88E61XX_PRT_CTRL_REG,
 		       reg | (swconfig->portstate & 0x03));
 	}
 
-	printf("%s Initialized on %s\n", idstr, name);
+	printf("%s Initialized on %s\n", idstr, swconfig->name);
 	return 0;
 }
diff --git a/drivers/net/phy/mv88e61xx.h b/drivers/net/phy/mv88e61xx.h
index 57762b6..4a3832c 100644
--- a/drivers/net/phy/mv88e61xx.h
+++ b/drivers/net/phy/mv88e61xx.h
@@ -25,7 +25,7 @@
 #ifndef _MV88E61XX_H
 #define _MV88E61XX_H
 
-#include <miiphy.h>
+#include <miidev.h>
 
 #define MV88E61XX_CPU_PORT		0x5
 #define MV88E61XX_MAX_PORTS_NUM		0x6
@@ -49,9 +49,11 @@
 #define MV88E61XX_ADDR_OFST		5
 
 #ifdef CONFIG_MV88E61XX_MULTICHIP_ADRMODE
-static int mv88e61xx_busychk_multic(char *name, u32 devaddr);
-static void mv88e61xx_wr_phy(char *name, u32 phy_adr, u32 reg_ofs, u16 data);
-static void mv88e61xx_rd_phy(char *name, u32 phy_adr, u32 reg_ofs, u16 * data);
+static int mv88e61xx_busychk_multic(struct mii_device *dev, u32 devaddr);
+static void mv88e61xx_wr_phy(struct mii_device *dev, u32 phy_adr, u32 reg_ofs,
+			     u16 data);
+static void mv88e61xx_rd_phy(struct mii_device *dev, u32 phy_adr, u32 reg_ofs,
+			     u16 * data);
 #define WR_PHY mv88e61xx_wr_phy
 #define RD_PHY mv88e61xx_rd_phy
 #else
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 18a729c..6390bb4 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -26,7 +26,7 @@
 #include <command.h>
 #include <malloc.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #include "smc911x.h"
 
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 9c9fd37..3c9707a 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -18,7 +18,7 @@
 #include <command.h>
 #include <tsec.h>
 
-#include "miiphy.h"
+#include "miidev.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -61,10 +61,9 @@ static void adjust_link(struct eth_device *dev);
 static void relocate_cmds(void);
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
 	&& !defined(BITBANGMII)
-static int tsec_miiphy_write(char *devname, unsigned char addr,
-			     unsigned char reg, unsigned short value);
-static int tsec_miiphy_read(char *devname, unsigned char addr,
-			    unsigned char reg, unsigned short *value);
+static int tsec_miiphy_write(struct mii_device *dev, int addr, int reg,
+			      int value);
+static int tsec_miiphy_read(struct mii_device *dev, int addr, int reg);
 #endif
 #ifdef CONFIG_MCAST_TFTP
 static int tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set);
@@ -117,6 +116,10 @@ int tsec_standard_init(bd_t *bis)
 int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info)
 {
 	struct eth_device *dev;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+	&& !defined(BITBANGMII)
+	struct mii_device *mii_dev;
+#endif
 	int i;
 	struct tsec_private *priv;
 
@@ -127,6 +130,16 @@ int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info)
 
 	memset(dev, 0, sizeof *dev);
 
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+	&& !defined(BITBANGMII)
+	mii_dev = (struct mii_device *)malloc(sizeof *mii_dev);
+
+	if (NULL == mii_dev)
+		return 0;
+
+	memset(mii_dev, 0, sizeof *mii_dev);
+#endif
+
 	priv = (struct tsec_private *)malloc(sizeof(*priv));
 
 	if (NULL == priv)
@@ -163,7 +176,11 @@ int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info)
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
 	&& !defined(BITBANGMII)
-	miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write);
+	mii_dev->name = dev->name;
+	mii_dev->read = tsec_miiphy_read;
+	mii_dev->write = tsec_miiphy_write;
+
+	mii_register(mii_dev);
 #endif
 
 	/* Try to initialize PHY here, and return */
@@ -460,9 +477,9 @@ uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
 		if (bmcr & PHY_BMCR_DPLX)
 			priv->duplexity = 1;
 
-		if (bmcr & PHY_BMCR_1000_MBPS)
+		if (bmcr & BMCR_SPEED1000)
 			priv->speed = 1000;
-		else if (bmcr & PHY_BMCR_100_MBPS)
+		else if (bmcr & BMCR_SPEED100)
 			priv->speed = 100;
 	}
 
@@ -1845,10 +1862,8 @@ static void relocate_cmds(void)
  * Returns:
  *  0 on success
  */
-static int tsec_miiphy_read(char *devname, unsigned char addr,
-			    unsigned char reg, unsigned short *value)
+static int tsec_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
-	unsigned short ret;
 	struct tsec_private *priv = privlist[0];
 
 	if (NULL == priv) {
@@ -1856,10 +1871,7 @@ static int tsec_miiphy_read(char *devname, unsigned char addr,
 		return -1;
 	}
 
-	ret = (unsigned short)tsec_local_mdio_read(priv->phyregs, addr, reg);
-	*value = ret;
-
-	return 0;
+	return tsec_local_mdio_read(priv->phyregs, addr, reg);
 }
 
 /*
@@ -1868,8 +1880,8 @@ static int tsec_miiphy_read(char *devname, unsigned char addr,
  * Returns:
  *  0 on success
  */
-static int tsec_miiphy_write(char *devname, unsigned char addr,
-			     unsigned char reg, unsigned short value)
+static int tsec_miiphy_write(struct mii_device *dev, int addr, int reg,
+			      int value)
 {
 	struct tsec_private *priv = privlist[0];
 
diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c
index 9477851..282d3ed 100644
--- a/drivers/net/uli526x.c
+++ b/drivers/net/uli526x.c
@@ -19,7 +19,7 @@
 #include <netdev.h>
 #include <asm/io.h>
 #include <pci.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 /* some kernel function compatible define */
 
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c
index db95ada..5dfeed1 100644
--- a/drivers/qe/uec.c
+++ b/drivers/qe/uec.c
@@ -29,7 +29,7 @@
 #include "uccf.h"
 #include "uec.h"
 #include "uec_phy.h"
-#include "miiphy.h"
+#include "miidev.h"
 
 /* Default UTBIPAR SMI address */
 #ifndef CONFIG_UTBIPAR_INIT_TBIPA
@@ -613,20 +613,19 @@ static int uec_miiphy_find_dev_by_name(char *devname)
  * Returns:
  *  0 on success
  */
-static int uec_miiphy_read(char *devname, unsigned char addr,
-			    unsigned char reg, unsigned short *value)
+static int uec_miiphy_read(struct mii_device *dev, int addr, int reg)
 {
 	int devindex = 0;
 
-	if (devname == NULL || value == NULL) {
+	if (dev == NULL) {
 		debug("%s: NULL pointer given\n", __FUNCTION__);
 	} else {
-		devindex = uec_miiphy_find_dev_by_name(devname);
+		devindex = uec_miiphy_find_dev_by_name(dev->name);
 		if (devindex >= 0) {
-			*value = uec_read_phy_reg(devlist[devindex], addr, reg);
+			return uec_read_phy_reg(devlist[devindex], addr, reg);
 		}
 	}
-	return 0;
+	return -1;
 }
 
 /*
@@ -635,15 +634,16 @@ static int uec_miiphy_read(char *devname, unsigned char addr,
  * Returns:
  *  0 on success
  */
-static int uec_miiphy_write(char *devname, unsigned char addr,
-			     unsigned char reg, unsigned short value)
+static int uec_miiphy_write(struct mii_device *dev, int addr, int reg,
+			     int value)
 {
 	int devindex = 0;
 
-	if (devname == NULL) {
+	if (dev == NULL) {
 		debug("%s: NULL pointer given\n", __FUNCTION__);
+		return -1;
 	} else {
-		devindex = uec_miiphy_find_dev_by_name(devname);
+		devindex = uec_miiphy_find_dev_by_name(dev->name);
 		if (devindex >= 0) {
 			uec_write_phy_reg(devlist[devindex], addr, reg, value);
 		}
@@ -1328,6 +1328,10 @@ int uec_initialize(bd_t *bis, uec_info_t *uec_info)
 	int			i;
 	uec_private_t		*uec;
 	int			err;
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+	&& !defined(BITBANGMII)
+	struct mii_device	*mii_dev;
+#endif
 
 	dev = (struct eth_device *)malloc(sizeof(struct eth_device));
 	if (!dev)
@@ -1341,6 +1345,16 @@ int uec_initialize(bd_t *bis, uec_info_t *uec_info)
 	}
 	memset(uec, 0, sizeof(uec_private_t));
 
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+	&& !defined(BITBANGMII)
+	mii_dev = (struct mii_device *)malloc(sizeof(struct mii_device));
+	if (!mii_dev) {
+		return -ENOMEM;
+	}
+	memset(mii_dev, 0, sizeof(struct mii_device));
+#endif
+
+
 	/* Adjust uec_info */
 #if (MAX_QE_RISC == 4)
 	uec_info->risc_tx = QE_RISC_ALLOCATION_FOUR_RISCS;
@@ -1374,7 +1388,11 @@ int uec_initialize(bd_t *bis, uec_info_t *uec_info)
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
 	&& !defined(BITBANGMII)
-	miiphy_register(dev->name, uec_miiphy_read, uec_miiphy_write);
+	mii_dev->name = dev->name;
+	mii_dev->read = uec_miiphy_read;
+	mii_dev->write = uec_miiphy_write;
+
+	mii_register(mii_dev);
 #endif
 
 	return 1;
diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c
index aa4eb5e..19398f8 100644
--- a/drivers/qe/uec_phy.c
+++ b/drivers/qe/uec_phy.c
@@ -24,7 +24,7 @@
 #include "uccf.h"
 #include "uec.h"
 #include "uec_phy.h"
-#include "miiphy.h"
+#include "miidev.h"
 
 #define ugphy_printk(format, arg...)  \
 	printf(format "\n", ## arg)
@@ -215,22 +215,22 @@ static void genmii_setup_forced (struct uec_mii_info *mii_info)
 
 	ctrl = phy_read (mii_info, PHY_BMCR);
 
-	ctrl &= ~(PHY_BMCR_DPLX | PHY_BMCR_100_MBPS |
-		  PHY_BMCR_1000_MBPS | PHY_BMCR_AUTON);
+	ctrl &= ~(PHY_BMCR_DPLX | BMCR_SPEED100 |
+		  BMCR_SPEED1000 | PHY_BMCR_AUTON);
 	ctrl |= PHY_BMCR_RESET;
 
 	switch (mii_info->speed) {
 	case SPEED_1000:
 		if (features & (SUPPORTED_1000baseT_Half
 				| SUPPORTED_1000baseT_Full)) {
-			ctrl |= PHY_BMCR_1000_MBPS;
+			ctrl |= BMCR_SPEED1000;
 			break;
 		}
 		mii_info->speed = SPEED_100;
 	case SPEED_100:
 		if (features & (SUPPORTED_100baseT_Half
 				| SUPPORTED_100baseT_Full)) {
-			ctrl |= PHY_BMCR_100_MBPS;
+			ctrl |= BMCR_SPEED100;
 			break;
 		}
 		mii_info->speed = SPEED_10;
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 7c63095..07e9981 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -30,6 +30,8 @@
 #define MII_NCONFIG	    0x1c	/* Network interface config    */
 
 /* Basic mode control register. */
+#define BMCR_SPEED_MASK		0x2040	/* Select 10Mbps	       */
+#define BMCR_SPEED10		0x0000	/* Select 10Mbps	       */
 #define BMCR_RESV		0x003f	/* Unused...		       */
 #define BMCR_SPEED1000		0x0040	/* MSB of Speed (1000)	       */
 #define BMCR_CTST		0x0080	/* Collision test	       */
diff --git a/include/miidev.h b/include/miidev.h
new file mode 100644
index 0000000..cacdd47
--- /dev/null
+++ b/include/miidev.h
@@ -0,0 +1,91 @@
+/*
+ * (C) Copyright 2001
+ * Gerald Van Baren, Custom IDEAS, vanbaren at cideas.com.
+ *
+ * (C) Copyright 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.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 __MIIDEV_H__
+#define __MIIDEV_H__
+
+#include <net.h>
+#include <miiphy.h>
+#include <linux/list.h>
+#include <linux/mii.h>
+
+struct mii_device {
+	int	id;
+	char	*name;
+
+	int	(*read) (struct mii_device *dev, int addr, int reg);
+	int	(*write) (struct mii_device *dev, int addr, int reg, int value);
+
+	void *priv;
+	struct list_head list;
+};
+
+void mii_dev_init(void);
+int mii_register(struct mii_device *dev);
+void miiphy_listdev(void);
+
+struct mii_device* mii_get_by_name(char* name);
+struct mii_device* mii_get_current_dev(void);
+int miiphy_set_current_dev(char *devname);
+
+static int inline mii_write(struct mii_device *dev, int addr, int reg, int value)
+{
+	return dev->write(dev, addr, reg, value);
+}
+
+static int inline mii_read(struct mii_device *dev, int addr, int reg)
+{
+	return dev->read(dev, addr, reg);
+}
+
+/* bit-banging API */
+#define BB_MII_DEVNAME	"bbmii"
+
+void mii_bitbang_write(struct mii_device *dev, int addr, int reg, int value);
+int mii_bitbang_read(struct mii_device *dev, int addr, int reg);
+
+/*
+ * Old compatible API
+ */
+int miiphy_read(struct mii_device *dev, unsigned char addr, unsigned char reg,
+		unsigned short *value);
+int miiphy_write(struct mii_device *dev, unsigned char addr, unsigned char reg,
+		 unsigned short value);
+
+int miiphy_info(struct mii_device *dev, unsigned char addr, unsigned int *oui,
+		unsigned char *model, unsigned char *rev);
+int miiphy_reset(struct mii_device *dev, unsigned char addr);
+int miiphy_speed(struct mii_device *dev, unsigned char addr);
+int miiphy_duplex(struct mii_device *dev, unsigned char addr);
+int miiphy_is_1000base_x(struct mii_device *dev, unsigned char addr);
+#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
+int miiphy_link(struct mii_device *dev, unsigned char addr);
+#endif
+
+int bb_miiphy_read(struct mii_device *dev, unsigned char addr,
+		   unsigned char reg, unsigned short *value);
+int bb_miiphy_write(struct mii_device *dev, unsigned char addr,
+		    unsigned char reg, unsigned short value);
+
+#endif /* __MIIDEV_H__ */
diff --git a/include/miiphy.h b/include/miiphy.h
index fa33ec7..c6a66f8 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -32,42 +32,6 @@
 #ifndef _miiphy_h_
 #define _miiphy_h_
 
-#include <net.h>
-
-int miiphy_read (char *devname, unsigned char addr, unsigned char reg,
-		 unsigned short *value);
-int miiphy_write (char *devname, unsigned char addr, unsigned char reg,
-		  unsigned short value);
-int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
-		 unsigned char *model, unsigned char *rev);
-int miiphy_reset (char *devname, unsigned char addr);
-int miiphy_speed (char *devname, unsigned char addr);
-int miiphy_duplex (char *devname, unsigned char addr);
-int miiphy_is_1000base_x (char *devname, unsigned char addr);
-#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
-int miiphy_link (char *devname, unsigned char addr);
-#endif
-
-void miiphy_init (void);
-
-void miiphy_register (char *devname,
-		      int (*read) (char *devname, unsigned char addr,
-				   unsigned char reg, unsigned short *value),
-		      int (*write) (char *devname, unsigned char addr,
-				    unsigned char reg, unsigned short value));
-
-int miiphy_set_current_dev (char *devname);
-char *miiphy_get_current_dev (void);
-
-void miiphy_listdev (void);
-
-#define BB_MII_DEVNAME	"bbmii"
-
-int bb_miiphy_read (char *devname, unsigned char addr,
-		    unsigned char reg, unsigned short *value);
-int bb_miiphy_write (char *devname, unsigned char addr,
-		     unsigned char reg, unsigned short value);
-
 /* phy seed setup */
 #define AUTO			99
 #define _1000BASET		1000
diff --git a/include/ns7520_eth.h b/include/ns7520_eth.h
index b509697..de7d62b 100644
--- a/include/ns7520_eth.h
+++ b/include/ns7520_eth.h
@@ -24,7 +24,7 @@
 
 #ifdef CONFIG_DRIVER_NS7520_ETHERNET
 
-#include <miiphy.h>
+#include <miidev.h>
 #include "lxt971a.h"
 
 /* The port addresses */
diff --git a/include/ns9750_eth.h b/include/ns9750_eth.h
index 80c721b..8952b68 100644
--- a/include/ns9750_eth.h
+++ b/include/ns9750_eth.h
@@ -31,7 +31,7 @@
 
 #ifdef CONFIG_DRIVER_NS9750_ETHERNET
 
-#include <miiphy.h>
+#include <miidev.h>
 #include "lxt971a.h"
 
 #define	NS9750_ETH_MODULE_BASE		(0xA0600000)
diff --git a/net/eth.c b/net/eth.c
index 9b50312..7b363c0 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -24,7 +24,7 @@
 #include <common.h>
 #include <command.h>
 #include <net.h>
-#include <miiphy.h>
+#include <miidev.h>
 
 #ifdef CONFIG_CMD_NET
 void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
@@ -195,7 +195,7 @@ int eth_initialize(bd_t *bis)
 
 	show_boot_progress (64);
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	miiphy_init();
+	mii_dev_init();
 #endif
 	/* Try board-specific initialization first.  If it fails or isn't
 	 * present, try the cpu-specific initialization */
@@ -504,7 +504,7 @@ extern int ns7520_miiphy_initialize(bd_t *bis);
 int eth_initialize(bd_t *bis)
 {
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-	miiphy_init();
+	mii_dev_init();
 #endif
 
 #if defined(CONFIG_AT91RM9200)
diff --git a/net/net.c b/net/net.c
index d1cc9b2..9c571aa 100644
--- a/net/net.c
+++ b/net/net.c
@@ -84,7 +84,7 @@
 #include "nfs.h"
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
-#include <miiphy.h>
+#include <miidev.h>
 #endif
 #if defined(CONFIG_CMD_SNTP)
 #include "sntp.h"
-- 
1.6.3.1



More information about the U-Boot mailing list