Commit 3c4b23b1 authored by Amit Kumar Salecha's avatar Amit Kumar Salecha Committed by David S. Miller

qlcnic: device state management fixes for virtual func

o NPAR state should be set to operationl by Mangement function only.
o NPAR state should be set to non operational before device reset.
o VF function should wait for NPAR state to be operational.
Signed-off-by: default avatarAmit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 933fce12
...@@ -718,8 +718,9 @@ enum { ...@@ -718,8 +718,9 @@ enum {
#define QLCNIC_DEV_FAILED 0x6 #define QLCNIC_DEV_FAILED 0x6
#define QLCNIC_DEV_QUISCENT 0x7 #define QLCNIC_DEV_QUISCENT 0x7
#define QLCNIC_DEV_NPAR_NOT_RDY 0 #define QLCNIC_DEV_NPAR_NON_OPER 0 /* NON Operational */
#define QLCNIC_DEV_NPAR_RDY 1 #define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */
#define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */
#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) #define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4)))
#define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4)))
......
...@@ -2398,7 +2398,7 @@ qlcnic_fwinit_work(struct work_struct *work) ...@@ -2398,7 +2398,7 @@ qlcnic_fwinit_work(struct work_struct *work)
{ {
struct qlcnic_adapter *adapter = container_of(work, struct qlcnic_adapter *adapter = container_of(work,
struct qlcnic_adapter, fw_work.work); struct qlcnic_adapter, fw_work.work);
u32 dev_state = 0xf, npar_state; u32 dev_state = 0xf;
if (qlcnic_api_lock(adapter)) if (qlcnic_api_lock(adapter))
goto err_ret; goto err_ret;
...@@ -2412,16 +2412,8 @@ qlcnic_fwinit_work(struct work_struct *work) ...@@ -2412,16 +2412,8 @@ qlcnic_fwinit_work(struct work_struct *work)
} }
if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); qlcnic_api_unlock(adapter);
if (npar_state == QLCNIC_DEV_NPAR_RDY) { goto wait_npar;
qlcnic_api_unlock(adapter);
goto wait_npar;
} else {
qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
FW_POLL_DELAY);
qlcnic_api_unlock(adapter);
return;
}
} }
if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
...@@ -2470,20 +2462,17 @@ qlcnic_fwinit_work(struct work_struct *work) ...@@ -2470,20 +2462,17 @@ qlcnic_fwinit_work(struct work_struct *work)
QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
switch (dev_state) { switch (dev_state) {
case QLCNIC_DEV_QUISCENT: case QLCNIC_DEV_READY:
case QLCNIC_DEV_NEED_QUISCENT:
case QLCNIC_DEV_NEED_RESET:
qlcnic_schedule_work(adapter,
qlcnic_fwinit_work, FW_POLL_DELAY);
return;
case QLCNIC_DEV_FAILED:
break;
default:
if (!adapter->nic_ops->start_firmware(adapter)) { if (!adapter->nic_ops->start_firmware(adapter)) {
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
return; return;
} }
case QLCNIC_DEV_FAILED:
break;
default:
qlcnic_schedule_work(adapter,
qlcnic_fwinit_work, FW_POLL_DELAY);
return;
} }
err_ret: err_ret:
...@@ -2530,6 +2519,22 @@ qlcnic_detach_work(struct work_struct *work) ...@@ -2530,6 +2519,22 @@ qlcnic_detach_work(struct work_struct *work)
} }
/*Transit NPAR state to NON Operational */
static void
qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
{
u32 state;
state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
if (state == QLCNIC_DEV_NPAR_NON_OPER)
return;
if (qlcnic_api_lock(adapter))
return;
QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
qlcnic_api_unlock(adapter);
}
/*Transit to RESET state from READY state only */ /*Transit to RESET state from READY state only */
static void static void
qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
...@@ -2548,6 +2553,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) ...@@ -2548,6 +2553,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
qlcnic_idc_debug_info(adapter, 0); qlcnic_idc_debug_info(adapter, 0);
} }
QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
qlcnic_api_unlock(adapter); qlcnic_api_unlock(adapter);
} }
...@@ -2555,21 +2561,14 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) ...@@ -2555,21 +2561,14 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
static void static void
qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
{ {
u32 state;
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
adapter->op_mode == QLCNIC_NON_PRIV_FUNC) adapter->op_mode != QLCNIC_MGMT_FUNC)
return; return;
if (qlcnic_api_lock(adapter)) if (qlcnic_api_lock(adapter))
return; return;
state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER);
QLCDB(adapter, DRV, "NPAR operational state set\n");
if (state != QLCNIC_DEV_NPAR_RDY) {
QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE,
QLCNIC_DEV_NPAR_RDY);
QLCDB(adapter, DRV, "NPAR READY state set\n");
}
qlcnic_api_unlock(adapter); qlcnic_api_unlock(adapter);
} }
...@@ -2631,8 +2630,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) ...@@ -2631,8 +2630,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
qlcnic_dev_request_reset(adapter); qlcnic_dev_request_reset(adapter);
state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT) if (state == QLCNIC_DEV_NEED_RESET ||
state == QLCNIC_DEV_NEED_QUISCENT) {
qlcnic_set_npar_non_operational(adapter);
adapter->need_fw_reset = 1; adapter->need_fw_reset = 1;
}
heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
if (heartbit != adapter->heartbit) { if (heartbit != adapter->heartbit) {
...@@ -2822,11 +2824,25 @@ static int ...@@ -2822,11 +2824,25 @@ static int
qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
{ {
int err; int err;
u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO;
u32 npar_state;
err = qlcnic_can_start_firmware(adapter); err = qlcnic_can_start_firmware(adapter);
if (err) if (err)
return err; return err;
npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) {
msleep(1000);
npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
}
if (!npar_opt_timeo) {
dev_err(&adapter->pdev->dev,
"Waiting for NPAR state to opertional timeout\n");
return -EIO;
}
qlcnic_check_options(adapter); qlcnic_check_options(adapter);
adapter->need_fw_reset = 0; adapter->need_fw_reset = 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