diff --git a/[refs] b/[refs] index a2809448f2dd..1e01bf1b7502 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 61c93f4eb45493f203d6bad24156599668be614f +refs/heads/master: bdcba1511b98f2e728b3a910b8771a0d3fce5bf3 diff --git a/trunk/drivers/net/macb.c b/trunk/drivers/net/macb.c index 047ea7be4850..e10528ed9081 100644 --- a/trunk/drivers/net/macb.c +++ b/trunk/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; }