diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-23 13:05:46 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-23 13:05:46 -0800 |
| commit | 2634d064c16cc897bc850a109bbea781b50d1ad5 (patch) | |
| tree | 89021349a41791a53eacb96839440a84b9388f4a /drivers/net/macb.c | |
| parent | c63f702068a445f682d7590c5fadfc266785a071 (diff) | |
| parent | bdcba1511b98f2e728b3a910b8771a0d3fce5bf3 (diff) | |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6:
MACB: clear transmit buffers properly on transmit underrun
3c359 endianness annotations and fixes
fec_mpc52xx: write in C...
3c574 and 3c589 endianness fixes (.24?)
rrunner: use offsetof() instead of homegrown insanity
r8169 endianness
dl2k endianness fixes (.24 fodder?)
yellowfin: annotations and fixes (.24 fodder?)
asix fixes
cycx: annotations and fixes (.24 fodder?)
typhoon: trivial endianness annotations
typhoon: memory corruptor on big-endian if TSO is enabled
typhoon: missed rx overruns on big-endian
typhoon: set_settings broken on big-endian
typhoon: missing le32_to_cpu() in get_drvinfo
typhoon: endianness bug in tx/rx byte counters
ipw2200: prevent alloc of unspecified size on stack
iwlwifi: fix possible priv->mutex deadlock during suspend
p54: add Kconfig description
rtl8187: Add USB ID for Sitecom WL-168 v1 001
Diffstat (limited to 'drivers/net/macb.c')
| -rw-r--r-- | drivers/net/macb.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 047ea7be4850..e10528ed9081 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -307,8 +307,31 @@ static void macb_tx(struct macb *bp) (unsigned long)status); if (status & MACB_BIT(UND)) { + int i; printk(KERN_ERR "%s: TX underrun, resetting buffers\n", - bp->dev->name); + bp->dev->name); + + head = bp->tx_head; + + /*Mark all the buffer as used to avoid sending a lost buffer*/ + for (i = 0; i < TX_RING_SIZE; i++) + bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); + + /* free transmit buffer in upper layer*/ + for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) { + struct ring_info *rp = &bp->tx_skb[tail]; + struct sk_buff *skb = rp->skb; + + BUG_ON(skb == NULL); + + rmb(); + + dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len, + DMA_TO_DEVICE); + rp->skb = NULL; + dev_kfree_skb_irq(skb); + } + bp->tx_head = bp->tx_tail = 0; } |
