Skip to content

Commit 819bfe7

Browse files
Rajesh Borundiadavem330
authored andcommitted
qlcnic: Fix mailbox completion handling during spurious interrupt
o While the driver is in the middle of a MB completion processing and it receives a spurious MB interrupt, it is mistaken as a good MB completion interrupt leading to premature completion of the next MB request. Fix the driver to guard against this by checking the current state of MB processing and ignore the spurious interrupt. Also added a stats counter to record this condition. Signed-off-by: Rajesh Borundia <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5bf9325 commit 819bfe7

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

drivers/net/ethernet/qlogic/qlcnic/qlcnic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ struct qlcnic_adapter_stats {
566566
u64 tx_dma_map_error;
567567
u64 spurious_intr;
568568
u64 mac_filter_limit_overrun;
569+
u64 mbx_spurious_intr;
569570
};
570571

571572
/*

drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,9 +2338,9 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
23382338

23392339
static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
23402340
{
2341+
u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
23412342
struct qlcnic_adapter *adapter = data;
23422343
struct qlcnic_mailbox *mbx;
2343-
u32 mask, resp, event;
23442344
unsigned long flags;
23452345

23462346
mbx = adapter->ahw->mailbox;
@@ -2350,10 +2350,14 @@ static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
23502350
goto out;
23512351

23522352
event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2353-
if (event & QLCNIC_MBX_ASYNC_EVENT)
2353+
if (event & QLCNIC_MBX_ASYNC_EVENT) {
23542354
__qlcnic_83xx_process_aen(adapter);
2355-
else
2356-
qlcnic_83xx_notify_mbx_response(mbx);
2355+
} else {
2356+
if (mbx->rsp_status != rsp_status)
2357+
qlcnic_83xx_notify_mbx_response(mbx);
2358+
else
2359+
adapter->stats.mbx_spurious_intr++;
2360+
}
23572361

23582362
out:
23592363
mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
@@ -4053,6 +4057,7 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
40534057
struct list_head *head = &mbx->cmd_q;
40544058
struct qlcnic_hardware_context *ahw;
40554059
struct qlcnic_cmd_args *cmd = NULL;
4060+
unsigned long flags;
40564061

40574062
ahw = adapter->ahw;
40584063

@@ -4062,7 +4067,9 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
40624067
return;
40634068
}
40644069

4070+
spin_lock_irqsave(&mbx->aen_lock, flags);
40654071
mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
4072+
spin_unlock_irqrestore(&mbx->aen_lock, flags);
40664073

40674074
spin_lock(&mbx->queue_lock);
40684075

drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
5959
QLC_OFF(stats.mac_filter_limit_overrun)},
6060
{"spurious intr", QLC_SIZEOF(stats.spurious_intr),
6161
QLC_OFF(stats.spurious_intr)},
62-
62+
{"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
63+
QLC_OFF(stats.mbx_spurious_intr)},
6364
};
6465

6566
static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {

0 commit comments

Comments
 (0)