[U-Boot] [PATCH 07/10] net: axi_emac: Move driver to DM

Simon Glass sjg at chromium.org
Tue Dec 15 19:57:56 CET 2015


Hi Michal,

On 11 December 2015 at 04:59, Michal Simek <michal.simek at xilinx.com> wrote:
> Move driver to DM.
>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
>  .../xilinx/microblaze-generic/microblaze-generic.c |   5 -
>  board/xilinx/zynq/board.c                          |   4 -
>  drivers/net/xilinx_axi_emac.c                      | 190 +++++++++++++--------
>  include/netdev.h                                   |   2 -
>  4 files changed, 122 insertions(+), 79 deletions(-)

Reviewed-by: Simon Glass <sjg at chromium.org>

See a few things below.

>
> diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c
> index dfa629322223..a3122da9acaa 100644
> --- a/board/xilinx/microblaze-generic/microblaze-generic.c
> +++ b/board/xilinx/microblaze-generic/microblaze-generic.c
> @@ -105,11 +105,6 @@ int board_eth_init(bd_t *bis)
>  {
>         int ret = 0;
>
> -#ifdef CONFIG_XILINX_AXIEMAC
> -       ret |= xilinx_axiemac_initialize(bis, XILINX_AXIEMAC_BASEADDR,
> -                                               XILINX_AXIDMA_BASEADDR);
> -#endif
> -
>  #if defined(CONFIG_XILINX_EMACLITE) && defined(XILINX_EMACLITE_BASEADDR)
>         u32 txpp = 0;
>         u32 rxpp = 0;
> diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
> index 414f5302a066..427e75485deb 100644
> --- a/board/xilinx/zynq/board.c
> +++ b/board/xilinx/zynq/board.c
> @@ -103,10 +103,6 @@ int board_eth_init(bd_t *bis)
>  {
>         u32 ret = 0;
>
> -#ifdef CONFIG_XILINX_AXIEMAC
> -       ret |= xilinx_axiemac_initialize(bis, XILINX_AXIEMAC_BASEADDR,
> -                                               XILINX_AXIDMA_BASEADDR);
> -#endif
>  #ifdef CONFIG_XILINX_EMACLITE
>         u32 txpp = 0;
>         u32 rxpp = 0;
> diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
> index 77b1869dc9dc..c03f8f730d3a 100644
> --- a/drivers/net/xilinx_axi_emac.c
> +++ b/drivers/net/xilinx_axi_emac.c
> @@ -8,12 +8,15 @@
>
>  #include <config.h>
>  #include <common.h>
> +#include <dm.h>
>  #include <net.h>
>  #include <malloc.h>
>  #include <asm/io.h>
>  #include <phy.h>
>  #include <miiphy.h>
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
>  #if !defined(CONFIG_PHYLIB)
>  # error AXI_ETHERNET requires PHYLIB
>  #endif
> @@ -87,6 +90,7 @@ struct axidma_priv {
>         struct axidma_reg *dmarx;
>         int phyaddr;
>         struct axi_regs *iobase;
> +       phy_interface_t interface;
>         struct phy_device *phydev;
>         struct mii_dev *bus;
>  };
> @@ -218,11 +222,11 @@ static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum,
>  }
>
>  /* Setting axi emac and phy to proper setting */
> -static int setup_phy(struct eth_device *dev)
> +static int setup_phy(struct udevice *dev)
>  {
>         u16 phyreg;
>         u32 i, speed, emmc_reg, ret;
> -       struct axidma_priv *priv = dev->priv;
> +       struct axidma_priv *priv = dev_get_priv(dev);
>         struct axi_regs *regs = priv->iobase;
>         struct phy_device *phydev;
>
> @@ -298,9 +302,9 @@ static int setup_phy(struct eth_device *dev)
>  }
>
>  /* STOP DMA transfers */
> -static void axiemac_halt(struct eth_device *dev)
> +static void axiemac_halt(struct udevice *dev)
>  {
> -       struct axidma_priv *priv = dev->priv;
> +       struct axidma_priv *priv = dev_get_priv(dev);
>         u32 temp;
>
>         /* Stop the hardware */
> @@ -358,16 +362,18 @@ static int axi_ethernet_init(struct axidma_priv *priv)
>         return 0;
>  }
>
> -static int axiemac_setup_mac(struct eth_device *dev)
> +static int axiemac_setup_mac(struct udevice *dev)
>  {
> -       struct axi_regs *regs = (struct axi_regs *)dev->iobase;
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +       struct axidma_priv *priv = dev_get_priv(dev);
> +       struct axi_regs *regs = priv->iobase;
>
>         /* Set the MAC address */
> -       int val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) |
> -               (dev->enetaddr[1] << 8) | (dev->enetaddr[0]));
> +       int val = ((pdata->enetaddr[3] << 24) | (pdata->enetaddr[2] << 16) |
> +               (pdata->enetaddr[1] << 8) | (pdata->enetaddr[0]));
>         out_be32(&regs->uaw0, val);
>
> -       val = (dev->enetaddr[5] << 8) | dev->enetaddr[4] ;
> +       val = (pdata->enetaddr[5] << 8) | pdata->enetaddr[4];
>         val |= in_be32(&regs->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK;
>         out_be32(&regs->uaw1, val);
>         return 0;
> @@ -396,10 +402,10 @@ static void axi_dma_init(struct axidma_priv *priv)
>                 printf("%s: Timeout\n", __func__);
>  }
>
> -static int axiemac_init(struct eth_device *dev, bd_t * bis)
> +static int axiemac_init(struct udevice *dev)
>  {
> -       struct axidma_priv *priv = dev->priv;
> -       struct axi_regs *regs = (struct axi_regs *)dev->iobase;
> +       struct axidma_priv *priv = dev_get_priv(dev);
> +       struct axi_regs *regs = priv->iobase;
>         u32 temp;
>
>         debug("axiemac: Init started\n");
> @@ -458,9 +464,9 @@ static int axiemac_init(struct eth_device *dev, bd_t * bis)
>         return 0;
>  }
>
> -static int axiemac_send(struct eth_device *dev, void *ptr, int len)
> +static int axiemac_send(struct udevice *dev, void *ptr, int len)
>  {
> -       struct axidma_priv *priv = dev->priv;
> +       struct axidma_priv *priv = dev_get_priv(dev);
>         u32 timeout;
>
>         if (len > PKTSIZE_ALIGN)
> @@ -530,15 +536,15 @@ static int isrxready(struct axidma_priv *priv)
>         return 0;
>  }
>
> -static int axiemac_recv(struct eth_device *dev)
> +static int axiemac_recv(struct udevice *dev, int flags, uchar **packetp)
>  {
>         u32 length;
> -       struct axidma_priv *priv = dev->priv;
> +       struct axidma_priv *priv = dev_get_priv(dev);
>         u32 temp;
>
>         /* Wait for an incoming packet */
>         if (!isrxready(priv))
> -               return 0;
> +               return -1;

I suggest -EAGAIN

>
>         debug("axiemac: RX data ready\n");
>
> @@ -578,77 +584,125 @@ static int axiemac_recv(struct eth_device *dev)
>
>         debug("axiemac: RX completed, framelength = %d\n", length);
>
> -       return length;
> +       return 0;

You do need to return the length here. You could update net.h to make
this clearer.

>  }
>
> -static int axiemac_miiphy_read(const char *devname, uchar addr,
> -                                                       uchar reg, ushort *val)
> +static int axiemac_miiphy_read(struct mii_dev *bus, int addr,
> +                              int devad, int reg)
>  {
> -       struct eth_device *dev = eth_get_dev();
> -       u32 ret;
> +       int ret;
> +       u16 value;
>
> -       ret = phyread(dev->priv, addr, reg, val);
> -       debug("axiemac: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val);
> -       return ret;
> +       ret = phyread(bus->priv, addr, reg, &value);
> +       debug("axiemac: Read MII 0x%x, 0x%x, 0x%x, %d\n", addr, reg,
> +             value, ret);
> +       return value;
>  }
>
> -static int axiemac_miiphy_write(const char *devname, uchar addr,
> -                                                       uchar reg, ushort val)
> +static int axiemac_miiphy_write(struct mii_dev *bus, int addr, int devad,
> +                               int reg, u16 value)
>  {
> -       struct eth_device *dev = eth_get_dev();
> -
> -       debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val);
> -       return phywrite(dev->priv, addr, reg, val);
> +       debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, value);
> +       return phywrite(bus->priv, addr, reg, value);
>  }
>
> -static int axiemac_bus_reset(struct mii_dev *bus)
> +static int axi_emac_probe(struct udevice *dev)
>  {
> -       debug("axiemac: Bus reset\n");
> +       struct axidma_priv *priv = dev_get_priv(dev);
> +       int ret;
> +
> +       priv->bus = mdio_alloc();
> +       priv->bus->read = axiemac_miiphy_read;
> +       priv->bus->write = axiemac_miiphy_write;
> +       priv->bus->priv = priv;
> +       strcpy(priv->bus->name, "axi_emac");
> +
> +       ret = mdio_register(priv->bus);
> +       if (ret)
> +               return ret;
> +
>         return 0;
>  }
>
> -int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
> -                                                       unsigned long dma_addr)
> +static int axi_emac_remove(struct udevice *dev)
>  {
> -       struct eth_device *dev;
> -       struct axidma_priv *priv;
> +       struct axidma_priv *priv = dev_get_priv(dev);
>
> -       dev = calloc(1, sizeof(struct eth_device));
> -       if (dev == NULL)
> -               return -1;
> +       free(priv->phydev);
> +       mdio_unregister(priv->bus);
> +       mdio_free(priv->bus);
>
> -       dev->priv = calloc(1, sizeof(struct axidma_priv));
> -       if (dev->priv == NULL) {
> -               free(dev);
> -               return -1;
> -       }
> -       priv = dev->priv;
> +       return 0;
> +}
>
> -       sprintf(dev->name, "aximac.%lx", base_addr);
> +static const struct eth_ops axi_emac_ops = {
> +       .start                  = axiemac_init,
> +       .send                   = axiemac_send,
> +       .recv                   = axiemac_recv,
> +       .stop                   = axiemac_halt,
> +       .write_hwaddr           = axiemac_setup_mac,
> +};
>
> -       dev->iobase = base_addr;
> -       priv->iobase = (struct axi_regs *)base_addr;
> -       priv->dmatx = (struct axidma_reg *)dma_addr;
> +static int axi_emac_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_platdata(dev);
> +       struct axidma_priv *priv = dev_get_priv(dev);
> +       int offset = 0;
> +       const char *phy_mode;
> +
> +       pdata->iobase = (phys_addr_t)dev_get_addr(dev);
> +       priv->iobase = (struct axi_regs *)pdata->iobase;
> +
> +       offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
> +                                      "axistream-connected");
> +       if (offset <= 0) {
> +               printf("%s: axistream is not found\n", __func__);
> +               return -EINVAL;
> +       }
> +       priv->dmatx = (struct axidma_reg *)fdtdec_get_int(gd->fdt_blob,
> +                                                         offset, "reg", 0);
> +       if (!priv->dmatx) {
> +               printf("%s: axi_dma register space not found\n", __func__);
> +               return -EINVAL;
> +       }
>         /* RX channel offset is 0x30 */
> -       priv->dmarx = (struct axidma_reg *)(dma_addr + 0x30);
> -       dev->init = axiemac_init;
> -       dev->halt = axiemac_halt;
> -       dev->send = axiemac_send;
> -       dev->recv = axiemac_recv;
> -       dev->write_hwaddr = axiemac_setup_mac;
> -
> -#ifdef CONFIG_PHY_ADDR
> -       priv->phyaddr = CONFIG_PHY_ADDR;
> -#else
> +       priv->dmarx = (struct axidma_reg *)((u32)priv->dmatx + 0x30);
> +
>         priv->phyaddr = -1;
> -#endif
>
> -       eth_register(dev);
> +       offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
> +                                      "phy-handle");
> +       if (offset > 0)
> +               priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
> +
> +       phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "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;
> +       }
> +       priv->interface = pdata->phy_interface;
>
> -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
> -       miiphy_register(dev->name, axiemac_miiphy_read, axiemac_miiphy_write);
> -       priv->bus = miiphy_get_dev_by_name(dev->name);
> -       priv->bus->reset = axiemac_bus_reset;
> -#endif
> -       return 1;
> +       printf("AXI EMAC: %lx, phyaddr %d, interface %s\n", (ulong)priv->iobase,
> +              priv->phyaddr, phy_string_for_interface(priv->interface));
> +
> +       return 0;
>  }
> +
> +static const struct udevice_id axi_emac_ids[] = {
> +       { .compatible = "xlnx,axi-ethernet-1.00.a" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(axi_emac) = {
> +       .name   = "axi_emac",
> +       .id     = UCLASS_ETH,
> +       .of_match = axi_emac_ids,
> +       .ofdata_to_platdata = axi_emac_ofdata_to_platdata,
> +       .probe  = axi_emac_probe,
> +       .remove = axi_emac_remove,
> +       .ops    = &axi_emac_ops,
> +       .priv_auto_alloc_size = sizeof(struct axidma_priv),
> +       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
> +};
> diff --git a/include/netdev.h b/include/netdev.h
> index de74b9a534b1..b8d4e6abd5cc 100644
> --- a/include/netdev.h
> +++ b/include/netdev.h
> @@ -80,8 +80,6 @@ int tsi108_eth_initialize(bd_t *bis);
>  int uec_standard_init(bd_t *bis);
>  int uli526x_initialize(bd_t *bis);
>  int armada100_fec_register(unsigned long base_addr);
> -int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
> -                                                       unsigned long dma_addr);
>  int xilinx_emaclite_of_init(const void *blob);
>  int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
>                                                         int txpp, int rxpp);
> --
> 1.9.1
>

Regards,
Simon


More information about the U-Boot mailing list