aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_hw.c
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-02-24 19:38:22 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-24 19:38:22 -0500
commitba599d4f0d2071abc049cb6345eab510a8a3643e (patch)
treee42bac74b45238e373d8d4b4de779ce83c1fd833 /drivers/net/netxen/netxen_nic_hw.c
parent32344a394029baeca5bcc9fa839694b23a82cc64 (diff)
netxen: firmware download support
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.c175
1 files changed, 164 insertions, 11 deletions
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index b2f67b98c93..aef39e7a5e2 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -35,7 +35,7 @@
35#include "netxen_nic_hw.h" 35#include "netxen_nic_hw.h"
36#include "netxen_nic_phan_reg.h" 36#include "netxen_nic_phan_reg.h"
37 37
38 38#include <linux/firmware.h>
39#include <net/ip.h> 39#include <net/ip.h>
40 40
41#define MASK(n) ((1ULL<<(n))-1) 41#define MASK(n) ((1ULL<<(n))-1)
@@ -951,24 +951,69 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
951 (ulong)adapter->ahw.pci_base0; 951 (ulong)adapter->ahw.pci_base0;
952} 952}
953 953
954int netxen_load_firmware(struct netxen_adapter *adapter) 954static int
955netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
956 const struct firmware *fw)
955{ 957{
956 int i; 958 u64 *ptr64;
957 u32 data, size = 0; 959 u32 i, flashaddr, size;
958 u32 flashaddr = NETXEN_BOOTLD_START; 960 struct pci_dev *pdev = adapter->pdev;
959 961
960 size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4; 962 if (fw)
963 dev_info(&pdev->dev, "loading firmware from file %s\n", fwname);
964 else
965 dev_info(&pdev->dev, "loading firmware from flash\n");
961 966
962 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 967 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
963 adapter->pci_write_normalize(adapter, 968 adapter->pci_write_normalize(adapter,
964 NETXEN_ROMUSB_GLB_CAS_RST, 1); 969 NETXEN_ROMUSB_GLB_CAS_RST, 1);
965 970
966 for (i = 0; i < size; i++) { 971 if (fw) {
967 if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) 972 __le64 data;
968 return -EIO; 973
974 size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
975
976 ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
977 flashaddr = NETXEN_BOOTLD_START;
978
979 for (i = 0; i < size; i++) {
980 data = cpu_to_le64(ptr64[i]);
981 adapter->pci_mem_write(adapter, flashaddr, &data, 8);
982 flashaddr += 8;
983 }
984
985 size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
986 size = (__force u32)cpu_to_le32(size) / 8;
987
988 ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
989 flashaddr = NETXEN_IMAGE_START;
990
991 for (i = 0; i < size; i++) {
992 data = cpu_to_le64(ptr64[i]);
993
994 if (adapter->pci_mem_write(adapter,
995 flashaddr, &data, 8))
996 return -EIO;
997
998 flashaddr += 8;
999 }
1000 } else {
1001 u32 data;
1002
1003 size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
1004 flashaddr = NETXEN_BOOTLD_START;
969 1005
970 adapter->pci_mem_write(adapter, flashaddr, &data, 4); 1006 for (i = 0; i < size; i++) {
971 flashaddr += 4; 1007 if (netxen_rom_fast_read(adapter,
1008 flashaddr, (int *)&data) != 0)
1009 return -EIO;
1010
1011 if (adapter->pci_mem_write(adapter,
1012 flashaddr, &data, 4))
1013 return -EIO;
1014
1015 flashaddr += 4;
1016 }
972 } 1017 }
973 msleep(1); 1018 msleep(1);
974 1019
@@ -985,6 +1030,114 @@ int netxen_load_firmware(struct netxen_adapter *adapter)
985 return 0; 1030 return 0;
986} 1031}
987 1032
1033static int
1034netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
1035 const struct firmware *fw)
1036{
1037 __le32 val;
1038 u32 major, minor, build, ver, min_ver, bios;
1039 struct pci_dev *pdev = adapter->pdev;
1040
1041 if (fw->size < NX_FW_MIN_SIZE)
1042 return -EINVAL;
1043
1044 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
1045 if ((__force u32)val != NETXEN_BDINFO_MAGIC)
1046 return -EINVAL;
1047
1048 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
1049 major = (__force u32)val & 0xff;
1050 minor = ((__force u32)val >> 8) & 0xff;
1051 build = (__force u32)val >> 16;
1052
1053 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1054 min_ver = NETXEN_VERSION_CODE(4, 0, 216);
1055 else
1056 min_ver = NETXEN_VERSION_CODE(3, 4, 216);
1057
1058 ver = NETXEN_VERSION_CODE(major, minor, build);
1059
1060 if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
1061 dev_err(&pdev->dev,
1062 "%s: firmware version %d.%d.%d unsupported\n",
1063 fwname, major, minor, build);
1064 return -EINVAL;
1065 }
1066
1067 val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
1068 netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
1069 if ((__force u32)val != bios) {
1070 dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
1071 fwname);
1072 return -EINVAL;
1073 }
1074
1075 netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc),
1076 NETXEN_BDINFO_MAGIC);
1077 return 0;
1078}
1079
1080int netxen_load_firmware(struct netxen_adapter *adapter)
1081{
1082 u32 capability, flashed_ver;
1083 const struct firmware *fw;
1084 char *fw_name = NULL;
1085 struct pci_dev *pdev = adapter->pdev;
1086 int rc = 0;
1087
1088 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1089 fw_name = NX_P2_MN_ROMIMAGE;
1090 goto request_fw;
1091 }
1092
1093 capability = 0;
1094
1095 netxen_rom_fast_read(adapter,
1096 NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
1097 if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
1098 adapter->hw_read_wx(adapter,
1099 NX_PEG_TUNE_CAPABILITY, &capability, 4);
1100 if (capability & NX_PEG_TUNE_MN_PRESENT) {
1101 fw_name = NX_P3_MN_ROMIMAGE;
1102 goto request_fw;
1103 }
1104 }
1105
1106request_ct:
1107 fw_name = NX_P3_CT_ROMIMAGE;
1108
1109request_fw:
1110 rc = request_firmware(&fw, fw_name, &pdev->dev);
1111 if (rc != 0) {
1112 if (fw_name == NX_P3_MN_ROMIMAGE) {
1113 msleep(1);
1114 goto request_ct;
1115 }
1116
1117 fw = NULL;
1118 goto load_fw;
1119 }
1120
1121 rc = netxen_validate_firmware(adapter, fw_name, fw);
1122 if (rc != 0) {
1123 release_firmware(fw);
1124
1125 if (fw_name == NX_P3_MN_ROMIMAGE) {
1126 msleep(1);
1127 goto request_ct;
1128 }
1129
1130 fw = NULL;
1131 }
1132
1133load_fw:
1134 rc = netxen_do_load_firmware(adapter, fw_name, fw);
1135
1136 if (fw)
1137 release_firmware(fw);
1138 return rc;
1139}
1140
988int 1141int
989netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, 1142netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
990 ulong off, void *data, int len) 1143 ulong off, void *data, int len)