diff options
-rw-r--r-- | drivers/net/sfc/efx.c | 12 | ||||
-rw-r--r-- | drivers/net/sfc/net_driver.h | 2 | ||||
-rw-r--r-- | drivers/net/sfc/nic.c | 6 |
3 files changed, 18 insertions, 2 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 05df20e47976..d06cb742164b 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -335,8 +335,10 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
335 | 335 | ||
336 | /* Disable interrupts and wait for ISRs to complete */ | 336 | /* Disable interrupts and wait for ISRs to complete */ |
337 | efx_nic_disable_interrupts(efx); | 337 | efx_nic_disable_interrupts(efx); |
338 | if (efx->legacy_irq) | 338 | if (efx->legacy_irq) { |
339 | synchronize_irq(efx->legacy_irq); | 339 | synchronize_irq(efx->legacy_irq); |
340 | efx->legacy_irq_enabled = false; | ||
341 | } | ||
340 | if (channel->irq) | 342 | if (channel->irq) |
341 | synchronize_irq(channel->irq); | 343 | synchronize_irq(channel->irq); |
342 | 344 | ||
@@ -351,6 +353,8 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
351 | efx_channel_processed(channel); | 353 | efx_channel_processed(channel); |
352 | 354 | ||
353 | napi_enable(&channel->napi_str); | 355 | napi_enable(&channel->napi_str); |
356 | if (efx->legacy_irq) | ||
357 | efx->legacy_irq_enabled = true; | ||
354 | efx_nic_enable_interrupts(efx); | 358 | efx_nic_enable_interrupts(efx); |
355 | } | 359 | } |
356 | 360 | ||
@@ -1400,6 +1404,8 @@ static void efx_start_all(struct efx_nic *efx) | |||
1400 | efx_start_channel(channel); | 1404 | efx_start_channel(channel); |
1401 | } | 1405 | } |
1402 | 1406 | ||
1407 | if (efx->legacy_irq) | ||
1408 | efx->legacy_irq_enabled = true; | ||
1403 | efx_nic_enable_interrupts(efx); | 1409 | efx_nic_enable_interrupts(efx); |
1404 | 1410 | ||
1405 | /* Switch to event based MCDI completions after enabling interrupts. | 1411 | /* Switch to event based MCDI completions after enabling interrupts. |
@@ -1460,8 +1466,10 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1460 | 1466 | ||
1461 | /* Disable interrupts and wait for ISR to complete */ | 1467 | /* Disable interrupts and wait for ISR to complete */ |
1462 | efx_nic_disable_interrupts(efx); | 1468 | efx_nic_disable_interrupts(efx); |
1463 | if (efx->legacy_irq) | 1469 | if (efx->legacy_irq) { |
1464 | synchronize_irq(efx->legacy_irq); | 1470 | synchronize_irq(efx->legacy_irq); |
1471 | efx->legacy_irq_enabled = false; | ||
1472 | } | ||
1465 | efx_for_each_channel(channel, efx) { | 1473 | efx_for_each_channel(channel, efx) { |
1466 | if (channel->irq) | 1474 | if (channel->irq) |
1467 | synchronize_irq(channel->irq); | 1475 | synchronize_irq(channel->irq); |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0a7e26d73b52..b137c889152b 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -621,6 +621,7 @@ struct efx_filter_state; | |||
621 | * @pci_dev: The PCI device | 621 | * @pci_dev: The PCI device |
622 | * @type: Controller type attributes | 622 | * @type: Controller type attributes |
623 | * @legacy_irq: IRQ number | 623 | * @legacy_irq: IRQ number |
624 | * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)? | ||
624 | * @workqueue: Workqueue for port reconfigures and the HW monitor. | 625 | * @workqueue: Workqueue for port reconfigures and the HW monitor. |
625 | * Work items do not hold and must not acquire RTNL. | 626 | * Work items do not hold and must not acquire RTNL. |
626 | * @workqueue_name: Name of workqueue | 627 | * @workqueue_name: Name of workqueue |
@@ -709,6 +710,7 @@ struct efx_nic { | |||
709 | struct pci_dev *pci_dev; | 710 | struct pci_dev *pci_dev; |
710 | const struct efx_nic_type *type; | 711 | const struct efx_nic_type *type; |
711 | int legacy_irq; | 712 | int legacy_irq; |
713 | bool legacy_irq_enabled; | ||
712 | struct workqueue_struct *workqueue; | 714 | struct workqueue_struct *workqueue; |
713 | char workqueue_name[16]; | 715 | char workqueue_name[16]; |
714 | struct work_struct reset_work; | 716 | struct work_struct reset_work; |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 41c36b9a4244..67cb0c96838c 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) | |||
1418 | u32 queues; | 1418 | u32 queues; |
1419 | int syserr; | 1419 | int syserr; |
1420 | 1420 | ||
1421 | /* Could this be ours? If interrupts are disabled then the | ||
1422 | * channel state may not be valid. | ||
1423 | */ | ||
1424 | if (!efx->legacy_irq_enabled) | ||
1425 | return result; | ||
1426 | |||
1421 | /* Read the ISR which also ACKs the interrupts */ | 1427 | /* Read the ISR which also ACKs the interrupts */ |
1422 | efx_readd(efx, ®, FR_BZ_INT_ISR0); | 1428 | efx_readd(efx, ®, FR_BZ_INT_ISR0); |
1423 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); | 1429 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); |