diff options
-rw-r--r-- | drivers/net/ethernet/atheros/atlx/atl1.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/atheros/atlx/atl1.h | 10 |
2 files changed, 29 insertions, 13 deletions
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 93c92291da9..f17cecae59e 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c | |||
@@ -2460,20 +2460,33 @@ static int atl1_rings_clean(struct napi_struct *napi, int budget) | |||
2460 | 2460 | ||
2461 | napi_complete(napi); | 2461 | napi_complete(napi); |
2462 | /* re-enable Interrupt */ | 2462 | /* re-enable Interrupt */ |
2463 | iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR); | 2463 | if (likely(adapter->int_enabled)) |
2464 | atlx_imr_set(adapter, IMR_NORMAL_MASK); | ||
2464 | return work_done; | 2465 | return work_done; |
2465 | } | 2466 | } |
2466 | 2467 | ||
2467 | static inline int atl1_sched_rings_clean(struct atl1_adapter* adapter) | 2468 | static inline int atl1_sched_rings_clean(struct atl1_adapter* adapter) |
2468 | { | 2469 | { |
2469 | if (likely(napi_schedule_prep(&adapter->napi))) { | 2470 | if (!napi_schedule_prep(&adapter->napi)) |
2470 | __napi_schedule(&adapter->napi); | 2471 | /* It is possible in case even the RX/TX ints are disabled via IMR |
2472 | * register the ISR bits are set anyway (but do not produce IRQ). | ||
2473 | * To handle such situation the napi functions used to check is | ||
2474 | * something scheduled or not. | ||
2475 | */ | ||
2476 | return 0; | ||
2477 | |||
2478 | __napi_schedule(&adapter->napi); | ||
2479 | |||
2480 | /* | ||
2481 | * Disable RX/TX ints via IMR register if it is | ||
2482 | * allowed. NAPI handler must reenable them in same | ||
2483 | * way. | ||
2484 | */ | ||
2485 | if (!adapter->int_enabled) | ||
2471 | return 1; | 2486 | return 1; |
2472 | } | ||
2473 | 2487 | ||
2474 | dev_printk(KERN_ERR, &adapter->pdev->dev, | 2488 | atlx_imr_set(adapter, IMR_NORXTX_MASK); |
2475 | "rx: INTs must be disabled!"); | 2489 | return 1; |
2476 | return 0; | ||
2477 | } | 2490 | } |
2478 | 2491 | ||
2479 | /* | 2492 | /* |
@@ -2538,8 +2551,7 @@ static irqreturn_t atl1_intr(int irq, void *data) | |||
2538 | /* transmit or receive event */ | 2551 | /* transmit or receive event */ |
2539 | if (status & (ISR_CMB_TX | ISR_CMB_RX) && | 2552 | if (status & (ISR_CMB_TX | ISR_CMB_RX) && |
2540 | atl1_sched_rings_clean(adapter)) | 2553 | atl1_sched_rings_clean(adapter)) |
2541 | /* Go away with INTs disabled */ | 2554 | break; |
2542 | return IRQ_HANDLED; | ||
2543 | 2555 | ||
2544 | /* rx exception */ | 2556 | /* rx exception */ |
2545 | if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | | 2557 | if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | |
@@ -2551,7 +2563,7 @@ static irqreturn_t atl1_intr(int irq, void *data) | |||
2551 | "rx exception, ISR = 0x%x\n", | 2563 | "rx exception, ISR = 0x%x\n", |
2552 | status); | 2564 | status); |
2553 | if (atl1_sched_rings_clean(adapter)) | 2565 | if (atl1_sched_rings_clean(adapter)) |
2554 | return IRQ_HANDLED; | 2566 | break; |
2555 | } | 2567 | } |
2556 | 2568 | ||
2557 | if (--max_ints < 0) | 2569 | if (--max_ints < 0) |
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h index 117a0da360b..1cb658b2ff9 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.h +++ b/drivers/net/ethernet/atheros/atlx/atl1.h | |||
@@ -275,13 +275,17 @@ static u32 atl1_check_link(struct atl1_adapter *adapter); | |||
275 | #define ISR_DIS_SMB 0x20000000 | 275 | #define ISR_DIS_SMB 0x20000000 |
276 | #define ISR_DIS_DMA 0x40000000 | 276 | #define ISR_DIS_DMA 0x40000000 |
277 | 277 | ||
278 | /* Normal Interrupt mask */ | 278 | /* Normal Interrupt mask without RX/TX enabled */ |
279 | #define IMR_NORMAL_MASK (\ | 279 | #define IMR_NORXTX_MASK (\ |
280 | ISR_SMB |\ | 280 | ISR_SMB |\ |
281 | ISR_GPHY |\ | 281 | ISR_GPHY |\ |
282 | ISR_PHY_LINKDOWN|\ | 282 | ISR_PHY_LINKDOWN|\ |
283 | ISR_DMAR_TO_RST |\ | 283 | ISR_DMAR_TO_RST |\ |
284 | ISR_DMAW_TO_RST |\ | 284 | ISR_DMAW_TO_RST) |
285 | |||
286 | /* Normal Interrupt mask */ | ||
287 | #define IMR_NORMAL_MASK (\ | ||
288 | IMR_NORXTX_MASK |\ | ||
285 | ISR_CMB_TX |\ | 289 | ISR_CMB_TX |\ |
286 | ISR_CMB_RX) | 290 | ISR_CMB_RX) |
287 | 291 | ||