diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 26afcb5658d46b249762bb71ad4f1c65551d7d79..e1cdba752e09daa397c331b9c5708da267d8a7d9 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -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); diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 3cc047844af30d42b555efe35e2aca774c14d4eb..82410367564838aff7f2b5872c3c436a377a183c 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -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) diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 7bdcbc67342f7e964d4b410fbc395b9c7af100fb..b899bd51fcd87e2563fa4fd495b8c760fe5c0e6d 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -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; } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2919a2d12bf40c5327f4979059eed3ea1de78878..27539ddf94c4f9304c8310e652c1ee7f120f78af 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -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);