aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAyaz Abdulla <aabdulla@nvidia.com>2009-03-05 03:02:34 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-10 08:29:51 -0400
commit1b2bb76f575699eff3f58b18dcfebf5d3b1f6ddb (patch)
tree19f8327f23dd7137b3b67588b3484d6f8dc62ade
parent6cef67a02f7994c97dbd716dbeb592265fb5b7b0 (diff)
forcedeth: fix irq clearing and napi spin lock changes
This patch clears the irqstatus register with the exact same events it has read from it. Since the read-write operation is not atomic, a new irqstatus bit could have been set in between these operations and would then be cleared accidentally. Secondly, we now don't need any spin lock protection when scheduling/completing napi poll as the isr will not execute anymore (as we turn off all interrupts now). Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/forcedeth.c18
1 files changed, 4 insertions, 14 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 28fc3357268a..514aaf189af9 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3464,10 +3464,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
3464 3464
3465 if (!(np->msi_flags & NV_MSI_X_ENABLED)) { 3465 if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
3466 np->events = readl(base + NvRegIrqStatus); 3466 np->events = readl(base + NvRegIrqStatus);
3467 writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); 3467 writel(np->events, base + NvRegIrqStatus);
3468 } else { 3468 } else {
3469 np->events = readl(base + NvRegMSIXIrqStatus); 3469 np->events = readl(base + NvRegMSIXIrqStatus);
3470 writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); 3470 writel(np->events, base + NvRegMSIXIrqStatus);
3471 } 3471 }
3472 dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); 3472 dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
3473 if (!(np->events & np->irqmask)) 3473 if (!(np->events & np->irqmask))
@@ -3476,15 +3476,12 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
3476 nv_msi_workaround(np); 3476 nv_msi_workaround(np);
3477 3477
3478#ifdef CONFIG_FORCEDETH_NAPI 3478#ifdef CONFIG_FORCEDETH_NAPI
3479 spin_lock(&np->lock);
3480 napi_schedule(&np->napi); 3479 napi_schedule(&np->napi);
3481 3480
3482 /* Disable furthur irq's 3481 /* Disable furthur irq's
3483 (msix not enabled with napi) */ 3482 (msix not enabled with napi) */
3484 writel(0, base + NvRegIrqMask); 3483 writel(0, base + NvRegIrqMask);
3485 3484
3486 spin_unlock(&np->lock);
3487
3488#else 3485#else
3489 do 3486 do
3490 { 3487 {
@@ -3568,10 +3565,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
3568 3565
3569 if (!(np->msi_flags & NV_MSI_X_ENABLED)) { 3566 if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
3570 np->events = readl(base + NvRegIrqStatus); 3567 np->events = readl(base + NvRegIrqStatus);
3571 writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); 3568 writel(np->events, base + NvRegIrqStatus);
3572 } else { 3569 } else {
3573 np->events = readl(base + NvRegMSIXIrqStatus); 3570 np->events = readl(base + NvRegMSIXIrqStatus);
3574 writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); 3571 writel(np->events, base + NvRegMSIXIrqStatus);
3575 } 3572 }
3576 dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); 3573 dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
3577 if (!(np->events & np->irqmask)) 3574 if (!(np->events & np->irqmask))
@@ -3580,15 +3577,12 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
3580 nv_msi_workaround(np); 3577 nv_msi_workaround(np);
3581 3578
3582#ifdef CONFIG_FORCEDETH_NAPI 3579#ifdef CONFIG_FORCEDETH_NAPI
3583 spin_lock(&np->lock);
3584 napi_schedule(&np->napi); 3580 napi_schedule(&np->napi);
3585 3581
3586 /* Disable furthur irq's 3582 /* Disable furthur irq's
3587 (msix not enabled with napi) */ 3583 (msix not enabled with napi) */
3588 writel(0, base + NvRegIrqMask); 3584 writel(0, base + NvRegIrqMask);
3589 3585
3590 spin_unlock(&np->lock);
3591
3592#else 3586#else
3593 do 3587 do
3594 { 3588 {
@@ -3758,13 +3752,9 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
3758 if (rx_work < budget) { 3752 if (rx_work < budget) {
3759 /* re-enable interrupts 3753 /* re-enable interrupts
3760 (msix not enabled in napi) */ 3754 (msix not enabled in napi) */
3761 spin_lock_irqsave(&np->lock, flags);
3762
3763 __napi_complete(napi); 3755 __napi_complete(napi);
3764 3756
3765 writel(np->irqmask, base + NvRegIrqMask); 3757 writel(np->irqmask, base + NvRegIrqMask);
3766
3767 spin_unlock_irqrestore(&np->lock, flags);
3768 } 3758 }
3769 return rx_work; 3759 return rx_work;
3770} 3760}