From: Michal Simek Date: Mon, 17 Aug 2015 07:57:46 +0000 (+0200) Subject: net: zynq: Wait till packet is sent X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=e4d2318adbcff084dbbed2f84e4a51da09a1b21b;p=u-boot.git net: zynq: Wait till packet is sent Wait till BD is processed 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 027b49bf7b..56651e94bb 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 @@ -86,6 +87,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 @@ -427,6 +430,33 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis) return 0; } +static int wait_for_bit(const 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; @@ -467,7 +497,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 */