aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Kumar Salecha <amit@netxen.com>2009-10-24 12:03:58 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-28 07:10:16 -0400
commitf50330f90b9aa42b7058650ce66b85f1b443ab11 (patch)
treed980282844c3636e60d6408984a52e613a88a530
parent516b4df1ce49304c188704decf60275c72d4cae1 (diff)
netxen: support for new firmware file format
Add support for extracting firmware from a unified file format which embeds firmware images for all chip revisions. Fallback to orginal file formats if new image is not found. Signed-off-by: Amit Kumar Salecha <amit@netxen.com> Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/netxen/netxen_nic.h34
-rw-r--r--drivers/net/netxen/netxen_nic_init.c307
2 files changed, 278 insertions, 63 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index e98cfa6baa8..5ba923bd9d7 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -421,6 +421,34 @@ struct status_desc {
421 __le64 status_desc_data[2]; 421 __le64 status_desc_data[2];
422} __attribute__ ((aligned(16))); 422} __attribute__ ((aligned(16)));
423 423
424/* UNIFIED ROMIMAGE *************************/
425#define NX_UNI_FW_MIN_SIZE 0x3eb000
426#define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0
427#define NX_UNI_DIR_SECT_BOOTLD 0x6
428#define NX_UNI_DIR_SECT_FW 0x7
429
430/*Offsets */
431#define NX_UNI_CHIP_REV_OFF 10
432#define NX_UNI_FLAGS_OFF 11
433#define NX_UNI_BIOS_VERSION_OFF 12
434#define NX_UNI_BOOTLD_IDX_OFF 27
435#define NX_UNI_FIRMWARE_IDX_OFF 29
436
437struct uni_table_desc{
438 uint32_t findex;
439 uint32_t num_entries;
440 uint32_t entry_size;
441 uint32_t reserved[5];
442};
443
444struct uni_data_desc{
445 uint32_t findex;
446 uint32_t size;
447 uint32_t reserved[5];
448};
449
450/* UNIFIED ROMIMAGE *************************/
451
424/* The version of the main data structure */ 452/* The version of the main data structure */
425#define NETXEN_BDINFO_VERSION 1 453#define NETXEN_BDINFO_VERSION 1
426 454
@@ -487,7 +515,9 @@ struct status_desc {
487#define NX_P2_MN_ROMIMAGE 0 515#define NX_P2_MN_ROMIMAGE 0
488#define NX_P3_CT_ROMIMAGE 1 516#define NX_P3_CT_ROMIMAGE 1
489#define NX_P3_MN_ROMIMAGE 2 517#define NX_P3_MN_ROMIMAGE 2
490#define NX_FLASH_ROMIMAGE 3 518#define NX_UNIFIED_ROMIMAGE 3
519#define NX_FLASH_ROMIMAGE 4
520#define NX_UNKNOWN_ROMIMAGE 0xff
491 521
492extern char netxen_nic_driver_name[]; 522extern char netxen_nic_driver_name[];
493 523
@@ -1210,7 +1240,7 @@ struct netxen_adapter {
1210 nx_nic_intr_coalesce_t coal; 1240 nx_nic_intr_coalesce_t coal;
1211 1241
1212 unsigned long state; 1242 unsigned long state;
1213 u32 resv5; 1243 __le32 file_prd_off; /*File fw product offset*/
1214 u32 fw_version; 1244 u32 fw_version;
1215 const struct firmware *fw; 1245 const struct firmware *fw;
1216}; 1246};
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 27d20cbae0a..e84a3bae779 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -46,6 +46,7 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
46static void 46static void
47netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, 47netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
48 struct nx_host_rds_ring *rds_ring); 48 struct nx_host_rds_ring *rds_ring);
49static int netxen_p3_has_mn(struct netxen_adapter *adapter);
49 50
50static void crb_addr_transform_setup(void) 51static void crb_addr_transform_setup(void)
51{ 52{
@@ -589,6 +590,172 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter)
589 return 0; 590 return 0;
590} 591}
591 592
593static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section)
594{
595 uint32_t i;
596 struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
597 __le32 entries = cpu_to_le32(directory->num_entries);
598
599 for (i = 0; i < entries; i++) {
600
601 __le32 offs = cpu_to_le32(directory->findex) +
602 (i * cpu_to_le32(directory->entry_size));
603 __le32 tab_type = cpu_to_le32(*((u32 *)&unirom[offs] + 8));
604
605 if (tab_type == section)
606 return (struct uni_table_desc *) &unirom[offs];
607 }
608
609 return NULL;
610}
611
612static int
613nx_set_product_offs(struct netxen_adapter *adapter)
614{
615 struct uni_table_desc *ptab_descr;
616 const u8 *unirom = adapter->fw->data;
617 uint32_t i;
618 __le32 entries;
619
620 ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL);
621 if (ptab_descr == NULL)
622 return -1;
623
624 entries = cpu_to_le32(ptab_descr->num_entries);
625
626 for (i = 0; i < entries; i++) {
627
628 __le32 flags, file_chiprev, offs;
629 u8 chiprev = adapter->ahw.revision_id;
630 int mn_present = netxen_p3_has_mn(adapter);
631 uint32_t flagbit;
632
633 offs = cpu_to_le32(ptab_descr->findex) +
634 (i * cpu_to_le32(ptab_descr->entry_size));
635 flags = cpu_to_le32(*((int *)&unirom[offs] + NX_UNI_FLAGS_OFF));
636 file_chiprev = cpu_to_le32(*((int *)&unirom[offs] +
637 NX_UNI_CHIP_REV_OFF));
638
639 flagbit = mn_present ? 1 : 2;
640
641 if ((chiprev == file_chiprev) &&
642 ((1ULL << flagbit) & flags)) {
643 adapter->file_prd_off = offs;
644 return 0;
645 }
646 }
647
648 return -1;
649}
650
651
652static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter,
653 u32 section, u32 idx_offset)
654{
655 const u8 *unirom = adapter->fw->data;
656 int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
657 idx_offset));
658 struct uni_table_desc *tab_desc;
659 __le32 offs;
660
661 tab_desc = nx_get_table_desc(unirom, section);
662
663 if (tab_desc == NULL)
664 return NULL;
665
666 offs = cpu_to_le32(tab_desc->findex) +
667 (cpu_to_le32(tab_desc->entry_size) * idx);
668
669 return (struct uni_data_desc *)&unirom[offs];
670}
671
672static u8 *
673nx_get_bootld_offs(struct netxen_adapter *adapter)
674{
675 u32 offs = NETXEN_BOOTLD_START;
676
677 if (adapter->fw_type == NX_UNIFIED_ROMIMAGE)
678 offs = cpu_to_le32((nx_get_data_desc(adapter,
679 NX_UNI_DIR_SECT_BOOTLD,
680 NX_UNI_BOOTLD_IDX_OFF))->findex);
681
682 return (u8 *)&adapter->fw->data[offs];
683}
684
685static u8 *
686nx_get_fw_offs(struct netxen_adapter *adapter)
687{
688 u32 offs = NETXEN_IMAGE_START;
689
690 if (adapter->fw_type == NX_UNIFIED_ROMIMAGE)
691 offs = cpu_to_le32((nx_get_data_desc(adapter,
692 NX_UNI_DIR_SECT_FW,
693 NX_UNI_FIRMWARE_IDX_OFF))->findex);
694
695 return (u8 *)&adapter->fw->data[offs];
696}
697
698static __le32
699nx_get_fw_size(struct netxen_adapter *adapter)
700{
701 if (adapter->fw_type == NX_UNIFIED_ROMIMAGE)
702 return cpu_to_le32((nx_get_data_desc(adapter,
703 NX_UNI_DIR_SECT_FW,
704 NX_UNI_FIRMWARE_IDX_OFF))->size);
705 else
706 return cpu_to_le32(
707 *(u32 *)&adapter->fw->data[NX_FW_SIZE_OFFSET]);
708}
709
710static __le32
711nx_get_fw_version(struct netxen_adapter *adapter)
712{
713 struct uni_data_desc *fw_data_desc;
714 const struct firmware *fw = adapter->fw;
715 __le32 major, minor, sub;
716 const u8 *ver_str;
717 int i, ret = 0;
718
719 if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
720
721 fw_data_desc = nx_get_data_desc(adapter,
722 NX_UNI_DIR_SECT_FW, NX_UNI_FIRMWARE_IDX_OFF);
723 ver_str = fw->data + cpu_to_le32(fw_data_desc->findex) +
724 cpu_to_le32(fw_data_desc->size) - 17;
725
726 for (i = 0; i < 12; i++) {
727 if (!strncmp(&ver_str[i], "REV=", 4)) {
728 ret = sscanf(&ver_str[i+4], "%u.%u.%u ",
729 &major, &minor, &sub);
730 break;
731 }
732 }
733
734 if (ret != 3)
735 return 0;
736
737 return major + (minor << 8) + (sub << 16);
738
739 } else
740 return cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
741}
742
743static __le32
744nx_get_bios_version(struct netxen_adapter *adapter)
745{
746 const struct firmware *fw = adapter->fw;
747 __le32 bios_ver, prd_off = adapter->file_prd_off;
748
749 if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
750 bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
751 + NX_UNI_BIOS_VERSION_OFF));
752 return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) +
753 (bios_ver >> 24);
754 } else
755 return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
756
757}
758
592int 759int
593netxen_need_fw_reset(struct netxen_adapter *adapter) 760netxen_need_fw_reset(struct netxen_adapter *adapter)
594{ 761{
@@ -628,9 +795,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter)
628 /* check if we have got newer or different file firmware */ 795 /* check if we have got newer or different file firmware */
629 if (adapter->fw) { 796 if (adapter->fw) {
630 797
631 const struct firmware *fw = adapter->fw; 798 val = nx_get_fw_version(adapter);
632 799
633 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
634 version = NETXEN_DECODE_VERSION(val); 800 version = NETXEN_DECODE_VERSION(val);
635 801
636 major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); 802 major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
@@ -640,7 +806,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter)
640 if (version > NETXEN_VERSION_CODE(major, minor, build)) 806 if (version > NETXEN_VERSION_CODE(major, minor, build))
641 return 1; 807 return 1;
642 808
643 if (version == NETXEN_VERSION_CODE(major, minor, build)) { 809 if (version == NETXEN_VERSION_CODE(major, minor, build) &&
810 adapter->fw_type != NX_UNIFIED_ROMIMAGE) {
644 811
645 val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); 812 val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
646 fw_type = (val & 0x4) ? 813 fw_type = (val & 0x4) ?
@@ -655,7 +822,7 @@ netxen_need_fw_reset(struct netxen_adapter *adapter)
655} 822}
656 823
657static char *fw_name[] = { 824static char *fw_name[] = {
658 "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash", 825 "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "phanfw.bin", "flash",
659}; 826};
660 827
661int 828int
@@ -677,22 +844,21 @@ netxen_load_firmware(struct netxen_adapter *adapter)
677 844
678 size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; 845 size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
679 846
680 ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; 847 ptr64 = (u64 *)nx_get_bootld_offs(adapter);
681 flashaddr = NETXEN_BOOTLD_START; 848 flashaddr = NETXEN_BOOTLD_START;
682 849
683 for (i = 0; i < size; i++) { 850 for (i = 0; i < size; i++) {
684 data = cpu_to_le64(ptr64[i]); 851 data = cpu_to_le64(ptr64[i]);
685 if (adapter->pci_mem_write(adapter, 852
686 flashaddr, data)) 853 if (adapter->pci_mem_write(adapter, flashaddr, data))
687 return -EIO; 854 return -EIO;
688 855
689 flashaddr += 8; 856 flashaddr += 8;
690 } 857 }
691 858
692 size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; 859 size = (__force u32)nx_get_fw_size(adapter) / 8;
693 size = (__force u32)cpu_to_le32(size) / 8;
694 860
695 ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; 861 ptr64 = (u64 *)nx_get_fw_offs(adapter);
696 flashaddr = NETXEN_IMAGE_START; 862 flashaddr = NETXEN_IMAGE_START;
697 863
698 for (i = 0; i < size; i++) { 864 for (i = 0; i < size; i++) {
@@ -745,21 +911,31 @@ netxen_load_firmware(struct netxen_adapter *adapter)
745} 911}
746 912
747static int 913static int
748netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) 914netxen_validate_firmware(struct netxen_adapter *adapter)
749{ 915{
750 __le32 val; 916 __le32 val;
751 u32 ver, min_ver, bios; 917 u32 ver, min_ver, bios, min_size;
752 struct pci_dev *pdev = adapter->pdev; 918 struct pci_dev *pdev = adapter->pdev;
753 const struct firmware *fw = adapter->fw; 919 const struct firmware *fw = adapter->fw;
920 u8 fw_type = adapter->fw_type;
754 921
755 if (fw->size < NX_FW_MIN_SIZE) 922 if (fw_type == NX_UNIFIED_ROMIMAGE) {
756 return -EINVAL; 923 if (nx_set_product_offs(adapter))
924 return -EINVAL;
925
926 min_size = NX_UNI_FW_MIN_SIZE;
927 } else {
928 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
929 if ((__force u32)val != NETXEN_BDINFO_MAGIC)
930 return -EINVAL;
757 931
758 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); 932 min_size = NX_FW_MIN_SIZE;
759 if ((__force u32)val != NETXEN_BDINFO_MAGIC) 933 }
934
935 if (fw->size < min_size)
760 return -EINVAL; 936 return -EINVAL;
761 937
762 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); 938 val = nx_get_fw_version(adapter);
763 939
764 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 940 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
765 min_ver = NETXEN_VERSION_CODE(4, 0, 216); 941 min_ver = NETXEN_VERSION_CODE(4, 0, 216);
@@ -771,15 +947,15 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
771 if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { 947 if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
772 dev_err(&pdev->dev, 948 dev_err(&pdev->dev,
773 "%s: firmware version %d.%d.%d unsupported\n", 949 "%s: firmware version %d.%d.%d unsupported\n",
774 fwname, _major(ver), _minor(ver), _build(ver)); 950 fw_name[fw_type], _major(ver), _minor(ver), _build(ver));
775 return -EINVAL; 951 return -EINVAL;
776 } 952 }
777 953
778 val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); 954 val = nx_get_bios_version(adapter);
779 netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); 955 netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
780 if ((__force u32)val != bios) { 956 if ((__force u32)val != bios) {
781 dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", 957 dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
782 fwname); 958 fw_name[fw_type]);
783 return -EINVAL; 959 return -EINVAL;
784 } 960 }
785 961
@@ -790,7 +966,7 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
790 val = NETXEN_DECODE_VERSION(val); 966 val = NETXEN_DECODE_VERSION(val);
791 if (val > ver) { 967 if (val > ver) {
792 dev_info(&pdev->dev, "%s: firmware is older than flash\n", 968 dev_info(&pdev->dev, "%s: firmware is older than flash\n",
793 fwname); 969 fw_name[fw_type]);
794 return -EINVAL; 970 return -EINVAL;
795 } 971 }
796 972
@@ -798,6 +974,41 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
798 return 0; 974 return 0;
799} 975}
800 976
977static void
978nx_get_next_fwtype(struct netxen_adapter *adapter)
979{
980 u8 fw_type;
981
982 switch (adapter->fw_type) {
983 case NX_UNKNOWN_ROMIMAGE:
984 fw_type = NX_UNIFIED_ROMIMAGE;
985 break;
986
987 case NX_UNIFIED_ROMIMAGE:
988 if (NX_IS_REVISION_P3P(adapter->ahw.revision_id))
989 fw_type = NX_FLASH_ROMIMAGE;
990 else if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
991 fw_type = NX_P2_MN_ROMIMAGE;
992 else if (netxen_p3_has_mn(adapter))
993 fw_type = NX_P3_MN_ROMIMAGE;
994 else
995 fw_type = NX_P3_CT_ROMIMAGE;
996 break;
997
998 case NX_P3_MN_ROMIMAGE:
999 fw_type = NX_P3_CT_ROMIMAGE;
1000 break;
1001
1002 case NX_P2_MN_ROMIMAGE:
1003 case NX_P3_CT_ROMIMAGE:
1004 default:
1005 fw_type = NX_FLASH_ROMIMAGE;
1006 break;
1007 }
1008
1009 adapter->fw_type = fw_type;
1010}
1011
801static int 1012static int
802netxen_p3_has_mn(struct netxen_adapter *adapter) 1013netxen_p3_has_mn(struct netxen_adapter *adapter)
803{ 1014{
@@ -819,55 +1030,29 @@ netxen_p3_has_mn(struct netxen_adapter *adapter)
819 1030
820void netxen_request_firmware(struct netxen_adapter *adapter) 1031void netxen_request_firmware(struct netxen_adapter *adapter)
821{ 1032{
822 u8 fw_type;
823 struct pci_dev *pdev = adapter->pdev; 1033 struct pci_dev *pdev = adapter->pdev;
824 int rc = 0; 1034 int rc = 0;
825 1035
826 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 1036 adapter->fw_type = NX_UNKNOWN_ROMIMAGE;
827 fw_type = NX_P2_MN_ROMIMAGE;
828 goto request_fw;
829 }
830 1037
831 if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { 1038next:
832 /* No file firmware for the time being */ 1039 nx_get_next_fwtype(adapter);
833 fw_type = NX_FLASH_ROMIMAGE;
834 goto done;
835 }
836 1040
837 fw_type = netxen_p3_has_mn(adapter) ? 1041 if (adapter->fw_type == NX_FLASH_ROMIMAGE) {
838 NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE;
839
840request_fw:
841 rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
842 if (rc != 0) {
843 if (fw_type == NX_P3_MN_ROMIMAGE) {
844 msleep(1);
845 fw_type = NX_P3_CT_ROMIMAGE;
846 goto request_fw;
847 }
848
849 fw_type = NX_FLASH_ROMIMAGE;
850 adapter->fw = NULL; 1042 adapter->fw = NULL;
851 goto done; 1043 } else {
852 } 1044 rc = request_firmware(&adapter->fw,
853 1045 fw_name[adapter->fw_type], &pdev->dev);
854 rc = netxen_validate_firmware(adapter, fw_name[fw_type]); 1046 if (rc != 0)
855 if (rc != 0) { 1047 goto next;
856 release_firmware(adapter->fw); 1048
857 1049 rc = netxen_validate_firmware(adapter);
858 if (fw_type == NX_P3_MN_ROMIMAGE) { 1050 if (rc != 0) {
1051 release_firmware(adapter->fw);
859 msleep(1); 1052 msleep(1);
860 fw_type = NX_P3_CT_ROMIMAGE; 1053 goto next;
861 goto request_fw;
862 } 1054 }
863
864 fw_type = NX_FLASH_ROMIMAGE;
865 adapter->fw = NULL;
866 goto done;
867 } 1055 }
868
869done:
870 adapter->fw_type = fw_type;
871} 1056}
872 1057
873 1058