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

Commit 67c38fc6 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller
Browse files

netxen: avoid frequent firmware reset



Restrict firmware reset to following cases -

o chip rev is NX2031 (firmare doesn't support heartbit).
o firmware is dead.
o previous attempt to init firmware had failed.
o we have got newer file firmware.

This speeds up module load tremendously (by upto 8 sec),
also avoids downtime for NCSI (management) pass-thru
traffic.

Signed-off-by: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 98e31bb0
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -625,6 +625,7 @@ struct netxen_new_user_info {
#define NX_P2_MN_ROMIMAGE	0
#define NX_P3_CT_ROMIMAGE	1
#define NX_P3_MN_ROMIMAGE	2
#define NX_FLASH_ROMIMAGE	3

#define NETXEN_USER_START_OLD NETXEN_PXE_START	/* for backward compatibility */

@@ -1254,7 +1255,7 @@ struct netxen_adapter {
	u32 resv3;

	u8 has_link_events;
	u8 resv1;
	u8 fw_type;
	u16 tx_context_id;
	u16 mtu;
	u16 is_up;
@@ -1398,6 +1399,7 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter);
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
int netxen_load_firmware(struct netxen_adapter *adapter);
int netxen_need_fw_reset(struct netxen_adapter *adapter);
void netxen_request_firmware(struct netxen_adapter *adapter);
void netxen_release_firmware(struct netxen_adapter *adapter);
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
+1 −0
Original line number Diff line number Diff line
@@ -853,6 +853,7 @@ enum {
#define NX_PEG_TUNE_CAPABILITY		(NETXEN_CAM_RAM(0x02c))

#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL		(0x14)
#define NETXEN_PEG_ALIVE_COUNTER	(NETXEN_CAM_RAM(0xb0))

#define	ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
#define ISR_LEGACY_INT_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)
+78 −8
Original line number Diff line number Diff line
@@ -683,12 +683,85 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
	return 0;
}

int
netxen_need_fw_reset(struct netxen_adapter *adapter)
{
	u32 count, old_count;
	u32 val, version, major, minor, build;
	int i, timeout;
	u8 fw_type;

	/* NX2031 firmware doesn't support heartbit */
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
		return 1;

	/* last attempt had failed */
	if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
		return 1;

	old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);

	for (i = 0; i < 10; i++) {

		timeout = msleep_interruptible(200);
		if (timeout) {
			NXWR32(adapter, CRB_CMDPEG_STATE,
					PHAN_INITIALIZE_FAILED);
			return -EINTR;
		}

		count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
		if (count != old_count)
			break;
	}

	/* firmware is dead */
	if (count == old_count)
		return 1;

	/* check if we have got newer or different file firmware */
	if (adapter->fw) {

		const struct firmware *fw = adapter->fw;

		val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
		version = NETXEN_DECODE_VERSION(val);

		major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
		minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
		build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);

		if (version > NETXEN_VERSION_CODE(major, minor, build))
			return 1;

		if (version == NETXEN_VERSION_CODE(major, minor, build)) {

			val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
			fw_type = (val & 0x4) ?
				NX_P3_CT_ROMIMAGE : NX_P3_MN_ROMIMAGE;

			if (adapter->fw_type != fw_type)
				return 1;
		}
	}

	return 0;
}

static char *fw_name[] = {
	"nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash",
};

int
netxen_load_firmware(struct netxen_adapter *adapter)
{
	u64 *ptr64;
	u32 i, flashaddr, size;
	const struct firmware *fw = adapter->fw;
	struct pci_dev *pdev = adapter->pdev;

	dev_info(&pdev->dev, "loading firmware from %s\n",
			fw_name[adapter->fw_type]);

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
		NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1);
@@ -806,12 +879,10 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
	return 0;
}

static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };

void netxen_request_firmware(struct netxen_adapter *adapter)
{
	u32 capability, flashed_ver;
	int fw_type;
	u8 fw_type;
	struct pci_dev *pdev = adapter->pdev;
	int rc = 0;

@@ -838,6 +909,7 @@ void netxen_request_firmware(struct netxen_adapter *adapter)
		}
	}

	fw_type = NX_FLASH_ROMIMAGE;
	adapter->fw = NULL;
	goto done;

@@ -849,6 +921,7 @@ void netxen_request_firmware(struct netxen_adapter *adapter)
			goto request_mn;
		}

		fw_type = NX_FLASH_ROMIMAGE;
		adapter->fw = NULL;
		goto done;
	}
@@ -862,16 +935,13 @@ void netxen_request_firmware(struct netxen_adapter *adapter)
			goto request_mn;
		}

		fw_type = NX_FLASH_ROMIMAGE;
		adapter->fw = NULL;
		goto done;
	}

done:
	if (adapter->fw)
		dev_info(&pdev->dev, "loading firmware from file %s\n",
				fw_name[fw_type]);
	else
		dev_info(&pdev->dev, "loading firmware from flash\n");
	adapter->fw_type = fw_type;
}


+4 −0
Original line number Diff line number Diff line
@@ -718,6 +718,10 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
	if (request_fw)
		netxen_request_firmware(adapter);

	err = netxen_need_fw_reset(adapter);
	if (err <= 0)
		return err;

	if (first_boot != 0x55555555) {
		NXWR32(adapter, CRB_CMDPEG_STATE, 0);
		netxen_pinit_from_rom(adapter, 0);