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.c167
1 files changed, 152 insertions, 15 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 1c63610ead42..388feaf60ee7 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/slab.h>
28#include "netxen_nic.h" 29#include "netxen_nic.h"
29#include "netxen_nic_hw.h" 30#include "netxen_nic_hw.h"
30 31
@@ -613,22 +614,123 @@ static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section)
613 return NULL; 614 return NULL;
614} 615}
615 616
617#define QLCNIC_FILEHEADER_SIZE (14 * 4)
618
616static int 619static int
617nx_set_product_offs(struct netxen_adapter *adapter) 620netxen_nic_validate_header(struct netxen_adapter *adapter)
618{ 621 {
619 struct uni_table_desc *ptab_descr;
620 const u8 *unirom = adapter->fw->data; 622 const u8 *unirom = adapter->fw->data;
621 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;
622 __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;
623 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;
624 int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ? 717 int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ?
625 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;
626 723
627 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);
628 if (ptab_descr == NULL) 725 if (ptab_descr == NULL)
629 return -1; 726 return -EINVAL;
630 727
631 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;
632 734
633nomn: 735nomn:
634 for (i = 0; i < entries; i++) { 736 for (i = 0; i < entries; i++) {
@@ -657,9 +759,38 @@ nomn:
657 goto nomn; 759 goto nomn;
658 } 760 }
659 761
660 return -1; 762 return -EINVAL;
661} 763}
662 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}
663 794
664static 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,
665 u32 section, u32 idx_offset) 796 u32 section, u32 idx_offset)
@@ -761,7 +892,7 @@ nx_get_bios_version(struct netxen_adapter *adapter)
761 if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { 892 if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
762 bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) 893 bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
763 + NX_UNI_BIOS_VERSION_OFF)); 894 + NX_UNI_BIOS_VERSION_OFF));
764 return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + 895 return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) +
765 (bios_ver >> 24); 896 (bios_ver >> 24);
766 } else 897 } else
767 return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); 898 return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
@@ -889,6 +1020,16 @@ netxen_load_firmware(struct netxen_adapter *adapter)
889 1020
890 flashaddr += 8; 1021 flashaddr += 8;
891 } 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
892 } else { 1033 } else {
893 u64 data; 1034 u64 data;
894 u32 hi, lo; 1035 u32 hi, lo;
@@ -933,27 +1074,23 @@ static int
933netxen_validate_firmware(struct netxen_adapter *adapter) 1074netxen_validate_firmware(struct netxen_adapter *adapter)
934{ 1075{
935 __le32 val; 1076 __le32 val;
936 u32 ver, min_ver, bios, min_size; 1077 u32 ver, min_ver, bios;
937 struct pci_dev *pdev = adapter->pdev; 1078 struct pci_dev *pdev = adapter->pdev;
938 const struct firmware *fw = adapter->fw; 1079 const struct firmware *fw = adapter->fw;
939 u8 fw_type = adapter->fw_type; 1080 u8 fw_type = adapter->fw_type;
940 1081
941 if (fw_type == NX_UNIFIED_ROMIMAGE) { 1082 if (fw_type == NX_UNIFIED_ROMIMAGE) {
942 if (nx_set_product_offs(adapter)) 1083 if (netxen_nic_validate_unified_romimage(adapter))
943 return -EINVAL; 1084 return -EINVAL;
944
945 min_size = NX_UNI_FW_MIN_SIZE;
946 } else { 1085 } else {
947 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); 1086 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
948 if ((__force u32)val != NETXEN_BDINFO_MAGIC) 1087 if ((__force u32)val != NETXEN_BDINFO_MAGIC)
949 return -EINVAL; 1088 return -EINVAL;
950 1089
951 min_size = NX_FW_MIN_SIZE; 1090 if (fw->size < NX_FW_MIN_SIZE)
1091 return -EINVAL;
952 } 1092 }
953 1093
954 if (fw->size < min_size)
955 return -EINVAL;
956
957 val = nx_get_fw_version(adapter); 1094 val = nx_get_fw_version(adapter);
958 1095
959 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1096 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))