aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/net/netxen/netxen_nic.h9
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h3
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c175
-rw-r--r--drivers/net/netxen/netxen_nic_main.c125
4 files changed, 238 insertions, 74 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index f4dd9acb687..b7261823189 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -712,6 +712,15 @@ typedef enum {
712 NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */ 712 NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */
713} netxen_flash_map_t; 713} netxen_flash_map_t;
714 714
715#define NX_FW_VERSION_OFFSET (NETXEN_USER_START+0x408)
716#define NX_FW_SIZE_OFFSET (NETXEN_USER_START+0x40c)
717#define NX_BIOS_VERSION_OFFSET (NETXEN_USER_START+0x83c)
718#define NX_FW_MAGIC_OFFSET (NETXEN_BRDCFG_START+0x128)
719#define NX_FW_MIN_SIZE (0x3fffff)
720#define NX_P2_MN_ROMIMAGE "nxromimg.bin"
721#define NX_P3_CT_ROMIMAGE "nx3fwct.bin"
722#define NX_P3_MN_ROMIMAGE "nx3fwmn.bin"
723
715#define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */ 724#define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */
716 725
717#define NETXEN_FLASH_START (NETXEN_CRBINIT_START) 726#define NETXEN_FLASH_START (NETXEN_CRBINIT_START)
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index e80f9e3e597..269a1f70688 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -858,6 +858,9 @@ enum {
858#define NETXEN_PORT_MODE_ADDR (NETXEN_CAM_RAM(0x24)) 858#define NETXEN_PORT_MODE_ADDR (NETXEN_CAM_RAM(0x24))
859#define NETXEN_WOL_PORT_MODE (NETXEN_CAM_RAM(0x198)) 859#define NETXEN_WOL_PORT_MODE (NETXEN_CAM_RAM(0x198))
860 860
861#define NX_PEG_TUNE_MN_PRESENT 0x1
862#define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c))
863
861#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) 864#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14)
862 865
863#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) 866#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
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)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 2648e902672..9d6e68fe0c9 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -457,18 +457,65 @@ static const struct net_device_ops netxen_netdev_ops = {
457#endif 457#endif
458}; 458};
459 459
460/* 460static int
461 * netxen_nic_probe() 461netxen_start_firmware(struct netxen_adapter *adapter)
462 * 462{
463 * The Linux system will invoke this after identifying the vendor ID and 463 int val, err, first_boot;
464 * device Id in the pci_tbl supported by this module. 464 struct pci_dev *pdev = adapter->pdev;
465 * 465
466 * A quad port card has one operational PCI config space, (function 0), 466 first_boot = adapter->pci_read_normalize(adapter,
467 * which is used to access all four ports. 467 NETXEN_CAM_RAM(0x1fc));
468 * 468
469 * This routine will initialize the adapter, and setup the global parameters 469 err = netxen_check_hw_init(adapter, first_boot);
470 * along with the port's specific structure. 470 if (err) {
471 */ 471 dev_err(&pdev->dev, "error in init HW init sequence\n");
472 return err;
473 }
474
475 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
476 netxen_set_port_mode(adapter);
477
478 if (first_boot != 0x55555555) {
479 adapter->pci_write_normalize(adapter,
480 CRB_CMDPEG_STATE, 0);
481 netxen_pinit_from_rom(adapter, 0);
482 msleep(1);
483 }
484 netxen_load_firmware(adapter);
485
486 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
487
488 /* Initialize multicast addr pool owners */
489 val = 0x7654;
490 if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
491 val |= 0x0f000000;
492 netxen_crb_writelit_adapter(adapter,
493 NETXEN_MAC_ADDR_CNTL_REG, val);
494
495 }
496
497 err = netxen_initialize_adapter_offload(adapter);
498 if (err)
499 return err;
500
501 /*
502 * Tell the hardware our version number.
503 */
504 val = (_NETXEN_NIC_LINUX_MAJOR << 16)
505 | ((_NETXEN_NIC_LINUX_MINOR << 8))
506 | (_NETXEN_NIC_LINUX_SUBVERSION);
507 adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val);
508
509 /* Handshake with the card before we register the devices. */
510 err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
511 if (err) {
512 netxen_free_adapter_offload(adapter);
513 return err;
514 }
515
516 return 0;
517}
518
472static int __devinit 519static int __devinit
473netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 520netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
474{ 521{
@@ -484,7 +531,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
484 u8 __iomem *db_ptr = NULL; 531 u8 __iomem *db_ptr = NULL;
485 unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0; 532 unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0;
486 int i = 0, err; 533 int i = 0, err;
487 int first_driver, first_boot; 534 int first_driver;
488 u32 val; 535 u32 val;
489 int pci_func_id = PCI_FUNC(pdev->devfn); 536 int pci_func_id = PCI_FUNC(pdev->devfn);
490 struct netxen_legacy_intr_set *legacy_intrp; 537 struct netxen_legacy_intr_set *legacy_intrp;
@@ -736,56 +783,10 @@ skip_doorbell:
736 } 783 }
737 784
738 if (first_driver) { 785 if (first_driver) {
739 first_boot = adapter->pci_read_normalize(adapter, 786 err = netxen_start_firmware(adapter);
740 NETXEN_CAM_RAM(0x1fc));
741
742 err = netxen_check_hw_init(adapter, first_boot);
743 if (err) {
744 printk(KERN_ERR "%s: error in init HW init sequence\n",
745 netxen_nic_driver_name);
746 goto err_out_iounmap;
747 }
748
749 if (NX_IS_REVISION_P3(revision_id))
750 netxen_set_port_mode(adapter);
751
752 if (first_boot != 0x55555555) {
753 adapter->pci_write_normalize(adapter,
754 CRB_CMDPEG_STATE, 0);
755 netxen_pinit_from_rom(adapter, 0);
756 msleep(1);
757 }
758 netxen_load_firmware(adapter);
759
760 if (NX_IS_REVISION_P2(revision_id)) {
761
762 /* Initialize multicast addr pool owners */
763 val = 0x7654;
764 if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
765 val |= 0x0f000000;
766 netxen_crb_writelit_adapter(adapter,
767 NETXEN_MAC_ADDR_CNTL_REG, val);
768
769 }
770
771 err = netxen_initialize_adapter_offload(adapter);
772 if (err) 787 if (err)
773 goto err_out_iounmap; 788 goto err_out_iounmap;
774 789 }
775 /*
776 * Tell the hardware our version number.
777 */
778 i = (_NETXEN_NIC_LINUX_MAJOR << 16)
779 | ((_NETXEN_NIC_LINUX_MINOR << 8))
780 | (_NETXEN_NIC_LINUX_SUBVERSION);
781 adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i);
782
783 /* Handshake with the card before we register the devices. */
784 err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
785 if (err)
786 goto err_out_free_offload;
787
788 } /* first_driver */
789 790
790 netxen_nic_flash_print(adapter); 791 netxen_nic_flash_print(adapter);
791 792
@@ -890,14 +891,12 @@ err_out_disable_msi:
890 if (adapter->flags & NETXEN_NIC_MSI_ENABLED) 891 if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
891 pci_disable_msi(pdev); 892 pci_disable_msi(pdev);
892 893
893err_out_free_offload:
894 if (first_driver) 894 if (first_driver)
895 netxen_free_adapter_offload(adapter); 895 netxen_free_adapter_offload(adapter);
896 896
897err_out_iounmap: 897err_out_iounmap:
898 if (db_ptr) 898 if (db_ptr)
899 iounmap(db_ptr); 899 iounmap(db_ptr);
900
901 if (mem_ptr0) 900 if (mem_ptr0)
902 iounmap(mem_ptr0); 901 iounmap(mem_ptr0);
903 if (mem_ptr1) 902 if (mem_ptr1)