Commit 068a8d19 authored by Manish Chopra's avatar Manish Chopra Committed by David S. Miller

qlcnic: Replace poll mode mailbox interface with interrupt based mailbox interface

Signed-off-by: default avatarManish Chopra <manish.chopra@qlogic.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e5c4e6c6
...@@ -466,7 +466,6 @@ struct qlcnic_hardware_context { ...@@ -466,7 +466,6 @@ struct qlcnic_hardware_context {
u32 *ext_reg_tbl; u32 *ext_reg_tbl;
u32 mbox_aen[QLC_83XX_MBX_AEN_CNT]; u32 mbox_aen[QLC_83XX_MBX_AEN_CNT];
u32 mbox_reg[4]; u32 mbox_reg[4];
spinlock_t mbx_lock;
struct qlcnic_mailbox *mailbox; struct qlcnic_mailbox *mailbox;
}; };
......
...@@ -644,8 +644,6 @@ int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state); ...@@ -644,8 +644,6 @@ int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state);
int qlcnic_83xx_flash_test(struct qlcnic_adapter *); int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *);
u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *);
void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *); void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *); void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *); void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
......
...@@ -399,6 +399,7 @@ static void qlcnic_83xx_idc_detach_driver(struct qlcnic_adapter *adapter) ...@@ -399,6 +399,7 @@ static void qlcnic_83xx_idc_detach_driver(struct qlcnic_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
netif_device_detach(netdev); netif_device_detach(netdev);
qlcnic_83xx_detach_mailbox_work(adapter);
/* Disable mailbox interrupt */ /* Disable mailbox interrupt */
qlcnic_83xx_disable_mbx_intr(adapter); qlcnic_83xx_disable_mbx_intr(adapter);
...@@ -610,6 +611,9 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter) ...@@ -610,6 +611,9 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
{ {
int err; int err;
qlcnic_83xx_reinit_mbx_work(adapter->ahw->mailbox);
qlcnic_83xx_enable_mbx_interrupt(adapter);
/* register for NIC IDC AEN Events */ /* register for NIC IDC AEN Events */
qlcnic_83xx_register_nic_idc_func(adapter, 1); qlcnic_83xx_register_nic_idc_func(adapter, 1);
...@@ -640,7 +644,6 @@ static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter) ...@@ -640,7 +644,6 @@ static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1); qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1);
set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
...@@ -810,9 +813,10 @@ static int qlcnic_83xx_idc_init_state(struct qlcnic_adapter *adapter) ...@@ -810,9 +813,10 @@ static int qlcnic_83xx_idc_init_state(struct qlcnic_adapter *adapter)
**/ **/
static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
{ {
u32 val;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_mailbox *mbx = ahw->mailbox;
int ret = 0; int ret = 0;
u32 val;
/* Perform NIC configuration based ready state entry actions */ /* Perform NIC configuration based ready state entry actions */
if (ahw->idc.state_entry(adapter)) if (ahw->idc.state_entry(adapter))
...@@ -824,7 +828,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) ...@@ -824,7 +828,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"Error: device temperature %d above limits\n", "Error: device temperature %d above limits\n",
adapter->ahw->temp); adapter->ahw->temp);
clear_bit(QLC_83XX_MBX_READY, &ahw->idc.status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
set_bit(__QLCNIC_RESETTING, &adapter->state); set_bit(__QLCNIC_RESETTING, &adapter->state);
qlcnic_83xx_idc_detach_driver(adapter); qlcnic_83xx_idc_detach_driver(adapter);
qlcnic_83xx_idc_enter_failed_state(adapter, 1); qlcnic_83xx_idc_enter_failed_state(adapter, 1);
...@@ -837,7 +841,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) ...@@ -837,7 +841,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
if (ret) { if (ret) {
adapter->flags |= QLCNIC_FW_HANG; adapter->flags |= QLCNIC_FW_HANG;
if (!(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) { if (!(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
clear_bit(QLC_83XX_MBX_READY, &ahw->idc.status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
set_bit(__QLCNIC_RESETTING, &adapter->state); set_bit(__QLCNIC_RESETTING, &adapter->state);
qlcnic_83xx_idc_enter_need_reset_state(adapter, 1); qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
} }
...@@ -845,6 +849,8 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) ...@@ -845,6 +849,8 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
} }
if ((val & QLC_83XX_IDC_GRACEFULL_RESET) || ahw->idc.collect_dump) { if ((val & QLC_83XX_IDC_GRACEFULL_RESET) || ahw->idc.collect_dump) {
clear_bit(QLC_83XX_MBX_READY, &mbx->status);
/* Move to need reset state and prepare for reset */ /* Move to need reset state and prepare for reset */
qlcnic_83xx_idc_enter_need_reset_state(adapter, 1); qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
return ret; return ret;
...@@ -882,12 +888,13 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) ...@@ -882,12 +888,13 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
**/ **/
static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter) static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
int ret = 0; int ret = 0;
if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) { if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) {
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
set_bit(__QLCNIC_RESETTING, &adapter->state); set_bit(__QLCNIC_RESETTING, &adapter->state);
clear_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE) if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
qlcnic_83xx_disable_vnic_mode(adapter, 1); qlcnic_83xx_disable_vnic_mode(adapter, 1);
...@@ -1079,7 +1086,6 @@ static void qlcnic_83xx_setup_idc_parameters(struct qlcnic_adapter *adapter) ...@@ -1079,7 +1086,6 @@ static void qlcnic_83xx_setup_idc_parameters(struct qlcnic_adapter *adapter)
adapter->ahw->idc.name = (char **)qlc_83xx_idc_states; adapter->ahw->idc.name = (char **)qlc_83xx_idc_states;
clear_bit(__QLCNIC_RESETTING, &adapter->state); clear_bit(__QLCNIC_RESETTING, &adapter->state);
set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
/* Check if reset recovery is disabled */ /* Check if reset recovery is disabled */
...@@ -1190,6 +1196,9 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *adapter, u32 key) ...@@ -1190,6 +1196,9 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *adapter, u32 key)
{ {
u32 val; u32 val;
if (qlcnic_sriov_vf_check(adapter))
return;
if (qlcnic_83xx_lock_driver(adapter)) { if (qlcnic_83xx_lock_driver(adapter)) {
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"%s:failed, please retry\n", __func__); "%s:failed, please retry\n", __func__);
...@@ -2110,17 +2119,35 @@ static void qlcnic_83xx_clear_function_resources(struct qlcnic_adapter *adapter) ...@@ -2110,17 +2119,35 @@ static void qlcnic_83xx_clear_function_resources(struct qlcnic_adapter *adapter)
int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int err = 0;
if (qlcnic_sriov_vf_check(adapter)) ahw->msix_supported = !!qlcnic_use_msi_x;
return qlcnic_sriov_vf_init(adapter, pci_using_dac); err = qlcnic_83xx_init_mailbox_work(adapter);
if (err)
goto exit;
if (qlcnic_83xx_check_hw_status(adapter)) if (qlcnic_sriov_vf_check(adapter)) {
return -EIO; err = qlcnic_sriov_vf_init(adapter, pci_using_dac);
if (err)
goto detach_mbx;
else
return err;
}
/* Initilaize 83xx mailbox spinlock */ err = qlcnic_83xx_check_hw_status(adapter);
spin_lock_init(&ahw->mbx_lock); if (err)
goto detach_mbx;
err = qlcnic_setup_intr(adapter, 0);
if (err) {
dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");
goto disable_intr;
}
err = qlcnic_83xx_setup_mbx_intr(adapter);
if (err)
goto disable_mbx_intr;
set_bit(QLC_83XX_MBX_READY, &ahw->idc.status);
qlcnic_83xx_clear_function_resources(adapter); qlcnic_83xx_clear_function_resources(adapter);
/* register for NIC IDC AEN Events */ /* register for NIC IDC AEN Events */
...@@ -2129,21 +2156,35 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) ...@@ -2129,21 +2156,35 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
if (!qlcnic_83xx_read_flash_descriptor_table(adapter)) if (!qlcnic_83xx_read_flash_descriptor_table(adapter))
qlcnic_83xx_read_flash_mfg_id(adapter); qlcnic_83xx_read_flash_mfg_id(adapter);
if (qlcnic_83xx_idc_init(adapter)) err = qlcnic_83xx_idc_init(adapter);
return -EIO; if (err)
goto disable_mbx_intr;
/* Configure default, SR-IOV or Virtual NIC mode of operation */ /* Configure default, SR-IOV or Virtual NIC mode of operation */
if (qlcnic_83xx_configure_opmode(adapter)) err = qlcnic_83xx_configure_opmode(adapter);
return -EIO; if (err)
goto disable_mbx_intr;
/* Perform operating mode specific initialization */ /* Perform operating mode specific initialization */
if (adapter->nic_ops->init_driver(adapter)) err = adapter->nic_ops->init_driver(adapter);
return -EIO; if (err)
goto disable_mbx_intr;
INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
/* Periodically monitor device status */ /* Periodically monitor device status */
qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work); qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
return 0;
return adapter->ahw->idc.err_code; disable_mbx_intr:
qlcnic_83xx_free_mbx_intr(adapter);
disable_intr:
qlcnic_teardown_intr(adapter);
detach_mbx:
qlcnic_83xx_detach_mailbox_work(adapter);
qlcnic_83xx_free_mailbox(ahw->mailbox);
exit:
return err;
} }
...@@ -2141,16 +2141,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2141,16 +2141,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"83xx adapter do not support MSI interrupts\n"); "83xx adapter do not support MSI interrupts\n");
err = qlcnic_setup_intr(adapter, 0); if (qlcnic_82xx_check(adapter)) {
if (err) { err = qlcnic_setup_intr(adapter, 0);
dev_err(&pdev->dev, "Failed to setup interrupt\n"); if (err) {
goto err_out_disable_msi; dev_err(&pdev->dev, "Failed to setup interrupt\n");
}
if (qlcnic_83xx_check(adapter)) {
err = qlcnic_83xx_setup_mbx_intr(adapter);
if (err)
goto err_out_disable_msi; goto err_out_disable_msi;
}
} }
err = qlcnic_get_act_pci_func(adapter); err = qlcnic_get_act_pci_func(adapter);
...@@ -2237,9 +2233,11 @@ static void qlcnic_remove(struct pci_dev *pdev) ...@@ -2237,9 +2233,11 @@ static void qlcnic_remove(struct pci_dev *pdev)
qlcnic_sriov_cleanup(adapter); qlcnic_sriov_cleanup(adapter);
if (qlcnic_83xx_check(adapter)) { if (qlcnic_83xx_check(adapter)) {
qlcnic_83xx_free_mbx_intr(adapter);
qlcnic_83xx_register_nic_idc_func(adapter, 0); qlcnic_83xx_register_nic_idc_func(adapter, 0);
cancel_delayed_work_sync(&adapter->idc_aen_work); cancel_delayed_work_sync(&adapter->idc_aen_work);
qlcnic_83xx_free_mbx_intr(adapter);
qlcnic_83xx_detach_mailbox_work(adapter);
qlcnic_83xx_free_mailbox(ahw->mailbox);
} }
qlcnic_detach(adapter); qlcnic_detach(adapter);
......
...@@ -286,96 +286,38 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) ...@@ -286,96 +286,38 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
u32 *pay, u8 pci_func, u8 size) u32 *pay, u8 pci_func, u8 size)
{ {
u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val, wait_time = 0;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
unsigned long flags; struct qlcnic_mailbox *mbx = ahw->mailbox;
u16 opcode; struct qlcnic_cmd_args cmd;
u8 mbx_err_code; unsigned long timeout;
int i, j; int err;
opcode = ((struct qlcnic_bc_hdr *)hdr)->cmd_op;
if (!test_bit(QLC_83XX_MBX_READY, &ahw->idc.status)) {
dev_info(&adapter->pdev->dev,
"Mailbox cmd attempted, 0x%x\n", opcode);
dev_info(&adapter->pdev->dev, "Mailbox detached\n");
return 0;
}
spin_lock_irqsave(&ahw->mbx_lock, flags);
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
if (mbx_val) {
QLCDB(adapter, DRV, "Mailbox cmd attempted, 0x%x\n", opcode);
spin_unlock_irqrestore(&ahw->mbx_lock, flags);
return QLCNIC_RCODE_TIMEOUT;
}
/* Fill in mailbox registers */
val = size + (sizeof(struct qlcnic_bc_hdr) / sizeof(u32));
mbx_cmd = 0x31 | (val << 16) | (adapter->ahw->fw_hal_version << 29);
writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
mbx_cmd = 0x1 | (1 << 4);
if (qlcnic_sriov_pf_check(adapter))
mbx_cmd |= (pci_func << 5);
writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1)); memset(&cmd, 0, sizeof(struct qlcnic_cmd_args));
for (i = 2, j = 0; j < (sizeof(struct qlcnic_bc_hdr) / sizeof(u32)); cmd.hdr = hdr;
i++, j++) { cmd.pay = pay;
writel(*(hdr++), QLCNIC_MBX_HOST(ahw, i)); cmd.pay_size = size;
cmd.func_num = pci_func;
cmd.op_type = QLC_83XX_MBX_POST_BC_OP;
cmd.cmd_op = ((struct qlcnic_bc_hdr *)hdr)->cmd_op;
err = mbx->ops->enqueue_cmd(adapter, &cmd, &timeout);
if (err) {
dev_err(&adapter->pdev->dev,
"%s: Mailbox not available, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
__func__, cmd.cmd_op, cmd.type, ahw->pci_func,
ahw->op_mode);
return err;
} }
for (j = 0; j < size; j++, i++)
writel(*(pay++), QLCNIC_MBX_HOST(ahw, i));
/* Signal FW about the impending command */ if (!wait_for_completion_timeout(&cmd.completion, timeout)) {
QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER); dev_err(&adapter->pdev->dev,
"%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
/* Waiting for the mailbox cmd to complete and while waiting here __func__, cmd.cmd_op, cmd.type, ahw->pci_func,
* some AEN might arrive. If more than 5 seconds expire we can ahw->op_mode);
* assume something is wrong. flush_workqueue(mbx->work_q);
*/
poll:
rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
if (rsp != QLCNIC_RCODE_TIMEOUT) {
/* Get the FW response data */
fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
__qlcnic_83xx_process_aen(adapter);
goto poll;
}
mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
opcode = QLCNIC_MBX_RSP(fw_data);
switch (mbx_err_code) {
case QLCNIC_MBX_RSP_OK:
case QLCNIC_MBX_PORT_RSP_OK:
rsp = QLCNIC_RCODE_SUCCESS;
break;
default:
if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
rsp = qlcnic_83xx_mac_rcode(adapter);
if (!rsp)
goto out;
}
dev_err(&adapter->pdev->dev,
"MBX command 0x%x failed with err:0x%x\n",
opcode, mbx_err_code);
rsp = mbx_err_code;
break;
}
goto out;
} }
dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n", return cmd.rsp_opcode;
QLCNIC_MBX_RSP(mbx_cmd));
rsp = QLCNIC_RCODE_TIMEOUT;
out:
/* clear fw mbx control register */
QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
return rsp;
} }
static void qlcnic_sriov_vf_cfg_buff_desc(struct qlcnic_adapter *adapter) static void qlcnic_sriov_vf_cfg_buff_desc(struct qlcnic_adapter *adapter)
...@@ -522,8 +464,8 @@ static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter) ...@@ -522,8 +464,8 @@ static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter)
static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter) static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_info nic_info;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_info nic_info;
int err; int err;
err = qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, 0); err = qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, 0);
...@@ -637,8 +579,6 @@ int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac) ...@@ -637,8 +579,6 @@ int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac)
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int err; int err;
spin_lock_init(&ahw->mbx_lock);
set_bit(QLC_83XX_MBX_READY, &ahw->idc.status);
set_bit(QLC_83XX_MODULE_LOADED, &ahw->idc.status); set_bit(QLC_83XX_MODULE_LOADED, &ahw->idc.status);
ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
ahw->reset_context = 0; ahw->reset_context = 0;
...@@ -1395,6 +1335,7 @@ static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, ...@@ -1395,6 +1335,7 @@ static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
struct qlcnic_cmd_args *cmd) struct qlcnic_cmd_args *cmd)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_mailbox *mbx = ahw->mailbox;
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
struct qlcnic_bc_trans *trans; struct qlcnic_bc_trans *trans;
int err; int err;
...@@ -1411,7 +1352,7 @@ static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, ...@@ -1411,7 +1352,7 @@ static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
goto cleanup_transaction; goto cleanup_transaction;
retry: retry:
if (!test_bit(QLC_83XX_MBX_READY, &ahw->idc.status)) { if (!test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
rsp = -EIO; rsp = -EIO;
QLCDB(adapter, DRV, "MBX not Ready!(cmd 0x%x) for VF 0x%x\n", QLCDB(adapter, DRV, "MBX not Ready!(cmd 0x%x) for VF 0x%x\n",
QLCNIC_MBX_RSP(cmd->req.arg[0]), func); QLCNIC_MBX_RSP(cmd->req.arg[0]), func);
...@@ -1454,7 +1395,7 @@ static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, ...@@ -1454,7 +1395,7 @@ static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
if (rsp == QLCNIC_RCODE_TIMEOUT) { if (rsp == QLCNIC_RCODE_TIMEOUT) {
ahw->reset_context = 1; ahw->reset_context = 1;
adapter->need_fw_reset = 1; adapter->need_fw_reset = 1;
clear_bit(QLC_83XX_MBX_READY, &ahw->idc.status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
} }
cleanup_transaction: cleanup_transaction:
...@@ -1657,8 +1598,10 @@ static void qlcnic_sriov_vf_detach(struct qlcnic_adapter *adapter) ...@@ -1657,8 +1598,10 @@ static void qlcnic_sriov_vf_detach(struct qlcnic_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
u8 i, max_ints = ahw->num_msix - 1; u8 i, max_ints = ahw->num_msix - 1;
qlcnic_83xx_disable_mbx_intr(adapter);
netif_device_detach(netdev); netif_device_detach(netdev);
qlcnic_83xx_detach_mailbox_work(adapter);
qlcnic_83xx_disable_mbx_intr(adapter);
if (netif_running(netdev)) if (netif_running(netdev))
qlcnic_down(adapter, netdev); qlcnic_down(adapter, netdev);
...@@ -1702,6 +1645,7 @@ static int qlcnic_sriov_vf_handle_dev_ready(struct qlcnic_adapter *adapter) ...@@ -1702,6 +1645,7 @@ static int qlcnic_sriov_vf_handle_dev_ready(struct qlcnic_adapter *adapter)
static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter) static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_mailbox *mbx = ahw->mailbox;
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
struct qlc_83xx_idc *idc = &ahw->idc; struct qlc_83xx_idc *idc = &ahw->idc;
u8 func = ahw->pci_func; u8 func = ahw->pci_func;
...@@ -1712,7 +1656,7 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter) ...@@ -1712,7 +1656,7 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
/* Skip the context reset and check if FW is hung */ /* Skip the context reset and check if FW is hung */
if (adapter->reset_ctx_cnt < 3) { if (adapter->reset_ctx_cnt < 3) {
adapter->need_fw_reset = 1; adapter->need_fw_reset = 1;
clear_bit(QLC_83XX_MBX_READY, &idc->status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
dev_info(dev, dev_info(dev,
"Resetting context, wait here to check if FW is in failed state\n"); "Resetting context, wait here to check if FW is in failed state\n");
return 0; return 0;
...@@ -1737,7 +1681,7 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter) ...@@ -1737,7 +1681,7 @@ static int qlcnic_sriov_vf_handle_context_reset(struct qlcnic_adapter *adapter)
__func__, adapter->reset_ctx_cnt, func); __func__, adapter->reset_ctx_cnt, func);
set_bit(__QLCNIC_RESETTING, &adapter->state); set_bit(__QLCNIC_RESETTING, &adapter->state);
adapter->need_fw_reset = 1; adapter->need_fw_reset = 1;
clear_bit(QLC_83XX_MBX_READY, &idc->status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
qlcnic_sriov_vf_detach(adapter); qlcnic_sriov_vf_detach(adapter);
adapter->need_fw_reset = 0; adapter->need_fw_reset = 0;
...@@ -1787,6 +1731,7 @@ static int qlcnic_sriov_vf_idc_failed_state(struct qlcnic_adapter *adapter) ...@@ -1787,6 +1731,7 @@ static int qlcnic_sriov_vf_idc_failed_state(struct qlcnic_adapter *adapter)
static int static int
qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter) qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
struct qlc_83xx_idc *idc = &adapter->ahw->idc; struct qlc_83xx_idc *idc = &adapter->ahw->idc;
dev_info(&adapter->pdev->dev, "Device is in quiescent state\n"); dev_info(&adapter->pdev->dev, "Device is in quiescent state\n");
...@@ -1794,7 +1739,7 @@ qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter) ...@@ -1794,7 +1739,7 @@ qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)
set_bit(__QLCNIC_RESETTING, &adapter->state); set_bit(__QLCNIC_RESETTING, &adapter->state);
adapter->tx_timeo_cnt = 0; adapter->tx_timeo_cnt = 0;
adapter->reset_ctx_cnt = 0; adapter->reset_ctx_cnt = 0;
clear_bit(QLC_83XX_MBX_READY, &idc->status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
qlcnic_sriov_vf_detach(adapter); qlcnic_sriov_vf_detach(adapter);
} }
...@@ -1803,6 +1748,7 @@ qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter) ...@@ -1803,6 +1748,7 @@ qlcnic_sriov_vf_idc_need_quiescent_state(struct qlcnic_adapter *adapter)
static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter) static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
struct qlc_83xx_idc *idc = &adapter->ahw->idc; struct qlc_83xx_idc *idc = &adapter->ahw->idc;
u8 func = adapter->ahw->pci_func; u8 func = adapter->ahw->pci_func;
...@@ -1812,7 +1758,7 @@ static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter) ...@@ -1812,7 +1758,7 @@ static int qlcnic_sriov_vf_idc_init_reset_state(struct qlcnic_adapter *adapter)
set_bit(__QLCNIC_RESETTING, &adapter->state); set_bit(__QLCNIC_RESETTING, &adapter->state);
adapter->tx_timeo_cnt = 0; adapter->tx_timeo_cnt = 0;
adapter->reset_ctx_cnt = 0; adapter->reset_ctx_cnt = 0;
clear_bit(QLC_83XX_MBX_READY, &idc->status); clear_bit(QLC_83XX_MBX_READY, &mbx->status);
qlcnic_sriov_vf_detach(adapter); qlcnic_sriov_vf_detach(adapter);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment