aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/igc/igc_nvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/igc/igc_nvm.c')
-rw-r--r--sys/dev/igc/igc_nvm.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/sys/dev/igc/igc_nvm.c b/sys/dev/igc/igc_nvm.c
index d86e04ffa0dc..b476a5fdbeac 100644
--- a/sys/dev/igc/igc_nvm.c
+++ b/sys/dev/igc/igc_nvm.c
@@ -716,4 +716,85 @@ static void igc_reload_nvm_generic(struct igc_hw *hw)
IGC_WRITE_FLUSH(hw);
}
+/**
+ * igc_get_fw_version - Get firmware version information
+ * @hw: pointer to the HW structure
+ * @fw_vers: pointer to output version structure
+ *
+ * unsupported/not present features return 0 in version structure
+ **/
+void igc_get_fw_version(struct igc_hw *hw, struct igc_fw_version *fw_vers)
+{
+ u16 eeprom_verh, eeprom_verl, etrack_test, fw_version;
+ u8 q, hval, rem, result;
+ u16 comb_verh, comb_verl, comb_offset;
+
+ memset(fw_vers, 0, sizeof(struct igc_fw_version));
+ /*
+ * basic eeprom version numbers, bits used vary by part and by tool
+ * used to create the nvm images. Check which data format we have.
+ */
+ switch (hw->mac.type) {
+ case igc_i225:
+ hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
+ /* find combo image version */
+ hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
+ if (comb_offset && 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:
+ hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
+ return;
+ }
+ hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
+ fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
+ >> NVM_MAJOR_SHIFT;
+
+ /* check for old style version format in newer images*/
+ if ((fw_version & NVM_NEW_DEC_MASK) == 0x0) {
+ eeprom_verl = (fw_version & NVM_COMB_VER_MASK);
+ } else {
+ eeprom_verl = (fw_version & NVM_MINOR_MASK)
+ >> NVM_MINOR_SHIFT;
+ }
+ /* Convert minor value to hex before assigning to output struct
+ * Val to be converted will not be higher than 99, per tool output
+ */
+ q = eeprom_verl / NVM_HEX_CONV;
+ hval = q * NVM_HEX_TENS;
+ rem = eeprom_verl % NVM_HEX_CONV;
+ result = hval + rem;
+ fw_vers->eep_minor = result;
+
+ if ((etrack_test & NVM_MAJOR_MASK) == NVM_ETRACK_VALID) {
+ 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;
+ } else if ((etrack_test & NVM_ETRACK_VALID) == 0) {
+ hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh);
+ hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl);
+ fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) |
+ eeprom_verl;
+ }
+}