diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_init.c')
| -rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 74 | 
1 files changed, 62 insertions, 12 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 7f999671c7b..e8993a76a08 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -964,6 +964,35 @@ netxen_need_fw_reset(struct netxen_adapter *adapter)  	return 0;  } +#define NETXEN_MIN_P3_FW_SUPP	NETXEN_VERSION_CODE(4, 0, 505) + +int +netxen_check_flash_fw_compatibility(struct netxen_adapter *adapter) +{ +	u32 flash_fw_ver, min_fw_ver; + +	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) +		return 0; + +	if (netxen_rom_fast_read(adapter, +			NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { +		dev_err(&adapter->pdev->dev, "Unable to read flash fw" +			"version\n"); +		return -EIO; +	} + +	flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); +	min_fw_ver = NETXEN_MIN_P3_FW_SUPP; +	if (flash_fw_ver >= min_fw_ver) +		return 0; + +	dev_info(&adapter->pdev->dev, "Flash fw[%d.%d.%d] is < min fw supported" +		"[4.0.505]. Please update firmware on flash\n", +		_major(flash_fw_ver), _minor(flash_fw_ver), +		_build(flash_fw_ver)); +	return -EINVAL; +} +  static char *fw_name[] = {  	NX_P2_MN_ROMIMAGE_NAME,  	NX_P3_CT_ROMIMAGE_NAME, @@ -1071,10 +1100,12 @@ static int  netxen_validate_firmware(struct netxen_adapter *adapter)  {  	__le32 val; -	u32 ver, min_ver, bios; +	__le32 flash_fw_ver; +	u32 file_fw_ver, min_ver, bios;  	struct pci_dev *pdev = adapter->pdev;  	const struct firmware *fw = adapter->fw;  	u8 fw_type = adapter->fw_type; +	u32 crbinit_fix_fw;  	if (fw_type == NX_UNIFIED_ROMIMAGE) {  		if (netxen_nic_validate_unified_romimage(adapter)) @@ -1091,16 +1122,18 @@ netxen_validate_firmware(struct netxen_adapter *adapter)  	val = nx_get_fw_version(adapter);  	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) -		min_ver = NETXEN_VERSION_CODE(4, 0, 216); +		min_ver = NETXEN_MIN_P3_FW_SUPP;  	else  		min_ver = NETXEN_VERSION_CODE(3, 4, 216); -	ver = NETXEN_DECODE_VERSION(val); +	file_fw_ver = NETXEN_DECODE_VERSION(val); -	if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { +	if ((_major(file_fw_ver) > _NETXEN_NIC_LINUX_MAJOR) || +	    (file_fw_ver < min_ver)) {  		dev_err(&pdev->dev,  				"%s: firmware version %d.%d.%d unsupported\n", -		fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); +		fw_name[fw_type], _major(file_fw_ver), _minor(file_fw_ver), +		 _build(file_fw_ver));  		return -EINVAL;  	} @@ -1112,17 +1145,34 @@ netxen_validate_firmware(struct netxen_adapter *adapter)  		return -EINVAL;  	} -	/* check if flashed firmware is newer */  	if (netxen_rom_fast_read(adapter, -			NX_FW_VERSION_OFFSET, (int *)&val)) +			NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { +		dev_err(&pdev->dev, "Unable to read flash fw version\n");  		return -EIO; -	val = NETXEN_DECODE_VERSION(val); -	if (val > ver) { -		dev_info(&pdev->dev, "%s: firmware is older than flash\n", -				fw_name[fw_type]); +	} +	flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); + +	/* New fw from file is not allowed, if fw on flash is < 4.0.554 */ +	crbinit_fix_fw = NETXEN_VERSION_CODE(4, 0, 554); +	if (file_fw_ver >= crbinit_fix_fw && flash_fw_ver < crbinit_fix_fw && +	    NX_IS_REVISION_P3(adapter->ahw.revision_id)) { +		dev_err(&pdev->dev, "Incompatibility detected between driver " +			"and firmware version on flash. This configuration " +			"is not recommended. Please update the firmware on " +			"flash immediately\n");  		return -EINVAL;  	} +	/* check if flashed firmware is newer only for no-mn and P2 case*/ +	if (!netxen_p3_has_mn(adapter) || +	    NX_IS_REVISION_P2(adapter->ahw.revision_id)) { +		if (flash_fw_ver > file_fw_ver) { +			dev_info(&pdev->dev, "%s: firmware is older than flash\n", +				fw_name[fw_type]); +			return -EINVAL; +		} +	} +  	NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);  	return 0;  } @@ -1279,7 +1329,7 @@ void netxen_free_dummy_dma(struct netxen_adapter *adapter)  			if (--i == 0)  				break; -		}; +		}  	}  	if (i) {  | 
