--- dl2k.c,orig-save-2004.12.20 2004-12-21 09:43:19.000000000 -0600 +++ dl2k.c 2005-01-04 15:26:57.162033944 -0600 @@ -429,23 +429,16 @@ 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 = dev->priv; + 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); - + alloc_list (dev); + /* DebugCtrl bit 4, 5, 9 must set */ writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl); @@ -453,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); @@ -488,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); @@ -505,10 +490,36 @@ 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); + + 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; } @@ -562,9 +573,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; @@ -1005,10 +1018,36 @@ 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); + + /* Free all the skbuffs in the queue. */ + for (i = 0; i < RX_RING_SIZE; i++) { + np->rx_ring[i].status = 0; + np->rx_ring[i].fraginfo = 0; + skb = np->rx_skbuff[i]; + if (skb) { + pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo, + skb->len, PCI_DMA_FROMDEVICE); + dev_kfree_skb (skb); + np->rx_skbuff[i] = NULL; + } + } + for (i = 0; i < TX_RING_SIZE; i++) { + skb = np->tx_skbuff[i]; + if (skb) { + pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb (skb); + np->tx_skbuff[i] = NULL; + } + } + mdelay (500); + + rio_up(dev); } }