Commit 75f9936e authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller

tg3: Prepare FW version code for VPD versioning

The code that extracts the firmware version from the device's NVRAM
assumes the firmware version member is a clean slate.  The following
patch will add code to extract the firmware version from the VPD area
of NVRAM, so this assumption will no longer be true.  This patch adjusts
the versioning code to respect the VPD version if it exists.
Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Signed-off-by: default avatarBenjamin Li <benli@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5129c3a3
...@@ -12685,7 +12685,7 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset) ...@@ -12685,7 +12685,7 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
static void __devinit tg3_read_bc_ver(struct tg3 *tp) static void __devinit tg3_read_bc_ver(struct tg3 *tp)
{ {
u32 val, offset, start, ver_offset; u32 val, offset, start, ver_offset;
int i; int i, dst_off;
bool newver = false; bool newver = false;
if (tg3_nvram_read(tp, 0xc, &offset) || if (tg3_nvram_read(tp, 0xc, &offset) ||
...@@ -12705,8 +12705,11 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp) ...@@ -12705,8 +12705,11 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp)
newver = true; newver = true;
} }
dst_off = strlen(tp->fw_ver);
if (newver) { if (newver) {
if (tg3_nvram_read(tp, offset + 8, &ver_offset)) if (TG3_VER_SIZE - dst_off < 16 ||
tg3_nvram_read(tp, offset + 8, &ver_offset))
return; return;
offset = offset + ver_offset - start; offset = offset + ver_offset - start;
...@@ -12715,7 +12718,7 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp) ...@@ -12715,7 +12718,7 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp)
if (tg3_nvram_read_be32(tp, offset + i, &v)) if (tg3_nvram_read_be32(tp, offset + i, &v))
return; return;
memcpy(tp->fw_ver + i, &v, sizeof(v)); memcpy(tp->fw_ver + dst_off + i, &v, sizeof(v));
} }
} else { } else {
u32 major, minor; u32 major, minor;
...@@ -12726,7 +12729,8 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp) ...@@ -12726,7 +12729,8 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp)
major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >> major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >>
TG3_NVM_BCVER_MAJSFT; TG3_NVM_BCVER_MAJSFT;
minor = ver_offset & TG3_NVM_BCVER_MINMSK; minor = ver_offset & TG3_NVM_BCVER_MINMSK;
snprintf(&tp->fw_ver[0], 32, "v%d.%02d", major, minor); snprintf(&tp->fw_ver[dst_off], TG3_VER_SIZE - dst_off,
"v%d.%02d", major, minor);
} }
} }
...@@ -12750,9 +12754,7 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val) ...@@ -12750,9 +12754,7 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
{ {
u32 offset, major, minor, build; u32 offset, major, minor, build;
tp->fw_ver[0] = 's'; strncat(tp->fw_ver, "sb", TG3_VER_SIZE - strlen(tp->fw_ver) - 1);
tp->fw_ver[1] = 'b';
tp->fw_ver[2] = '\0';
if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1) if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1)
return; return;
...@@ -12789,11 +12791,14 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val) ...@@ -12789,11 +12791,14 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
if (minor > 99 || build > 26) if (minor > 99 || build > 26)
return; return;
snprintf(&tp->fw_ver[2], 30, " v%d.%02d", major, minor); offset = strlen(tp->fw_ver);
snprintf(&tp->fw_ver[offset], TG3_VER_SIZE - offset,
" v%d.%02d", major, minor);
if (build > 0) { if (build > 0) {
tp->fw_ver[8] = 'a' + build - 1; offset = strlen(tp->fw_ver);
tp->fw_ver[9] = '\0'; if (offset < TG3_VER_SIZE - 1)
tp->fw_ver[offset] = 'a' + build - 1;
} }
} }
...@@ -12880,12 +12885,13 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp) ...@@ -12880,12 +12885,13 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp)
static void __devinit tg3_read_fw_ver(struct tg3 *tp) static void __devinit tg3_read_fw_ver(struct tg3 *tp)
{ {
u32 val; u32 val;
bool vpd_vers = false;
if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) { if (tp->fw_ver[0] != 0)
tp->fw_ver[0] = 's'; vpd_vers = true;
tp->fw_ver[1] = 'b';
tp->fw_ver[2] = '\0';
if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
strcat(tp->fw_ver, "sb");
return; return;
} }
...@@ -12902,11 +12908,12 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) ...@@ -12902,11 +12908,12 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
return; return;
if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) || if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) || vpd_vers)
return; goto done;
tg3_read_mgmtfw_ver(tp); tg3_read_mgmtfw_ver(tp);
done:
tp->fw_ver[TG3_VER_SIZE - 1] = 0; tp->fw_ver[TG3_VER_SIZE - 1] = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment