diff options
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 79c6e0517ba..6a7b8138835 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -2043,8 +2043,11 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) | |||
2043 | 2043 | ||
2044 | do { | 2044 | do { |
2045 | msleep(1000); | 2045 | msleep(1000); |
2046 | } while ((QLCRD32(adapter, QLCNIC_CRB_DEV_STATE) != QLCNIC_DEV_READY) | 2046 | prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2047 | && --dev_init_timeo); | 2047 | |
2048 | if (prev_state == QLCNIC_DEV_QUISCENT) | ||
2049 | continue; | ||
2050 | } while ((prev_state != QLCNIC_DEV_READY) && --dev_init_timeo); | ||
2048 | 2051 | ||
2049 | if (!dev_init_timeo) { | 2052 | if (!dev_init_timeo) { |
2050 | dev_err(&adapter->pdev->dev, | 2053 | dev_err(&adapter->pdev->dev, |
@@ -2075,6 +2078,14 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2075 | if (qlcnic_api_lock(adapter)) | 2078 | if (qlcnic_api_lock(adapter)) |
2076 | goto err_ret; | 2079 | goto err_ret; |
2077 | 2080 | ||
2081 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
2082 | if (dev_state == QLCNIC_DEV_QUISCENT) { | ||
2083 | qlcnic_api_unlock(adapter); | ||
2084 | qlcnic_schedule_work(adapter, qlcnic_fwinit_work, | ||
2085 | FW_POLL_DELAY * 2); | ||
2086 | return; | ||
2087 | } | ||
2088 | |||
2078 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { | 2089 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { |
2079 | dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", | 2090 | dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", |
2080 | adapter->reset_ack_timeo); | 2091 | adapter->reset_ack_timeo); |
@@ -2084,6 +2095,17 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2084 | if (!qlcnic_check_drv_state(adapter)) { | 2095 | if (!qlcnic_check_drv_state(adapter)) { |
2085 | skip_ack_check: | 2096 | skip_ack_check: |
2086 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2097 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2098 | |||
2099 | if (dev_state == QLCNIC_DEV_NEED_QUISCENT) { | ||
2100 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, | ||
2101 | QLCNIC_DEV_QUISCENT); | ||
2102 | qlcnic_schedule_work(adapter, qlcnic_fwinit_work, | ||
2103 | FW_POLL_DELAY * 2); | ||
2104 | QLCDB(adapter, DRV, "Quiscing the driver\n"); | ||
2105 | qlcnic_api_unlock(adapter); | ||
2106 | return; | ||
2107 | } | ||
2108 | |||
2087 | if (dev_state == QLCNIC_DEV_NEED_RESET) { | 2109 | if (dev_state == QLCNIC_DEV_NEED_RESET) { |
2088 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, | 2110 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, |
2089 | QLCNIC_DEV_INITIALIZING); | 2111 | QLCNIC_DEV_INITIALIZING); |
@@ -2106,6 +2128,8 @@ skip_ack_check: | |||
2106 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); | 2128 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); |
2107 | 2129 | ||
2108 | switch (dev_state) { | 2130 | switch (dev_state) { |
2131 | case QLCNIC_DEV_QUISCENT: | ||
2132 | case QLCNIC_DEV_NEED_QUISCENT: | ||
2109 | case QLCNIC_DEV_NEED_RESET: | 2133 | case QLCNIC_DEV_NEED_RESET: |
2110 | qlcnic_schedule_work(adapter, | 2134 | qlcnic_schedule_work(adapter, |
2111 | qlcnic_fwinit_work, FW_POLL_DELAY); | 2135 | qlcnic_fwinit_work, FW_POLL_DELAY); |