aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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