diff options
author | Amit Kumar Salecha <amit@netxen.com> | 2009-10-24 12:03:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-28 07:10:16 -0400 |
commit | f50330f90b9aa42b7058650ce66b85f1b443ab11 (patch) | |
tree | d980282844c3636e60d6408984a52e613a88a530 /drivers/net/netxen | |
parent | 516b4df1ce49304c188704decf60275c72d4cae1 (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>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 34 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 307 |
2 files changed, 278 insertions, 63 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index e98cfa6baa8f..5ba923bd9d77 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 | |||
437 | struct uni_table_desc{ | ||
438 | uint32_t findex; | ||
439 | uint32_t num_entries; | ||
440 | uint32_t entry_size; | ||
441 | uint32_t reserved[5]; | ||
442 | }; | ||
443 | |||
444 | struct 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 | ||
492 | extern char netxen_nic_driver_name[]; | 522 | extern 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 27d20cbae0aa..e84a3bae779b 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]; | |||
46 | static void | 46 | static void |
47 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | 47 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, |
48 | struct nx_host_rds_ring *rds_ring); | 48 | struct nx_host_rds_ring *rds_ring); |
49 | static int netxen_p3_has_mn(struct netxen_adapter *adapter); | ||
49 | 50 | ||
50 | static void crb_addr_transform_setup(void) | 51 | static 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 | ||
593 | static 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 | |||
612 | static int | ||
613 | nx_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 | |||
652 | static 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 | |||
672 | static u8 * | ||
673 | nx_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 | |||
685 | static u8 * | ||
686 | nx_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 | |||
698 | static __le32 | ||
699 | nx_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 | |||
710 | static __le32 | ||
711 | nx_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 | |||
743 | static __le32 | ||
744 | nx_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 | |||
592 | int | 759 | int |
593 | netxen_need_fw_reset(struct netxen_adapter *adapter) | 760 | netxen_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 | ||
657 | static char *fw_name[] = { | 824 | static 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 | ||
661 | int | 828 | int |
@@ -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 | ||
747 | static int | 913 | static int |
748 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | 914 | netxen_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 | ||
977 | static void | ||
978 | nx_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 | |||
801 | static int | 1012 | static int |
802 | netxen_p3_has_mn(struct netxen_adapter *adapter) | 1013 | netxen_p3_has_mn(struct netxen_adapter *adapter) |
803 | { | 1014 | { |
@@ -819,55 +1030,29 @@ netxen_p3_has_mn(struct netxen_adapter *adapter) | |||
819 | 1030 | ||
820 | void netxen_request_firmware(struct netxen_adapter *adapter) | 1031 | void 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)) { | 1038 | next: |
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 | |||
840 | request_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 | |||
869 | done: | ||
870 | adapter->fw_type = fw_type; | ||
871 | } | 1056 | } |
872 | 1057 | ||
873 | 1058 | ||