diff options
author | Rajesh K Borundia <rajesh.borundia@qlogic.com> | 2010-06-29 04:01:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-29 18:12:36 -0400 |
commit | 346fe763d7706cccdf90ba24f04f0facdd79b91a (patch) | |
tree | 45ba5093b60ca7ac2df3b56c882fd97fd3413deb /drivers/net/qlcnic | |
parent | 45918e2fe582d845a2649ffa015754ae44be9a8b (diff) |
qlcnic: Add support for configuring eswitch and npars
Following changes are made:
1.Obtain capabilities of Nic partition.
2.Configure tx bandwidth of particular Nic partition.
3.Configure the eswitch for setting port mirroring, enable mac
learning, promiscous mode.
Signed-off-by: Rajesh K Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 77 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_ctx.c | 90 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 450 |
3 files changed, 542 insertions, 75 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 3675678bbf01..60ea7cb3308f 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -959,8 +959,6 @@ struct qlcnic_adapter { | |||
959 | u16 switch_mode; | 959 | u16 switch_mode; |
960 | u16 max_tx_ques; | 960 | u16 max_tx_ques; |
961 | u16 max_rx_ques; | 961 | u16 max_rx_ques; |
962 | u16 min_tx_bw; | ||
963 | u16 max_tx_bw; | ||
964 | u16 max_mtu; | 962 | u16 max_mtu; |
965 | 963 | ||
966 | u32 fw_hal_version; | 964 | u32 fw_hal_version; |
@@ -984,7 +982,7 @@ struct qlcnic_adapter { | |||
984 | 982 | ||
985 | u64 dev_rst_time; | 983 | u64 dev_rst_time; |
986 | 984 | ||
987 | struct qlcnic_pci_info *npars; | 985 | struct qlcnic_npar_info *npars; |
988 | struct qlcnic_eswitch *eswitch; | 986 | struct qlcnic_eswitch *eswitch; |
989 | struct qlcnic_nic_template *nic_ops; | 987 | struct qlcnic_nic_template *nic_ops; |
990 | 988 | ||
@@ -1042,6 +1040,18 @@ struct qlcnic_pci_info { | |||
1042 | u8 reserved2[106]; | 1040 | u8 reserved2[106]; |
1043 | }; | 1041 | }; |
1044 | 1042 | ||
1043 | struct qlcnic_npar_info { | ||
1044 | u16 vlan_id; | ||
1045 | u8 phy_port; | ||
1046 | u8 type; | ||
1047 | u8 active; | ||
1048 | u8 enable_pm; | ||
1049 | u8 dest_npar; | ||
1050 | u8 host_vlan_tag; | ||
1051 | u8 promisc_mode; | ||
1052 | u8 discard_tagged; | ||
1053 | u8 mac_learning; | ||
1054 | }; | ||
1045 | struct qlcnic_eswitch { | 1055 | struct qlcnic_eswitch { |
1046 | u8 port; | 1056 | u8 port; |
1047 | u8 active_vports; | 1057 | u8 active_vports; |
@@ -1057,6 +1067,63 @@ struct qlcnic_eswitch { | |||
1057 | #define QLCNIC_SWITCH_PORT_MIRRORING BIT_4 | 1067 | #define QLCNIC_SWITCH_PORT_MIRRORING BIT_4 |
1058 | }; | 1068 | }; |
1059 | 1069 | ||
1070 | |||
1071 | /* Return codes for Error handling */ | ||
1072 | #define QL_STATUS_INVALID_PARAM -1 | ||
1073 | |||
1074 | #define MAX_BW 10000 | ||
1075 | #define MIN_BW 100 | ||
1076 | #define MAX_VLAN_ID 4095 | ||
1077 | #define MIN_VLAN_ID 2 | ||
1078 | #define MAX_TX_QUEUES 1 | ||
1079 | #define MAX_RX_QUEUES 4 | ||
1080 | #define DEFAULT_MAC_LEARN 1 | ||
1081 | |||
1082 | #define IS_VALID_VLAN(vlan) (vlan >= MIN_VLAN_ID && vlan <= MAX_VLAN_ID) | ||
1083 | #define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW \ | ||
1084 | && (bw % 100) == 0) | ||
1085 | #define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) | ||
1086 | #define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) | ||
1087 | #define IS_VALID_MODE(mode) (mode == 0 || mode == 1) | ||
1088 | |||
1089 | struct qlcnic_pci_func_cfg { | ||
1090 | u16 func_type; | ||
1091 | u16 min_bw; | ||
1092 | u16 max_bw; | ||
1093 | u16 port_num; | ||
1094 | u8 pci_func; | ||
1095 | u8 func_state; | ||
1096 | u8 def_mac_addr[6]; | ||
1097 | }; | ||
1098 | |||
1099 | struct qlcnic_npar_func_cfg { | ||
1100 | u32 fw_capab; | ||
1101 | u16 port_num; | ||
1102 | u16 min_bw; | ||
1103 | u16 max_bw; | ||
1104 | u16 max_tx_queues; | ||
1105 | u16 max_rx_queues; | ||
1106 | u8 pci_func; | ||
1107 | u8 op_mode; | ||
1108 | }; | ||
1109 | |||
1110 | struct qlcnic_pm_func_cfg { | ||
1111 | u8 pci_func; | ||
1112 | u8 action; | ||
1113 | u8 dest_npar; | ||
1114 | u8 reserved[5]; | ||
1115 | }; | ||
1116 | |||
1117 | struct qlcnic_esw_func_cfg { | ||
1118 | u16 vlan_id; | ||
1119 | u8 pci_func; | ||
1120 | u8 host_vlan_tag; | ||
1121 | u8 promisc_mode; | ||
1122 | u8 discard_tagged; | ||
1123 | u8 mac_learning; | ||
1124 | u8 reserved; | ||
1125 | }; | ||
1126 | |||
1060 | int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); | 1127 | int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); |
1061 | int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val); | 1128 | int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val); |
1062 | 1129 | ||
@@ -1169,9 +1236,9 @@ void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); | |||
1169 | /* Management functions */ | 1236 | /* Management functions */ |
1170 | int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*); | 1237 | int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*); |
1171 | int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); | 1238 | int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); |
1172 | int qlcnic_get_nic_info(struct qlcnic_adapter *, u8); | 1239 | int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8); |
1173 | int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); | 1240 | int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); |
1174 | int qlcnic_get_pci_info(struct qlcnic_adapter *); | 1241 | int qlcnic_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*); |
1175 | int qlcnic_reset_partition(struct qlcnic_adapter *, u8); | 1242 | int qlcnic_reset_partition(struct qlcnic_adapter *, u8); |
1176 | 1243 | ||
1177 | /* eSwitch management functions */ | 1244 | /* eSwitch management functions */ |
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 7969a7a87c85..cdd44b4136ae 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c | |||
@@ -611,7 +611,8 @@ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) | |||
611 | } | 611 | } |
612 | 612 | ||
613 | /* Get info of a NIC partition */ | 613 | /* Get info of a NIC partition */ |
614 | int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id) | 614 | int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, |
615 | struct qlcnic_info *npar_info, u8 func_id) | ||
615 | { | 616 | { |
616 | int err; | 617 | int err; |
617 | dma_addr_t nic_dma_t; | 618 | dma_addr_t nic_dma_t; |
@@ -635,29 +636,23 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id) | |||
635 | QLCNIC_CDRP_CMD_GET_NIC_INFO); | 636 | QLCNIC_CDRP_CMD_GET_NIC_INFO); |
636 | 637 | ||
637 | if (err == QLCNIC_RCODE_SUCCESS) { | 638 | if (err == QLCNIC_RCODE_SUCCESS) { |
638 | adapter->physical_port = le16_to_cpu(nic_info->phys_port); | 639 | npar_info->phys_port = le16_to_cpu(nic_info->phys_port); |
639 | adapter->switch_mode = le16_to_cpu(nic_info->switch_mode); | 640 | npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode); |
640 | adapter->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques); | 641 | npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques); |
641 | adapter->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); | 642 | npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); |
642 | adapter->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw); | 643 | npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw); |
643 | adapter->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw); | 644 | npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw); |
644 | adapter->max_mtu = le16_to_cpu(nic_info->max_mtu); | 645 | npar_info->capabilities = le32_to_cpu(nic_info->capabilities); |
645 | adapter->capabilities = le32_to_cpu(nic_info->capabilities); | 646 | npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu); |
646 | adapter->max_mac_filters = nic_info->max_mac_filters; | ||
647 | |||
648 | if (adapter->capabilities & BIT_6) | ||
649 | adapter->flags |= QLCNIC_ESWITCH_ENABLED; | ||
650 | else | ||
651 | adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; | ||
652 | 647 | ||
653 | dev_info(&adapter->pdev->dev, | 648 | dev_info(&adapter->pdev->dev, |
654 | "phy port: %d switch_mode: %d,\n" | 649 | "phy port: %d switch_mode: %d,\n" |
655 | "\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n" | 650 | "\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n" |
656 | "\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n", | 651 | "\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n", |
657 | adapter->physical_port, adapter->switch_mode, | 652 | npar_info->phys_port, npar_info->switch_mode, |
658 | adapter->max_tx_ques, adapter->max_rx_ques, | 653 | npar_info->max_tx_ques, npar_info->max_rx_ques, |
659 | adapter->min_tx_bw, adapter->max_tx_bw, | 654 | npar_info->min_tx_bw, npar_info->max_tx_bw, |
660 | adapter->max_mtu, adapter->capabilities); | 655 | npar_info->max_mtu, npar_info->capabilities); |
661 | } else { | 656 | } else { |
662 | dev_err(&adapter->pdev->dev, | 657 | dev_err(&adapter->pdev->dev, |
663 | "Failed to get nic info%d\n", err); | 658 | "Failed to get nic info%d\n", err); |
@@ -672,7 +667,6 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id) | |||
672 | int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | 667 | int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) |
673 | { | 668 | { |
674 | int err = -EIO; | 669 | int err = -EIO; |
675 | u32 func_state; | ||
676 | dma_addr_t nic_dma_t; | 670 | dma_addr_t nic_dma_t; |
677 | void *nic_info_addr; | 671 | void *nic_info_addr; |
678 | struct qlcnic_info *nic_info; | 672 | struct qlcnic_info *nic_info; |
@@ -681,17 +675,6 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | |||
681 | if (adapter->op_mode != QLCNIC_MGMT_FUNC) | 675 | if (adapter->op_mode != QLCNIC_MGMT_FUNC) |
682 | return err; | 676 | return err; |
683 | 677 | ||
684 | if (qlcnic_api_lock(adapter)) | ||
685 | return err; | ||
686 | |||
687 | func_state = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
688 | if (QLC_DEV_CHECK_ACTIVE(func_state, nic->pci_func)) { | ||
689 | qlcnic_api_unlock(adapter); | ||
690 | return err; | ||
691 | } | ||
692 | |||
693 | qlcnic_api_unlock(adapter); | ||
694 | |||
695 | nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size, | 678 | nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size, |
696 | &nic_dma_t); | 679 | &nic_dma_t); |
697 | if (!nic_info_addr) | 680 | if (!nic_info_addr) |
@@ -716,7 +699,7 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | |||
716 | adapter->fw_hal_version, | 699 | adapter->fw_hal_version, |
717 | MSD(nic_dma_t), | 700 | MSD(nic_dma_t), |
718 | LSD(nic_dma_t), | 701 | LSD(nic_dma_t), |
719 | nic_size, | 702 | ((nic->pci_func << 16) | nic_size), |
720 | QLCNIC_CDRP_CMD_SET_NIC_INFO); | 703 | QLCNIC_CDRP_CMD_SET_NIC_INFO); |
721 | 704 | ||
722 | if (err != QLCNIC_RCODE_SUCCESS) { | 705 | if (err != QLCNIC_RCODE_SUCCESS) { |
@@ -730,7 +713,8 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | |||
730 | } | 713 | } |
731 | 714 | ||
732 | /* Get PCI Info of a partition */ | 715 | /* Get PCI Info of a partition */ |
733 | int qlcnic_get_pci_info(struct qlcnic_adapter *adapter) | 716 | int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, |
717 | struct qlcnic_pci_info *pci_info) | ||
734 | { | 718 | { |
735 | int err = 0, i; | 719 | int err = 0, i; |
736 | dma_addr_t pci_info_dma_t; | 720 | dma_addr_t pci_info_dma_t; |
@@ -745,21 +729,6 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter) | |||
745 | return -ENOMEM; | 729 | return -ENOMEM; |
746 | memset(pci_info_addr, 0, pci_size); | 730 | memset(pci_info_addr, 0, pci_size); |
747 | 731 | ||
748 | if (!adapter->npars) | ||
749 | adapter->npars = kzalloc(pci_size, GFP_KERNEL); | ||
750 | if (!adapter->npars) { | ||
751 | err = -ENOMEM; | ||
752 | goto err_npar; | ||
753 | } | ||
754 | |||
755 | if (!adapter->eswitch) | ||
756 | adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * | ||
757 | QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); | ||
758 | if (!adapter->eswitch) { | ||
759 | err = -ENOMEM; | ||
760 | goto err_eswitch; | ||
761 | } | ||
762 | |||
763 | npar = (struct qlcnic_pci_info *) pci_info_addr; | 732 | npar = (struct qlcnic_pci_info *) pci_info_addr; |
764 | err = qlcnic_issue_cmd(adapter, | 733 | err = qlcnic_issue_cmd(adapter, |
765 | adapter->ahw.pci_func, | 734 | adapter->ahw.pci_func, |
@@ -770,31 +739,24 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter) | |||
770 | QLCNIC_CDRP_CMD_GET_PCI_INFO); | 739 | QLCNIC_CDRP_CMD_GET_PCI_INFO); |
771 | 740 | ||
772 | if (err == QLCNIC_RCODE_SUCCESS) { | 741 | if (err == QLCNIC_RCODE_SUCCESS) { |
773 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++) { | 742 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) { |
774 | adapter->npars[i].id = le32_to_cpu(npar->id); | 743 | pci_info->id = le32_to_cpu(npar->id); |
775 | adapter->npars[i].active = le32_to_cpu(npar->active); | 744 | pci_info->active = le32_to_cpu(npar->active); |
776 | adapter->npars[i].type = le32_to_cpu(npar->type); | 745 | pci_info->type = le32_to_cpu(npar->type); |
777 | adapter->npars[i].default_port = | 746 | pci_info->default_port = |
778 | le32_to_cpu(npar->default_port); | 747 | le32_to_cpu(npar->default_port); |
779 | adapter->npars[i].tx_min_bw = | 748 | pci_info->tx_min_bw = |
780 | le32_to_cpu(npar->tx_min_bw); | 749 | le32_to_cpu(npar->tx_min_bw); |
781 | adapter->npars[i].tx_max_bw = | 750 | pci_info->tx_max_bw = |
782 | le32_to_cpu(npar->tx_max_bw); | 751 | le32_to_cpu(npar->tx_max_bw); |
783 | memcpy(adapter->npars[i].mac, npar->mac, ETH_ALEN); | 752 | memcpy(pci_info->mac, npar->mac, ETH_ALEN); |
784 | } | 753 | } |
785 | } else { | 754 | } else { |
786 | dev_err(&adapter->pdev->dev, | 755 | dev_err(&adapter->pdev->dev, |
787 | "Failed to get PCI Info%d\n", err); | 756 | "Failed to get PCI Info%d\n", err); |
788 | kfree(adapter->npars); | ||
789 | err = -EIO; | 757 | err = -EIO; |
790 | } | 758 | } |
791 | goto err_npar; | ||
792 | |||
793 | err_eswitch: | ||
794 | kfree(adapter->npars); | ||
795 | adapter->npars = NULL; | ||
796 | 759 | ||
797 | err_npar: | ||
798 | pci_free_consistent(adapter->pdev, pci_size, pci_info_addr, | 760 | pci_free_consistent(adapter->pdev, pci_size, pci_info_addr, |
799 | pci_info_dma_t); | 761 | pci_info_dma_t); |
800 | return err; | 762 | return err; |
@@ -1012,9 +974,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id, | |||
1012 | if (err != QLCNIC_RCODE_SUCCESS) { | 974 | if (err != QLCNIC_RCODE_SUCCESS) { |
1013 | dev_err(&adapter->pdev->dev, | 975 | dev_err(&adapter->pdev->dev, |
1014 | "Failed to configure eswitch port%d\n", eswitch->port); | 976 | "Failed to configure eswitch port%d\n", eswitch->port); |
1015 | eswitch->flags |= QLCNIC_SWITCH_ENABLE; | ||
1016 | } else { | 977 | } else { |
1017 | eswitch->flags &= ~QLCNIC_SWITCH_ENABLE; | ||
1018 | dev_info(&adapter->pdev->dev, | 978 | dev_info(&adapter->pdev->dev, |
1019 | "Configured eSwitch for port %d\n", eswitch->port); | 979 | "Configured eSwitch for port %d\n", eswitch->port); |
1020 | } | 980 | } |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 981aa91efc8c..18e2b2e6626d 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -476,6 +476,53 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | |||
476 | } | 476 | } |
477 | 477 | ||
478 | static int | 478 | static int |
479 | qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | ||
480 | { | ||
481 | struct qlcnic_pci_info pci_info[QLCNIC_MAX_PCI_FUNC]; | ||
482 | int i, ret = 0, err; | ||
483 | u8 pfn; | ||
484 | |||
485 | if (!adapter->npars) | ||
486 | adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * | ||
487 | QLCNIC_MAX_PCI_FUNC, GFP_KERNEL); | ||
488 | if (!adapter->npars) | ||
489 | return -ENOMEM; | ||
490 | |||
491 | if (!adapter->eswitch) | ||
492 | adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * | ||
493 | QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); | ||
494 | if (!adapter->eswitch) { | ||
495 | err = -ENOMEM; | ||
496 | goto err_eswitch; | ||
497 | } | ||
498 | |||
499 | ret = qlcnic_get_pci_info(adapter, pci_info); | ||
500 | if (!ret) { | ||
501 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
502 | pfn = pci_info[i].id; | ||
503 | if (pfn > QLCNIC_MAX_PCI_FUNC) | ||
504 | return QL_STATUS_INVALID_PARAM; | ||
505 | adapter->npars[pfn].active = pci_info[i].active; | ||
506 | adapter->npars[pfn].type = pci_info[i].type; | ||
507 | adapter->npars[pfn].phy_port = pci_info[i].default_port; | ||
508 | adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN; | ||
509 | } | ||
510 | |||
511 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) | ||
512 | adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; | ||
513 | |||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | kfree(adapter->eswitch); | ||
518 | adapter->eswitch = NULL; | ||
519 | err_eswitch: | ||
520 | kfree(adapter->npars); | ||
521 | |||
522 | return ret; | ||
523 | } | ||
524 | |||
525 | static int | ||
479 | qlcnic_set_function_modes(struct qlcnic_adapter *adapter) | 526 | qlcnic_set_function_modes(struct qlcnic_adapter *adapter) |
480 | { | 527 | { |
481 | u8 id; | 528 | u8 id; |
@@ -494,7 +541,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) | |||
494 | 541 | ||
495 | if (qlcnic_config_npars) { | 542 | if (qlcnic_config_npars) { |
496 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 543 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { |
497 | id = adapter->npars[i].id; | 544 | id = i; |
498 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC || | 545 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC || |
499 | id == adapter->ahw.pci_func) | 546 | id == adapter->ahw.pci_func) |
500 | continue; | 547 | continue; |
@@ -519,6 +566,7 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) | |||
519 | { | 566 | { |
520 | void __iomem *msix_base_addr; | 567 | void __iomem *msix_base_addr; |
521 | void __iomem *priv_op; | 568 | void __iomem *priv_op; |
569 | struct qlcnic_info nic_info; | ||
522 | u32 func; | 570 | u32 func; |
523 | u32 msix_base; | 571 | u32 msix_base; |
524 | u32 op_mode, priv_level; | 572 | u32 op_mode, priv_level; |
@@ -533,7 +581,14 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) | |||
533 | func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; | 581 | func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; |
534 | adapter->ahw.pci_func = func; | 582 | adapter->ahw.pci_func = func; |
535 | 583 | ||
536 | qlcnic_get_nic_info(adapter, adapter->ahw.pci_func); | 584 | if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) { |
585 | adapter->capabilities = nic_info.capabilities; | ||
586 | |||
587 | if (adapter->capabilities & BIT_6) | ||
588 | adapter->flags |= QLCNIC_ESWITCH_ENABLED; | ||
589 | else | ||
590 | adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; | ||
591 | } | ||
537 | 592 | ||
538 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | 593 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { |
539 | adapter->nic_ops = &qlcnic_ops; | 594 | adapter->nic_ops = &qlcnic_ops; |
@@ -552,7 +607,7 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) | |||
552 | case QLCNIC_MGMT_FUNC: | 607 | case QLCNIC_MGMT_FUNC: |
553 | adapter->op_mode = QLCNIC_MGMT_FUNC; | 608 | adapter->op_mode = QLCNIC_MGMT_FUNC; |
554 | adapter->nic_ops = &qlcnic_ops; | 609 | adapter->nic_ops = &qlcnic_ops; |
555 | qlcnic_get_pci_info(adapter); | 610 | qlcnic_init_pci_info(adapter); |
556 | /* Set privilege level for other functions */ | 611 | /* Set privilege level for other functions */ |
557 | qlcnic_set_function_modes(adapter); | 612 | qlcnic_set_function_modes(adapter); |
558 | dev_info(&adapter->pdev->dev, | 613 | dev_info(&adapter->pdev->dev, |
@@ -654,7 +709,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
654 | int i, offset, val; | 709 | int i, offset, val; |
655 | int *ptr32; | 710 | int *ptr32; |
656 | struct pci_dev *pdev = adapter->pdev; | 711 | struct pci_dev *pdev = adapter->pdev; |
657 | 712 | struct qlcnic_info nic_info; | |
658 | adapter->driver_mismatch = 0; | 713 | adapter->driver_mismatch = 0; |
659 | 714 | ||
660 | ptr32 = (int *)&serial_num; | 715 | ptr32 = (int *)&serial_num; |
@@ -696,7 +751,15 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
696 | adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; | 751 | adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; |
697 | } | 752 | } |
698 | 753 | ||
699 | qlcnic_get_nic_info(adapter, adapter->ahw.pci_func); | 754 | if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) { |
755 | adapter->physical_port = nic_info.phys_port; | ||
756 | adapter->switch_mode = nic_info.switch_mode; | ||
757 | adapter->max_tx_ques = nic_info.max_tx_ques; | ||
758 | adapter->max_rx_ques = nic_info.max_rx_ques; | ||
759 | adapter->capabilities = nic_info.capabilities; | ||
760 | adapter->max_mac_filters = nic_info.max_mac_filters; | ||
761 | adapter->max_mtu = nic_info.max_mtu; | ||
762 | } | ||
700 | 763 | ||
701 | adapter->msix_supported = !!use_msi_x; | 764 | adapter->msix_supported = !!use_msi_x; |
702 | adapter->rss_supported = !!use_msi_x; | 765 | adapter->rss_supported = !!use_msi_x; |
@@ -2822,6 +2885,364 @@ static struct bin_attribute bin_attr_mem = { | |||
2822 | .write = qlcnic_sysfs_write_mem, | 2885 | .write = qlcnic_sysfs_write_mem, |
2823 | }; | 2886 | }; |
2824 | 2887 | ||
2888 | int | ||
2889 | validate_pm_config(struct qlcnic_adapter *adapter, | ||
2890 | struct qlcnic_pm_func_cfg *pm_cfg, int count) | ||
2891 | { | ||
2892 | |||
2893 | u8 src_pci_func, s_esw_id, d_esw_id; | ||
2894 | u8 dest_pci_func; | ||
2895 | int i; | ||
2896 | |||
2897 | for (i = 0; i < count; i++) { | ||
2898 | src_pci_func = pm_cfg[i].pci_func; | ||
2899 | dest_pci_func = pm_cfg[i].dest_npar; | ||
2900 | if (src_pci_func >= QLCNIC_MAX_PCI_FUNC | ||
2901 | || dest_pci_func >= QLCNIC_MAX_PCI_FUNC) | ||
2902 | return QL_STATUS_INVALID_PARAM; | ||
2903 | |||
2904 | if (adapter->npars[src_pci_func].type != QLCNIC_TYPE_NIC) | ||
2905 | return QL_STATUS_INVALID_PARAM; | ||
2906 | |||
2907 | if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) | ||
2908 | return QL_STATUS_INVALID_PARAM; | ||
2909 | |||
2910 | if (!IS_VALID_MODE(pm_cfg[i].action)) | ||
2911 | return QL_STATUS_INVALID_PARAM; | ||
2912 | |||
2913 | s_esw_id = adapter->npars[src_pci_func].phy_port; | ||
2914 | d_esw_id = adapter->npars[dest_pci_func].phy_port; | ||
2915 | |||
2916 | if (s_esw_id != d_esw_id) | ||
2917 | return QL_STATUS_INVALID_PARAM; | ||
2918 | |||
2919 | } | ||
2920 | return 0; | ||
2921 | |||
2922 | } | ||
2923 | |||
2924 | static ssize_t | ||
2925 | qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj, | ||
2926 | struct bin_attribute *attr, char *buf, loff_t offset, size_t size) | ||
2927 | { | ||
2928 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2929 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2930 | struct qlcnic_pm_func_cfg *pm_cfg; | ||
2931 | u32 id, action, pci_func; | ||
2932 | int count, rem, i, ret; | ||
2933 | |||
2934 | count = size / sizeof(struct qlcnic_pm_func_cfg); | ||
2935 | rem = size % sizeof(struct qlcnic_pm_func_cfg); | ||
2936 | if (rem) | ||
2937 | return QL_STATUS_INVALID_PARAM; | ||
2938 | |||
2939 | pm_cfg = (struct qlcnic_pm_func_cfg *) buf; | ||
2940 | |||
2941 | ret = validate_pm_config(adapter, pm_cfg, count); | ||
2942 | if (ret) | ||
2943 | return ret; | ||
2944 | for (i = 0; i < count; i++) { | ||
2945 | pci_func = pm_cfg[i].pci_func; | ||
2946 | action = pm_cfg[i].action; | ||
2947 | id = adapter->npars[pci_func].phy_port; | ||
2948 | ret = qlcnic_config_port_mirroring(adapter, id, | ||
2949 | action, pci_func); | ||
2950 | if (ret) | ||
2951 | return ret; | ||
2952 | } | ||
2953 | |||
2954 | for (i = 0; i < count; i++) { | ||
2955 | pci_func = pm_cfg[i].pci_func; | ||
2956 | id = adapter->npars[pci_func].phy_port; | ||
2957 | adapter->npars[pci_func].enable_pm = pm_cfg[i].action; | ||
2958 | adapter->npars[pci_func].dest_npar = id; | ||
2959 | } | ||
2960 | return size; | ||
2961 | } | ||
2962 | |||
2963 | static ssize_t | ||
2964 | qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj, | ||
2965 | struct bin_attribute *attr, char *buf, loff_t offset, size_t size) | ||
2966 | { | ||
2967 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2968 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
2969 | struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; | ||
2970 | int i; | ||
2971 | |||
2972 | if (size != sizeof(pm_cfg)) | ||
2973 | return QL_STATUS_INVALID_PARAM; | ||
2974 | |||
2975 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
2976 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | ||
2977 | continue; | ||
2978 | pm_cfg[i].action = adapter->npars[i].enable_pm; | ||
2979 | pm_cfg[i].dest_npar = 0; | ||
2980 | pm_cfg[i].pci_func = i; | ||
2981 | } | ||
2982 | memcpy(buf, &pm_cfg, size); | ||
2983 | |||
2984 | return size; | ||
2985 | } | ||
2986 | |||
2987 | int | ||
2988 | validate_esw_config(struct qlcnic_adapter *adapter, | ||
2989 | struct qlcnic_esw_func_cfg *esw_cfg, int count) | ||
2990 | { | ||
2991 | u8 pci_func; | ||
2992 | int i; | ||
2993 | |||
2994 | for (i = 0; i < count; i++) { | ||
2995 | pci_func = esw_cfg[i].pci_func; | ||
2996 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) | ||
2997 | return QL_STATUS_INVALID_PARAM; | ||
2998 | |||
2999 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | ||
3000 | return QL_STATUS_INVALID_PARAM; | ||
3001 | |||
3002 | if (esw_cfg->host_vlan_tag == 1) | ||
3003 | if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) | ||
3004 | return QL_STATUS_INVALID_PARAM; | ||
3005 | |||
3006 | if (!IS_VALID_MODE(esw_cfg[i].promisc_mode) | ||
3007 | || !IS_VALID_MODE(esw_cfg[i].host_vlan_tag) | ||
3008 | || !IS_VALID_MODE(esw_cfg[i].mac_learning) | ||
3009 | || !IS_VALID_MODE(esw_cfg[i].discard_tagged)) | ||
3010 | return QL_STATUS_INVALID_PARAM; | ||
3011 | } | ||
3012 | |||
3013 | return 0; | ||
3014 | } | ||
3015 | |||
3016 | static ssize_t | ||
3017 | qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, | ||
3018 | struct bin_attribute *attr, char *buf, loff_t offset, size_t size) | ||
3019 | { | ||
3020 | struct device *dev = container_of(kobj, struct device, kobj); | ||
3021 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
3022 | struct qlcnic_esw_func_cfg *esw_cfg; | ||
3023 | u8 id, discard_tagged, promsc_mode, mac_learn; | ||
3024 | u8 vlan_tagging, pci_func, vlan_id; | ||
3025 | int count, rem, i, ret; | ||
3026 | |||
3027 | count = size / sizeof(struct qlcnic_esw_func_cfg); | ||
3028 | rem = size % sizeof(struct qlcnic_esw_func_cfg); | ||
3029 | if (rem) | ||
3030 | return QL_STATUS_INVALID_PARAM; | ||
3031 | |||
3032 | esw_cfg = (struct qlcnic_esw_func_cfg *) buf; | ||
3033 | ret = validate_esw_config(adapter, esw_cfg, count); | ||
3034 | if (ret) | ||
3035 | return ret; | ||
3036 | |||
3037 | for (i = 0; i < count; i++) { | ||
3038 | pci_func = esw_cfg[i].pci_func; | ||
3039 | id = adapter->npars[pci_func].phy_port; | ||
3040 | vlan_tagging = esw_cfg[i].host_vlan_tag; | ||
3041 | promsc_mode = esw_cfg[i].promisc_mode; | ||
3042 | mac_learn = esw_cfg[i].mac_learning; | ||
3043 | vlan_id = esw_cfg[i].vlan_id; | ||
3044 | discard_tagged = esw_cfg[i].discard_tagged; | ||
3045 | ret = qlcnic_config_switch_port(adapter, id, vlan_tagging, | ||
3046 | discard_tagged, | ||
3047 | promsc_mode, | ||
3048 | mac_learn, | ||
3049 | pci_func, | ||
3050 | vlan_id); | ||
3051 | if (ret) | ||
3052 | return ret; | ||
3053 | } | ||
3054 | |||
3055 | for (i = 0; i < count; i++) { | ||
3056 | pci_func = esw_cfg[i].pci_func; | ||
3057 | adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode; | ||
3058 | adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning; | ||
3059 | adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id; | ||
3060 | adapter->npars[pci_func].discard_tagged = | ||
3061 | esw_cfg[i].discard_tagged; | ||
3062 | adapter->npars[pci_func].host_vlan_tag = | ||
3063 | esw_cfg[i].host_vlan_tag; | ||
3064 | } | ||
3065 | |||
3066 | return size; | ||
3067 | } | ||
3068 | |||
3069 | static ssize_t | ||
3070 | qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj, | ||
3071 | struct bin_attribute *attr, char *buf, loff_t offset, size_t size) | ||
3072 | { | ||
3073 | struct device *dev = container_of(kobj, struct device, kobj); | ||
3074 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
3075 | struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; | ||
3076 | int i; | ||
3077 | |||
3078 | if (size != sizeof(esw_cfg)) | ||
3079 | return QL_STATUS_INVALID_PARAM; | ||
3080 | |||
3081 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
3082 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | ||
3083 | continue; | ||
3084 | |||
3085 | esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag; | ||
3086 | esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode; | ||
3087 | esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged; | ||
3088 | esw_cfg[i].vlan_id = adapter->npars[i].vlan_id; | ||
3089 | esw_cfg[i].mac_learning = adapter->npars[i].mac_learning; | ||
3090 | } | ||
3091 | memcpy(buf, &esw_cfg, size); | ||
3092 | |||
3093 | return size; | ||
3094 | } | ||
3095 | |||
3096 | int | ||
3097 | validate_npar_config(struct qlcnic_adapter *adapter, | ||
3098 | struct qlcnic_npar_func_cfg *np_cfg, int count) | ||
3099 | { | ||
3100 | u8 pci_func, i; | ||
3101 | |||
3102 | for (i = 0; i < count; i++) { | ||
3103 | pci_func = np_cfg[i].pci_func; | ||
3104 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) | ||
3105 | return QL_STATUS_INVALID_PARAM; | ||
3106 | |||
3107 | if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) | ||
3108 | return QL_STATUS_INVALID_PARAM; | ||
3109 | |||
3110 | if (!IS_VALID_BW(np_cfg[i].min_bw) | ||
3111 | || !IS_VALID_BW(np_cfg[i].max_bw) | ||
3112 | || !IS_VALID_RX_QUEUES(np_cfg[i].max_rx_queues) | ||
3113 | || !IS_VALID_TX_QUEUES(np_cfg[i].max_tx_queues)) | ||
3114 | return QL_STATUS_INVALID_PARAM; | ||
3115 | } | ||
3116 | return 0; | ||
3117 | } | ||
3118 | |||
3119 | static ssize_t | ||
3120 | qlcnic_sysfs_write_npar_config(struct file *file, struct kobject *kobj, | ||
3121 | struct bin_attribute *attr, char *buf, loff_t offset, size_t size) | ||
3122 | { | ||
3123 | struct device *dev = container_of(kobj, struct device, kobj); | ||
3124 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
3125 | struct qlcnic_info nic_info; | ||
3126 | struct qlcnic_npar_func_cfg *np_cfg; | ||
3127 | int i, count, rem, ret; | ||
3128 | u8 pci_func; | ||
3129 | |||
3130 | count = size / sizeof(struct qlcnic_npar_func_cfg); | ||
3131 | rem = size % sizeof(struct qlcnic_npar_func_cfg); | ||
3132 | if (rem) | ||
3133 | return QL_STATUS_INVALID_PARAM; | ||
3134 | |||
3135 | np_cfg = (struct qlcnic_npar_func_cfg *) buf; | ||
3136 | ret = validate_npar_config(adapter, np_cfg, count); | ||
3137 | if (ret) | ||
3138 | return ret; | ||
3139 | |||
3140 | for (i = 0; i < count ; i++) { | ||
3141 | pci_func = np_cfg[i].pci_func; | ||
3142 | ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func); | ||
3143 | if (ret) | ||
3144 | return ret; | ||
3145 | nic_info.pci_func = pci_func; | ||
3146 | nic_info.min_tx_bw = np_cfg[i].min_bw; | ||
3147 | nic_info.max_tx_bw = np_cfg[i].max_bw; | ||
3148 | ret = qlcnic_set_nic_info(adapter, &nic_info); | ||
3149 | if (ret) | ||
3150 | return ret; | ||
3151 | } | ||
3152 | |||
3153 | return size; | ||
3154 | |||
3155 | } | ||
3156 | static ssize_t | ||
3157 | qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj, | ||
3158 | struct bin_attribute *attr, char *buf, loff_t offset, size_t size) | ||
3159 | { | ||
3160 | struct device *dev = container_of(kobj, struct device, kobj); | ||
3161 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
3162 | struct qlcnic_info nic_info; | ||
3163 | struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC]; | ||
3164 | int i, ret; | ||
3165 | |||
3166 | if (size != sizeof(np_cfg)) | ||
3167 | return QL_STATUS_INVALID_PARAM; | ||
3168 | |||
3169 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) { | ||
3170 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | ||
3171 | continue; | ||
3172 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); | ||
3173 | if (ret) | ||
3174 | return ret; | ||
3175 | |||
3176 | np_cfg[i].pci_func = i; | ||
3177 | np_cfg[i].op_mode = nic_info.op_mode; | ||
3178 | np_cfg[i].port_num = nic_info.phys_port; | ||
3179 | np_cfg[i].fw_capab = nic_info.capabilities; | ||
3180 | np_cfg[i].min_bw = nic_info.min_tx_bw ; | ||
3181 | np_cfg[i].max_bw = nic_info.max_tx_bw; | ||
3182 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; | ||
3183 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; | ||
3184 | } | ||
3185 | memcpy(buf, &np_cfg, size); | ||
3186 | return size; | ||
3187 | } | ||
3188 | |||
3189 | static ssize_t | ||
3190 | qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj, | ||
3191 | struct bin_attribute *attr, char *buf, loff_t offset, size_t size) | ||
3192 | { | ||
3193 | struct device *dev = container_of(kobj, struct device, kobj); | ||
3194 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
3195 | struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC]; | ||
3196 | struct qlcnic_pci_info pci_info[QLCNIC_MAX_PCI_FUNC]; | ||
3197 | int i, ret; | ||
3198 | |||
3199 | if (size != sizeof(pci_cfg)) | ||
3200 | return QL_STATUS_INVALID_PARAM; | ||
3201 | |||
3202 | ret = qlcnic_get_pci_info(adapter, pci_info); | ||
3203 | if (ret) | ||
3204 | return ret; | ||
3205 | |||
3206 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) { | ||
3207 | pci_cfg[i].pci_func = pci_info[i].id; | ||
3208 | pci_cfg[i].func_type = pci_info[i].type; | ||
3209 | pci_cfg[i].port_num = pci_info[i].default_port; | ||
3210 | pci_cfg[i].min_bw = pci_info[i].tx_min_bw; | ||
3211 | pci_cfg[i].max_bw = pci_info[i].tx_max_bw; | ||
3212 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); | ||
3213 | } | ||
3214 | memcpy(buf, &pci_cfg, size); | ||
3215 | return size; | ||
3216 | |||
3217 | } | ||
3218 | static struct bin_attribute bin_attr_npar_config = { | ||
3219 | .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)}, | ||
3220 | .size = 0, | ||
3221 | .read = qlcnic_sysfs_read_npar_config, | ||
3222 | .write = qlcnic_sysfs_write_npar_config, | ||
3223 | }; | ||
3224 | |||
3225 | static struct bin_attribute bin_attr_pci_config = { | ||
3226 | .attr = {.name = "pci_config", .mode = (S_IRUGO | S_IWUSR)}, | ||
3227 | .size = 0, | ||
3228 | .read = qlcnic_sysfs_read_pci_config, | ||
3229 | .write = NULL, | ||
3230 | }; | ||
3231 | |||
3232 | static struct bin_attribute bin_attr_esw_config = { | ||
3233 | .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)}, | ||
3234 | .size = 0, | ||
3235 | .read = qlcnic_sysfs_read_esw_config, | ||
3236 | .write = qlcnic_sysfs_write_esw_config, | ||
3237 | }; | ||
3238 | |||
3239 | static struct bin_attribute bin_attr_pm_config = { | ||
3240 | .attr = {.name = "pm_config", .mode = (S_IRUGO | S_IWUSR)}, | ||
3241 | .size = 0, | ||
3242 | .read = qlcnic_sysfs_read_pm_config, | ||
3243 | .write = qlcnic_sysfs_write_pm_config, | ||
3244 | }; | ||
3245 | |||
2825 | static void | 3246 | static void |
2826 | qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) | 3247 | qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) |
2827 | { | 3248 | { |
@@ -2853,6 +3274,18 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | |||
2853 | dev_info(dev, "failed to create crb sysfs entry\n"); | 3274 | dev_info(dev, "failed to create crb sysfs entry\n"); |
2854 | if (device_create_bin_file(dev, &bin_attr_mem)) | 3275 | if (device_create_bin_file(dev, &bin_attr_mem)) |
2855 | dev_info(dev, "failed to create mem sysfs entry\n"); | 3276 | dev_info(dev, "failed to create mem sysfs entry\n"); |
3277 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || | ||
3278 | adapter->op_mode != QLCNIC_MGMT_FUNC) | ||
3279 | return; | ||
3280 | if (device_create_bin_file(dev, &bin_attr_pci_config)) | ||
3281 | dev_info(dev, "failed to create pci config sysfs entry"); | ||
3282 | if (device_create_bin_file(dev, &bin_attr_npar_config)) | ||
3283 | dev_info(dev, "failed to create npar config sysfs entry"); | ||
3284 | if (device_create_bin_file(dev, &bin_attr_esw_config)) | ||
3285 | dev_info(dev, "failed to create esw config sysfs entry"); | ||
3286 | if (device_create_bin_file(dev, &bin_attr_pm_config)) | ||
3287 | dev_info(dev, "failed to create pm config sysfs entry"); | ||
3288 | |||
2856 | } | 3289 | } |
2857 | 3290 | ||
2858 | 3291 | ||
@@ -2864,6 +3297,13 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) | |||
2864 | device_remove_file(dev, &dev_attr_diag_mode); | 3297 | device_remove_file(dev, &dev_attr_diag_mode); |
2865 | device_remove_bin_file(dev, &bin_attr_crb); | 3298 | device_remove_bin_file(dev, &bin_attr_crb); |
2866 | device_remove_bin_file(dev, &bin_attr_mem); | 3299 | device_remove_bin_file(dev, &bin_attr_mem); |
3300 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || | ||
3301 | adapter->op_mode != QLCNIC_MGMT_FUNC) | ||
3302 | return; | ||
3303 | device_remove_bin_file(dev, &bin_attr_pci_config); | ||
3304 | device_remove_bin_file(dev, &bin_attr_npar_config); | ||
3305 | device_remove_bin_file(dev, &bin_attr_esw_config); | ||
3306 | device_remove_bin_file(dev, &bin_attr_pm_config); | ||
2867 | } | 3307 | } |
2868 | 3308 | ||
2869 | #ifdef CONFIG_INET | 3309 | #ifdef CONFIG_INET |