|
@@ -11951,6 +11951,51 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
|
|
|
+{
|
|
|
+ u32 offset, major, minor, build;
|
|
|
+
|
|
|
+ tp->fw_ver[0] = 's';
|
|
|
+ tp->fw_ver[1] = 'b';
|
|
|
+ tp->fw_ver[2] = '\0';
|
|
|
+
|
|
|
+ if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1)
|
|
|
+ return;
|
|
|
+
|
|
|
+ switch (val & TG3_EEPROM_SB_REVISION_MASK) {
|
|
|
+ case TG3_EEPROM_SB_REVISION_0:
|
|
|
+ offset = TG3_EEPROM_SB_F1R0_EDH_OFF;
|
|
|
+ break;
|
|
|
+ case TG3_EEPROM_SB_REVISION_2:
|
|
|
+ offset = TG3_EEPROM_SB_F1R2_EDH_OFF;
|
|
|
+ break;
|
|
|
+ case TG3_EEPROM_SB_REVISION_3:
|
|
|
+ offset = TG3_EEPROM_SB_F1R3_EDH_OFF;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tg3_nvram_read_swab(tp, offset, &val))
|
|
|
+ return;
|
|
|
+
|
|
|
+ build = (val & TG3_EEPROM_SB_EDH_BLD_MASK) >>
|
|
|
+ TG3_EEPROM_SB_EDH_BLD_SHFT;
|
|
|
+ major = (val & TG3_EEPROM_SB_EDH_MAJ_MASK) >>
|
|
|
+ TG3_EEPROM_SB_EDH_MAJ_SHFT;
|
|
|
+ minor = val & TG3_EEPROM_SB_EDH_MIN_MASK;
|
|
|
+
|
|
|
+ if (minor > 99 || build > 26)
|
|
|
+ return;
|
|
|
+
|
|
|
+ snprintf(&tp->fw_ver[2], 30, " v%d.%02d", major, minor);
|
|
|
+
|
|
|
+ if (build > 0) {
|
|
|
+ tp->fw_ver[8] = 'a' + build - 1;
|
|
|
+ tp->fw_ver[9] = '\0';
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void __devinit tg3_read_fw_ver(struct tg3 *tp)
|
|
|
{
|
|
|
u32 val, offset, start;
|
|
@@ -11960,8 +12005,12 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
|
|
|
if (tg3_nvram_read_swab(tp, 0, &val))
|
|
|
return;
|
|
|
|
|
|
- if (val != TG3_EEPROM_MAGIC)
|
|
|
+ if (val != TG3_EEPROM_MAGIC) {
|
|
|
+ if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
|
|
|
+ tg3_read_sb_ver(tp, val);
|
|
|
+
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
|
|
|
tg3_nvram_read_swab(tp, 0x4, &start))
|