aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_init.c')
-rw-r--r--drivers/net/netxen/netxen_nic_init.c164
1 files changed, 150 insertions, 14 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 02876f59cbb2..388feaf60ee7 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -614,22 +614,123 @@ static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section)
614 return NULL; 614 return NULL;
615} 615}
616 616
617#define QLCNIC_FILEHEADER_SIZE (14 * 4)
618
617static int 619static int
618nx_set_product_offs(struct netxen_adapter *adapter) 620netxen_nic_validate_header(struct netxen_adapter *adapter)
619{ 621 {
620 struct uni_table_desc *ptab_descr;
621 const u8 *unirom = adapter->fw->data; 622 const u8 *unirom = adapter->fw->data;
622 uint32_t i; 623 struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
624 u32 fw_file_size = adapter->fw->size;
625 u32 tab_size;
623 __le32 entries; 626 __le32 entries;
627 __le32 entry_size;
628
629 if (fw_file_size < QLCNIC_FILEHEADER_SIZE)
630 return -EINVAL;
631
632 entries = cpu_to_le32(directory->num_entries);
633 entry_size = cpu_to_le32(directory->entry_size);
634 tab_size = cpu_to_le32(directory->findex) + (entries * entry_size);
635
636 if (fw_file_size < tab_size)
637 return -EINVAL;
638
639 return 0;
640}
641
642static int
643netxen_nic_validate_bootld(struct netxen_adapter *adapter)
644{
645 struct uni_table_desc *tab_desc;
646 struct uni_data_desc *descr;
647 const u8 *unirom = adapter->fw->data;
648 __le32 idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
649 NX_UNI_BOOTLD_IDX_OFF));
650 u32 offs;
651 u32 tab_size;
652 u32 data_size;
653
654 tab_desc = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_BOOTLD);
655
656 if (!tab_desc)
657 return -EINVAL;
658
659 tab_size = cpu_to_le32(tab_desc->findex) +
660 (cpu_to_le32(tab_desc->entry_size) * (idx + 1));
661
662 if (adapter->fw->size < tab_size)
663 return -EINVAL;
664
665 offs = cpu_to_le32(tab_desc->findex) +
666 (cpu_to_le32(tab_desc->entry_size) * (idx));
667 descr = (struct uni_data_desc *)&unirom[offs];
668
669 data_size = cpu_to_le32(descr->findex) + cpu_to_le32(descr->size);
670
671 if (adapter->fw->size < data_size)
672 return -EINVAL;
624 673
674 return 0;
675}
676
677static int
678netxen_nic_validate_fw(struct netxen_adapter *adapter)
679{
680 struct uni_table_desc *tab_desc;
681 struct uni_data_desc *descr;
682 const u8 *unirom = adapter->fw->data;
683 __le32 idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
684 NX_UNI_FIRMWARE_IDX_OFF));
685 u32 offs;
686 u32 tab_size;
687 u32 data_size;
688
689 tab_desc = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_FW);
690
691 if (!tab_desc)
692 return -EINVAL;
693
694 tab_size = cpu_to_le32(tab_desc->findex) +
695 (cpu_to_le32(tab_desc->entry_size) * (idx + 1));
696
697 if (adapter->fw->size < tab_size)
698 return -EINVAL;
699
700 offs = cpu_to_le32(tab_desc->findex) +
701 (cpu_to_le32(tab_desc->entry_size) * (idx));
702 descr = (struct uni_data_desc *)&unirom[offs];
703 data_size = cpu_to_le32(descr->findex) + cpu_to_le32(descr->size);
704
705 if (adapter->fw->size < data_size)
706 return -EINVAL;
707
708 return 0;
709}
710
711
712static int
713netxen_nic_validate_product_offs(struct netxen_adapter *adapter)
714{
715 struct uni_table_desc *ptab_descr;
716 const u8 *unirom = adapter->fw->data;
625 int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ? 717 int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ?
626 1 : netxen_p3_has_mn(adapter); 718 1 : netxen_p3_has_mn(adapter);
719 __le32 entries;
720 __le32 entry_size;
721 u32 tab_size;
722 u32 i;
627 723
628 ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL); 724 ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL);
629 if (ptab_descr == NULL) 725 if (ptab_descr == NULL)
630 return -1; 726 return -EINVAL;
631 727
632 entries = cpu_to_le32(ptab_descr->num_entries); 728 entries = cpu_to_le32(ptab_descr->num_entries);
729 entry_size = cpu_to_le32(ptab_descr->entry_size);
730 tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size);
731
732 if (adapter->fw->size < tab_size)
733 return -EINVAL;
633 734
634nomn: 735nomn:
635 for (i = 0; i < entries; i++) { 736 for (i = 0; i < entries; i++) {
@@ -658,9 +759,38 @@ nomn:
658 goto nomn; 759 goto nomn;
659 } 760 }
660 761
661 return -1; 762 return -EINVAL;
662} 763}
663 764
765static int
766netxen_nic_validate_unified_romimage(struct netxen_adapter *adapter)
767{
768 if (netxen_nic_validate_header(adapter)) {
769 dev_err(&adapter->pdev->dev,
770 "unified image: header validation failed\n");
771 return -EINVAL;
772 }
773
774 if (netxen_nic_validate_product_offs(adapter)) {
775 dev_err(&adapter->pdev->dev,
776 "unified image: product validation failed\n");
777 return -EINVAL;
778 }
779
780 if (netxen_nic_validate_bootld(adapter)) {
781 dev_err(&adapter->pdev->dev,
782 "unified image: bootld validation failed\n");
783 return -EINVAL;
784 }
785
786 if (netxen_nic_validate_fw(adapter)) {
787 dev_err(&adapter->pdev->dev,
788 "unified image: firmware validation failed\n");
789 return -EINVAL;
790 }
791
792 return 0;
793}
664 794
665static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter, 795static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter,
666 u32 section, u32 idx_offset) 796 u32 section, u32 idx_offset)
@@ -890,6 +1020,16 @@ netxen_load_firmware(struct netxen_adapter *adapter)
890 1020
891 flashaddr += 8; 1021 flashaddr += 8;
892 } 1022 }
1023
1024 size = (__force u32)nx_get_fw_size(adapter) % 8;
1025 if (size) {
1026 data = cpu_to_le64(ptr64[i]);
1027
1028 if (adapter->pci_mem_write(adapter,
1029 flashaddr, data))
1030 return -EIO;
1031 }
1032
893 } else { 1033 } else {
894 u64 data; 1034 u64 data;
895 u32 hi, lo; 1035 u32 hi, lo;
@@ -934,27 +1074,23 @@ static int
934netxen_validate_firmware(struct netxen_adapter *adapter) 1074netxen_validate_firmware(struct netxen_adapter *adapter)
935{ 1075{
936 __le32 val; 1076 __le32 val;
937 u32 ver, min_ver, bios, min_size; 1077 u32 ver, min_ver, bios;
938 struct pci_dev *pdev = adapter->pdev; 1078 struct pci_dev *pdev = adapter->pdev;
939 const struct firmware *fw = adapter->fw; 1079 const struct firmware *fw = adapter->fw;
940 u8 fw_type = adapter->fw_type; 1080 u8 fw_type = adapter->fw_type;
941 1081
942 if (fw_type == NX_UNIFIED_ROMIMAGE) { 1082 if (fw_type == NX_UNIFIED_ROMIMAGE) {
943 if (nx_set_product_offs(adapter)) 1083 if (netxen_nic_validate_unified_romimage(adapter))
944 return -EINVAL; 1084 return -EINVAL;
945
946 min_size = NX_UNI_FW_MIN_SIZE;
947 } else { 1085 } else {
948 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); 1086 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
949 if ((__force u32)val != NETXEN_BDINFO_MAGIC) 1087 if ((__force u32)val != NETXEN_BDINFO_MAGIC)
950 return -EINVAL; 1088 return -EINVAL;
951 1089
952 min_size = NX_FW_MIN_SIZE; 1090 if (fw->size < NX_FW_MIN_SIZE)
1091 return -EINVAL;
953 } 1092 }
954 1093
955 if (fw->size < min_size)
956 return -EINVAL;
957
958 val = nx_get_fw_version(adapter); 1094 val = nx_get_fw_version(adapter);
959 1095
960 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1096 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))