mirror of https://gitee.com/openkylin/linux.git
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 <davem@davemloft.net>
This commit is contained in:
commit
e49038d6ee
|
@ -566,6 +566,7 @@ struct qlcnic_adapter_stats {
|
||||||
u64 tx_dma_map_error;
|
u64 tx_dma_map_error;
|
||||||
u64 spurious_intr;
|
u64 spurious_intr;
|
||||||
u64 mac_filter_limit_overrun;
|
u64 mac_filter_limit_overrun;
|
||||||
|
u64 mbx_spurious_intr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1099,7 +1100,7 @@ struct qlcnic_mailbox {
|
||||||
unsigned long status;
|
unsigned long status;
|
||||||
spinlock_t queue_lock; /* Mailbox queue lock */
|
spinlock_t queue_lock; /* Mailbox queue lock */
|
||||||
spinlock_t aen_lock; /* Mailbox response/AEN lock */
|
spinlock_t aen_lock; /* Mailbox response/AEN lock */
|
||||||
atomic_t rsp_status;
|
u32 rsp_status;
|
||||||
u32 num_cmds;
|
u32 num_cmds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -491,7 +491,7 @@ irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
|
||||||
|
|
||||||
static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
|
static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
|
||||||
{
|
{
|
||||||
atomic_set(&mbx->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
|
mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
|
||||||
complete(&mbx->completion);
|
complete(&mbx->completion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +510,7 @@ static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
|
||||||
if (event & QLCNIC_MBX_ASYNC_EVENT) {
|
if (event & QLCNIC_MBX_ASYNC_EVENT) {
|
||||||
__qlcnic_83xx_process_aen(adapter);
|
__qlcnic_83xx_process_aen(adapter);
|
||||||
} else {
|
} else {
|
||||||
if (atomic_read(&mbx->rsp_status) != rsp_status)
|
if (mbx->rsp_status != rsp_status)
|
||||||
qlcnic_83xx_notify_mbx_response(mbx);
|
qlcnic_83xx_notify_mbx_response(mbx);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
@ -1023,7 +1023,7 @@ static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
|
||||||
if (event & QLCNIC_MBX_ASYNC_EVENT) {
|
if (event & QLCNIC_MBX_ASYNC_EVENT) {
|
||||||
__qlcnic_83xx_process_aen(adapter);
|
__qlcnic_83xx_process_aen(adapter);
|
||||||
} else {
|
} else {
|
||||||
if (atomic_read(&mbx->rsp_status) != rsp_status)
|
if (mbx->rsp_status != rsp_status)
|
||||||
qlcnic_83xx_notify_mbx_response(mbx);
|
qlcnic_83xx_notify_mbx_response(mbx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2338,9 +2338,9 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
|
||||||
|
|
||||||
static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
|
static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
|
||||||
{
|
{
|
||||||
|
u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
|
||||||
struct qlcnic_adapter *adapter = data;
|
struct qlcnic_adapter *adapter = data;
|
||||||
struct qlcnic_mailbox *mbx;
|
struct qlcnic_mailbox *mbx;
|
||||||
u32 mask, resp, event;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
mbx = adapter->ahw->mailbox;
|
mbx = adapter->ahw->mailbox;
|
||||||
|
@ -2350,10 +2350,14 @@ static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
|
event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
|
||||||
if (event & QLCNIC_MBX_ASYNC_EVENT)
|
if (event & QLCNIC_MBX_ASYNC_EVENT) {
|
||||||
__qlcnic_83xx_process_aen(adapter);
|
__qlcnic_83xx_process_aen(adapter);
|
||||||
else
|
} else {
|
||||||
qlcnic_83xx_notify_mbx_response(mbx);
|
if (mbx->rsp_status != rsp_status)
|
||||||
|
qlcnic_83xx_notify_mbx_response(mbx);
|
||||||
|
else
|
||||||
|
adapter->stats.mbx_spurious_intr++;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
|
mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
|
||||||
|
@ -4050,10 +4054,10 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
|
||||||
struct qlcnic_adapter *adapter = mbx->adapter;
|
struct qlcnic_adapter *adapter = mbx->adapter;
|
||||||
const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
|
const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
|
||||||
struct device *dev = &adapter->pdev->dev;
|
struct device *dev = &adapter->pdev->dev;
|
||||||
atomic_t *rsp_status = &mbx->rsp_status;
|
|
||||||
struct list_head *head = &mbx->cmd_q;
|
struct list_head *head = &mbx->cmd_q;
|
||||||
struct qlcnic_hardware_context *ahw;
|
struct qlcnic_hardware_context *ahw;
|
||||||
struct qlcnic_cmd_args *cmd = NULL;
|
struct qlcnic_cmd_args *cmd = NULL;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
ahw = adapter->ahw;
|
ahw = adapter->ahw;
|
||||||
|
|
||||||
|
@ -4063,7 +4067,9 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
|
spin_lock_irqsave(&mbx->aen_lock, flags);
|
||||||
|
mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
|
||||||
|
spin_unlock_irqrestore(&mbx->aen_lock, flags);
|
||||||
|
|
||||||
spin_lock(&mbx->queue_lock);
|
spin_lock(&mbx->queue_lock);
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,8 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
|
||||||
QLC_OFF(stats.mac_filter_limit_overrun)},
|
QLC_OFF(stats.mac_filter_limit_overrun)},
|
||||||
{"spurious intr", QLC_SIZEOF(stats.spurious_intr),
|
{"spurious intr", QLC_SIZEOF(stats.spurious_intr),
|
||||||
QLC_OFF(stats.spurious_intr)},
|
QLC_OFF(stats.spurious_intr)},
|
||||||
|
{"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
|
||||||
|
QLC_OFF(stats.mbx_spurious_intr)},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
|
static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
|
||||||
|
|
Loading…
Reference in New Issue