[U-Boot] [PATCH v2 00/11] Moving Axi emac to DM

Hi,
This patch series depends on microblaze cleanup series. All these patches will be available in git://git.denx.de/u-boot-microblaze.git also with patches which I am going to send now.
Thanks, Michal
Changes in v2: - Change commit message - Joe - Remove additional blank line - Joe - Remove one comment - Joe - new patch is this series
Michal Simek (11): net: axi_emac: Fix parentheses around operand ! net: axi_emac: Show phy address instead of register content net: axi_emac: Pass directly pointer to register space net: axi_emac: Put iobase to private structure net: axi_emac: Pass private structure to phyread/phywrite net: axi_emac: Pass private structure where possible net: axi_emac: Move driver to DM net: axi_emac: Enable access to MDIO in probe net: axi_emac: Split recv from free_pkt net: axi_emac: Rename start, stop, write_hwaddr functions net: Add axi emac to Kconfig
.../xilinx/microblaze-generic/microblaze-generic.c | 5 - board/xilinx/zynq/board.c | 4 - drivers/net/Kconfig | 8 + drivers/net/xilinx_axi_emac.c | 280 +++++++++++++-------- include/netdev.h | 2 - 5 files changed, 183 insertions(+), 116 deletions(-)

Fix these compilation warning by proper grouping: In function 'axi_dma_init': drivers/net/xilinx_axi_emac.c:391:7: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] if (!(in_be32(&priv->dmatx->control) | ^ In function 'axiemac_send': drivers/net/xilinx_axi_emac.c:501:21: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses] while (timeout && (!in_be32(&priv->dmatx->status) &
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
drivers/net/xilinx_axi_emac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index df053feee8c8..994affa66fc4 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -388,9 +388,9 @@ static void axi_dma_init(struct eth_device *dev) while (timeout--) { /* Check transmit/receive channel */ /* Reset is done when the reset bit is low */ - if (!(in_be32(&priv->dmatx->control) | + if (!((in_be32(&priv->dmatx->control) | in_be32(&priv->dmarx->control)) - & XAXIDMA_CR_RESET_MASK) { + & XAXIDMA_CR_RESET_MASK)) { break; } } @@ -498,8 +498,8 @@ static int axiemac_send(struct eth_device *dev, void *ptr, int len) /* Wait for transmission to complete */ debug("axiemac: Waiting for tx to be done\n"); timeout = 200; - while (timeout && (!in_be32(&priv->dmatx->status) & - (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) { + while (timeout && (!(in_be32(&priv->dmatx->status) & + (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK)))) { timeout--; udelay(1); }

Fix debug message.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
drivers/net/xilinx_axi_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 994affa66fc4..f08823008908 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -243,7 +243,7 @@ static int setup_phy(struct eth_device *dev) /* Found a valid PHY address */ priv->phyaddr = i; debug("axiemac: Found valid phy address, %x\n", - phyreg); + i); break; } }

Simplify mdio_wait function by passing regs directly.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
drivers/net/xilinx_axi_emac.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index f08823008908..071e0a85b582 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -147,9 +147,8 @@ struct axi_regs { */ #define PHY_DETECT_MASK 0x1808
-static inline int mdio_wait(struct eth_device *dev) +static inline int mdio_wait(struct axi_regs *regs) { - struct axi_regs *regs = (struct axi_regs *)dev->iobase; u32 timeout = 200;
/* Wait till MDIO interface is ready to accept a new transaction. */ @@ -171,7 +170,7 @@ static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum, struct axi_regs *regs = (struct axi_regs *)dev->iobase; u32 mdioctrlreg = 0;
- if (mdio_wait(dev)) + if (mdio_wait(regs)) return 1;
mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) & @@ -183,7 +182,7 @@ static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum,
out_be32(®s->mdio_mcr, mdioctrlreg);
- if (mdio_wait(dev)) + if (mdio_wait(regs)) return 1;
/* Read data */ @@ -197,7 +196,7 @@ static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum, struct axi_regs *regs = (struct axi_regs *)dev->iobase; u32 mdioctrlreg = 0;
- if (mdio_wait(dev)) + if (mdio_wait(regs)) return 1;
mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) & @@ -212,7 +211,7 @@ static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum,
out_be32(®s->mdio_mcr, mdioctrlreg);
- if (mdio_wait(dev)) + if (mdio_wait(regs)) return 1;
return 0;

Saving iobase directly to private structure helps with moving to DM. There is an option to load iobase from pdata but it is additional load. Pointer to private structure is available all the time.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
drivers/net/xilinx_axi_emac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 071e0a85b582..3c980657729e 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -86,7 +86,7 @@ struct axidma_priv { struct axidma_reg *dmatx; struct axidma_reg *dmarx; int phyaddr; - + struct axi_regs *iobase; struct phy_device *phydev; struct mii_dev *bus; }; @@ -223,7 +223,7 @@ static int setup_phy(struct eth_device *dev) u16 phyreg; u32 i, speed, emmc_reg, ret; struct axidma_priv *priv = dev->priv; - struct axi_regs *regs = (struct axi_regs *)dev->iobase; + struct axi_regs *regs = priv->iobase; struct phy_device *phydev;
u32 supported = SUPPORTED_10baseT_Half | @@ -629,6 +629,7 @@ int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr, sprintf(dev->name, "aximac.%lx", base_addr);
dev->iobase = base_addr; + priv->iobase = (struct axi_regs *)base_addr; priv->dmatx = (struct axidma_reg *)dma_addr; /* RX channel offset is 0x30 */ priv->dmarx = (struct axidma_reg *)(dma_addr + 0x30);

Prepare for move to DM.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
drivers/net/xilinx_axi_emac.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 3c980657729e..20ff6b089830 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -164,10 +164,10 @@ static inline int mdio_wait(struct axi_regs *regs) return 0; }
-static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum, - u16 *val) +static u32 phyread(struct axidma_priv *priv, u32 phyaddress, u32 registernum, + u16 *val) { - struct axi_regs *regs = (struct axi_regs *)dev->iobase; + struct axi_regs *regs = priv->iobase; u32 mdioctrlreg = 0;
if (mdio_wait(regs)) @@ -190,10 +190,10 @@ static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum, return 0; }
-static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum, - u32 data) +static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum, + u32 data) { - struct axi_regs *regs = (struct axi_regs *)dev->iobase; + struct axi_regs *regs = priv->iobase; u32 mdioctrlreg = 0;
if (mdio_wait(regs)) @@ -236,7 +236,7 @@ static int setup_phy(struct eth_device *dev) if (priv->phyaddr == -1) { /* Detect the PHY address */ for (i = 31; i >= 0; i--) { - ret = phyread(dev, i, PHY_DETECT_REG, &phyreg); + ret = phyread(priv, i, PHY_DETECT_REG, &phyreg); if (!ret && (phyreg != 0xFFFF) && ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { /* Found a valid PHY address */ @@ -589,7 +589,7 @@ static int axiemac_miiphy_read(const char *devname, uchar addr, struct eth_device *dev = eth_get_dev(); u32 ret;
- ret = phyread(dev, addr, reg, val); + ret = phyread(dev->priv, addr, reg, val); debug("axiemac: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val); return ret; } @@ -600,7 +600,7 @@ static int axiemac_miiphy_write(const char *devname, uchar addr, struct eth_device *dev = eth_get_dev();
debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val); - return phywrite(dev, addr, reg, val); + return phywrite(dev->priv, addr, reg, val); }
static int axiemac_bus_reset(struct mii_dev *bus)

Use axidma_priv instead of ethdevice in preparation of the DM move.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
Changes in v2: - Change commit message - Joe
drivers/net/xilinx_axi_emac.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 20ff6b089830..77b1869dc9dc 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -315,9 +315,9 @@ static void axiemac_halt(struct eth_device *dev) debug("axiemac: Halted\n"); }
-static int axi_ethernet_init(struct eth_device *dev) +static int axi_ethernet_init(struct axidma_priv *priv) { - struct axi_regs *regs = (struct axi_regs *)dev->iobase; + struct axi_regs *regs = priv->iobase; u32 timeout = 200;
/* @@ -374,9 +374,8 @@ static int axiemac_setup_mac(struct eth_device *dev) }
/* Reset DMA engine */ -static void axi_dma_init(struct eth_device *dev) +static void axi_dma_init(struct axidma_priv *priv) { - struct axidma_priv *priv = dev->priv; u32 timeout = 500;
/* Reset the engine so the hardware starts from a known state */ @@ -410,10 +409,10 @@ static int axiemac_init(struct eth_device *dev, bd_t * bis) * reset, and since AXIDMA reset line is connected to AxiEthernet, this * would ensure a reset of AxiEthernet. */ - axi_dma_init(dev); + axi_dma_init(priv);
/* Initialize AxiEthernet hardware. */ - if (axi_ethernet_init(dev)) + if (axi_ethernet_init(priv)) return -1;
/* Disable all RX interrupts before RxBD space setup */ @@ -511,10 +510,9 @@ static int axiemac_send(struct eth_device *dev, void *ptr, int len) return 0; }
-static int isrxready(struct eth_device *dev) +static int isrxready(struct axidma_priv *priv) { u32 status; - struct axidma_priv *priv = dev->priv;
/* Read pending interrupts */ status = in_be32(&priv->dmarx->status); @@ -539,7 +537,7 @@ static int axiemac_recv(struct eth_device *dev) u32 temp;
/* Wait for an incoming packet */ - if (!isrxready(dev)) + if (!isrxready(priv)) return 0;
debug("axiemac: RX data ready\n");

Move driver to DM.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
.../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(-)
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(®s->uaw0, val);
- val = (dev->enetaddr[5] << 8) | dev->enetaddr[4] ; + val = (pdata->enetaddr[5] << 8) | pdata->enetaddr[4]; val |= in_be32(®s->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK; out_be32(®s->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;
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; }
-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);

Detect phy when driver probes.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: - Remove additional blank line - Joe - Remove one comment - Joe
drivers/net/xilinx_axi_emac.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index c03f8f730d3a..172ccc5b952b 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -221,11 +221,10 @@ static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum, return 0; }
-/* Setting axi emac and phy to proper setting */ -static int setup_phy(struct udevice *dev) +static int axiemac_phy_init(struct udevice *dev) { u16 phyreg; - u32 i, speed, emmc_reg, ret; + u32 i, ret; struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->iobase; struct phy_device *phydev; @@ -237,6 +236,9 @@ static int setup_phy(struct udevice *dev) SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+ /* Set default MDIO divisor */ + out_be32(®s->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK); + if (priv->phyaddr == -1) { /* Detect the PHY address */ for (i = 31; i >= 0; i--) { @@ -259,6 +261,18 @@ static int setup_phy(struct udevice *dev) phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); + + return 0; +} + +/* Setting axi emac and phy to proper setting */ +static int setup_phy(struct udevice *dev) +{ + u32 speed, emmc_reg; + struct axidma_priv *priv = dev_get_priv(dev); + struct axi_regs *regs = priv->iobase; + struct phy_device *phydev = priv->phydev; + if (phy_startup(phydev)) { printf("axiemac: could not initialize PHY %s\n", phydev->dev->name); @@ -621,6 +635,8 @@ static int axi_emac_probe(struct udevice *dev) if (ret) return ret;
+ axiemac_phy_init(dev); + return 0; }

Call net_process_received_packet() by core.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
drivers/net/xilinx_axi_emac.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 172ccc5b952b..adfee8c15123 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -571,9 +571,14 @@ static int axiemac_recv(struct udevice *dev, int flags, uchar **packetp) #ifdef DEBUG print_buffer(&rxframe, &rxframe[0], 1, length, 16); #endif - /* Pass the received frame up for processing */ - if (length) - net_process_received_packet(rxframe, length); + + *packetp = rxframe; + return length; +} + +static int axiemac_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct axidma_priv *priv = dev_get_priv(dev);
#ifdef DEBUG /* It is useful to clear buffer to be sure that it is consistent */ @@ -655,6 +660,7 @@ static const struct eth_ops axi_emac_ops = { .start = axiemac_init, .send = axiemac_send, .recv = axiemac_recv, + .free_pkt = axiemac_free_pkt, .stop = axiemac_halt, .write_hwaddr = axiemac_setup_mac, };

Rename few functions to fit to the new name convention used by DM.
Suggested-by: Joe Hershberger joe.hershberger@ni.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
Changes in v2: - new patch is this series
drivers/net/xilinx_axi_emac.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index adfee8c15123..4a514d08ae0f 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -316,7 +316,7 @@ static int setup_phy(struct udevice *dev) }
/* STOP DMA transfers */ -static void axiemac_halt(struct udevice *dev) +static void axiemac_stop(struct udevice *dev) { struct axidma_priv *priv = dev_get_priv(dev); u32 temp; @@ -376,7 +376,7 @@ static int axi_ethernet_init(struct axidma_priv *priv) return 0; }
-static int axiemac_setup_mac(struct udevice *dev) +static int axiemac_write_hwaddr(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct axidma_priv *priv = dev_get_priv(dev); @@ -416,7 +416,7 @@ static void axi_dma_init(struct axidma_priv *priv) printf("%s: Timeout\n", __func__); }
-static int axiemac_init(struct udevice *dev) +static int axiemac_start(struct udevice *dev) { struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->iobase; @@ -470,7 +470,7 @@ static int axiemac_init(struct udevice *dev)
/* PHY setup */ if (!setup_phy(dev)) { - axiemac_halt(dev); + axiemac_stop(dev); return -1; }
@@ -657,12 +657,12 @@ static int axi_emac_remove(struct udevice *dev) }
static const struct eth_ops axi_emac_ops = { - .start = axiemac_init, + .start = axiemac_start, .send = axiemac_send, .recv = axiemac_recv, .free_pkt = axiemac_free_pkt, - .stop = axiemac_halt, - .write_hwaddr = axiemac_setup_mac, + .stop = axiemac_stop, + .write_hwaddr = axiemac_write_hwaddr, };
static int axi_emac_ofdata_to_platdata(struct udevice *dev)

Also add dependency on PHYLIB and MII which is required. Clean PHYLIB dependency from the driver too.
Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Joe Hershberger joe.hershberger@ni.com ---
Changes in v2: None
drivers/net/Kconfig | 8 ++++++++ drivers/net/xilinx_axi_emac.c | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ae5e78dd3449..9dc106cc93b7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -101,6 +101,14 @@ config PCH_GBE This MAC is present in Intel Platform Controller Hub EG20T. It supports 10/100/1000 Mbps operation.
+config XILINX_AXIEMAC + depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP) + select PHYLIB + select MII + bool "Xilinx AXI Ethernet" + help + This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs. + config ZYNQ_GEM depends on DM_ETH && (ARCH_ZYNQ || ARCH_ZYNQMP) select PHYLIB diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 4a514d08ae0f..81274ee13bca 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -17,10 +17,6 @@
DECLARE_GLOBAL_DATA_PTR;
-#if !defined(CONFIG_PHYLIB) -# error AXI_ETHERNET requires PHYLIB -#endif - /* Link setup */ #define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */ #define XAE_EMMC_LINKSPD_10 0x00000000 /* Link Speed mask for 10 Mbit */
participants (1)
-
Michal Simek