diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-04-28 11:29:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-29 01:44:31 -0400 |
commit | f7185c71234434d48b96f9a0387737df1759a4af (patch) | |
tree | 1974fad5606305f11a750e66ec1e45f0f89a65ac /drivers/net | |
parent | 4ea528a151549df795c984649d75860ea40390bd (diff) |
netxen: fix firmware download
o hold the firmware in memory across suspend, since filesystem
may not be up after resuming.
o reset the chip after requesting firmware, to minimize downtime
for NC-SI.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 9 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 195 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 196 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 23 |
4 files changed, 216 insertions, 207 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 16f5e2267eb3..8dacfbb003e2 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/in.h> | 42 | #include <linux/in.h> |
43 | #include <linux/tcp.h> | 43 | #include <linux/tcp.h> |
44 | #include <linux/skbuff.h> | 44 | #include <linux/skbuff.h> |
45 | #include <linux/firmware.h> | ||
45 | 46 | ||
46 | #include <linux/ethtool.h> | 47 | #include <linux/ethtool.h> |
47 | #include <linux/mii.h> | 48 | #include <linux/mii.h> |
@@ -1255,8 +1256,6 @@ struct netxen_adapter { | |||
1255 | u32 flags; | 1256 | u32 flags; |
1256 | u32 irq; | 1257 | u32 irq; |
1257 | u32 temp; | 1258 | u32 temp; |
1258 | u32 fw_major; | ||
1259 | u32 fw_version; | ||
1260 | 1259 | ||
1261 | struct netxen_adapter_stats stats; | 1260 | struct netxen_adapter_stats stats; |
1262 | 1261 | ||
@@ -1295,6 +1294,10 @@ struct netxen_adapter { | |||
1295 | struct net_device_stats net_stats; | 1294 | struct net_device_stats net_stats; |
1296 | 1295 | ||
1297 | nx_nic_intr_coalesce_t coal; | 1296 | nx_nic_intr_coalesce_t coal; |
1297 | |||
1298 | u32 fw_major; | ||
1299 | u32 fw_version; | ||
1300 | const struct firmware *fw; | ||
1298 | }; | 1301 | }; |
1299 | 1302 | ||
1300 | /* | 1303 | /* |
@@ -1376,6 +1379,8 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter); | |||
1376 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); | 1379 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); |
1377 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); | 1380 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); |
1378 | int netxen_load_firmware(struct netxen_adapter *adapter); | 1381 | int netxen_load_firmware(struct netxen_adapter *adapter); |
1382 | void netxen_request_firmware(struct netxen_adapter *adapter); | ||
1383 | void netxen_release_firmware(struct netxen_adapter *adapter); | ||
1379 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1384 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); |
1380 | 1385 | ||
1381 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); | 1386 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index db53d9cfad07..9f5ced3eaf9d 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include "netxen_nic_hw.h" | 32 | #include "netxen_nic_hw.h" |
33 | #include "netxen_nic_phan_reg.h" | 33 | #include "netxen_nic_phan_reg.h" |
34 | 34 | ||
35 | #include <linux/firmware.h> | ||
36 | #include <net/ip.h> | 35 | #include <net/ip.h> |
37 | 36 | ||
38 | #define MASK(n) ((1ULL<<(n))-1) | 37 | #define MASK(n) ((1ULL<<(n))-1) |
@@ -1016,200 +1015,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off) | |||
1016 | (ulong)adapter->ahw.pci_base0; | 1015 | (ulong)adapter->ahw.pci_base0; |
1017 | } | 1016 | } |
1018 | 1017 | ||
1019 | static int | ||
1020 | netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname, | ||
1021 | const struct firmware *fw) | ||
1022 | { | ||
1023 | u64 *ptr64; | ||
1024 | u32 i, flashaddr, size; | ||
1025 | struct pci_dev *pdev = adapter->pdev; | ||
1026 | |||
1027 | if (fw) | ||
1028 | dev_info(&pdev->dev, "loading firmware from file %s\n", fwname); | ||
1029 | else | ||
1030 | dev_info(&pdev->dev, "loading firmware from flash\n"); | ||
1031 | |||
1032 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
1033 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); | ||
1034 | |||
1035 | if (fw) { | ||
1036 | __le64 data; | ||
1037 | |||
1038 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; | ||
1039 | |||
1040 | ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; | ||
1041 | flashaddr = NETXEN_BOOTLD_START; | ||
1042 | |||
1043 | for (i = 0; i < size; i++) { | ||
1044 | data = cpu_to_le64(ptr64[i]); | ||
1045 | adapter->pci_mem_write(adapter, flashaddr, &data, 8); | ||
1046 | flashaddr += 8; | ||
1047 | } | ||
1048 | |||
1049 | size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; | ||
1050 | size = (__force u32)cpu_to_le32(size) / 8; | ||
1051 | |||
1052 | ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; | ||
1053 | flashaddr = NETXEN_IMAGE_START; | ||
1054 | |||
1055 | for (i = 0; i < size; i++) { | ||
1056 | data = cpu_to_le64(ptr64[i]); | ||
1057 | |||
1058 | if (adapter->pci_mem_write(adapter, | ||
1059 | flashaddr, &data, 8)) | ||
1060 | return -EIO; | ||
1061 | |||
1062 | flashaddr += 8; | ||
1063 | } | ||
1064 | } else { | ||
1065 | u32 data; | ||
1066 | |||
1067 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4; | ||
1068 | flashaddr = NETXEN_BOOTLD_START; | ||
1069 | |||
1070 | for (i = 0; i < size; i++) { | ||
1071 | if (netxen_rom_fast_read(adapter, | ||
1072 | flashaddr, (int *)&data) != 0) | ||
1073 | return -EIO; | ||
1074 | |||
1075 | if (adapter->pci_mem_write(adapter, | ||
1076 | flashaddr, &data, 4)) | ||
1077 | return -EIO; | ||
1078 | |||
1079 | flashaddr += 4; | ||
1080 | } | ||
1081 | } | ||
1082 | msleep(1); | ||
1083 | |||
1084 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
1085 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); | ||
1086 | else { | ||
1087 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); | ||
1088 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0); | ||
1089 | } | ||
1090 | |||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | static int | ||
1095 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname, | ||
1096 | const struct firmware *fw) | ||
1097 | { | ||
1098 | __le32 val; | ||
1099 | u32 major, minor, build, ver, min_ver, bios; | ||
1100 | struct pci_dev *pdev = adapter->pdev; | ||
1101 | |||
1102 | if (fw->size < NX_FW_MIN_SIZE) | ||
1103 | return -EINVAL; | ||
1104 | |||
1105 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | ||
1106 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | ||
1107 | return -EINVAL; | ||
1108 | |||
1109 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
1110 | major = (__force u32)val & 0xff; | ||
1111 | minor = ((__force u32)val >> 8) & 0xff; | ||
1112 | build = (__force u32)val >> 16; | ||
1113 | |||
1114 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
1115 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); | ||
1116 | else | ||
1117 | min_ver = NETXEN_VERSION_CODE(3, 4, 216); | ||
1118 | |||
1119 | ver = NETXEN_VERSION_CODE(major, minor, build); | ||
1120 | |||
1121 | if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { | ||
1122 | dev_err(&pdev->dev, | ||
1123 | "%s: firmware version %d.%d.%d unsupported\n", | ||
1124 | fwname, major, minor, build); | ||
1125 | return -EINVAL; | ||
1126 | } | ||
1127 | |||
1128 | val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | ||
1129 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); | ||
1130 | if ((__force u32)val != bios) { | ||
1131 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", | ||
1132 | fwname); | ||
1133 | return -EINVAL; | ||
1134 | } | ||
1135 | |||
1136 | /* check if flashed firmware is newer */ | ||
1137 | if (netxen_rom_fast_read(adapter, | ||
1138 | NX_FW_VERSION_OFFSET, (int *)&val)) | ||
1139 | return -EIO; | ||
1140 | major = (__force u32)val & 0xff; | ||
1141 | minor = ((__force u32)val >> 8) & 0xff; | ||
1142 | build = (__force u32)val >> 16; | ||
1143 | if (NETXEN_VERSION_CODE(major, minor, build) > ver) | ||
1144 | return -EINVAL; | ||
1145 | |||
1146 | NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | ||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" }; | ||
1151 | |||
1152 | int netxen_load_firmware(struct netxen_adapter *adapter) | ||
1153 | { | ||
1154 | u32 capability, flashed_ver; | ||
1155 | const struct firmware *fw; | ||
1156 | int fw_type; | ||
1157 | struct pci_dev *pdev = adapter->pdev; | ||
1158 | int rc = 0; | ||
1159 | |||
1160 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
1161 | fw_type = NX_P2_MN_ROMIMAGE; | ||
1162 | goto request_fw; | ||
1163 | } else { | ||
1164 | fw_type = NX_P3_CT_ROMIMAGE; | ||
1165 | goto request_fw; | ||
1166 | } | ||
1167 | |||
1168 | request_mn: | ||
1169 | capability = 0; | ||
1170 | |||
1171 | netxen_rom_fast_read(adapter, | ||
1172 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); | ||
1173 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { | ||
1174 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); | ||
1175 | if (capability & NX_PEG_TUNE_MN_PRESENT) { | ||
1176 | fw_type = NX_P3_MN_ROMIMAGE; | ||
1177 | goto request_fw; | ||
1178 | } | ||
1179 | } | ||
1180 | |||
1181 | request_fw: | ||
1182 | rc = request_firmware(&fw, fw_name[fw_type], &pdev->dev); | ||
1183 | if (rc != 0) { | ||
1184 | if (fw_type == NX_P3_CT_ROMIMAGE) { | ||
1185 | msleep(1); | ||
1186 | goto request_mn; | ||
1187 | } | ||
1188 | |||
1189 | fw = NULL; | ||
1190 | goto load_fw; | ||
1191 | } | ||
1192 | |||
1193 | rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw); | ||
1194 | if (rc != 0) { | ||
1195 | release_firmware(fw); | ||
1196 | |||
1197 | if (fw_type == NX_P3_CT_ROMIMAGE) { | ||
1198 | msleep(1); | ||
1199 | goto request_mn; | ||
1200 | } | ||
1201 | |||
1202 | fw = NULL; | ||
1203 | } | ||
1204 | |||
1205 | load_fw: | ||
1206 | rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw); | ||
1207 | |||
1208 | if (fw) | ||
1209 | release_firmware(fw); | ||
1210 | return rc; | ||
1211 | } | ||
1212 | |||
1213 | int | 1018 | int |
1214 | netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) | 1019 | netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) |
1215 | { | 1020 | { |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 363ef701e71e..d18216779a09 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -683,6 +683,202 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
683 | return 0; | 683 | return 0; |
684 | } | 684 | } |
685 | 685 | ||
686 | int | ||
687 | netxen_load_firmware(struct netxen_adapter *adapter) | ||
688 | { | ||
689 | u64 *ptr64; | ||
690 | u32 i, flashaddr, size; | ||
691 | const struct firmware *fw = adapter->fw; | ||
692 | |||
693 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
694 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); | ||
695 | |||
696 | if (fw) { | ||
697 | __le64 data; | ||
698 | |||
699 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; | ||
700 | |||
701 | ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; | ||
702 | flashaddr = NETXEN_BOOTLD_START; | ||
703 | |||
704 | for (i = 0; i < size; i++) { | ||
705 | data = cpu_to_le64(ptr64[i]); | ||
706 | adapter->pci_mem_write(adapter, flashaddr, &data, 8); | ||
707 | flashaddr += 8; | ||
708 | } | ||
709 | |||
710 | size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; | ||
711 | size = (__force u32)cpu_to_le32(size) / 8; | ||
712 | |||
713 | ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; | ||
714 | flashaddr = NETXEN_IMAGE_START; | ||
715 | |||
716 | for (i = 0; i < size; i++) { | ||
717 | data = cpu_to_le64(ptr64[i]); | ||
718 | |||
719 | if (adapter->pci_mem_write(adapter, | ||
720 | flashaddr, &data, 8)) | ||
721 | return -EIO; | ||
722 | |||
723 | flashaddr += 8; | ||
724 | } | ||
725 | } else { | ||
726 | u32 data; | ||
727 | |||
728 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4; | ||
729 | flashaddr = NETXEN_BOOTLD_START; | ||
730 | |||
731 | for (i = 0; i < size; i++) { | ||
732 | if (netxen_rom_fast_read(adapter, | ||
733 | flashaddr, (int *)&data) != 0) | ||
734 | return -EIO; | ||
735 | |||
736 | if (adapter->pci_mem_write(adapter, | ||
737 | flashaddr, &data, 4)) | ||
738 | return -EIO; | ||
739 | |||
740 | flashaddr += 4; | ||
741 | } | ||
742 | } | ||
743 | msleep(1); | ||
744 | |||
745 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
746 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); | ||
747 | else { | ||
748 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); | ||
749 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0); | ||
750 | } | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static int | ||
756 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | ||
757 | { | ||
758 | __le32 val; | ||
759 | u32 major, minor, build, ver, min_ver, bios; | ||
760 | struct pci_dev *pdev = adapter->pdev; | ||
761 | const struct firmware *fw = adapter->fw; | ||
762 | |||
763 | if (fw->size < NX_FW_MIN_SIZE) | ||
764 | return -EINVAL; | ||
765 | |||
766 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | ||
767 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | ||
768 | return -EINVAL; | ||
769 | |||
770 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
771 | major = (__force u32)val & 0xff; | ||
772 | minor = ((__force u32)val >> 8) & 0xff; | ||
773 | build = (__force u32)val >> 16; | ||
774 | |||
775 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
776 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); | ||
777 | else | ||
778 | min_ver = NETXEN_VERSION_CODE(3, 4, 216); | ||
779 | |||
780 | ver = NETXEN_VERSION_CODE(major, minor, build); | ||
781 | |||
782 | if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { | ||
783 | dev_err(&pdev->dev, | ||
784 | "%s: firmware version %d.%d.%d unsupported\n", | ||
785 | fwname, major, minor, build); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | |||
789 | val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | ||
790 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); | ||
791 | if ((__force u32)val != bios) { | ||
792 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", | ||
793 | fwname); | ||
794 | return -EINVAL; | ||
795 | } | ||
796 | |||
797 | /* check if flashed firmware is newer */ | ||
798 | if (netxen_rom_fast_read(adapter, | ||
799 | NX_FW_VERSION_OFFSET, (int *)&val)) | ||
800 | return -EIO; | ||
801 | major = (__force u32)val & 0xff; | ||
802 | minor = ((__force u32)val >> 8) & 0xff; | ||
803 | build = (__force u32)val >> 16; | ||
804 | if (NETXEN_VERSION_CODE(major, minor, build) > ver) | ||
805 | return -EINVAL; | ||
806 | |||
807 | NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | ||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" }; | ||
812 | |||
813 | void netxen_request_firmware(struct netxen_adapter *adapter) | ||
814 | { | ||
815 | u32 capability, flashed_ver; | ||
816 | int fw_type; | ||
817 | struct pci_dev *pdev = adapter->pdev; | ||
818 | int rc = 0; | ||
819 | |||
820 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
821 | fw_type = NX_P2_MN_ROMIMAGE; | ||
822 | goto request_fw; | ||
823 | } else { | ||
824 | fw_type = NX_P3_CT_ROMIMAGE; | ||
825 | goto request_fw; | ||
826 | } | ||
827 | |||
828 | request_mn: | ||
829 | capability = 0; | ||
830 | |||
831 | netxen_rom_fast_read(adapter, | ||
832 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); | ||
833 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { | ||
834 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); | ||
835 | if (capability & NX_PEG_TUNE_MN_PRESENT) { | ||
836 | fw_type = NX_P3_MN_ROMIMAGE; | ||
837 | goto request_fw; | ||
838 | } | ||
839 | } | ||
840 | |||
841 | request_fw: | ||
842 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); | ||
843 | if (rc != 0) { | ||
844 | if (fw_type == NX_P3_CT_ROMIMAGE) { | ||
845 | msleep(1); | ||
846 | goto request_mn; | ||
847 | } | ||
848 | |||
849 | adapter->fw = NULL; | ||
850 | goto done; | ||
851 | } | ||
852 | |||
853 | rc = netxen_validate_firmware(adapter, fw_name[fw_type]); | ||
854 | if (rc != 0) { | ||
855 | release_firmware(adapter->fw); | ||
856 | |||
857 | if (fw_type == NX_P3_CT_ROMIMAGE) { | ||
858 | msleep(1); | ||
859 | goto request_mn; | ||
860 | } | ||
861 | |||
862 | adapter->fw = NULL; | ||
863 | goto done; | ||
864 | } | ||
865 | |||
866 | done: | ||
867 | if (adapter->fw) | ||
868 | dev_info(&pdev->dev, "loading firmware from file %s\n", | ||
869 | fw_name[fw_type]); | ||
870 | else | ||
871 | dev_info(&pdev->dev, "loading firmware from flash\n"); | ||
872 | } | ||
873 | |||
874 | |||
875 | void | ||
876 | netxen_release_firmware(struct netxen_adapter *adapter) | ||
877 | { | ||
878 | if (adapter->fw) | ||
879 | release_firmware(adapter->fw); | ||
880 | } | ||
881 | |||
686 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) | 882 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) |
687 | { | 883 | { |
688 | uint64_t addr; | 884 | uint64_t addr; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 07959fe06f22..5d79c19a6ec0 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -654,19 +654,17 @@ err_out: | |||
654 | } | 654 | } |
655 | 655 | ||
656 | static int | 656 | static int |
657 | netxen_start_firmware(struct netxen_adapter *adapter) | 657 | netxen_start_firmware(struct netxen_adapter *adapter, int request_fw) |
658 | { | 658 | { |
659 | int val, err, first_boot; | 659 | int val, err, first_boot; |
660 | struct pci_dev *pdev = adapter->pdev; | 660 | struct pci_dev *pdev = adapter->pdev; |
661 | 661 | ||
662 | int first_driver = 0; | 662 | int first_driver = 0; |
663 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | 663 | |
664 | if (adapter->ahw.pci_func == 0) | 664 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
665 | first_driver = 1; | 665 | first_driver = (adapter->portnum == 0); |
666 | } else { | 666 | else |
667 | if (adapter->portnum == 0) | 667 | first_driver = (adapter->ahw.pci_func == 0); |
668 | first_driver = 1; | ||
669 | } | ||
670 | 668 | ||
671 | if (!first_driver) | 669 | if (!first_driver) |
672 | return 0; | 670 | return 0; |
@@ -679,6 +677,9 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
679 | return err; | 677 | return err; |
680 | } | 678 | } |
681 | 679 | ||
680 | if (request_fw) | ||
681 | netxen_request_firmware(adapter); | ||
682 | |||
682 | if (first_boot != 0x55555555) { | 683 | if (first_boot != 0x55555555) { |
683 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); | 684 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); |
684 | netxen_pinit_from_rom(adapter, 0); | 685 | netxen_pinit_from_rom(adapter, 0); |
@@ -1014,7 +1015,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1014 | break; | 1015 | break; |
1015 | } | 1016 | } |
1016 | 1017 | ||
1017 | err = netxen_start_firmware(adapter); | 1018 | err = netxen_start_firmware(adapter, 1); |
1018 | if (err) | 1019 | if (err) |
1019 | goto err_out_iounmap; | 1020 | goto err_out_iounmap; |
1020 | 1021 | ||
@@ -1125,6 +1126,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
1125 | 1126 | ||
1126 | netxen_cleanup_pci_map(adapter); | 1127 | netxen_cleanup_pci_map(adapter); |
1127 | 1128 | ||
1129 | netxen_release_firmware(adapter); | ||
1130 | |||
1128 | pci_release_regions(pdev); | 1131 | pci_release_regions(pdev); |
1129 | pci_disable_device(pdev); | 1132 | pci_disable_device(pdev); |
1130 | pci_set_drvdata(pdev, NULL); | 1133 | pci_set_drvdata(pdev, NULL); |
@@ -1176,7 +1179,7 @@ netxen_nic_resume(struct pci_dev *pdev) | |||
1176 | 1179 | ||
1177 | adapter->curr_window = 255; | 1180 | adapter->curr_window = 255; |
1178 | 1181 | ||
1179 | err = netxen_start_firmware(adapter); | 1182 | err = netxen_start_firmware(adapter, 0); |
1180 | if (err) { | 1183 | if (err) { |
1181 | dev_err(&pdev->dev, "failed to start firmware\n"); | 1184 | dev_err(&pdev->dev, "failed to start firmware\n"); |
1182 | return err; | 1185 | return err; |