diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 83 |
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 | ||
10824 | static 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 | |||
10824 | static void __devinit tg3_read_fw_ver(struct tg3 *tp) | 10837 | static 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 | ||
10864 | static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); | 10921 | static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); |