Let's be sure that the driver will make some progress/reset when crap hits the packet size descriptor. drivers/net/8139too.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) diff -puN drivers/net/8139too.c~r8139-20 drivers/net/8139too.c --- linux-2.6.8-rc2/drivers/net/8139too.c~r8139-20 2004-08-02 23:21:36.000000000 +0200 +++ linux-2.6.8-rc2-romieu/drivers/net/8139too.c 2004-08-03 00:13:56.000000000 +0200 @@ -593,6 +593,7 @@ struct rtl8139_private { int time_to_die; struct mii_if_info mii; unsigned int regs_len; + unsigned long fifo_copy_timeout; }; MODULE_AUTHOR ("Jeff Garzik "); @@ -1937,7 +1938,7 @@ static int rtl8139_rx(struct net_device u16 status; DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x," - " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, + " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx, RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); @@ -1978,10 +1979,24 @@ static int rtl8139_rx(struct net_device * since EarlyRx is disabled. */ if (unlikely(rx_size == 0xfff0)) { + if (!tp->fifo_copy_timeout) + tp->fifo_copy_timeout = jiffies + 2; + else if (time_after(jiffies, tp->fifo_copy_timeout)) { + DPRINTK ("%s: hung FIFO. Reset.", dev->name); + rx_size = 0; + goto no_early_rx; + } + if (netif_msg_intr(tp)) { + printk(KERN_DEBUG "%s: fifo copy in progress.", + dev->name); + } tp->xstats.early_rx++; break; } +no_early_rx: + tp->fifo_copy_timeout = 0; + /* If Rx err or invalid rx_size/rx_status received * (which happens if we get lost in the ring), * Rx process gets reset, so we abort any further @@ -2049,6 +2064,14 @@ static int rtl8139_rx(struct net_device #endif tp->cur_rx = cur_rx; + + /* + * The receive buffer should be mostly empty. + * Tell NAPI to reenable the Rx irq. + */ + if (tp->fifo_copy_timeout) + received = budget; + out: return received; } _