[U-Boot] [PATCH 00/10] 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
Michal Simek (10): 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: 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 | 278 +++++++++++++-------- include/netdev.h | 2 - 5 files changed, 183 insertions(+), 114 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 ---
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); }

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
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

Fix debug message.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
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; } }

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Fix debug message.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

Simplify mdio_wait function by passing regs directly.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
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;

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
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

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 ---
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);

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
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.
As long as the information is still coming from the pdata or device tree that should be fine.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

Prepare for move to DM.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
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)

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Prepare for move to DM.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

Simplify move to DM to avoid handling with eth_device structure.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
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");

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Simplify move to DM to avoid handling with eth_device structure.
I think you need to change this commit log. You are moving functions to use axidma_priv instead of eth_device in preparation of the DM move. You are not actually moving to DM with this patch.
Signed-off-by: Michal Simek michal.simek@xilinx.com

Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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(-)
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);

Hi Michal,
On 11 December 2015 at 04:59, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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@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(®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;
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

On 15.12.2015 19:57, Simon Glass wrote:
Hi Michal,
On 11 December 2015 at 04:59, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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@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(®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;
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.
Are you sure?
recv part is calling net_process_received_packet(rxframe, length); already and then the core is checking for returning value. which should be 0 or less to quit this loop.
447 for (i = 0; i < 32; i++) { 448 ret = eth_get_ops(current)->recv(current, flags, &packet); 449 flags = 0; 450 if (ret > 0) 451 net_process_received_packet(packet, ret); 452 if (ret >= 0 && eth_get_ops(current)->free_pkt) 453 eth_get_ops(current)->free_pkt(current, packet, ret ); 454 if (ret <= 0) 455 break; 456 }
Thanks, Michal

Hi Michal,
On Tue, Dec 15, 2015 at 1:40 PM, Michal Simek michal.simek@xilinx.com wrote:
On 15.12.2015 19:57, Simon Glass wrote:
Hi Michal,
On 11 December 2015 at 04:59, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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@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(®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;
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.
Are you sure?
recv part is calling net_process_received_packet(rxframe, length); already and then the core is checking for returning value. which should be 0 or less to quit this loop.
447 for (i = 0; i < 32; i++) { 448 ret = eth_get_ops(current)->recv(current, flags, &packet); 449 flags = 0; 450 if (ret > 0)
If you return 0, your packet is not processed. 0 means you got nothing.
451 net_process_received_packet(packet, ret); 452 if (ret >= 0 && eth_get_ops(current)->free_pkt) 453 eth_get_ops(current)->free_pkt(current, packet, ret ); 454 if (ret <= 0) 455 break; 456 }
Thanks, Michal
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi Simon,
On Tue, Dec 15, 2015 at 12:57 PM, Simon Glass sjg@chromium.org wrote:
Hi Michal,
On 11 December 2015 at 04:59, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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@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(®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;
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.
I think I figured out what Michal is doing here. What's not clear from this patch is that he doesn't want net_process_received_packet() to run on the packet since this function already calls it directly above.
He has a follow-on patch that fixes that and resumes returning the length from recv().
}
-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;
}
<snip>

Hi Joe,
On 15 December 2015 at 13:52, Joe Hershberger joe.hershberger@gmail.com wrote:
Hi Simon,
On Tue, Dec 15, 2015 at 12:57 PM, Simon Glass sjg@chromium.org wrote:
Hi Michal,
On 11 December 2015 at 04:59, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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@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(®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;
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.
I think I figured out what Michal is doing here. What's not clear from this patch is that he doesn't want net_process_received_packet() to run on the packet since this function already calls it directly above.
He has a follow-on patch that fixes that and resumes returning the length from recv().
OK I see, thanks.
}
-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;
}
<snip>
Regards, SImon

On 15.12.2015 23:34, Simon Glass wrote:
Hi Joe,
On 15 December 2015 at 13:52, Joe Hershberger joe.hershberger@gmail.com wrote:
Hi Simon,
On Tue, Dec 15, 2015 at 12:57 PM, Simon Glass sjg@chromium.org wrote:
Hi Michal,
On 11 December 2015 at 04:59, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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@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(®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;
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.
I think I figured out what Michal is doing here. What's not clear from this patch is that he doesn't want net_process_received_packet() to run on the packet since this function already calls it directly above.
He has a follow-on patch that fixes that and resumes returning the length from recv().
OK I see, thanks.
That's what I meant by word "already" below. "recv part is calling net_process_received_packet(rxframe, length); already and then the core is checking for returning value. which should be 0 or less to quit this loop."
I wanted to do separation by two patches to make it clear but it looks like I have confused you a little bit. :-)
Does that mean that I can add Simon's Reviewed-by tag? Joe: What about you?
Thanks, Michal

On Wed, Dec 16, 2015 at 2:14 AM, Michal Simek michal.simek@xilinx.com wrote:
On 15.12.2015 23:34, Simon Glass wrote:
Hi Joe,
On 15 December 2015 at 13:52, Joe Hershberger joe.hershberger@gmail.com wrote:
Hi Simon,
On Tue, Dec 15, 2015 at 12:57 PM, Simon Glass sjg@chromium.org wrote:
Hi Michal,
On 11 December 2015 at 04:59, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@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@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(®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;
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.
I think I figured out what Michal is doing here. What's not clear from this patch is that he doesn't want net_process_received_packet() to run on the packet since this function already calls it directly above.
He has a follow-on patch that fixes that and resumes returning the length from recv().
OK I see, thanks.
That's what I meant by word "already" below. "recv part is calling net_process_received_packet(rxframe, length); already and then the core is checking for returning value. which should be 0 or less to quit this loop."
I wanted to do separation by two patches to make it clear but it looks like I have confused you a little bit. :-)
Does that mean that I can add Simon's Reviewed-by tag? Joe: What about you?
Yes, Acked-by: Joe Hershberger joe.hershberger@ni.com

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Other than a few nits below and the issue with recv return value,
Acked-by: Joe Hershberger <joe.hershberger>
.../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,
Now would be a good time to rename the driver function start.
.send = axiemac_send,
.recv = axiemac_recv,
.stop = axiemac_halt,
Now would be a good time to rename the driver function stop.
.write_hwaddr = axiemac_setup_mac,
It would be good to call this axiemac_write_hwaddr.
+};
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);
It's nice to see these disappearing.
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
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 15.12.2015 21:31, Joe Hershberger wrote:
On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Move driver to DM.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Other than a few nits below and the issue with recv return value,
Acked-by: Joe Hershberger <joe.hershberger>
.../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,
Now would be a good time to rename the driver function start.
.send = axiemac_send,
.recv = axiemac_recv,
.stop = axiemac_halt,
Now would be a good time to rename the driver function stop.
.write_hwaddr = axiemac_setup_mac,
It would be good to call this axiemac_write_hwaddr.
Will be in separate patch.
Thanks, Michal

Detect phy when driver probes.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
drivers/net/xilinx_axi_emac.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index c03f8f730d3a..bff4d1b5affe 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -222,10 +222,10 @@ static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum, }
/* 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 +237,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 +262,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); @@ -358,6 +373,7 @@ static int axi_ethernet_init(struct axidma_priv *priv) /* Set default MDIO divisor */ out_be32(®s->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK);
+ debug("axiemac: InitHw done\n"); return 0; } @@ -621,6 +637,8 @@ static int axi_emac_probe(struct udevice *dev) if (ret) return ret;
+ axiemac_phy_init(dev); + return 0; }

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Detect phy when driver probes.
Signed-off-by: Michal Simek michal.simek@xilinx.com
A few nits below, but otherwise,
Acked-by: Joe Hershberger joe.hershberger@ni.com
drivers/net/xilinx_axi_emac.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index c03f8f730d3a..bff4d1b5affe 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -222,10 +222,10 @@ static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum, }
/* Setting axi emac and phy to proper setting */
I think you didn't mean to leave this comment here.
-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 +237,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 +262,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);
@@ -358,6 +373,7 @@ static int axi_ethernet_init(struct axidma_priv *priv) /* Set default MDIO divisor */ out_be32(®s->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK);
Why do we need two blank lines?
debug("axiemac: InitHw done\n"); return 0;
} @@ -621,6 +637,8 @@ static int axi_emac_probe(struct udevice *dev) if (ret) return ret;
axiemac_phy_init(dev);
return 0;
}
-- 1.9.1
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 15.12.2015 21:42, Joe Hershberger wrote:
On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Detect phy when driver probes.
Signed-off-by: Michal Simek michal.simek@xilinx.com
A few nits below, but otherwise,
Acked-by: Joe Hershberger joe.hershberger@ni.com
All nits are valid and fixed in v2.
Thanks, Michal

Call net_process_received_packet() by core.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
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 bff4d1b5affe..e8a8d9cc2744 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -573,9 +573,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 */ @@ -657,6 +662,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, };

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
Call net_process_received_packet() by core.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

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 ---
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 13e0269a30b0..15422e93fb93 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 e8a8d9cc2744..555952ffdc83 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 */

On Fri, Dec 11, 2015 at 5:59 AM, Michal Simek michal.simek@xilinx.com wrote:
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
participants (3)
-
Joe Hershberger
-
Michal Simek
-
Simon Glass