diff mbox series

[U-Boot] net: cpsw: ti: Reap completed packets before stopping interface

Message ID 1526110202-859-1-git-send-email-alex.kiernan@gmail.com
State Accepted
Commit 286bea2e85a73602624b8dc05dd0dfac8e7e4263
Delegated to: Joe Hershberger
Headers show
Series [U-Boot] net: cpsw: ti: Reap completed packets before stopping interface | expand

Commit Message

Alex Kiernan May 12, 2018, 7:30 a.m. UTC
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>
---

 drivers/net/cpsw.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

Comments

Joe Hershberger May 16, 2018, 7:24 p.m. UTC | #1
On Sat, May 12, 2018 at 2:30 AM, Alex Kiernan <alex.kiernan@gmail.com> wrote:
> 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>
Joe Hershberger June 13, 2018, 7:01 p.m. UTC | #2
Hi Alex,

https://patchwork.ozlabs.org/patch/912382/ was applied to http://git.denx.de/?p=u-boot/u-boot-net.git

Thanks!
-Joe
diff mbox series

Patch

diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index e2395db..9919d39 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -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;