aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 253d7613b921..98f465828110 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10821,9 +10821,24 @@ out_not_found:
10821 strcpy(tp->board_part_number, "none"); 10821 strcpy(tp->board_part_number, "none");
10822} 10822}
10823 10823
10824static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
10825{
10826 u32 val;
10827
10828 if (tg3_nvram_read_swab(tp, offset, &val) ||
10829 (val & 0xfc000000) != 0x0c000000 ||
10830 tg3_nvram_read_swab(tp, offset + 4, &val) ||
10831 val != 0)
10832 return 0;
10833
10834 return 1;
10835}
10836
10824static void __devinit tg3_read_fw_ver(struct tg3 *tp) 10837static void __devinit tg3_read_fw_ver(struct tg3 *tp)
10825{ 10838{
10826 u32 val, offset, start; 10839 u32 val, offset, start;
10840 u32 ver_offset;
10841 int i, bcnt;
10827 10842
10828 if (tg3_nvram_read_swab(tp, 0, &val)) 10843 if (tg3_nvram_read_swab(tp, 0, &val))
10829 return; 10844 return;
@@ -10836,29 +10851,71 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
10836 return; 10851 return;
10837 10852
10838 offset = tg3_nvram_logical_addr(tp, offset); 10853 offset = tg3_nvram_logical_addr(tp, offset);
10839 if (tg3_nvram_read_swab(tp, offset, &val)) 10854
10855 if (!tg3_fw_img_is_valid(tp, offset) ||
10856 tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
10840 return; 10857 return;
10841 10858
10842 if ((val & 0xfc000000) == 0x0c000000) { 10859 offset = offset + ver_offset - start;
10843 u32 ver_offset, addr; 10860 for (i = 0; i < 16; i += 4) {
10844 int i; 10861 if (tg3_nvram_read(tp, offset + i, &val))
10862 return;
10863
10864 val = le32_to_cpu(val);
10865 memcpy(tp->fw_ver + i, &val, 4);
10866 }
10845 10867
10846 if (tg3_nvram_read_swab(tp, offset + 4, &val) || 10868 if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
10847 tg3_nvram_read_swab(tp, offset + 8, &ver_offset)) 10869 (tp->tg3_flags & TG3_FLG3_ENABLE_APE))
10870 return;
10871
10872 for (offset = TG3_NVM_DIR_START;
10873 offset < TG3_NVM_DIR_END;
10874 offset += TG3_NVM_DIRENT_SIZE) {
10875 if (tg3_nvram_read_swab(tp, offset, &val))
10848 return; 10876 return;
10849 10877
10850 if (val != 0) 10878 if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
10879 break;
10880 }
10881
10882 if (offset == TG3_NVM_DIR_END)
10883 return;
10884
10885 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
10886 start = 0x08000000;
10887 else if (tg3_nvram_read_swab(tp, offset - 4, &start))
10888 return;
10889
10890 if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
10891 !tg3_fw_img_is_valid(tp, offset) ||
10892 tg3_nvram_read_swab(tp, offset + 8, &val))
10893 return;
10894
10895 offset += val - start;
10896
10897 bcnt = strlen(tp->fw_ver);
10898
10899 tp->fw_ver[bcnt++] = ',';
10900 tp->fw_ver[bcnt++] = ' ';
10901
10902 for (i = 0; i < 4; i++) {
10903 if (tg3_nvram_read(tp, offset, &val))
10851 return; 10904 return;
10852 10905
10853 addr = offset + ver_offset - start; 10906 val = le32_to_cpu(val);
10854 for (i = 0; i < 16; i += 4) { 10907 offset += sizeof(val);
10855 if (tg3_nvram_read(tp, addr + i, &val))
10856 return;
10857 10908
10858 val = cpu_to_le32(val); 10909 if (bcnt > TG3_VER_SIZE - sizeof(val)) {
10859 memcpy(tp->fw_ver + i, &val, 4); 10910 memcpy(&tp->fw_ver[bcnt], &val, TG3_VER_SIZE - bcnt);
10911 break;
10860 } 10912 }
10913
10914 memcpy(&tp->fw_ver[bcnt], &val, sizeof(val));
10915 bcnt += sizeof(val);
10861 } 10916 }
10917
10918 tp->fw_ver[TG3_VER_SIZE - 1] = 0;
10862} 10919}
10863 10920
10864static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); 10921static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);