Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -819,7 +819,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
	if (err < 0)
		goto err_out;
	if (err == 0)
		goto ready;
		goto wait_init;

	if (first_boot != 0x55555555) {
		NXWR32(adapter, CRB_CMDPEG_STATE, 0);
@@ -862,9 +862,6 @@ netxen_start_firmware(struct netxen_adapter *adapter)
		| (_NETXEN_NIC_LINUX_SUBVERSION);
	NXWR32(adapter, CRB_DRIVER_VERSION, val);

ready:
	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);

wait_init:
	/* Handshake with the card before we register the devices. */
	err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
@@ -873,6 +870,8 @@ netxen_start_firmware(struct netxen_adapter *adapter)
		goto err_out;
	}

	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);

	nx_update_dma_mask(adapter);

	netxen_check_options(adapter);
@@ -1282,7 +1281,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

	err = netxen_start_firmware(adapter);
	if (err)
		goto err_out_iounmap;
		goto err_out_decr_ref;

	/*
	 * 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)

	netxen_free_dummy_dma(adapter);

err_out_decr_ref:
	nx_decr_dev_ref_cnt(adapter);

err_out_iounmap:
@@ -2189,14 +2189,13 @@ netxen_fwinit_work(struct work_struct *work)
					netxen_fwinit_work, 2 * FW_POLL_DELAY);
			return;
		}
		break;

	case NX_DEV_FAILED:
	default:
		nx_incr_dev_ref_cnt(adapter);
		break;
	}

	nx_incr_dev_ref_cnt(adapter);
	clear_bit(__NX_RESETTING, &adapter->state);
}

@@ -2218,18 +2217,23 @@ netxen_detach_work(struct work_struct *work)

	status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);

	ref_cnt = nx_decr_dev_ref_cnt(adapter);

	if (status & NX_RCODE_FATAL_ERROR)
		return;
		goto err_ret;

	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);

	adapter->fw_wait_cnt = 0;
	netxen_schedule_work(adapter, netxen_fwinit_work, delay);

	return;

err_ret:
	clear_bit(__NX_RESETTING, &adapter->state);
}

static int