]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
net: xilinx: axiethernet: Check for queue full in transmit path
authorRadhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Mon, 18 Mar 2019 13:07:04 +0000 (18:37 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 18 Mar 2019 14:57:34 +0000 (15:57 +0100)
As per DMA programming sequence, software must not resubmit a BD which
is already under the hardware control else results are undefined. In
iperf3 stress testing, we observed intermittent zero bandwidth and DMA
IP going into stall state. To fix this behavior, in the transmit path
add a check for queue space before adding new BD elements.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/net/ethernet/xilinx/xilinx_axienet_main.c

index a235ef89b2579afec1fdbf944c8cadaddfe86d51..f3a44f2b5ce9b8d6a5eb70a56c594aac2aaec37b 100644 (file)
@@ -20,6 +20,7 @@
  *  - Add support for extended VLAN support.
  */
 
+#include <linux/circ_buf.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/module.h>
@@ -803,12 +804,18 @@ static inline int axienet_check_tx_bd_space(struct axienet_dma_q *q,
 #ifdef CONFIG_AXIENET_HAS_MCDMA
        struct aximcdma_bd *cur_p;
 
+       if (CIRC_SPACE(q->tx_bd_tail, q->tx_bd_ci, TX_BD_NUM) < (num_frag + 1))
+               return NETDEV_TX_BUSY;
+
        cur_p = &q->txq_bd_v[(q->tx_bd_tail + num_frag) % TX_BD_NUM];
        if (cur_p->sband_stats & XMCDMA_BD_STS_ALL_MASK)
                return NETDEV_TX_BUSY;
 #else
        struct axidma_bd *cur_p;
 
+       if (CIRC_SPACE(q->tx_bd_tail, q->tx_bd_ci, TX_BD_NUM) < (num_frag + 1))
+               return NETDEV_TX_BUSY;
+
        cur_p = &q->tx_bd_v[(q->tx_bd_tail + num_frag) % TX_BD_NUM];
        if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
                return NETDEV_TX_BUSY;