From: Michal Simek Date: Mon, 17 Aug 2015 07:57:46 +0000 (+0200) Subject: net: gem: Wait till packet is sent X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7aee1161c94bf218c6bd00836be09f2ad86d2c4e;p=thirdparty%2Fu-boot.git net: gem: Wait till packet is sent Wait till BD is process to ensure that packet was sent successfully. Signed-off-by: Michal Simek --- diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index c5c22aefac9..7d633b60bb0 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -23,6 +23,7 @@ #include #include #include +#include #if !defined(CONFIG_PHYLIB) # error XILINX_GEM_ETHERNET requires PHYLIB @@ -89,6 +90,8 @@ ZYNQ_GEM_DMACR_TXSIZE | \ ZYNQ_GEM_DMACR_RXBUF) +#define ZYNQ_GEM_TSR_DONE 0x00000020 /* Tx done mask */ + /* Use MII register 1 (MII status register) to detect PHY */ #define PHY_DETECT_REG 1 @@ -401,6 +404,33 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis) return 0; } +static inline int wait_for_bit(char *func, u32 *reg, const u32 mask, bool set, + unsigned int timeout) +{ + u32 val; + unsigned long start = get_timer(0); + + while(1) { + val = readl(reg); + + if (!set) + val = ~val; + + if ((val & mask) == mask) + return 0; + + if (get_timer(start) > timeout) + break; + + udelay(1); + } + + debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n", + func, reg, mask, set); + + return -ETIMEDOUT; +} + static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) { u32 addr, size; @@ -436,7 +466,8 @@ static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED) printf("TX buffers exhausted in mid frame\n"); - return 0; + return wait_for_bit(__func__, ®s->txsr, ZYNQ_GEM_TSR_DONE, + true, 20000); } /* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */