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/netxen/netxen_nic_hw.c | |
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/netxen/netxen_nic_hw.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 195 |
1 files changed, 0 insertions, 195 deletions
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 | { |