diff mbox series

[U-Boot,2/2] net: mvgbe: convert to DM

Message ID 20180627100628.24603-2-judge.packham@gmail.com
State Superseded
Delegated to: Stefan Roese
Headers show
Series [U-Boot,1/2] net: mvgbe: prepare for conversion to driver model | expand

Commit Message

Chris Packham June 27, 2018, 10:06 a.m. UTC
Add driver model support to the mvgbe driver. As a temporary measure
both DM and non-DM uses are supported. Once all the users have been
converted the non-DM support can be dropped.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---

 drivers/net/mvgbe.c | 201 +++++++++++++++++++++++++++++++++++++++++++-
 drivers/net/mvgbe.h |  16 ++++
 2 files changed, 213 insertions(+), 4 deletions(-)

Comments

Joe Hershberger July 2, 2018, 8:59 p.m. UTC | #1
On Wed, Jun 27, 2018 at 5:06 AM, Chris Packham <judge.packham@gmail.com> wrote:
> Add driver model support to the mvgbe driver. As a temporary measure
> both DM and non-DM uses are supported. Once all the users have been
> converted the non-DM support can be dropped.
>
> Signed-off-by: Chris Packham <judge.packham@gmail.com>
> ---
>
>  drivers/net/mvgbe.c | 201 +++++++++++++++++++++++++++++++++++++++++++-
>  drivers/net/mvgbe.h |  16 ++++
>  2 files changed, 213 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
> index 96ca35512f01..bddf2bc29aac 100644
> --- a/drivers/net/mvgbe.c
> +++ b/drivers/net/mvgbe.c
> @@ -12,6 +12,7 @@
>   */
>
>  #include <common.h>
> +#include <dm.h>
>  #include <net.h>
>  #include <malloc.h>
>  #include <miiphy.h>
> @@ -127,8 +128,12 @@ static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr,
>  static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
>                         int reg_ofs)
>  {
> +#ifdef CONFIG_DM_ETH
> +       struct mvgbe_device *dmvgbe = bus->priv;
> +#else
>         struct eth_device *dev = eth_get_dev_by_name(bus->name);
>         struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> +#endif
>
>         return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
>  }
> @@ -180,8 +185,12 @@ static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
>  static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
>                          int reg_ofs, u16 data)
>  {
> +#ifdef CONFIG_DM_ETH
> +       struct mvgbe_device *dmvgbe = bus->priv;
> +#else
>         struct eth_device *dev = eth_get_dev_by_name(bus->name);
>         struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> +#endif
>
>         return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
>  }
> @@ -415,11 +424,12 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
>         dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
>  }
>
> -static int __mvgbe_init(struct mvgbe_device *dmvgbe)
> +static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr)
>  {
>         struct mvgbe_registers *regs = dmvgbe->regs;
>  #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) &&  \
>         !defined(CONFIG_PHYLIB) &&                       \
> +       !defined(CONFIG_DM_ETH) &&                       \
>         defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
>         int i;
>  #endif
> @@ -436,7 +446,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
>
>         set_dram_access(regs);
>         port_init_mac_tables(regs);
> -       port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
> +       port_uc_addr_set(dmvgbe, enetaddr);
>
>         /* Assign port configuration and command. */
>         MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
> @@ -473,6 +483,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
>
>  #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
>         !defined(CONFIG_PHYLIB) && \
> +       !defined(CONFIG_DM_ETH) && \
>         defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
>         /* Wait up to 5s for the link status */
>         for (i = 0; i < 5; i++) {
> @@ -492,12 +503,14 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
>         return 0;
>  }
>
> +#ifndef CONFIG_DM_ETH
>  static int mvgbe_init(struct eth_device *dev)
>  {
>         struct mvgbe_device *dmvgbe = to_mvgbe(dev);
>
> -       return __mvgbe_init(dmvgbe);
> +       return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr);
>  }
> +#endif
>
>  static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
>  {
> @@ -524,6 +537,7 @@ static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
>         MVGBE_REG_WR(regs->peim, 0);
>  }
>
> +#ifndef CONFIG_DM_ETH
>  static int mvgbe_halt(struct eth_device *dev)
>  {
>         struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> @@ -532,7 +546,18 @@ static int mvgbe_halt(struct eth_device *dev)
>
>         return 0;
>  }
> +#endif
>
> +#ifdef CONFIG_DM_ETH
> +static int mvgbe_write_hwaddr(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +
> +       port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr);
> +
> +       return 0;
> +}
> +#else
>  static int mvgbe_write_hwaddr(struct eth_device *dev)
>  {
>         struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> @@ -541,6 +566,7 @@ static int mvgbe_write_hwaddr(struct eth_device *dev)
>         port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
>         return 0;
>  }
> +#endif
>
>  static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
>                         int datasize)
> @@ -597,12 +623,14 @@ static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
>         return 0;
>  }
>
> +#ifndef CONFIG_DM_ETH
>  static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
>  {
>         struct mvgbe_device *dmvgbe = to_mvgbe(dev);
>
>         return __mvgbe_send(dmvgbe, dataptr, datasize);
>  }
> +#endif
>
>  static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
>  {
> @@ -677,6 +705,7 @@ static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
>         return rx_bytes;
>  }
>
> +#ifndef CONFIG_DM_ETH
>  static int mvgbe_recv(struct eth_device *dev)
>  {
>         struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> @@ -691,8 +720,9 @@ static int mvgbe_recv(struct eth_device *dev)
>
>         return 0;
>  }
> +#endif
>
> -#if defined(CONFIG_PHYLIB)
> +#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH)
>  int mvgbe_phylib_init(struct eth_device *dev, int phyid)
>  {
>         struct mii_dev *bus;
> @@ -731,6 +761,7 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid)
>  }
>  #endif
>
> +#ifndef CONFIG_DM_ETH
>  int mvgbe_initialize(bd_t *bis)
>  {
>         struct mvgbe_device *dmvgbe;
> @@ -834,3 +865,165 @@ error1:
>         }
>         return 0;
>  }
> +#endif
> +
> +#ifdef CONFIG_DM_ETH
> +static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe)
> +{
> +       return dmvgbe->phyaddr > PHY_MAX_ADDR;
> +}
> +
> +static int mvgbe_start(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +       struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +       struct phy_device *phydev;
> +       int ret;
> +
> +       ret = __mvgbe_init(dmvgbe, pdata->enetaddr);
> +       if (ret)
> +               return ret;
> +
> +       if (!mvgbe_port_is_fixed_link(dmvgbe)) {
> +               /* Set phy address of the port */
> +               miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
> +                            dmvgbe->phyaddr);
> +
> +               phydev = phy_connect(dmvgbe->bus, dmvgbe->phyaddr, dev,
> +                                    dmvgbe->phy_interface);
> +               if (!phydev) {
> +                       printf("phy_connect failed\n");
> +                       return -ENODEV;
> +               }
> +
> +               phy_config(phydev);
> +               phy_startup(phydev);
> +       }

Please use a helper function to consolidate this with mvgbe_phylib_init().

> +
> +       return 0;
> +}
> +
> +static int mvgbe_send(struct udevice *dev, void *packet, int length)
> +{
> +       struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +
> +       return __mvgbe_send(dmvgbe, packet, length);
> +}
> +
> +static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp)
> +{
> +       struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +
> +       return __mvgbe_recv(dmvgbe, packetp);
> +}
> +
> +static void mvgbe_stop(struct udevice *dev)
> +{
> +       struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +
> +       __mvgbe_halt(dmvgbe);
> +}
> +
> +static int mvgbe_probe(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +       struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +       void *blob = (void *)gd->fdt_blob;
> +       int node = dev_of_offset(dev);
> +       struct mii_dev *bus;
> +       unsigned long addr;
> +       int ret;
> +       int fl_node;
> +
> +       dmvgbe->p_rxdesc =
> +               (struct mvgbe_rxdesc *)memalign(PKTALIGN,
> +               MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
> +       dmvgbe->p_rxbuf = (u8 *)memalign(PKTALIGN,
> +               RINGSZ * PKTSIZE_ALIGN + 1);
> +       dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
> +       dmvgbe->p_txdesc = (struct mvgbe_txdesc *)memalign(
> +               PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);

Please use a helper function to consolidate this setup between probe
and mvgbe_initialize().

> +
> +       dmvgbe->regs = (void __iomem *)pdata->iobase;
> +
> +       /* PHY interface is already decoded in mvneta_ofdata_to_platdata() */
> +       dmvgbe->phy_interface = pdata->phy_interface;
> +
> +       /* fetch 'fixed-link' property from 'neta' node */
> +       fl_node = fdt_subnode_offset(blob, node, "fixed-link");
> +       if (fl_node != -FDT_ERR_NOTFOUND) {
> +               /* set phy_addr to invalid value for fixed link */
> +               dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
> +               dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
> +               dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
> +       } else {
> +               /* Now read phyaddr from DT */
> +               addr = fdtdec_get_int(blob, node, "phy", 0);
> +               addr = fdt_node_offset_by_phandle(blob, addr);
> +               dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
> +       }

I think this stuff reading from the DT should be in mvgbe_ofdata_to_platdata().

> +
> +       bus  = mdio_alloc();
> +       if (!bus) {
> +               printf("Failed to allocate MDIO bus\n");
> +               return -ENOMEM;
> +       }
> +
> +       bus->read = smi_reg_read;
> +       bus->write = smi_reg_write;
> +       snprintf(bus->name, sizeof(bus->name), dev->name);
> +       bus->priv = dmvgbe;
> +       dmvgbe->bus = bus;
> +
> +       ret = mdio_register(bus);
> +       if (ret < 0)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static const struct eth_ops mvgbe_ops = {
> +       .start          = mvgbe_start,
> +       .send           = mvgbe_send,
> +       .recv           = mvgbe_recv,
> +       .stop           = mvgbe_stop,
> +       .write_hwaddr   = mvgbe_write_hwaddr,
> +};
> +
> +static int mvgbe_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +       const char *phy_mode;
> +
> +       pdata->iobase = devfdt_get_addr(dev);
> +
> +       /* Get phy-mode / phy_interface from DT */
> +       pdata->phy_interface = -1;
> +       phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
> +                              NULL);
> +       if (phy_mode)
> +               pdata->phy_interface = phy_get_interface_by_name(phy_mode);
> +       if (pdata->phy_interface == -1) {
> +               debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct udevice_id mvgbe_ids[] = {
> +       { .compatible = "marvell,kirkwood-eth" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(mvgbe) = {
> +       .name   = "mvgbe",
> +       .id     = UCLASS_ETH,
> +       .of_match = mvgbe_ids,
> +       .ofdata_to_platdata = mvgbe_ofdata_to_platdata,
> +       .probe  = mvgbe_probe,
> +       .ops    = &mvgbe_ops,
> +       .priv_auto_alloc_size = sizeof(struct mvgbe_device),
> +       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
> +};
> +#endif /* CONFIG_DM_ETH */
> diff --git a/drivers/net/mvgbe.h b/drivers/net/mvgbe.h
> index 1dc9bbea2f42..44541c0a85e3 100644
> --- a/drivers/net/mvgbe.h
> +++ b/drivers/net/mvgbe.h
> @@ -30,7 +30,9 @@
>  #define RXUQ   0 /* Used Rx queue */
>  #define TXUQ   0 /* Used Rx queue */
>
> +#ifndef CONFIG_DM_ETH
>  #define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev)
> +#endif
>  #define MVGBE_REG_WR(adr, val)         writel(val, &adr)
>  #define MVGBE_REG_RD(adr)              readl(&adr)
>  #define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr)
> @@ -479,13 +481,27 @@ struct mvgbe_txdesc {
>
>  /* port device data struct */
>  struct mvgbe_device {
> +#ifndef CONFIG_DM_ETH
>         struct eth_device dev;
> +#endif
>         struct mvgbe_registers *regs;
>         struct mvgbe_txdesc *p_txdesc;
>         struct mvgbe_rxdesc *p_rxdesc;
>         struct mvgbe_rxdesc *p_rxdesc_curr;
>         u8 *p_rxbuf;
>         u8 *p_aligned_txbuf;
> +
> +#ifdef CONFIG_DM_ETH
> +       phy_interface_t phy_interface;
> +       unsigned int link;
> +       unsigned int duplex;
> +       unsigned int speed;
> +
> +       int init;
> +       int phyaddr;
> +       struct phy_device *phydev;
> +       struct mii_dev *bus;
> +#endif
>  };
>
>  #endif /* __MVGBE_H__ */
> --
> 2.18.0
>
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> https://lists.denx.de/listinfo/u-boot
diff mbox series

Patch

diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index 96ca35512f01..bddf2bc29aac 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -12,6 +12,7 @@ 
  */
 
 #include <common.h>
+#include <dm.h>
 #include <net.h>
 #include <malloc.h>
 #include <miiphy.h>
@@ -127,8 +128,12 @@  static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr,
 static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
 			int reg_ofs)
 {
+#ifdef CONFIG_DM_ETH
+	struct mvgbe_device *dmvgbe = bus->priv;
+#else
 	struct eth_device *dev = eth_get_dev_by_name(bus->name);
 	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+#endif
 
 	return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
 }
@@ -180,8 +185,12 @@  static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
 static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
 			 int reg_ofs, u16 data)
 {
+#ifdef CONFIG_DM_ETH
+	struct mvgbe_device *dmvgbe = bus->priv;
+#else
 	struct eth_device *dev = eth_get_dev_by_name(bus->name);
 	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+#endif
 
 	return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
 }
@@ -415,11 +424,12 @@  static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
 	dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
 }
 
-static int __mvgbe_init(struct mvgbe_device *dmvgbe)
+static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr)
 {
 	struct mvgbe_registers *regs = dmvgbe->regs;
 #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) &&  \
 	!defined(CONFIG_PHYLIB) &&			 \
+	!defined(CONFIG_DM_ETH) &&			 \
 	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
 	int i;
 #endif
@@ -436,7 +446,7 @@  static int __mvgbe_init(struct mvgbe_device *dmvgbe)
 
 	set_dram_access(regs);
 	port_init_mac_tables(regs);
-	port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
+	port_uc_addr_set(dmvgbe, enetaddr);
 
 	/* Assign port configuration and command. */
 	MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
@@ -473,6 +483,7 @@  static int __mvgbe_init(struct mvgbe_device *dmvgbe)
 
 #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
 	!defined(CONFIG_PHYLIB) && \
+	!defined(CONFIG_DM_ETH) && \
 	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
 	/* Wait up to 5s for the link status */
 	for (i = 0; i < 5; i++) {
@@ -492,12 +503,14 @@  static int __mvgbe_init(struct mvgbe_device *dmvgbe)
 	return 0;
 }
 
+#ifndef CONFIG_DM_ETH
 static int mvgbe_init(struct eth_device *dev)
 {
 	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 
-	return __mvgbe_init(dmvgbe);
+	return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr);
 }
+#endif
 
 static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
 {
@@ -524,6 +537,7 @@  static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
 	MVGBE_REG_WR(regs->peim, 0);
 }
 
+#ifndef CONFIG_DM_ETH
 static int mvgbe_halt(struct eth_device *dev)
 {
 	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
@@ -532,7 +546,18 @@  static int mvgbe_halt(struct eth_device *dev)
 
 	return 0;
 }
+#endif
 
+#ifdef CONFIG_DM_ETH
+static int mvgbe_write_hwaddr(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+
+	port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr);
+
+	return 0;
+}
+#else
 static int mvgbe_write_hwaddr(struct eth_device *dev)
 {
 	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
@@ -541,6 +566,7 @@  static int mvgbe_write_hwaddr(struct eth_device *dev)
 	port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
 	return 0;
 }
+#endif
 
 static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
 			int datasize)
@@ -597,12 +623,14 @@  static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
 	return 0;
 }
 
+#ifndef CONFIG_DM_ETH
 static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
 {
 	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 
 	return __mvgbe_send(dmvgbe, dataptr, datasize);
 }
+#endif
 
 static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
 {
@@ -677,6 +705,7 @@  static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
 	return rx_bytes;
 }
 
+#ifndef CONFIG_DM_ETH
 static int mvgbe_recv(struct eth_device *dev)
 {
 	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
@@ -691,8 +720,9 @@  static int mvgbe_recv(struct eth_device *dev)
 
 	return 0;
 }
+#endif
 
-#if defined(CONFIG_PHYLIB)
+#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH)
 int mvgbe_phylib_init(struct eth_device *dev, int phyid)
 {
 	struct mii_dev *bus;
@@ -731,6 +761,7 @@  int mvgbe_phylib_init(struct eth_device *dev, int phyid)
 }
 #endif
 
+#ifndef CONFIG_DM_ETH
 int mvgbe_initialize(bd_t *bis)
 {
 	struct mvgbe_device *dmvgbe;
@@ -834,3 +865,165 @@  error1:
 	}
 	return 0;
 }
+#endif
+
+#ifdef CONFIG_DM_ETH
+static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe)
+{
+	return dmvgbe->phyaddr > PHY_MAX_ADDR;
+}
+
+static int mvgbe_start(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+	struct phy_device *phydev;
+	int ret;
+
+	ret = __mvgbe_init(dmvgbe, pdata->enetaddr);
+	if (ret)
+		return ret;
+
+	if (!mvgbe_port_is_fixed_link(dmvgbe)) {
+		/* Set phy address of the port */
+		miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
+			     dmvgbe->phyaddr);
+
+		phydev = phy_connect(dmvgbe->bus, dmvgbe->phyaddr, dev,
+				     dmvgbe->phy_interface);
+		if (!phydev) {
+			printf("phy_connect failed\n");
+			return -ENODEV;
+		}
+
+		phy_config(phydev);
+		phy_startup(phydev);
+	}
+
+	return 0;
+}
+
+static int mvgbe_send(struct udevice *dev, void *packet, int length)
+{
+	struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+
+	return __mvgbe_send(dmvgbe, packet, length);
+}
+
+static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+
+	return __mvgbe_recv(dmvgbe, packetp);
+}
+
+static void mvgbe_stop(struct udevice *dev)
+{
+	struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+
+	__mvgbe_halt(dmvgbe);
+}
+
+static int mvgbe_probe(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+	void *blob = (void *)gd->fdt_blob;
+	int node = dev_of_offset(dev);
+	struct mii_dev *bus;
+	unsigned long addr;
+	int ret;
+	int fl_node;
+
+	dmvgbe->p_rxdesc =
+		(struct mvgbe_rxdesc *)memalign(PKTALIGN,
+		MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
+	dmvgbe->p_rxbuf = (u8 *)memalign(PKTALIGN,
+		RINGSZ * PKTSIZE_ALIGN + 1);
+	dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
+	dmvgbe->p_txdesc = (struct mvgbe_txdesc *)memalign(
+		PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
+
+	dmvgbe->regs = (void __iomem *)pdata->iobase;
+
+	/* PHY interface is already decoded in mvneta_ofdata_to_platdata() */
+	dmvgbe->phy_interface = pdata->phy_interface;
+
+	/* fetch 'fixed-link' property from 'neta' node */
+	fl_node = fdt_subnode_offset(blob, node, "fixed-link");
+	if (fl_node != -FDT_ERR_NOTFOUND) {
+		/* set phy_addr to invalid value for fixed link */
+		dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
+		dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
+		dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
+	} else {
+		/* Now read phyaddr from DT */
+		addr = fdtdec_get_int(blob, node, "phy", 0);
+		addr = fdt_node_offset_by_phandle(blob, addr);
+		dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
+	}
+
+	bus  = mdio_alloc();
+	if (!bus) {
+		printf("Failed to allocate MDIO bus\n");
+		return -ENOMEM;
+	}
+
+	bus->read = smi_reg_read;
+	bus->write = smi_reg_write;
+	snprintf(bus->name, sizeof(bus->name), dev->name);
+	bus->priv = dmvgbe;
+	dmvgbe->bus = bus;
+
+	ret = mdio_register(bus);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static const struct eth_ops mvgbe_ops = {
+	.start		= mvgbe_start,
+	.send		= mvgbe_send,
+	.recv		= mvgbe_recv,
+	.stop		= mvgbe_stop,
+	.write_hwaddr	= mvgbe_write_hwaddr,
+};
+
+static int mvgbe_ofdata_to_platdata(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	const char *phy_mode;
+
+	pdata->iobase = devfdt_get_addr(dev);
+
+	/* Get phy-mode / phy_interface from DT */
+	pdata->phy_interface = -1;
+	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+			       NULL);
+	if (phy_mode)
+		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+	if (pdata->phy_interface == -1) {
+		debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id mvgbe_ids[] = {
+	{ .compatible = "marvell,kirkwood-eth" },
+	{ }
+};
+
+U_BOOT_DRIVER(mvgbe) = {
+	.name	= "mvgbe",
+	.id	= UCLASS_ETH,
+	.of_match = mvgbe_ids,
+	.ofdata_to_platdata = mvgbe_ofdata_to_platdata,
+	.probe	= mvgbe_probe,
+	.ops	= &mvgbe_ops,
+	.priv_auto_alloc_size = sizeof(struct mvgbe_device),
+	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+#endif /* CONFIG_DM_ETH */
diff --git a/drivers/net/mvgbe.h b/drivers/net/mvgbe.h
index 1dc9bbea2f42..44541c0a85e3 100644
--- a/drivers/net/mvgbe.h
+++ b/drivers/net/mvgbe.h
@@ -30,7 +30,9 @@ 
 #define RXUQ	0 /* Used Rx queue */
 #define TXUQ	0 /* Used Rx queue */
 
+#ifndef CONFIG_DM_ETH
 #define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev)
+#endif
 #define MVGBE_REG_WR(adr, val)		writel(val, &adr)
 #define MVGBE_REG_RD(adr)		readl(&adr)
 #define MVGBE_REG_BITS_RESET(adr, val)	writel(readl(&adr) & ~(val), &adr)
@@ -479,13 +481,27 @@  struct mvgbe_txdesc {
 
 /* port device data struct */
 struct mvgbe_device {
+#ifndef CONFIG_DM_ETH
 	struct eth_device dev;
+#endif
 	struct mvgbe_registers *regs;
 	struct mvgbe_txdesc *p_txdesc;
 	struct mvgbe_rxdesc *p_rxdesc;
 	struct mvgbe_rxdesc *p_rxdesc_curr;
 	u8 *p_rxbuf;
 	u8 *p_aligned_txbuf;
+
+#ifdef CONFIG_DM_ETH
+	phy_interface_t phy_interface;
+	unsigned int link;
+	unsigned int duplex;
+	unsigned int speed;
+
+	int init;
+	int phyaddr;
+	struct phy_device *phydev;
+	struct mii_dev *bus;
+#endif
 };
 
 #endif /* __MVGBE_H__ */