qlcnic: helper routine to handle async events
Create a helper routine to handle async events, as it is being called from multiple places Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3d73b5fda4
commit
483202d590
4 changed files with 45 additions and 64 deletions
|
@ -12,13 +12,6 @@
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
#define QLCNIC_MAX_TX_QUEUES 1
|
#define QLCNIC_MAX_TX_QUEUES 1
|
||||||
|
|
||||||
#define QLCNIC_MBX_RSP(reg) LSW(reg)
|
|
||||||
#define QLCNIC_MBX_NUM_REGS(reg) (MSW(reg) & 0x1FF)
|
|
||||||
#define QLCNIC_MBX_STATUS(reg) (((reg) >> 25) & 0x7F)
|
|
||||||
#define QLCNIC_MBX_HOST(ahw, i) ((ahw)->pci_base0 + ((i) * 4))
|
|
||||||
#define QLCNIC_MBX_FW(ahw, i) ((ahw)->pci_base0 + 0x800 + ((i) * 4))
|
|
||||||
|
|
||||||
#define RSS_HASHTYPE_IP_TCP 0x3
|
#define RSS_HASHTYPE_IP_TCP 0x3
|
||||||
|
|
||||||
/* status descriptor mailbox data
|
/* status descriptor mailbox data
|
||||||
|
@ -696,7 +689,7 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
|
||||||
int i;
|
int i;
|
||||||
u16 opcode;
|
u16 opcode;
|
||||||
u8 mbx_err_code, mac_cmd_rcode;
|
u8 mbx_err_code, mac_cmd_rcode;
|
||||||
u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, temp, fw[8];
|
u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
|
||||||
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||||
|
|
||||||
opcode = LSW(cmd->req.arg[0]);
|
opcode = LSW(cmd->req.arg[0]);
|
||||||
|
@ -738,42 +731,8 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
|
||||||
opcode = QLCNIC_MBX_RSP(fw_data);
|
opcode = QLCNIC_MBX_RSP(fw_data);
|
||||||
|
|
||||||
if (rsp != QLCNIC_RCODE_TIMEOUT) {
|
if (rsp != QLCNIC_RCODE_TIMEOUT) {
|
||||||
if (opcode == QLCNIC_MBX_LINK_EVENT) {
|
if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
|
||||||
for (i = 0; i < rsp_num; i++) {
|
qlcnic_83xx_process_aen(adapter);
|
||||||
temp = readl(QLCNIC_MBX_FW(ahw, i));
|
|
||||||
fw[i] = temp;
|
|
||||||
}
|
|
||||||
qlcnic_83xx_handle_link_aen(adapter, fw);
|
|
||||||
/* clear fw mbx control register */
|
|
||||||
QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
|
|
||||||
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
|
|
||||||
if (mbx_val)
|
|
||||||
goto poll;
|
|
||||||
} else if (opcode == QLCNIC_MBX_COMP_EVENT) {
|
|
||||||
for (i = 0; i < rsp_num; i++) {
|
|
||||||
temp = readl(QLCNIC_MBX_FW(ahw, i));
|
|
||||||
fw[i] = temp;
|
|
||||||
}
|
|
||||||
qlcnic_83xx_handle_idc_comp_aen(adapter, fw);
|
|
||||||
/* clear fw mbx control register */
|
|
||||||
QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
|
|
||||||
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
|
|
||||||
if (mbx_val)
|
|
||||||
goto poll;
|
|
||||||
} else if (opcode == QLCNIC_MBX_REQUEST_EVENT) {
|
|
||||||
/* IDC Request Notification */
|
|
||||||
for (i = 0; i < rsp_num; i++) {
|
|
||||||
temp = readl(QLCNIC_MBX_FW(ahw, i));
|
|
||||||
fw[i] = temp;
|
|
||||||
}
|
|
||||||
for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++) {
|
|
||||||
temp = QLCNIC_MBX_RSP(fw[i]);
|
|
||||||
adapter->ahw->mbox_aen[i] = temp;
|
|
||||||
}
|
|
||||||
queue_delayed_work(adapter->qlcnic_wq,
|
|
||||||
&adapter->idc_aen_work, 0);
|
|
||||||
/* clear fw mbx control register */
|
|
||||||
QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
|
|
||||||
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
|
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
|
||||||
if (mbx_val)
|
if (mbx_val)
|
||||||
goto poll;
|
goto poll;
|
||||||
|
@ -875,20 +834,10 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
|
||||||
|
|
||||||
void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
|
void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
u32 mask, resp, event[QLC_83XX_MBX_AEN_CNT];
|
u32 event[QLC_83XX_MBX_AEN_CNT];
|
||||||
int i;
|
int i;
|
||||||
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||||
|
|
||||||
if (!spin_trylock(&ahw->mbx_lock)) {
|
|
||||||
mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
|
|
||||||
writel(0, adapter->ahw->pci_base0 + mask);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
|
|
||||||
|
|
||||||
if (!(resp & QLCNIC_SET_OWNER))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
|
for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
|
||||||
event[i] = readl(QLCNIC_MBX_FW(ahw, i));
|
event[i] = readl(QLCNIC_MBX_FW(ahw, i));
|
||||||
|
|
||||||
|
@ -923,10 +872,6 @@ void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
|
QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
|
||||||
out:
|
|
||||||
mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
|
|
||||||
writel(0, adapter->ahw->pci_base0 + mask);
|
|
||||||
spin_unlock(&ahw->mbx_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
|
static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
|
||||||
|
@ -1620,7 +1565,21 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
|
||||||
irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
|
irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct qlcnic_adapter *adapter = data;
|
struct qlcnic_adapter *adapter = data;
|
||||||
qlcnic_83xx_process_aen(adapter);
|
unsigned long flags;
|
||||||
|
u32 mask, resp, event;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
|
||||||
|
resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
|
||||||
|
if (!(resp & QLCNIC_SET_OWNER))
|
||||||
|
goto out;
|
||||||
|
event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
|
||||||
|
if (event & QLCNIC_MBX_ASYNC_EVENT)
|
||||||
|
qlcnic_83xx_process_aen(adapter);
|
||||||
|
out:
|
||||||
|
mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
|
||||||
|
writel(0, adapter->ahw->pci_base0 + mask);
|
||||||
|
spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,9 +137,6 @@ struct qlc_83xx_reset {
|
||||||
#define QLC_83XX_IDC_MINOR_VERSION 0
|
#define QLC_83XX_IDC_MINOR_VERSION 0
|
||||||
#define QLC_83XX_IDC_FLASH_PARAM_ADDR 0x3e8020
|
#define QLC_83XX_IDC_FLASH_PARAM_ADDR 0x3e8020
|
||||||
|
|
||||||
/* Mailbox process AEN count */
|
|
||||||
#define QLC_83XX_MBX_AEN_CNT 5
|
|
||||||
|
|
||||||
struct qlcnic_adapter;
|
struct qlcnic_adapter;
|
||||||
struct qlc_83xx_idc {
|
struct qlc_83xx_idc {
|
||||||
int (*state_entry) (struct qlcnic_adapter *);
|
int (*state_entry) (struct qlcnic_adapter *);
|
||||||
|
@ -156,6 +153,12 @@ struct qlc_83xx_idc {
|
||||||
char **name;
|
char **name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define QLCNIC_MBX_RSP(reg) LSW(reg)
|
||||||
|
#define QLCNIC_MBX_NUM_REGS(reg) (MSW(reg) & 0x1FF)
|
||||||
|
#define QLCNIC_MBX_STATUS(reg) (((reg) >> 25) & 0x7F)
|
||||||
|
#define QLCNIC_MBX_HOST(ahw, i) ((ahw)->pci_base0 + ((i) * 4))
|
||||||
|
#define QLCNIC_MBX_FW(ahw, i) ((ahw)->pci_base0 + 0x800 + ((i) * 4))
|
||||||
|
|
||||||
/* Mailbox process AEN count */
|
/* Mailbox process AEN count */
|
||||||
#define QLC_83XX_IDC_COMP_AEN 3
|
#define QLC_83XX_IDC_COMP_AEN 3
|
||||||
#define QLC_83XX_MBX_AEN_CNT 5
|
#define QLC_83XX_MBX_AEN_CNT 5
|
||||||
|
|
|
@ -135,6 +135,7 @@ struct qlcnic_mailbox_metadata {
|
||||||
|
|
||||||
#define QLCNIC_MBX_RSP_OK 1
|
#define QLCNIC_MBX_RSP_OK 1
|
||||||
#define QLCNIC_MBX_PORT_RSP_OK 0x1a
|
#define QLCNIC_MBX_PORT_RSP_OK 0x1a
|
||||||
|
#define QLCNIC_MBX_ASYNC_EVENT BIT_15
|
||||||
|
|
||||||
struct qlcnic_pci_info;
|
struct qlcnic_pci_info;
|
||||||
struct qlcnic_info;
|
struct qlcnic_info;
|
||||||
|
|
|
@ -1553,6 +1553,24 @@ static int qlcnic_83xx_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
u32 mask, resp, event;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
|
||||||
|
resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
|
||||||
|
if (!(resp & QLCNIC_SET_OWNER))
|
||||||
|
goto out;
|
||||||
|
event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
|
||||||
|
if (event & QLCNIC_MBX_ASYNC_EVENT)
|
||||||
|
qlcnic_83xx_process_aen(adapter);
|
||||||
|
out:
|
||||||
|
mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
|
||||||
|
writel(0, adapter->ahw->pci_base0 + mask);
|
||||||
|
spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
|
static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
|
||||||
{
|
{
|
||||||
int tx_complete;
|
int tx_complete;
|
||||||
|
@ -1567,7 +1585,7 @@ static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
|
||||||
tx_ring = adapter->tx_ring;
|
tx_ring = adapter->tx_ring;
|
||||||
|
|
||||||
if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
|
if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
|
||||||
qlcnic_83xx_process_aen(adapter);
|
qlcnic_83xx_poll_process_aen(adapter);
|
||||||
|
|
||||||
tx_complete = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
|
tx_complete = qlcnic_process_cmd_ring(adapter, tx_ring, budget);
|
||||||
work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
|
work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
|
||||||
|
|
Loading…
Reference in a new issue