net: cpsw: ti: Reap completed packets before stopping interface
authorAlex Kiernan <alex.kiernan@gmail.com>
Sat, 12 May 2018 07:30:02 +0000 (07:30 +0000)
committerJoe Hershberger <joe.hershberger@ni.com>
Wed, 13 Jun 2018 18:54:16 +0000 (13:54 -0500)
If you send a final packet just before stopping the interface (e.g. a final
ACK as part of the UDP fastboot protocol), then that packet isn't reliably
delivered onto the wire.

Reap packets prior to stopping the interface to ensure any which are
in-flight make it out. Also remove buffer and len from the call to
cpdma_process() as we weren't using them on their return.

Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
drivers/net/cpsw.c

index e2395dbeb9ccc4a9715ed91b8525491a8edbc365..9919d3919fafda77a0bcc399cfe670a5e5215fcf 100644 (file)
@@ -910,8 +910,22 @@ out:
        return ret;
 }
 
+static int cpsw_reap_completed_packets(struct cpsw_priv *priv)
+{
+       int timeout = CPDMA_TIMEOUT;
+
+       /* reap completed packets */
+       while (timeout-- &&
+              (cpdma_process(priv, &priv->tx_chan, NULL, NULL) >= 0))
+               ;
+
+       return timeout;
+}
+
 static void _cpsw_halt(struct cpsw_priv *priv)
 {
+       cpsw_reap_completed_packets(priv);
+
        writel(0, priv->dma_regs + CPDMA_TXCONTROL);
        writel(0, priv->dma_regs + CPDMA_RXCONTROL);
 
@@ -925,18 +939,12 @@ static void _cpsw_halt(struct cpsw_priv *priv)
 
 static int _cpsw_send(struct cpsw_priv *priv, void *packet, int length)
 {
-       void *buffer;
-       int len;
-       int timeout = CPDMA_TIMEOUT;
+       int timeout;
 
        flush_dcache_range((unsigned long)packet,
                           (unsigned long)packet + ALIGN(length, PKTALIGN));
 
-       /* first reap completed packets */
-       while (timeout-- &&
-               (cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0))
-               ;
-
+       timeout = cpsw_reap_completed_packets(priv);
        if (timeout == -1) {
                printf("cpdma_process timeout\n");
                return -ETIMEDOUT;