aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index eea418124be1..a629706e2b37 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -488,7 +488,8 @@ static void tg3_disable_ints(struct tg3 *tp)
488 488
489static inline void tg3_cond_int(struct tg3 *tp) 489static inline void tg3_cond_int(struct tg3 *tp)
490{ 490{
491 if (tp->hw_status->status & SD_STATUS_UPDATED) 491 if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
492 (tp->hw_status->status & SD_STATUS_UPDATED))
492 tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); 493 tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
493} 494}
494 495
@@ -3220,18 +3221,17 @@ static int tg3_poll(struct net_device *netdev, int *budget)
3220 netdev->quota -= work_done; 3221 netdev->quota -= work_done;
3221 } 3222 }
3222 3223
3223 if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) 3224 if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
3224 tp->last_tag = sblk->status_tag; 3225 tp->last_tag = sblk->status_tag;
3225 rmb(); 3226 rmb();
3226 sblk->status &= ~SD_STATUS_UPDATED; 3227 } else
3228 sblk->status &= ~SD_STATUS_UPDATED;
3227 3229
3228 /* if no more work, tell net stack and NIC we're done */ 3230 /* if no more work, tell net stack and NIC we're done */
3229 done = !tg3_has_work(tp); 3231 done = !tg3_has_work(tp);
3230 if (done) { 3232 if (done) {
3231 spin_lock(&tp->lock);
3232 netif_rx_complete(netdev); 3233 netif_rx_complete(netdev);
3233 tg3_restart_ints(tp); 3234 tg3_restart_ints(tp);
3234 spin_unlock(&tp->lock);
3235 } 3235 }
3236 3236
3237 return (done ? 0 : 1); 3237 return (done ? 0 : 1);
@@ -3351,7 +3351,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
3351 * Reading the PCI State register will confirm whether the 3351 * Reading the PCI State register will confirm whether the
3352 * interrupt is ours and will flush the status block. 3352 * interrupt is ours and will flush the status block.
3353 */ 3353 */
3354 if ((sblk->status & SD_STATUS_UPDATED) || 3354 if ((sblk->status_tag != tp->last_tag) ||
3355 !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { 3355 !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
3356 /* 3356 /*
3357 * writing any value to intr-mbox-0 clears PCI INTA# and 3357 * writing any value to intr-mbox-0 clears PCI INTA# and
@@ -3362,20 +3362,17 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
3362 */ 3362 */
3363 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 3363 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
3364 0x00000001); 3364 0x00000001);
3365 tp->last_tag = sblk->status_tag;
3366 rmb();
3367 if (tg3_irq_sync(tp)) 3365 if (tg3_irq_sync(tp))
3368 goto out; 3366 goto out;
3369 sblk->status &= ~SD_STATUS_UPDATED; 3367 if (netif_rx_schedule_prep(dev)) {
3370 if (likely(tg3_has_work(tp))) {
3371 prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); 3368 prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
3372 netif_rx_schedule(dev); /* schedule NAPI poll */ 3369 /* Update last_tag to mark that this status has been
3373 } else { 3370 * seen. Because interrupt may be shared, we may be
3374 /* no work, shared interrupt perhaps? re-enable 3371 * racing with tg3_poll(), so only update last_tag
3375 * interrupts, and flush that PCI write 3372 * if tg3_poll() is not scheduled.
3376 */ 3373 */
3377 tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 3374 tp->last_tag = sblk->status_tag;
3378 tp->last_tag << 24); 3375 __netif_rx_schedule(dev);
3379 } 3376 }
3380 } else { /* shared interrupt */ 3377 } else { /* shared interrupt */
3381 handled = 0; 3378 handled = 0;
@@ -6238,6 +6235,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
6238 if (err) 6235 if (err)
6239 return err; 6236 return err;
6240 6237
6238 tp->hw_status->status &= ~SD_STATUS_UPDATED;
6241 tg3_enable_ints(tp); 6239 tg3_enable_ints(tp);
6242 6240
6243 tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | 6241 tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |