Messages in this thread Patch in this message | | | Subject | Re: [PATCH] macb: RLE and BNA handling | From | Erik Waling <> | Date | Wed, 14 Jan 2009 08:47:52 +0100 |
| |
Woops, just realized that the tabs in my previous post might have been messed up. One more try...
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); /*
| |