Skip to content

Commit e49038d

Browse files
committed
Merge branch 'qlcnic-next'
Rajesh Borundia says: ==================== qlcnic fixes This series adds following fixes. o While processing mailbox if driver gets a spurious mailbox interrupt it leads into premature completion of a next mailbox request. Added a guard against this by checking current state of mailbox and ignored spurious interrupt. Added a stats counter to record this condition. v2: o Added patch that removes usage of atomic_t as we are not implemeting atomicity by using atomic_t value. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b795a21 + 819bfe7 commit e49038d

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

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

Lines changed: 2 additions & 1 deletion
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
/*
@@ -1099,7 +1100,7 @@ struct qlcnic_mailbox {
10991100
unsigned long status;
11001101
spinlock_t queue_lock; /* Mailbox queue lock */
11011102
spinlock_t aen_lock; /* Mailbox response/AEN lock */
1102-
atomic_t rsp_status;
1103+
u32 rsp_status;
11031104
u32 num_cmds;
11041105
};
11051106

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
491491

492492
static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
493493
{
494-
atomic_set(&mbx->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
494+
mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
495495
complete(&mbx->completion);
496496
}
497497

@@ -510,7 +510,7 @@ static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
510510
if (event & QLCNIC_MBX_ASYNC_EVENT) {
511511
__qlcnic_83xx_process_aen(adapter);
512512
} else {
513-
if (atomic_read(&mbx->rsp_status) != rsp_status)
513+
if (mbx->rsp_status != rsp_status)
514514
qlcnic_83xx_notify_mbx_response(mbx);
515515
}
516516
out:
@@ -1023,7 +1023,7 @@ static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
10231023
if (event & QLCNIC_MBX_ASYNC_EVENT) {
10241024
__qlcnic_83xx_process_aen(adapter);
10251025
} else {
1026-
if (atomic_read(&mbx->rsp_status) != rsp_status)
1026+
if (mbx->rsp_status != rsp_status)
10271027
qlcnic_83xx_notify_mbx_response(mbx);
10281028
}
10291029
}
@@ -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);
@@ -4050,10 +4054,10 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
40504054
struct qlcnic_adapter *adapter = mbx->adapter;
40514055
const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
40524056
struct device *dev = &adapter->pdev->dev;
4053-
atomic_t *rsp_status = &mbx->rsp_status;
40544057
struct list_head *head = &mbx->cmd_q;
40554058
struct qlcnic_hardware_context *ahw;
40564059
struct qlcnic_cmd_args *cmd = NULL;
4060+
unsigned long flags;
40574061

40584062
ahw = adapter->ahw;
40594063

@@ -4063,7 +4067,9 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
40634067
return;
40644068
}
40654069

4066-
atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
4070+
spin_lock_irqsave(&mbx->aen_lock, flags);
4071+
mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
4072+
spin_unlock_irqrestore(&mbx->aen_lock, flags);
40674073

40684074
spin_lock(&mbx->queue_lock);
40694075

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)