Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" (Plain)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dec 20 18:49:08 urutu kernel: eth1: HostError! IntStatus 0002. 202 143 8 7c2
Dec 20 18:54:15 urutu kernel: eth1: Tx timed out (d50080) 214 143 800 0
Dec 20 18:59:31 urutu kernel: eth1: Tx timed out (d30080) 212 143 800 0

With the above numbers corresponding to the current tx descriptor, the
current rx descriptor, the DMACtrl register, and the IntEnable
register.

I think we have the culprit.  It appears that the adapter reset in the
function that contains HostError disables interrupts (which prevents
any rx from being serviced).  I have a new patch which should
<crossing fingers> fix the problem (attached for easier patching).  If
it doesn't work, it will fail the same way.  Please apply it to the
original driver.

Thanks,
Jon


--- dl2k.c.orig 2004-12-20 13:59:47.123631016 -0600
+++ dl2k.c      2004-12-20 14:22:31.820165608 -0600
@@ -431,23 +431,14 @@ parse_eeprom (struct net_device *dev)
        return 0;
 }

-static int
-rio_open (struct net_device *dev)
+static void
+rio_up (struct net_device *dev)
 {
        struct netdev_private *np = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int i;
        u16 macctrl;

-       i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
-       if (i)
-               return i;
-
-       /* Reset all logic functions */
-       writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
-               ioaddr + ASICCtrl + 2);
-       mdelay(10);
-
        /* DebugCtrl bit 4, 5, 9 must set */
        writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);

@@ -455,8 +446,6 @@ rio_open (struct net_device *dev)
        if (np->jumbo != 0)
                writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);

-       alloc_list (dev);
-
        /* Get station address */
        for (i = 0; i < 6; i++)
                writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
@@ -490,12 +479,6 @@ rio_open (struct net_device *dev)
                        ioaddr + MACCtrl);
        }

-       init_timer (&np->timer);
-       np->timer.expires = jiffies + 1*HZ;
-       np->timer.data = (unsigned long) dev;
-       np->timer.function = &rio_timer;
-       add_timer (&np->timer);
-
        /* Start Tx/Rx */
        writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable,
                        ioaddr + MACCtrl);
@@ -507,10 +490,38 @@ rio_open (struct net_device *dev)
        macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
        writew(macctrl, ioaddr + MACCtrl);

-       netif_start_queue (dev);
-
        /* Enable default interrupts */
        EnableInt ();
+}
+
+static int
+rio_open (struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       long ioaddr = dev->base_addr;
+       int i;
+
+       i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
+       if (i)
+               return i;
+
+       /* Reset all logic functions */
+       writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
+               ioaddr + ASICCtrl + 2);
+       mdelay(10);
+
+       alloc_list (dev);
+
+       rio_up (dev);
+
+       init_timer (&np->timer);
+       np->timer.expires = jiffies + 1*HZ;
+       np->timer.data = (unsigned long) dev;
+       np->timer.function = &rio_timer;
+       add_timer (&np->timer);
+
+       netif_start_queue (dev);
+
        return 0;
 }

@@ -564,9 +575,11 @@ static void
 rio_tx_timeout (struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
+       struct netdev_private *np = dev->priv;

-       printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
-               dev->name, readl (ioaddr + TxStatus));
+       printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
+               dev->name, readl (ioaddr + TxStatus), np->cur_tx, np->cur_rx,
+               readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
        rio_free_tx(dev, 0);
        dev->if_port = 0;
        dev->trans_start = jiffies;
@@ -1007,10 +1020,13 @@ rio_error (struct net_device *dev, int i
        /* PCI Error, a catastronphic error related to the bus interface
           occurs, set GlobalReset and HostReset to reset. */
        if (int_status & HostError) {
-               printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
-                       dev->name, int_status);
+               printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d
%d %x %x\n",
+                       dev->name, int_status, np->cur_tx, np->cur_rx,
+                       readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
                writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
                mdelay (500);
+
+               rio_up(dev);
        }
 }
--- dl2k.c.orig	2004-12-20 13:59:47.123631016 -0600
+++ dl2k.c	2004-12-20 14:22:31.820165608 -0600
@@ -431,23 +431,14 @@ parse_eeprom (struct net_device *dev)
 	return 0;
 }
 
-static int
-rio_open (struct net_device *dev)
+static void
+rio_up (struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int i;
 	u16 macctrl;
 	
-	i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
-	if (i)
-		return i;
-	
-	/* Reset all logic functions */
-	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
-		ioaddr + ASICCtrl + 2);
-	mdelay(10);
-	
 	/* DebugCtrl bit 4, 5, 9 must set */
 	writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);
 
@@ -455,8 +446,6 @@ rio_open (struct net_device *dev)
 	if (np->jumbo != 0)
 		writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);
 
-	alloc_list (dev);
-
 	/* Get station address */
 	for (i = 0; i < 6; i++)
 		writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
@@ -490,12 +479,6 @@ rio_open (struct net_device *dev)
 			ioaddr + MACCtrl);
 	}
 
-	init_timer (&np->timer);
-	np->timer.expires = jiffies + 1*HZ;
-	np->timer.data = (unsigned long) dev;
-	np->timer.function = &rio_timer;
-	add_timer (&np->timer);
-
 	/* Start Tx/Rx */
 	writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable, 
 			ioaddr + MACCtrl);
@@ -507,10 +490,38 @@ rio_open (struct net_device *dev)
 	macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
 	writew(macctrl,	ioaddr + MACCtrl);
 
-	netif_start_queue (dev);
-	
 	/* Enable default interrupts */
 	EnableInt ();
+}
+
+static int
+rio_open (struct net_device *dev)
+{
+	struct netdev_private *np = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	int i;
+	
+	i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
+	if (i)
+		return i;
+	
+	/* Reset all logic functions */
+	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
+		ioaddr + ASICCtrl + 2);
+	mdelay(10);
+	
+	alloc_list (dev);
+
+	rio_up (dev);
+	
+	init_timer (&np->timer);
+	np->timer.expires = jiffies + 1*HZ;
+	np->timer.data = (unsigned long) dev;
+	np->timer.function = &rio_timer;
+	add_timer (&np->timer);
+
+	netif_start_queue (dev);
+	
 	return 0;
 }
 
@@ -564,9 +575,11 @@ static void
 rio_tx_timeout (struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 
-	printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
-		dev->name, readl (ioaddr + TxStatus));
+	printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
+		dev->name, readl (ioaddr + TxStatus), np->cur_tx, np->cur_rx,
+		readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
 	rio_free_tx(dev, 0);
 	dev->if_port = 0;
 	dev->trans_start = jiffies;
@@ -1007,10 +1020,13 @@ rio_error (struct net_device *dev, int i
 	/* PCI Error, a catastronphic error related to the bus interface 
 	   occurs, set GlobalReset and HostReset to reset. */
 	if (int_status & HostError) {
-		printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
-			dev->name, int_status);
+		printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d %d %x %x\n",
+			dev->name, int_status, np->cur_tx, np->cur_rx,
+			readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
 		writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
 		mdelay (500);
+
+		rio_up(dev);
 	}
 }
 

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux