Pull bugzilla-5737 into release branch
[powerpc.git] / drivers / net / tulip / de2104x.c
index d6c3d52..e3dd144 100644 (file)
@@ -1327,11 +1327,11 @@ static void de_clean_rings (struct de_private *de)
                struct sk_buff *skb = de->tx_skb[i].skb;
                if ((skb) && (skb != DE_DUMMY_SKB)) {
                        if (skb != DE_SETUP_SKB) {
-                               dev_kfree_skb(skb);
                                de->net_stats.tx_dropped++;
                                pci_unmap_single(de->pdev,
                                        de->tx_skb[i].mapping,
                                        skb->len, PCI_DMA_TODEVICE);
+                               dev_kfree_skb(skb);
                        } else {
                                pci_unmap_single(de->pdev,
                                        de->tx_skb[i].mapping,
@@ -1357,7 +1357,6 @@ static int de_open (struct net_device *dev)
 {
        struct de_private *de = dev->priv;
        int rc;
-       unsigned long flags;
 
        if (netif_msg_ifup(de))
                printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
@@ -1371,18 +1370,20 @@ static int de_open (struct net_device *dev)
                return rc;
        }
 
-       rc = de_init_hw(de);
-       if (rc) {
-               printk(KERN_ERR "%s: h/w init failure, err=%d\n",
-                      dev->name, rc);
-               goto err_out_free;
-       }
+       dw32(IntrMask, 0);
 
        rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev);
        if (rc) {
                printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n",
                       dev->name, dev->irq, rc);
-               goto err_out_hw;
+               goto err_out_free;
+       }
+
+       rc = de_init_hw(de);
+       if (rc) {
+               printk(KERN_ERR "%s: h/w init failure, err=%d\n",
+                      dev->name, rc);
+               goto err_out_free_irq;
        }
 
        netif_start_queue(dev);
@@ -1390,11 +1391,8 @@ static int de_open (struct net_device *dev)
 
        return 0;
 
-err_out_hw:
-       spin_lock_irqsave(&de->lock, flags);
-       de_stop_hw(de);
-       spin_unlock_irqrestore(&de->lock, flags);
-
+err_out_free_irq:
+       free_irq(dev->irq, dev);
 err_out_free:
        de_free_rings(de);
        return rc;
@@ -1450,6 +1448,8 @@ static void de_tx_timeout (struct net_device *dev)
        synchronize_irq(dev->irq);
        de_clean_rings(de);
 
+       de_init_rings(de);
+
        de_init_hw(de);
        
        netif_wake_queue(dev);