aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic
diff options
context:
space:
mode:
authorRajesh K Borundia <rajesh.borundia@qlogic.com>2010-06-29 04:01:20 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-29 18:12:36 -0400
commit346fe763d7706cccdf90ba24f04f0facdd79b91a (patch)
tree45ba5093b60ca7ac2df3b56c882fd97fd3413deb /drivers/net/qlcnic
parent45918e2fe582d845a2649ffa015754ae44be9a8b (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.h77
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c90
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c450
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
1043struct 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};
1045struct qlcnic_eswitch { 1055struct 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
1089struct 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
1099struct 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
1110struct qlcnic_pm_func_cfg {
1111 u8 pci_func;
1112 u8 action;
1113 u8 dest_npar;
1114 u8 reserved[5];
1115};
1116
1117struct 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
1060int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); 1127int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val);
1061int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val); 1128int 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 */
1170int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*); 1237int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*);
1171int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); 1238int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
1172int qlcnic_get_nic_info(struct qlcnic_adapter *, u8); 1239int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8);
1173int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); 1240int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *);
1174int qlcnic_get_pci_info(struct qlcnic_adapter *); 1241int qlcnic_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*);
1175int qlcnic_reset_partition(struct qlcnic_adapter *, u8); 1242int 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 */
614int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id) 614int 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)
672int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) 667int 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 */
733int qlcnic_get_pci_info(struct qlcnic_adapter *adapter) 716int 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
793err_eswitch:
794 kfree(adapter->npars);
795 adapter->npars = NULL;
796 759
797err_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
478static int 478static int
479qlcnic_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;
519err_eswitch:
520 kfree(adapter->npars);
521
522 return ret;
523}
524
525static int
479qlcnic_set_function_modes(struct qlcnic_adapter *adapter) 526qlcnic_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
2888int
2889validate_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
2924static ssize_t
2925qlcnic_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
2963static ssize_t
2964qlcnic_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
2987int
2988validate_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
3016static ssize_t
3017qlcnic_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
3069static ssize_t
3070qlcnic_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
3096int
3097validate_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
3119static ssize_t
3120qlcnic_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}
3156static ssize_t
3157qlcnic_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
3189static ssize_t
3190qlcnic_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}
3218static 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
3225static 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
3232static 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
3239static 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
2825static void 3246static void
2826qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) 3247qlcnic_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