diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-09-05 17:43:08 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-07 01:53:06 -0700 |
commit | 6a581e93981e8838c85e407303186faf937830d3 (patch) | |
tree | 3e2f083971fc33d4a3e88e7cc37e346f775d7168 /drivers/net/netxen/netxen_nic_ctx.c | |
parent | db4cfd8a6149e778befb2ff6e6f91cdc6394cbe6 (diff) | |
download | lwn-6a581e93981e8838c85e407303186faf937830d3.tar.gz lwn-6a581e93981e8838c85e407303186faf937830d3.zip |
netxen: firmware hang detection
Implement state machine to detect firmware hung state
and recover. Since firmware will be shared by all PCI
functions that have different class drivers (NIC or
FCOE or iSCSI), explicit hardware based serialization
is required for initializing firmware.
o Used global scratchpad register to maintain device
reference count. Every probed pci function adds to
ref count.
o Implement timer (delayed work) for each pci func
that checks firmware heartbit every 5 sec and detaches
itself if firmware is dead. Last detaching function
reloads firmware. Other functions wait for firmware
init, and re-attach themselves.
Heartbit is not supported by NX2031 firmware.
Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_ctx.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 0f42ab998368..8ab5773e47d6 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -678,6 +678,9 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state)) + goto done; + err = nx_fw_cmd_create_rx_ctx(adapter); if (err) goto err_out_free; @@ -690,6 +693,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) goto err_out_free; } +done: return 0; err_out_free: @@ -708,6 +712,9 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) int port = adapter->portnum; if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state)) + goto done; + nx_fw_cmd_destroy_rx_ctx(adapter); nx_fw_cmd_destroy_tx_ctx(adapter); } else { @@ -720,6 +727,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) /* Allow dma queues to drain after context reset */ msleep(20); +done: recv_ctx = &adapter->recv_ctx; if (recv_ctx->hwctx != NULL) { |