aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2010-04-05 06:19:24 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-06 06:58:01 -0400
commit75f9936e1150be739a9f6577a9d34de120ea35f1 (patch)
treeacadac3910f4e7f8ea3a2117f6b70c5b1edb1abf
parent5129c3a3faf8c5f4e6dd6ca581e1c4b06f8e837f (diff)
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: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Benjamin Li <benli@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tg3.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 973c8f51f4e8..4e7f3de7013f 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12685,7 +12685,7 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
12685static void __devinit tg3_read_bc_ver(struct tg3 *tp) 12685static void __devinit tg3_read_bc_ver(struct tg3 *tp)
12686{ 12686{
12687 u32 val, offset, start, ver_offset; 12687 u32 val, offset, start, ver_offset;
12688 int i; 12688 int i, dst_off;
12689 bool newver = false; 12689 bool newver = false;
12690 12690
12691 if (tg3_nvram_read(tp, 0xc, &offset) || 12691 if (tg3_nvram_read(tp, 0xc, &offset) ||
@@ -12705,8 +12705,11 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp)
12705 newver = true; 12705 newver = true;
12706 } 12706 }
12707 12707
12708 dst_off = strlen(tp->fw_ver);
12709
12708 if (newver) { 12710 if (newver) {
12709 if (tg3_nvram_read(tp, offset + 8, &ver_offset)) 12711 if (TG3_VER_SIZE - dst_off < 16 ||
12712 tg3_nvram_read(tp, offset + 8, &ver_offset))
12710 return; 12713 return;
12711 12714
12712 offset = offset + ver_offset - start; 12715 offset = offset + ver_offset - start;
@@ -12715,7 +12718,7 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp)
12715 if (tg3_nvram_read_be32(tp, offset + i, &v)) 12718 if (tg3_nvram_read_be32(tp, offset + i, &v))
12716 return; 12719 return;
12717 12720
12718 memcpy(tp->fw_ver + i, &v, sizeof(v)); 12721 memcpy(tp->fw_ver + dst_off + i, &v, sizeof(v));
12719 } 12722 }
12720 } else { 12723 } else {
12721 u32 major, minor; 12724 u32 major, minor;
@@ -12726,7 +12729,8 @@ static void __devinit tg3_read_bc_ver(struct tg3 *tp)
12726 major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >> 12729 major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >>
12727 TG3_NVM_BCVER_MAJSFT; 12730 TG3_NVM_BCVER_MAJSFT;
12728 minor = ver_offset & TG3_NVM_BCVER_MINMSK; 12731 minor = ver_offset & TG3_NVM_BCVER_MINMSK;
12729 snprintf(&tp->fw_ver[0], 32, "v%d.%02d", major, minor); 12732 snprintf(&tp->fw_ver[dst_off], TG3_VER_SIZE - dst_off,
12733 "v%d.%02d", major, minor);
12730 } 12734 }
12731} 12735}
12732 12736
@@ -12750,9 +12754,7 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
12750{ 12754{
12751 u32 offset, major, minor, build; 12755 u32 offset, major, minor, build;
12752 12756
12753 tp->fw_ver[0] = 's'; 12757 strncat(tp->fw_ver, "sb", TG3_VER_SIZE - strlen(tp->fw_ver) - 1);
12754 tp->fw_ver[1] = 'b';
12755 tp->fw_ver[2] = '\0';
12756 12758
12757 if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1) 12759 if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1)
12758 return; 12760 return;
@@ -12789,11 +12791,14 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
12789 if (minor > 99 || build > 26) 12791 if (minor > 99 || build > 26)
12790 return; 12792 return;
12791 12793
12792 snprintf(&tp->fw_ver[2], 30, " v%d.%02d", major, minor); 12794 offset = strlen(tp->fw_ver);
12795 snprintf(&tp->fw_ver[offset], TG3_VER_SIZE - offset,
12796 " v%d.%02d", major, minor);
12793 12797
12794 if (build > 0) { 12798 if (build > 0) {
12795 tp->fw_ver[8] = 'a' + build - 1; 12799 offset = strlen(tp->fw_ver);
12796 tp->fw_ver[9] = '\0'; 12800 if (offset < TG3_VER_SIZE - 1)
12801 tp->fw_ver[offset] = 'a' + build - 1;
12797 } 12802 }
12798} 12803}
12799 12804
@@ -12880,12 +12885,13 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp)
12880static void __devinit tg3_read_fw_ver(struct tg3 *tp) 12885static void __devinit tg3_read_fw_ver(struct tg3 *tp)
12881{ 12886{
12882 u32 val; 12887 u32 val;
12888 bool vpd_vers = false;
12883 12889
12884 if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) { 12890 if (tp->fw_ver[0] != 0)
12885 tp->fw_ver[0] = 's'; 12891 vpd_vers = true;
12886 tp->fw_ver[1] = 'b';
12887 tp->fw_ver[2] = '\0';
12888 12892
12893 if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
12894 strcat(tp->fw_ver, "sb");
12889 return; 12895 return;
12890 } 12896 }
12891 12897
@@ -12902,11 +12908,12 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
12902 return; 12908 return;
12903 12909
12904 if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) || 12910 if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
12905 (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) 12911 (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) || vpd_vers)
12906 return; 12912 goto done;
12907 12913
12908 tg3_read_mgmtfw_ver(tp); 12914 tg3_read_mgmtfw_ver(tp);
12909 12915
12916done:
12910 tp->fw_ver[TG3_VER_SIZE - 1] = 0; 12917 tp->fw_ver[TG3_VER_SIZE - 1] = 0;
12911} 12918}
12912 12919