aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGovindarajulu Varadarajan <_govind@gmx.com>2015-10-01 14:18:46 +0530
committerDavid S. Miller <davem@davemloft.net>2015-10-05 03:51:33 -0700
commitcc809237e1f215141165f221ad729803d88bcbbe (patch)
tree98fc6e430ec08f04950db630083227be76641865
parent2905f5bb1cad66a37d142c4370d23d9e9632368e (diff)
downloadnet-next-cc809237e1f215141165f221ad729803d88bcbbe.tar.gz
enic: handle spurious error interrupt
Some of the enic adaptors are know to generate spurious interrupts. When error interrupt is generated, driver just resets the device. This patch resets the device only when an error is occurred. Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 3352d027ab895..0b54429865071 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -178,13 +178,15 @@ static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
return 0;
}
-static void enic_log_q_error(struct enic *enic)
+static bool enic_log_q_error(struct enic *enic)
{
unsigned int i;
u32 error_status;
+ bool err = false;
for (i = 0; i < enic->wq_count; i++) {
error_status = vnic_wq_error_status(&enic->wq[i]);
+ err |= error_status;
if (error_status)
netdev_err(enic->netdev, "WQ[%d] error_status %d\n",
i, error_status);
@@ -192,10 +194,13 @@ static void enic_log_q_error(struct enic *enic)
for (i = 0; i < enic->rq_count; i++) {
error_status = vnic_rq_error_status(&enic->rq[i]);
+ err |= error_status;
if (error_status)
netdev_err(enic->netdev, "RQ[%d] error_status %d\n",
i, error_status);
}
+
+ return err;
}
static void enic_msglvl_check(struct enic *enic)
@@ -333,10 +338,9 @@ static irqreturn_t enic_isr_msix_err(int irq, void *data)
vnic_intr_return_all_credits(&enic->intr[intr]);
- enic_log_q_error(enic);
-
- /* schedule recovery from WQ/RQ error */
- schedule_work(&enic->reset);
+ if (enic_log_q_error(enic))
+ /* schedule recovery from WQ/RQ error */
+ schedule_work(&enic->reset);
return IRQ_HANDLED;
}