]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
net: gem: Wait till packet is sent
authorMichal Simek <michal.simek@xilinx.com>
Mon, 17 Aug 2015 07:57:46 +0000 (09:57 +0200)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 24 Aug 2015 07:06:59 +0000 (09:06 +0200)
Wait till BD is process to ensure that packet was sent successfully.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/net/zynq_gem.c

index c5c22aefac90b32f9bfcc98d2ba9c19ba9db298a..7d633b60bb087c0e281ee94f5a1d6cbe8d4b93a7 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/system.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
+#include <asm-generic/errno.h>
 
 #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__, &regs->txsr, ZYNQ_GEM_TSR_DONE,
+                           true, 20000);
 }
 
 /* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */