diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2010-08-26 14:02:52 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-26 17:13:19 -0700 |
commit | 0866d96da02cccc3ca837d0d71687aba962b3f2f (patch) | |
tree | fdf48e0ccd0c92819c2d96d3e18562c4092bb471 /drivers/net/qlcnic/qlcnic_init.c | |
parent | 8cfdce080722101a7fd2a1eff9763ca4008ec626 (diff) | |
download | linux-0866d96da02cccc3ca837d0d71687aba962b3f2f.tar.bz2 |
qlcnic: Fix driver load issue in FW hang
If there is a FW hang when the driver loads, it can not determine the FW operational
mode. Fix it by checking the FW state first before issuing any FW commands to
determine its capabilities and thereby detecting driver operational mode.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_init.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_init.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index df91b754bb70..eb8256bec516 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -547,7 +547,7 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) int qlcnic_check_fw_status(struct qlcnic_adapter *adapter) { - u32 heartbit, ret = -EIO; + u32 heartbit, cmdpeg_state, ret = -EIO; int retries = QLCNIC_HEARTBEAT_RETRY_COUNT; adapter->heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); @@ -555,10 +555,16 @@ qlcnic_check_fw_status(struct qlcnic_adapter *adapter) msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); if (heartbit != adapter->heartbit) { - /* Complete firmware handshake */ - QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); - ret = QLCNIC_RCODE_SUCCESS; - break; + cmdpeg_state = QLCRD32(adapter, CRB_CMDPEG_STATE); + /* Ensure peg states are initialized */ + if (cmdpeg_state == PHAN_INITIALIZE_COMPLETE || + cmdpeg_state == PHAN_INITIALIZE_ACK) { + /* Complete firmware handshake */ + QLCWR32(adapter, CRB_CMDPEG_STATE, + PHAN_INITIALIZE_ACK); + ret = QLCNIC_RCODE_SUCCESS; + break; + } } } while (--retries); |