]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/tg3.c
meth driver renovation
[linux-2.6-omap-h63xx.git] / drivers / net / tg3.c
index 630c8a6c9f738126fe1adc50da079a9cad520491..923b9c725cc3f4e5cd75434914dbb4ce466c151f 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.75"
-#define DRV_MODULE_RELDATE     "March 23, 2007"
+#define DRV_MODULE_VERSION     "3.76"
+#define DRV_MODULE_RELDATE     "May 5, 2007"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -3590,8 +3590,12 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
         * Writing non-zero to intr-mbox-0 additional tells the
         * NIC to stop sending us irqs, engaging "in-intr-handler"
         * event coalescing.
+        *
+        * Flush the mailbox to de-assert the IRQ immediately to prevent
+        * spurious interrupts.  The flush impacts performance but
+        * excessive spurious interrupts can be worse in some cases.
         */
-       tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+       tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
        if (tg3_irq_sync(tp))
                goto out;
        sblk->status &= ~SD_STATUS_UPDATED;
@@ -3635,8 +3639,12 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
         * writing non-zero to intr-mbox-0 additional tells the
         * NIC to stop sending us irqs, engaging "in-intr-handler"
         * event coalescing.
+        *
+        * Flush the mailbox to de-assert the IRQ immediately to prevent
+        * spurious interrupts.  The flush impacts performance but
+        * excessive spurious interrupts can be worse in some cases.
         */
-       tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+       tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
        if (tg3_irq_sync(tp))
                goto out;
        if (netif_rx_schedule_prep(dev)) {
@@ -3708,10 +3716,8 @@ static void tg3_reset_task(struct work_struct *work)
        unsigned int restart_timer;
 
        tg3_full_lock(tp, 0);
-       tp->tg3_flags |= TG3_FLAG_IN_RESET_TASK;
 
        if (!netif_running(tp->dev)) {
-               tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
                tg3_full_unlock(tp);
                return;
        }
@@ -3742,8 +3748,6 @@ static void tg3_reset_task(struct work_struct *work)
                mod_timer(&tp->timer, jiffies + 1);
 
 out:
-       tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
-
        tg3_full_unlock(tp);
 }
 
@@ -7382,12 +7386,7 @@ static int tg3_close(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       /* Calling flush_scheduled_work() may deadlock because
-        * linkwatch_event() may be on the workqueue and it will try to get
-        * the rtnl_lock which we are holding.
-        */
-       while (tp->tg3_flags & TG3_FLAG_IN_RESET_TASK)
-               msleep(1);
+       cancel_work_sync(&tp->reset_task);
 
        netif_stop_queue(dev);