aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-04-28 11:29:11 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-29 01:44:31 -0400
commitf7185c71234434d48b96f9a0387737df1759a4af (patch)
tree1974fad5606305f11a750e66ec1e45f0f89a65ac /drivers/net
parent4ea528a151549df795c984649d75860ea40390bd (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.h9
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c195
-rw-r--r--drivers/net/netxen/netxen_nic_init.c196
-rw-r--r--drivers/net/netxen/netxen_nic_main.c23
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);
1376int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); 1379int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
1377int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); 1380int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
1378int netxen_load_firmware(struct netxen_adapter *adapter); 1381int netxen_load_firmware(struct netxen_adapter *adapter);
1382void netxen_request_firmware(struct netxen_adapter *adapter);
1383void netxen_release_firmware(struct netxen_adapter *adapter);
1379int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); 1384int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
1380 1385
1381int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); 1386int 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
1019static int
1020netxen_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
1094static int
1095netxen_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
1150static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
1151
1152int 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
1168request_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
1181request_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
1205load_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
1213int 1018int
1214netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) 1019netxen_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
686int
687netxen_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
755static int
756netxen_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
811static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
812
813void 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
828request_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
841request_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
866done:
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
875void
876netxen_release_firmware(struct netxen_adapter *adapter)
877{
878 if (adapter->fw)
879 release_firmware(adapter->fw);
880}
881
686int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) 882int 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
656static int 656static int
657netxen_start_firmware(struct netxen_adapter *adapter) 657netxen_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;