diff options
| -rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_defines.h | 14 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_nvm.c | 70 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_nvm.h | 16 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 70 | 
4 files changed, 123 insertions, 47 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index de4b41ec3c4..e647cff9a5e 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h @@ -636,6 +636,7 @@  /* NVM Word Offsets */  #define NVM_COMPAT                 0x0003  #define NVM_ID_LED_SETTINGS        0x0004 /* SERDES output amplitude */ +#define NVM_VERSION                0x0005  #define NVM_INIT_CONTROL2_REG      0x000F  #define NVM_INIT_CONTROL3_PORT_B   0x0014  #define NVM_INIT_CONTROL3_PORT_A   0x0024 @@ -653,6 +654,19 @@  #define NVM_LED_1_CFG              0x001C  #define NVM_LED_0_2_CFG            0x001F +/* NVM version defines */ +#define NVM_ETRACK_WORD            0x0042 +#define NVM_COMB_VER_OFF           0x0083 +#define NVM_COMB_VER_PTR           0x003d +#define NVM_MAJOR_MASK             0xF000 +#define NVM_MINOR_MASK             0x0FF0 +#define NVM_BUILD_MASK             0x000F +#define NVM_COMB_VER_MASK          0x00FF +#define NVM_MAJOR_SHIFT                12 +#define NVM_MINOR_SHIFT                 4 +#define NVM_COMB_VER_SHFT               8 +#define NVM_VER_INVALID            0xFFFF +#define NVM_ETRACK_SHIFT               16  #define E1000_NVM_CFG_DONE_PORT_0  0x040000 /* MNG config cycle done */  #define E1000_NVM_CFG_DONE_PORT_1  0x080000 /* ...for second port */ diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c index aa5fcdf3f35..54ff53905ff 100644 --- a/drivers/net/ethernet/intel/igb/e1000_nvm.c +++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c @@ -710,3 +710,73 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)  out:  	return ret_val;  } + +/** + *  igb_get_fw_version - Get firmware version information + *  @hw: pointer to the HW structure + *  @fw_vers: pointer to output structure + * + *  unsupported MAC types will return all 0 version structure + **/ +void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers) +{ +	u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset; +	u16 fw_version; + +	memset(fw_vers, 0, sizeof(struct e1000_fw_version)); + +	switch (hw->mac.type) { +	case e1000_i211: +		return; +	case e1000_82575: +	case e1000_82576: +	case e1000_82580: +	case e1000_i350: +	case e1000_i210: +		break; +	default: +		return; +	} +	/* basic eeprom version numbers */ +	hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version); +	fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK) >> NVM_MAJOR_SHIFT; +	fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK); + +	/* etrack id */ +	hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl); +	hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh); +	fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) | eeprom_verl; + +	switch (hw->mac.type) { +	case e1000_i210: +	case e1000_i350: +		/* find combo image version */ +		hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset); +		if ((comb_offset != 0x0) && (comb_offset != NVM_VER_INVALID)) { + +			hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset +					 + 1), 1, &comb_verh); +			hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset), +					 1, &comb_verl); + +			/* get Option Rom version if it exists and is valid */ +			if ((comb_verh && comb_verl) && +			    ((comb_verh != NVM_VER_INVALID) && +			     (comb_verl != NVM_VER_INVALID))) { + +				fw_vers->or_valid = true; +				fw_vers->or_major = +					comb_verl >> NVM_COMB_VER_SHFT; +				fw_vers->or_build = +					((comb_verl << NVM_COMB_VER_SHFT) +					| (comb_verh >> NVM_COMB_VER_SHFT)); +				fw_vers->or_patch = +					comb_verh & NVM_COMB_VER_MASK; +			} +		} +		break; +	default: +		break; +	} +	return; +} diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.h b/drivers/net/ethernet/intel/igb/e1000_nvm.h index 825b0228cac..7012d458c6f 100644 --- a/drivers/net/ethernet/intel/igb/e1000_nvm.h +++ b/drivers/net/ethernet/intel/igb/e1000_nvm.h @@ -40,4 +40,20 @@ s32  igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);  s32  igb_validate_nvm_checksum(struct e1000_hw *hw);  s32  igb_update_nvm_checksum(struct e1000_hw *hw); +struct e1000_fw_version { +	u32 etrack_id; +	u16 eep_major; +	u16 eep_minor; + +	u8 invm_major; +	u8 invm_minor; +	u8 invm_img_type; + +	bool or_valid; +	u16 or_major; +	u16 or_build; +	u16 or_patch; +}; +void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers); +  #endif diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index b07d679b46f..df1e7907bba 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1785,58 +1785,34 @@ static const struct net_device_ops igb_netdev_ops = {  void igb_set_fw_version(struct igb_adapter *adapter)  {  	struct e1000_hw *hw = &adapter->hw; -	u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset; -	u16 major, build, patch, fw_version; -	u32 etrack_id; +	struct e1000_fw_version fw; -	hw->nvm.ops.read(hw, 5, 1, &fw_version); -	if (adapter->hw.mac.type != e1000_i211) { -		hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh); -		hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl); -		etrack_id = (eeprom_verh << IGB_ETRACK_SHIFT) | eeprom_verl; +	igb_get_fw_version(hw, &fw); -		/* combo image version needs to be found */ -		hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset); -		if ((comb_offset != 0x0) && -		    (comb_offset != IGB_NVM_VER_INVALID)) { -			hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset -					 + 1), 1, &comb_verh); -			hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset), -					 1, &comb_verl); +	switch (hw->mac.type) { +	case e1000_i211: +		snprintf(adapter->fw_version, sizeof(adapter->fw_version), +			 "%2d.%2d-%d", +			 fw.invm_major, fw.invm_minor, fw.invm_img_type); +		break; -			/* Only display Option Rom if it exists and is valid */ -			if ((comb_verh && comb_verl) && -			    ((comb_verh != IGB_NVM_VER_INVALID) && -			     (comb_verl != IGB_NVM_VER_INVALID))) { -				major = comb_verl >> IGB_COMB_VER_SHFT; -				build = (comb_verl << IGB_COMB_VER_SHFT) | -					(comb_verh >> IGB_COMB_VER_SHFT); -				patch = comb_verh & IGB_COMB_VER_MASK; -				snprintf(adapter->fw_version, -					 sizeof(adapter->fw_version), -					 "%d.%d%d, 0x%08x, %d.%d.%d", -					 (fw_version & IGB_MAJOR_MASK) >> -					 IGB_MAJOR_SHIFT, -					 (fw_version & IGB_MINOR_MASK) >> -					 IGB_MINOR_SHIFT, -					 (fw_version & IGB_BUILD_MASK), -					 etrack_id, major, build, patch); -				goto out; -			} +	default: +		/* if option is rom valid, display its version too */ +		if (fw.or_valid) { +			snprintf(adapter->fw_version, +				 sizeof(adapter->fw_version), +				 "%d.%d, 0x%08x, %d.%d.%d", +				 fw.eep_major, fw.eep_minor, fw.etrack_id, +				 fw.or_major, fw.or_build, fw.or_patch); +		/* no option rom */ +		} else { +			snprintf(adapter->fw_version, +				 sizeof(adapter->fw_version), +				 "%d.%d, 0x%08x", +				 fw.eep_major, fw.eep_minor, fw.etrack_id);  		} -		snprintf(adapter->fw_version, sizeof(adapter->fw_version), -			 "%d.%d%d, 0x%08x", -			 (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT, -			 (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT, -			 (fw_version & IGB_BUILD_MASK), etrack_id); -	} else { -		snprintf(adapter->fw_version, sizeof(adapter->fw_version), -			 "%d.%d%d", -			 (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT, -			 (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT, -			 (fw_version & IGB_BUILD_MASK)); +		break;  	} -out:  	return;  }  |