public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Erik Waling <erik.waling@konftel.se>
To: <hskinnemoen@atmel.com>
Cc: <linux-kernel@vger.kernel.org>
Subject: [PATCH] macb: RLE and BNA handling
Date: Tue, 13 Jan 2009 17:21:53 +0100	[thread overview]
Message-ID: <1231863713.10152.11.camel@konftel> (raw)

This patch (against 2.6.28) solves two issues we have been experiencing
when connecting the EMAC module on our AT91SAM9260 board to an ethernet
repeater hub. When transfering large amounts of data we sometimes
experienced that the Retry Limit Exceeded (RLE) bit got set in TSR
during transmission attempts. When this happened the driver would stall
in a state that prevented any more data from being sent.

The other issue experienced was in the RX part of the driver. Sometimes
the driver runs out of unused slots in the RX ring buffer. All slots
will be filled with data but the driver is not able to extract a
complete frame from the fragments in the buffer. When this happens the
Buffer Not Available (BNA) bit is set in RSR.

This patch adds handling for RLE and BNA.

Signed-off-by: Erik Waling <erik.waling@konftel.com>

---

diff -urpN linux-2.6.28.orig/drivers/net/macb.c linux-2.6.28.rle_and_bna_fix/drivers/net/macb.c
--- linux-2.6.28.orig/drivers/net/macb.c        2009-01-13 10:36:13.000000000 +0100
+++ linux-2.6.28.rle_and_bna_fix/drivers/net/macb.c     2009-01-13 16:50:34.000000000 +0100
@@ -2,6 +2,7 @@
  * Atmel MACB Ethernet Controller driver
  *
  * Copyright (C) 2004-2006 Atmel Corporation
+ * Copyright (C) 2008-2009 Konftel AB
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -316,10 +317,11 @@ static void macb_tx(struct macb *bp)
        dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n",
                (unsigned long)status);

-       if (status & MACB_BIT(UND)) {
+       if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
                int i;
-               printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
-                       bp->dev->name);
+               printk(KERN_ERR "%s: TX %s, resetting buffers\n",
+                       bp->dev->name, status & MACB_BIT(UND) ?
+                       "underrun" : "retry limit exceeded");

                head = bp->tx_head;

@@ -527,18 +529,31 @@ static int macb_poll(struct napi_struct
        dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
                (unsigned long)status, budget);

-       if (!(status & MACB_BIT(REC))) {
+       if (status & MACB_BIT(REC)) {
+               work_done = macb_rx(bp, budget);
+               if (work_done < budget)
+                       netif_rx_complete(dev, napi);
+       } else if (status & MACB_BIT(BNA)) {
+               /* No slots available in RX ring. Mark all slots
+                * as unused.
+                */
+               int i;
+
+               dev_warn(&bp->pdev->dev,
+                               "No free RX buffers. Marking all as unused.\n");
+
+               for (i = 0; i < RX_RING_SIZE; i++)
+                       bp->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
+
+               wmb();
+               netif_rx_complete(dev, napi);
+       } else if (!(status & MACB_BIT(REC))) {
                dev_warn(&bp->pdev->dev,
                         "No RX buffers complete, status = %02lx\n",
                         (unsigned long)status);
                netif_rx_complete(dev, napi);
-               goto out;
        }

-       work_done = macb_rx(bp, budget);
-       if (work_done < budget)
-               netif_rx_complete(dev, napi);
-
        /*
         * We've done what we can to clean the buffers. Make sure we
         * get notified when new packets arrive.
@@ -584,7 +599,8 @@ static irqreturn_t macb_interrupt(int ir
                        }
                }

-               if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND)))
+               if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) |
+                            MACB_BIT(ISR_RLE)))
                        macb_tx(bp);

                /*



             reply	other threads:[~2009-01-13 16:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-13 16:21 Erik Waling [this message]
2009-01-14  7:47 ` [PATCH] macb: RLE and BNA handling Erik Waling
2009-01-14 10:15 ` Haavard Skinnemoen
2009-01-14 10:27   ` Erik Waling
2009-01-14 12:03     ` Haavard Skinnemoen
2009-01-15 13:37       ` Erik Waling
2009-03-26  9:38         ` Erik Waling
2009-03-30 12:04           ` Haavard Skinnemoen
2009-03-31 14:50             ` Erik Waling
2009-04-01  9:31               ` Haavard Skinnemoen
2009-04-01 13:05                 ` Erik Waling

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1231863713.10152.11.camel@konftel \
    --to=erik.waling@konftel.se \
    --cc=hskinnemoen@atmel.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox