aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index e4d697894364..c980ce9719af 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3277,6 +3277,20 @@ static void nv_link_irq(struct net_device *dev)
3277 dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); 3277 dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
3278} 3278}
3279 3279
3280static void nv_msi_workaround(struct fe_priv *np)
3281{
3282
3283 /* Need to toggle the msi irq mask within the ethernet device,
3284 * otherwise, future interrupts will not be detected.
3285 */
3286 if (np->msi_flags & NV_MSI_ENABLED) {
3287 u8 __iomem *base = np->base;
3288
3289 writel(0, base + NvRegMSIIrqMask);
3290 writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask);
3291 }
3292}
3293
3280static irqreturn_t nv_nic_irq(int foo, void *data) 3294static irqreturn_t nv_nic_irq(int foo, void *data)
3281{ 3295{
3282 struct net_device *dev = (struct net_device *) data; 3296 struct net_device *dev = (struct net_device *) data;
@@ -3299,6 +3313,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
3299 if (!(events & np->irqmask)) 3313 if (!(events & np->irqmask))
3300 break; 3314 break;
3301 3315
3316 nv_msi_workaround(np);
3317
3302 spin_lock(&np->lock); 3318 spin_lock(&np->lock);
3303 nv_tx_done(dev); 3319 nv_tx_done(dev);
3304 spin_unlock(&np->lock); 3320 spin_unlock(&np->lock);
@@ -3414,6 +3430,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
3414 if (!(events & np->irqmask)) 3430 if (!(events & np->irqmask))
3415 break; 3431 break;
3416 3432
3433 nv_msi_workaround(np);
3434
3417 spin_lock(&np->lock); 3435 spin_lock(&np->lock);
3418 nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); 3436 nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
3419 spin_unlock(&np->lock); 3437 spin_unlock(&np->lock);
@@ -3754,6 +3772,8 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data)
3754 if (!(events & NVREG_IRQ_TIMER)) 3772 if (!(events & NVREG_IRQ_TIMER))
3755 return IRQ_RETVAL(0); 3773 return IRQ_RETVAL(0);
3756 3774
3775 nv_msi_workaround(np);
3776
3757 spin_lock(&np->lock); 3777 spin_lock(&np->lock);
3758 np->intr_test = 1; 3778 np->intr_test = 1;
3759 spin_unlock(&np->lock); 3779 spin_unlock(&np->lock);