diff options
Diffstat (limited to 'drivers/net/netxen')
| -rw-r--r-- | drivers/net/netxen/netxen_nic.h | 5 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 14 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 6 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 13 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 167 | ||||
| -rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 79 |
6 files changed, 225 insertions, 59 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 144d2e880422..174ac8ef82fa 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
| @@ -53,8 +53,8 @@ | |||
| 53 | 53 | ||
| 54 | #define _NETXEN_NIC_LINUX_MAJOR 4 | 54 | #define _NETXEN_NIC_LINUX_MAJOR 4 |
| 55 | #define _NETXEN_NIC_LINUX_MINOR 0 | 55 | #define _NETXEN_NIC_LINUX_MINOR 0 |
| 56 | #define _NETXEN_NIC_LINUX_SUBVERSION 72 | 56 | #define _NETXEN_NIC_LINUX_SUBVERSION 73 |
| 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.72" | 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.73" |
| 58 | 58 | ||
| 59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) | 59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
| 60 | #define _major(v) (((v) >> 24) & 0xff) | 60 | #define _major(v) (((v) >> 24) & 0xff) |
| @@ -420,7 +420,6 @@ struct status_desc { | |||
| 420 | } __attribute__ ((aligned(16))); | 420 | } __attribute__ ((aligned(16))); |
| 421 | 421 | ||
| 422 | /* UNIFIED ROMIMAGE *************************/ | 422 | /* UNIFIED ROMIMAGE *************************/ |
| 423 | #define NX_UNI_FW_MIN_SIZE 0xc8000 | ||
| 424 | #define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0 | 423 | #define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0 |
| 425 | #define NX_UNI_DIR_SECT_BOOTLD 0x6 | 424 | #define NX_UNI_DIR_SECT_BOOTLD 0x6 |
| 426 | #define NX_UNI_DIR_SECT_FW 0x7 | 425 | #define NX_UNI_DIR_SECT_FW 0x7 |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 2a8ef5fc9663..f26e54716c88 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
| @@ -669,13 +669,15 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
| 669 | } | 669 | } |
| 670 | sds_ring->desc_head = (struct status_desc *)addr; | 670 | sds_ring->desc_head = (struct status_desc *)addr; |
| 671 | 671 | ||
| 672 | sds_ring->crb_sts_consumer = | 672 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
| 673 | netxen_get_ioaddr(adapter, | 673 | sds_ring->crb_sts_consumer = |
| 674 | recv_crb_registers[port].crb_sts_consumer[ring]); | 674 | netxen_get_ioaddr(adapter, |
| 675 | recv_crb_registers[port].crb_sts_consumer[ring]); | ||
| 675 | 676 | ||
| 676 | sds_ring->crb_intr_mask = | 677 | sds_ring->crb_intr_mask = |
| 677 | netxen_get_ioaddr(adapter, | 678 | netxen_get_ioaddr(adapter, |
| 678 | recv_crb_registers[port].sw_int_mask[ring]); | 679 | recv_crb_registers[port].sw_int_mask[ring]); |
| 680 | } | ||
| 679 | } | 681 | } |
| 680 | 682 | ||
| 681 | 683 | ||
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index f8499e56cbee..aecba787f7c8 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
| @@ -703,6 +703,11 @@ netxen_nic_get_ethtool_stats(struct net_device *dev, | |||
| 703 | } | 703 | } |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | static u32 netxen_nic_get_tx_csum(struct net_device *dev) | ||
| 707 | { | ||
| 708 | return dev->features & NETIF_F_IP_CSUM; | ||
| 709 | } | ||
| 710 | |||
| 706 | static u32 netxen_nic_get_rx_csum(struct net_device *dev) | 711 | static u32 netxen_nic_get_rx_csum(struct net_device *dev) |
| 707 | { | 712 | { |
| 708 | struct netxen_adapter *adapter = netdev_priv(dev); | 713 | struct netxen_adapter *adapter = netdev_priv(dev); |
| @@ -909,6 +914,7 @@ const struct ethtool_ops netxen_nic_ethtool_ops = { | |||
| 909 | .set_ringparam = netxen_nic_set_ringparam, | 914 | .set_ringparam = netxen_nic_set_ringparam, |
| 910 | .get_pauseparam = netxen_nic_get_pauseparam, | 915 | .get_pauseparam = netxen_nic_get_pauseparam, |
| 911 | .set_pauseparam = netxen_nic_set_pauseparam, | 916 | .set_pauseparam = netxen_nic_set_pauseparam, |
| 917 | .get_tx_csum = netxen_nic_get_tx_csum, | ||
| 912 | .set_tx_csum = ethtool_op_set_tx_csum, | 918 | .set_tx_csum = ethtool_op_set_tx_csum, |
| 913 | .set_sg = ethtool_op_set_sg, | 919 | .set_sg = ethtool_op_set_sg, |
| 914 | .get_tso = netxen_nic_get_tso, | 920 | .get_tso = netxen_nic_get_tso, |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index a945591298a8..5e5fe2fd6397 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <linux/slab.h> | ||
| 26 | #include "netxen_nic.h" | 27 | #include "netxen_nic.h" |
| 27 | #include "netxen_nic_hw.h" | 28 | #include "netxen_nic_hw.h" |
| 28 | 29 | ||
| @@ -537,7 +538,7 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter, | |||
| 537 | void netxen_p2_nic_set_multi(struct net_device *netdev) | 538 | void netxen_p2_nic_set_multi(struct net_device *netdev) |
| 538 | { | 539 | { |
| 539 | struct netxen_adapter *adapter = netdev_priv(netdev); | 540 | struct netxen_adapter *adapter = netdev_priv(netdev); |
| 540 | struct dev_mc_list *mc_ptr; | 541 | struct netdev_hw_addr *ha; |
| 541 | u8 null_addr[6]; | 542 | u8 null_addr[6]; |
| 542 | int i; | 543 | int i; |
| 543 | 544 | ||
| @@ -571,8 +572,8 @@ void netxen_p2_nic_set_multi(struct net_device *netdev) | |||
| 571 | netxen_nic_enable_mcast_filter(adapter); | 572 | netxen_nic_enable_mcast_filter(adapter); |
| 572 | 573 | ||
| 573 | i = 0; | 574 | i = 0; |
| 574 | netdev_for_each_mc_addr(mc_ptr, netdev) | 575 | netdev_for_each_mc_addr(ha, netdev) |
| 575 | netxen_nic_set_mcast_addr(adapter, i++, mc_ptr->dmi_addr); | 576 | netxen_nic_set_mcast_addr(adapter, i++, ha->addr); |
| 576 | 577 | ||
| 577 | /* Clear out remaining addresses */ | 578 | /* Clear out remaining addresses */ |
| 578 | while (i < adapter->max_mc_count) | 579 | while (i < adapter->max_mc_count) |
| @@ -680,7 +681,7 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, | |||
| 680 | void netxen_p3_nic_set_multi(struct net_device *netdev) | 681 | void netxen_p3_nic_set_multi(struct net_device *netdev) |
| 681 | { | 682 | { |
| 682 | struct netxen_adapter *adapter = netdev_priv(netdev); | 683 | struct netxen_adapter *adapter = netdev_priv(netdev); |
| 683 | struct dev_mc_list *mc_ptr; | 684 | struct netdev_hw_addr *ha; |
| 684 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 685 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
| 685 | u32 mode = VPORT_MISS_MODE_DROP; | 686 | u32 mode = VPORT_MISS_MODE_DROP; |
| 686 | LIST_HEAD(del_list); | 687 | LIST_HEAD(del_list); |
| @@ -707,8 +708,8 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
| 707 | } | 708 | } |
| 708 | 709 | ||
| 709 | if (!netdev_mc_empty(netdev)) { | 710 | if (!netdev_mc_empty(netdev)) { |
| 710 | netdev_for_each_mc_addr(mc_ptr, netdev) | 711 | netdev_for_each_mc_addr(ha, netdev) |
| 711 | nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list); | 712 | nx_p3_nic_add_mac(adapter, ha->addr, &del_list); |
| 712 | } | 713 | } |
| 713 | 714 | ||
| 714 | send_fw_cmd: | 715 | send_fw_cmd: |
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 | |||
| 616 | static int | 619 | static int |
| 617 | nx_set_product_offs(struct netxen_adapter *adapter) | 620 | netxen_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 | |||
| 642 | static int | ||
| 643 | netxen_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 | |||
| 677 | static int | ||
| 678 | netxen_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 | |||
| 712 | static int | ||
| 713 | netxen_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 | ||
| 633 | nomn: | 735 | nomn: |
| 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 | ||
| 765 | static int | ||
| 766 | netxen_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 | ||
| 664 | static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter, | 795 | static 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 | |||
| 933 | netxen_validate_firmware(struct netxen_adapter *adapter) | 1074 | netxen_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)) |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 08780ef1c1f8..b665b420a4f2 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <linux/slab.h> | ||
| 26 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
| 27 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 28 | #include "netxen_nic_hw.h" | 29 | #include "netxen_nic_hw.h" |
| @@ -604,16 +605,14 @@ netxen_cleanup_pci_map(struct netxen_adapter *adapter) | |||
| 604 | static int | 605 | static int |
| 605 | netxen_setup_pci_map(struct netxen_adapter *adapter) | 606 | netxen_setup_pci_map(struct netxen_adapter *adapter) |
| 606 | { | 607 | { |
| 607 | void __iomem *mem_ptr0 = NULL; | ||
| 608 | void __iomem *mem_ptr1 = NULL; | ||
| 609 | void __iomem *mem_ptr2 = NULL; | ||
| 610 | void __iomem *db_ptr = NULL; | 608 | void __iomem *db_ptr = NULL; |
| 611 | 609 | ||
| 612 | resource_size_t mem_base, db_base; | 610 | resource_size_t mem_base, db_base; |
| 613 | unsigned long mem_len, db_len = 0, pci_len0 = 0; | 611 | unsigned long mem_len, db_len = 0; |
| 614 | 612 | ||
| 615 | struct pci_dev *pdev = adapter->pdev; | 613 | struct pci_dev *pdev = adapter->pdev; |
| 616 | int pci_func = adapter->ahw.pci_func; | 614 | int pci_func = adapter->ahw.pci_func; |
| 615 | struct netxen_hardware_context *ahw = &adapter->ahw; | ||
| 617 | 616 | ||
| 618 | int err = 0; | 617 | int err = 0; |
| 619 | 618 | ||
| @@ -630,24 +629,40 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
| 630 | 629 | ||
| 631 | /* 128 Meg of memory */ | 630 | /* 128 Meg of memory */ |
| 632 | if (mem_len == NETXEN_PCI_128MB_SIZE) { | 631 | if (mem_len == NETXEN_PCI_128MB_SIZE) { |
| 633 | mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); | 632 | |
| 634 | mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, | 633 | ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); |
| 634 | ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, | ||
| 635 | SECOND_PAGE_GROUP_SIZE); | 635 | SECOND_PAGE_GROUP_SIZE); |
| 636 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, | 636 | ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, |
| 637 | THIRD_PAGE_GROUP_SIZE); | 637 | THIRD_PAGE_GROUP_SIZE); |
| 638 | pci_len0 = FIRST_PAGE_GROUP_SIZE; | 638 | if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL || |
| 639 | ahw->pci_base2 == NULL) { | ||
| 640 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | ||
| 641 | err = -EIO; | ||
| 642 | goto err_out; | ||
| 643 | } | ||
| 644 | |||
| 645 | ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE; | ||
| 646 | |||
| 639 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { | 647 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { |
| 640 | mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); | 648 | |
| 641 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | 649 | ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); |
| 650 | ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | ||
| 642 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); | 651 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); |
| 652 | if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) { | ||
| 653 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | ||
| 654 | err = -EIO; | ||
| 655 | goto err_out; | ||
| 656 | } | ||
| 657 | |||
| 643 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { | 658 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { |
| 644 | 659 | ||
| 645 | mem_ptr0 = pci_ioremap_bar(pdev, 0); | 660 | ahw->pci_base0 = pci_ioremap_bar(pdev, 0); |
| 646 | if (mem_ptr0 == NULL) { | 661 | if (ahw->pci_base0 == NULL) { |
| 647 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | 662 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); |
| 648 | return -EIO; | 663 | return -EIO; |
| 649 | } | 664 | } |
| 650 | pci_len0 = mem_len; | 665 | ahw->pci_len0 = mem_len; |
| 651 | } else { | 666 | } else { |
| 652 | return -EIO; | 667 | return -EIO; |
| 653 | } | 668 | } |
| @@ -656,11 +671,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
| 656 | 671 | ||
| 657 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); | 672 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); |
| 658 | 673 | ||
| 659 | adapter->ahw.pci_base0 = mem_ptr0; | ||
| 660 | adapter->ahw.pci_len0 = pci_len0; | ||
| 661 | adapter->ahw.pci_base1 = mem_ptr1; | ||
| 662 | adapter->ahw.pci_base2 = mem_ptr2; | ||
| 663 | |||
| 664 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { | 674 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { |
| 665 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, | 675 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, |
| 666 | NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); | 676 | NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); |
| @@ -772,15 +782,22 @@ netxen_check_options(struct netxen_adapter *adapter) | |||
| 772 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | 782 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
| 773 | adapter->msix_supported = !!use_msi_x; | 783 | adapter->msix_supported = !!use_msi_x; |
| 774 | adapter->rss_supported = !!use_msi_x; | 784 | adapter->rss_supported = !!use_msi_x; |
| 775 | } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) { | 785 | } else { |
| 776 | switch (adapter->ahw.board_type) { | 786 | u32 flashed_ver = 0; |
| 777 | case NETXEN_BRDTYPE_P2_SB31_10G: | 787 | netxen_rom_fast_read(adapter, |
| 778 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | 788 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); |
| 779 | adapter->msix_supported = !!use_msi_x; | 789 | flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); |
| 780 | adapter->rss_supported = !!use_msi_x; | 790 | |
| 781 | break; | 791 | if (flashed_ver >= NETXEN_VERSION_CODE(3, 4, 336)) { |
| 782 | default: | 792 | switch (adapter->ahw.board_type) { |
| 783 | break; | 793 | case NETXEN_BRDTYPE_P2_SB31_10G: |
| 794 | case NETXEN_BRDTYPE_P2_SB31_10G_CX4: | ||
| 795 | adapter->msix_supported = !!use_msi_x; | ||
| 796 | adapter->rss_supported = !!use_msi_x; | ||
| 797 | break; | ||
| 798 | default: | ||
| 799 | break; | ||
| 800 | } | ||
| 784 | } | 801 | } |
| 785 | } | 802 | } |
| 786 | 803 | ||
| @@ -1246,8 +1263,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1246 | int pci_func_id = PCI_FUNC(pdev->devfn); | 1263 | int pci_func_id = PCI_FUNC(pdev->devfn); |
| 1247 | uint8_t revision_id; | 1264 | uint8_t revision_id; |
| 1248 | 1265 | ||
| 1249 | if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) { | 1266 | if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) { |
| 1250 | pr_warning("%s: chip revisions between 0x%x-0x%x" | 1267 | pr_warning("%s: chip revisions between 0x%x-0x%x " |
| 1251 | "will not be enabled.\n", | 1268 | "will not be enabled.\n", |
| 1252 | module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1); | 1269 | module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1); |
| 1253 | return -ENODEV; | 1270 | return -ENODEV; |
| @@ -2294,6 +2311,7 @@ netxen_fwinit_work(struct work_struct *work) | |||
| 2294 | } | 2311 | } |
| 2295 | break; | 2312 | break; |
| 2296 | 2313 | ||
| 2314 | case NX_DEV_NEED_RESET: | ||
| 2297 | case NX_DEV_INITALIZING: | 2315 | case NX_DEV_INITALIZING: |
| 2298 | if (++adapter->fw_wait_cnt < FW_POLL_THRESH) { | 2316 | if (++adapter->fw_wait_cnt < FW_POLL_THRESH) { |
| 2299 | netxen_schedule_work(adapter, | 2317 | netxen_schedule_work(adapter, |
| @@ -2337,6 +2355,9 @@ netxen_detach_work(struct work_struct *work) | |||
| 2337 | 2355 | ||
| 2338 | ref_cnt = nx_decr_dev_ref_cnt(adapter); | 2356 | ref_cnt = nx_decr_dev_ref_cnt(adapter); |
| 2339 | 2357 | ||
| 2358 | if (ref_cnt == -EIO) | ||
| 2359 | goto err_ret; | ||
| 2360 | |||
| 2340 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); | 2361 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); |
| 2341 | 2362 | ||
| 2342 | adapter->fw_wait_cnt = 0; | 2363 | adapter->fw_wait_cnt = 0; |
