Commit 39eddb4c3970e9aadbc87b8a7cab7b4fefff077f

Authored by Richard Röjfors
Committed by David S. Miller
1 parent 24e94de41e

macb: avoid lockup when TGO during underrun

In rare cases when an underrun occur, all macb buffers where consumed
and the netif_queue was stopped infinitely. This happens then the TGO
(transfer ongoing) bit in the TSR is set (and UND). It seems like
clening up after the underrun makes the driver and the macb hardware
end up in an inconsistent state. The result of this is that in the
following calls to macb_tx no TX buffers are released -> the
netif_queue was stopped, and never woken up again.

The solution is to disable the transmitter, if TGO is set, before
clening up after the underrun, and re-enable the transmitter when the
cleaning up is done.

Signed-off-by: Richard Röjfors <richard.rojfors@endian.se>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 8 additions and 0 deletions Side-by-side Diff

... ... @@ -321,6 +321,10 @@
321 321 printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
322 322 bp->dev->name);
323 323  
  324 + /* Transfer ongoing, disable transmitter, to avoid confusion */
  325 + if (status & MACB_BIT(TGO))
  326 + macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE));
  327 +
324 328 head = bp->tx_head;
325 329  
326 330 /*Mark all the buffer as used to avoid sending a lost buffer*/
... ... @@ -343,6 +347,10 @@
343 347 }
344 348  
345 349 bp->tx_head = bp->tx_tail = 0;
  350 +
  351 + /* Enable the transmitter again */
  352 + if (status & MACB_BIT(TGO))
  353 + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
346 354 }
347 355  
348 356 if (!(status & MACB_BIT(COMP)))