===== drivers/net/tg3.c 1.40 vs edited ===== --- 1.40/drivers/net/tg3.c Mon Dec 9 21:32:02 2002 +++ edited/drivers/net/tg3.c Sat Dec 21 15:06:34 2002 @@ -217,22 +217,6 @@ tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); } -static inline void tg3_mask_ints(struct tg3 *tp) -{ - tw32(TG3PCI_MISC_HOST_CTRL, - (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); -} - -static inline void tg3_unmask_ints(struct tg3 *tp) -{ - tw32(TG3PCI_MISC_HOST_CTRL, - (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); - if (tp->hw_status->status & SD_STATUS_UPDATED) { - tw32(GRC_LOCAL_CTRL, - tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); - } -} - static void tg3_switch_clocks(struct tg3 *tp) { if (tr32(TG3PCI_CLOCK_CTRL) & CLOCK_CTRL_44MHZ_CORE) { @@ -2014,8 +1998,9 @@ struct tg3 *tp = netdev->priv; struct tg3_hw_status *sblk = tp->hw_status; int done; + unsigned long flags; - spin_lock_irq(&tp->lock); + spin_lock_irqsave(&tp->lock, flags); if (!(tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | @@ -2052,15 +2037,18 @@ if (done) { netif_rx_complete(netdev); - tg3_unmask_ints(tp); + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + 0x00000000); + /* don't care about flushing this write immediately */ } - spin_unlock_irq(&tp->lock); + spin_unlock_irqrestore(&tp->lock, flags); return (done ? 0 : 1); } -static __inline__ void tg3_interrupt_main_work(struct net_device *dev, struct tg3 *tp) +static inline unsigned int tg3_interrupt_main_work(struct net_device *dev, + struct tg3 *tp) { struct tg3_hw_status *sblk = tp->hw_status; int work_exists = 0; @@ -2075,19 +2063,10 @@ sblk->idx[0].rx_producer != tp->rx_rcb_ptr) work_exists = 1; - if (!work_exists) - return; + if (work_exists) + netif_rx_schedule(dev); - if (netif_rx_schedule_prep(dev)) { - /* NOTE: These writes are posted by the readback of - * the mailbox register done by our caller. - */ - tg3_mask_ints(tp); - __netif_rx_schedule(dev); - } else { - printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", - dev->name); - } + return work_exists; } static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -2102,13 +2081,16 @@ if (sblk->status & SD_STATUS_UPDATED) { tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + /* flush the intr clear-and-mask before updating status block */ + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); sblk->status &= ~SD_STATUS_UPDATED; - tg3_interrupt_main_work(dev, tp); - - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000000); - tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); + if (!tg3_interrupt_main_work(dev, tp)) { + /* if work doesn't exist... */ + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + 0x00000000); + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); + } } spin_unlock_irqrestore(&tp->lock, flags);