[PATCH] macb: RLE and BNA handling



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@xxxxxxxxxxx>

---

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);

/*


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • Re: Degradation of TCP connection
    ... Gigabit ethernet. ... D card's data buffer can only hold about 64K samples worth of data ... link you posted is for an older version of VxWorks that used a BSD- ... but a bug in the ethernet driver. ...
    (comp.os.vxworks)
  • Re: Degradation of TCP connection
    ... Gigabit ethernet. ... D card's data buffer can only hold about 64K samples worth of data ... link you posted is for an older version of VxWorks that used a BSD- ... but a bug in the ethernet driver. ...
    (comp.os.vxworks)
  • Re: Ethernet Slowdown Every 20 sec
    ... Maybe the driver is missing an interrupt and thereby using up a buffer, ... Ethernet connection instead, everything works perfectly. ... Obviously I'd like to get rid of this pause in UDP throughput... ...
    (microsoft.public.windowsce.embedded)
  • Re: Difference between synchronous and asynchronous operation/calls (NDISPROT)
    ... The main problem with synchronous operation/calls seems to be the lack of buffers for the driver to store data into. ... Each "read call" supplies the driver with a buffer and optionally a completion routine so that the driver can inform the application when the requested operation is/was done. ... However it seems the current windows/driver design does some copies as well? ...
    (microsoft.public.development.device.drivers)
  • Re: PCI bus-master and large contiguous memory buffers
    ... As soon as device reaches the end of the buffer ... Sure, I am developing both PCI adapter and device driver, so, it is ... not afford reinitializing DMA on my device after every transfer. ... x86 CPU memory management structures I never tried to dig into Windows ...
    (microsoft.public.development.device.drivers)