aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros/atlx
diff options
context:
space:
mode:
authorTony Zelenoff <antonz@parallels.com>2012-04-13 02:09:54 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-15 13:00:12 -0400
commit136cd14e1ea2bfde66d212d8e18e81552c94e4e3 (patch)
tree7d0bab86b0a308fa9590fac420da0662ad4adc30 /drivers/net/ethernet/atheros/atlx
parent2a9bc71e9a1a099e1aab745f1755a3c15a745ad8 (diff)
atl1: do not drop rx/tx interrupts before they are scheduled
To prevent interrupts lost they should be dropped only if they are scheduled via napi interfaces. In other case, there is exists situation when napi handler process TX interrupt, stay in RX processing and in that moment any other interrupt received. Then before this patch TX bit in ISR will be cleaned, napi schedule will not occur in case of currently processing event and TX interrupt definitely will be lost. Signed-off-by: Tony Zelenoff <antonz@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros/atlx')
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index 066b980cc2f0..7f1e498c3c06 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -2504,8 +2504,12 @@ static irqreturn_t atl1_intr(int irq, void *data)
2504 if (!status) 2504 if (!status)
2505 return IRQ_NONE; 2505 return IRQ_NONE;
2506 2506
2507 /* clear CMB interrupt status at once */ 2507 /* clear CMB interrupt status at once,
2508 adapter->cmb.cmb->int_stats = 0; 2508 * but leave rx/tx interrupt status in case it should be dropped
2509 * only if rx/tx processing queued. In other case interrupt
2510 * can be lost.
2511 */
2512 adapter->cmb.cmb->int_stats = status & (ISR_CMB_TX | ISR_CMB_RX);
2509 2513
2510 if (status & ISR_GPHY) /* clear phy status */ 2514 if (status & ISR_GPHY) /* clear phy status */
2511 atlx_clear_phy_int(adapter); 2515 atlx_clear_phy_int(adapter);
@@ -2547,8 +2551,10 @@ static irqreturn_t atl1_intr(int irq, void *data)
2547 } 2551 }
2548 2552
2549 /* transmit or receive event */ 2553 /* transmit or receive event */
2550 if (status & (ISR_CMB_TX | ISR_CMB_RX)) 2554 if (status & (ISR_CMB_TX | ISR_CMB_RX) &&
2551 atl1_sched_rings_clean(adapter); 2555 atl1_sched_rings_clean(adapter))
2556 adapter->cmb.cmb->int_stats = adapter->cmb.cmb->int_stats &
2557 ~(ISR_CMB_TX | ISR_CMB_RX);
2552 2558
2553 /* rx exception */ 2559 /* rx exception */
2554 if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | 2560 if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |