mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 06:26:39 +07:00
qlcnic: fix fw initialization responsibility
Now any pci-func can start fw, whoever sees the reset ack first. Before this, pci-func which sets the RESET state has the responsibility to start fw. Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
bbd8c6a45b
commit
f73dfc50f1
@ -2015,6 +2015,7 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter)
|
|||||||
clear_bit(__QLCNIC_RESETTING, &adapter->state);
|
clear_bit(__QLCNIC_RESETTING, &adapter->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Grab api lock, before checking state */
|
||||||
static int
|
static int
|
||||||
qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
|
qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
@ -2037,6 +2038,9 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
|
|||||||
u8 dev_init_timeo = adapter->dev_init_timeo;
|
u8 dev_init_timeo = adapter->dev_init_timeo;
|
||||||
int portnum = adapter->portnum;
|
int portnum = adapter->portnum;
|
||||||
|
|
||||||
|
if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (qlcnic_api_lock(adapter))
|
if (qlcnic_api_lock(adapter))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -2044,8 +2048,6 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
|
|||||||
if (!(val & ((int)0x1 << (portnum * 4)))) {
|
if (!(val & ((int)0x1 << (portnum * 4)))) {
|
||||||
val |= ((u32)0x1 << (portnum * 4));
|
val |= ((u32)0x1 << (portnum * 4));
|
||||||
QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
|
QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
|
||||||
} else if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) {
|
|
||||||
goto start_fw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
|
prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
|
||||||
@ -2053,7 +2055,6 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
|
|||||||
|
|
||||||
switch (prev_state) {
|
switch (prev_state) {
|
||||||
case QLCNIC_DEV_COLD:
|
case QLCNIC_DEV_COLD:
|
||||||
start_fw:
|
|
||||||
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
|
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
|
||||||
qlcnic_api_unlock(adapter);
|
qlcnic_api_unlock(adapter);
|
||||||
return 1;
|
return 1;
|
||||||
@ -2113,51 +2114,59 @@ 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);
|
||||||
int dev_state;
|
u32 dev_state = 0xf;
|
||||||
|
|
||||||
if (test_bit(__QLCNIC_START_FW, &adapter->state)) {
|
if (qlcnic_api_lock(adapter))
|
||||||
|
goto err_ret;
|
||||||
|
|
||||||
if (qlcnic_check_drv_state(adapter) &&
|
if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
|
||||||
(adapter->fw_wait_cnt++ < adapter->reset_ack_timeo)) {
|
dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n",
|
||||||
qlcnic_schedule_work(adapter,
|
adapter->reset_ack_timeo);
|
||||||
qlcnic_fwinit_work, FW_POLL_DELAY);
|
goto skip_ack_check;
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
if (!qlcnic_check_drv_state(adapter)) {
|
||||||
|
skip_ack_check:
|
||||||
|
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
|
||||||
|
if (dev_state == QLCNIC_DEV_NEED_RESET) {
|
||||||
|
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
|
||||||
|
QLCNIC_DEV_INITIALIZING);
|
||||||
|
set_bit(__QLCNIC_START_FW, &adapter->state);
|
||||||
|
QLCDB(adapter, DRV, "Restarting fw\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
QLCDB(adapter, DRV, "Resetting FW\n");
|
qlcnic_api_unlock(adapter);
|
||||||
|
|
||||||
if (!qlcnic_start_firmware(adapter)) {
|
if (!qlcnic_start_firmware(adapter)) {
|
||||||
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
|
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto err_ret;
|
goto err_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter->fw_wait_cnt++ > (adapter->dev_init_timeo / 2)) {
|
qlcnic_api_unlock(adapter);
|
||||||
dev_err(&adapter->pdev->dev,
|
|
||||||
"Waiting for device to reset timeout\n");
|
|
||||||
goto err_ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
|
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
|
||||||
QLCDB(adapter, HW, "Func waiting: Device state=%d\n", dev_state);
|
QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
|
||||||
|
|
||||||
switch (dev_state) {
|
switch (dev_state) {
|
||||||
case QLCNIC_DEV_READY:
|
case QLCNIC_DEV_NEED_RESET:
|
||||||
if (!qlcnic_start_firmware(adapter)) {
|
qlcnic_schedule_work(adapter,
|
||||||
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
|
qlcnic_fwinit_work, FW_POLL_DELAY);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
case QLCNIC_DEV_FAILED:
|
case QLCNIC_DEV_FAILED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qlcnic_schedule_work(adapter,
|
if (!qlcnic_start_firmware(adapter)) {
|
||||||
qlcnic_fwinit_work, 2 * FW_POLL_DELAY);
|
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err_ret:
|
err_ret:
|
||||||
|
dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u "
|
||||||
|
"fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt);
|
||||||
netif_device_attach(adapter->netdev);
|
netif_device_attach(adapter->netdev);
|
||||||
qlcnic_clr_all_drv_state(adapter);
|
qlcnic_clr_all_drv_state(adapter);
|
||||||
}
|
}
|
||||||
@ -2202,6 +2211,7 @@ qlcnic_detach_work(struct work_struct *work)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*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)
|
||||||
{
|
{
|
||||||
@ -2212,10 +2222,8 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
|
|||||||
|
|
||||||
state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
|
state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
|
||||||
|
|
||||||
if (state != QLCNIC_DEV_INITIALIZING &&
|
if (state == QLCNIC_DEV_READY) {
|
||||||
state != QLCNIC_DEV_NEED_RESET) {
|
|
||||||
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
|
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
|
||||||
set_bit(__QLCNIC_START_FW, &adapter->state);
|
|
||||||
QLCDB(adapter, DRV, "NEED_RESET state set\n");
|
QLCDB(adapter, DRV, "NEED_RESET state set\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user