summaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_init.c
diff options
context:
space:
mode:
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>2010-08-26 14:02:52 +0000
committerDavid S. Miller <davem@davemloft.net>2010-08-26 17:13:19 -0700
commit0866d96da02cccc3ca837d0d71687aba962b3f2f (patch)
treefdf48e0ccd0c92819c2d96d3e18562c4092bb471 /drivers/net/qlcnic/qlcnic_init.c
parent8cfdce080722101a7fd2a1eff9763ca4008ec626 (diff)
downloadlinux-0866d96da02cccc3ca837d0d71687aba962b3f2f.tar.gz
linux-0866d96da02cccc3ca837d0d71687aba962b3f2f.tar.bz2
linux-0866d96da02cccc3ca837d0d71687aba962b3f2f.zip
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.c16
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);