Commit 8f9b3f69 authored by Amit Kumar Salecha's avatar Amit Kumar Salecha Committed by David S. Miller

netxen: fix failure cases for fw hang recovery

Handle few corner cases in firmware hang detection and recovery:

o Don't mark device state as READY, till handshake with
  firmware is done.
o During probe, if start_firmware fails, restore reference
  count.
o Don't increment refernce count, if start_firmware fails
  during firmware reset.
o Clear __NX_RESETTING bit, incase of fatal error or tempeature
  reaches critical limit so that pci remove() doesn't poll on
  this bit.
Signed-off-by: default avatarAmit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f58dbd73
...@@ -819,7 +819,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) ...@@ -819,7 +819,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
if (err < 0) if (err < 0)
goto err_out; goto err_out;
if (err == 0) if (err == 0)
goto ready; goto wait_init;
if (first_boot != 0x55555555) { if (first_boot != 0x55555555) {
NXWR32(adapter, CRB_CMDPEG_STATE, 0); NXWR32(adapter, CRB_CMDPEG_STATE, 0);
...@@ -862,9 +862,6 @@ netxen_start_firmware(struct netxen_adapter *adapter) ...@@ -862,9 +862,6 @@ netxen_start_firmware(struct netxen_adapter *adapter)
| (_NETXEN_NIC_LINUX_SUBVERSION); | (_NETXEN_NIC_LINUX_SUBVERSION);
NXWR32(adapter, CRB_DRIVER_VERSION, val); NXWR32(adapter, CRB_DRIVER_VERSION, val);
ready:
NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);
wait_init: wait_init:
/* Handshake with the card before we register the devices. */ /* Handshake with the card before we register the devices. */
err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
...@@ -873,6 +870,8 @@ netxen_start_firmware(struct netxen_adapter *adapter) ...@@ -873,6 +870,8 @@ netxen_start_firmware(struct netxen_adapter *adapter)
goto err_out; goto err_out;
} }
NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);
nx_update_dma_mask(adapter); nx_update_dma_mask(adapter);
netxen_check_options(adapter); netxen_check_options(adapter);
...@@ -1282,7 +1281,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1282,7 +1281,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = netxen_start_firmware(adapter); err = netxen_start_firmware(adapter);
if (err) if (err)
goto err_out_iounmap; goto err_out_decr_ref;
/* /*
* See if the firmware gave us a virtual-physical port mapping. * See if the firmware gave us a virtual-physical port mapping.
...@@ -1326,6 +1325,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1326,6 +1325,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netxen_free_dummy_dma(adapter); netxen_free_dummy_dma(adapter);
err_out_decr_ref:
nx_decr_dev_ref_cnt(adapter); nx_decr_dev_ref_cnt(adapter);
err_out_iounmap: err_out_iounmap:
...@@ -2189,14 +2189,13 @@ netxen_fwinit_work(struct work_struct *work) ...@@ -2189,14 +2189,13 @@ netxen_fwinit_work(struct work_struct *work)
netxen_fwinit_work, 2 * FW_POLL_DELAY); netxen_fwinit_work, 2 * FW_POLL_DELAY);
return; return;
} }
break;
case NX_DEV_FAILED: case NX_DEV_FAILED:
default: default:
nx_incr_dev_ref_cnt(adapter);
break; break;
} }
nx_incr_dev_ref_cnt(adapter);
clear_bit(__NX_RESETTING, &adapter->state); clear_bit(__NX_RESETTING, &adapter->state);
} }
...@@ -2218,18 +2217,23 @@ netxen_detach_work(struct work_struct *work) ...@@ -2218,18 +2217,23 @@ netxen_detach_work(struct work_struct *work)
status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
ref_cnt = nx_decr_dev_ref_cnt(adapter);
if (status & NX_RCODE_FATAL_ERROR) if (status & NX_RCODE_FATAL_ERROR)
return; goto err_ret;
if (adapter->temp == NX_TEMP_PANIC) if (adapter->temp == NX_TEMP_PANIC)
return; goto err_ret;
ref_cnt = nx_decr_dev_ref_cnt(adapter);
delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY);
adapter->fw_wait_cnt = 0; adapter->fw_wait_cnt = 0;
netxen_schedule_work(adapter, netxen_fwinit_work, delay); netxen_schedule_work(adapter, netxen_fwinit_work, delay);
return;
err_ret:
clear_bit(__NX_RESETTING, &adapter->state);
} }
static int static int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment