aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorRajesh Borundia <rajesh.borundia@qlogic.com>2010-08-19 01:08:25 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-19 19:52:38 -0400
commit4e8acb011f0e9e86e29b53ff051e699ba0c5726d (patch)
treea8f74029aa29ce99403f283a6c33368bda0762b9 /drivers/net
parent251b036a22f530aff26cf70f5cdb0cf64a072e46 (diff)
qlcnic: configure port on eswitch
o Nic partition capable devices has embedded switch, this needs to support various features like external switch. Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com> Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/qlcnic/qlcnic.h22
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c174
-rw-r--r--drivers/net/qlcnic/qlcnic_hdr.h7
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c185
4 files changed, 254 insertions, 134 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index d19836758c6e..9433a05555f1 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -556,6 +556,7 @@ struct qlcnic_recv_context {
556#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026 556#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026
557#define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027 557#define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027
558#define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028 558#define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028
559#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029
559#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a 560#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a
560 561
561#define QLCNIC_RCODE_SUCCESS 0 562#define QLCNIC_RCODE_SUCCESS 0
@@ -1044,7 +1045,7 @@ struct qlcnic_pci_info {
1044}; 1045};
1045 1046
1046struct qlcnic_npar_info { 1047struct qlcnic_npar_info {
1047 u16 vlan_id; 1048 u16 pvid;
1048 u16 min_bw; 1049 u16 min_bw;
1049 u16 max_bw; 1050 u16 max_bw;
1050 u8 phy_port; 1051 u8 phy_port;
@@ -1052,11 +1053,13 @@ struct qlcnic_npar_info {
1052 u8 active; 1053 u8 active;
1053 u8 enable_pm; 1054 u8 enable_pm;
1054 u8 dest_npar; 1055 u8 dest_npar;
1055 u8 host_vlan_tag;
1056 u8 promisc_mode;
1057 u8 discard_tagged; 1056 u8 discard_tagged;
1058 u8 mac_learning; 1057 u8 mac_learning;
1058 u8 mac_anti_spoof;
1059 u8 promisc_mode;
1060 u8 offload_flags;
1059}; 1061};
1062
1060struct qlcnic_eswitch { 1063struct qlcnic_eswitch {
1061 u8 port; 1064 u8 port;
1062 u8 active_vports; 1065 u8 active_vports;
@@ -1088,7 +1091,6 @@ struct qlcnic_eswitch {
1088#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW) 1091#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW)
1089#define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) 1092#define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES)
1090#define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) 1093#define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES)
1091#define IS_VALID_MODE(mode) (mode == 0 || mode == 1)
1092 1094
1093struct qlcnic_pci_func_cfg { 1095struct qlcnic_pci_func_cfg {
1094 u16 func_type; 1096 u16 func_type;
@@ -1120,12 +1122,16 @@ struct qlcnic_pm_func_cfg {
1120 1122
1121struct qlcnic_esw_func_cfg { 1123struct qlcnic_esw_func_cfg {
1122 u16 vlan_id; 1124 u16 vlan_id;
1125 u8 op_mode;
1126 u8 op_type;
1123 u8 pci_func; 1127 u8 pci_func;
1124 u8 host_vlan_tag; 1128 u8 host_vlan_tag;
1125 u8 promisc_mode; 1129 u8 promisc_mode;
1126 u8 discard_tagged; 1130 u8 discard_tagged;
1127 u8 mac_learning; 1131 u8 mac_learning;
1128 u8 reserved; 1132 u8 mac_anti_spoof;
1133 u8 offload_flags;
1134 u8 reserved[5];
1129}; 1135};
1130 1136
1131#define QLCNIC_STATS_VERSION 1 1137#define QLCNIC_STATS_VERSION 1
@@ -1276,8 +1282,10 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8,
1276int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8, 1282int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8,
1277 struct qlcnic_eswitch *); 1283 struct qlcnic_eswitch *);
1278int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8); 1284int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8);
1279int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8, 1285int qlcnic_config_switch_port(struct qlcnic_adapter *,
1280 u8, u8, u16); 1286 struct qlcnic_esw_func_cfg *);
1287int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *,
1288 struct qlcnic_esw_func_cfg *);
1281int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8); 1289int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
1282int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8, 1290int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8,
1283 struct __qlcnic_esw_statistics *); 1291 struct __qlcnic_esw_statistics *);
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 57c9b09bd16a..74ae3b0a5ea8 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -813,9 +813,8 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port,
813 arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); 813 arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
814 814
815 eswitch->port = arg1 & 0xf; 815 eswitch->port = arg1 & 0xf;
816 eswitch->active_vports = LSB(arg2); 816 eswitch->max_ucast_filters = LSW(arg2);
817 eswitch->max_ucast_filters = MSB(arg2); 817 eswitch->max_active_vlans = MSW(arg2) & 0xfff;
818 eswitch->max_active_vlans = LSB(MSW(arg2));
819 if (arg1 & BIT_6) 818 if (arg1 & BIT_6)
820 eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; 819 eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING;
821 if (arg1 & BIT_7) 820 if (arg1 & BIT_7)
@@ -943,47 +942,6 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
943 return err; 942 return err;
944} 943}
945 944
946/* Configure eSwitch port */
947int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
948 int vlan_tagging, u8 discard_tagged, u8 promsc_mode,
949 u8 mac_learn, u8 pci_func, u16 vlan_id)
950{
951 int err = -EIO;
952 u32 arg1;
953 struct qlcnic_eswitch *eswitch;
954
955 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
956 return err;
957
958 eswitch = &adapter->eswitch[id];
959 if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE))
960 return err;
961
962 arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0);
963 arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0);
964 arg1 |= pci_func << 8;
965 if (vlan_tagging)
966 arg1 |= BIT_5 | (vlan_id << 16);
967
968 err = qlcnic_issue_cmd(adapter,
969 adapter->ahw.pci_func,
970 adapter->fw_hal_version,
971 arg1,
972 0,
973 0,
974 QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH);
975
976 if (err != QLCNIC_RCODE_SUCCESS) {
977 dev_err(&adapter->pdev->dev,
978 "Failed to configure eswitch port%d\n", eswitch->port);
979 } else {
980 dev_info(&adapter->pdev->dev,
981 "Configured eSwitch for port %d\n", eswitch->port);
982 }
983
984 return err;
985}
986
987int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, 945int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
988 const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { 946 const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
989 947
@@ -1108,3 +1066,131 @@ err_ret:
1108 "rx_ctx=%d\n", func_esw, port, rx_tx); 1066 "rx_ctx=%d\n", func_esw, port, rx_tx);
1109 return -EIO; 1067 return -EIO;
1110} 1068}
1069
1070static int
1071__qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
1072 u32 *arg1, u32 *arg2)
1073{
1074 int err = -EIO;
1075 u8 pci_func;
1076 pci_func = (*arg1 >> 8);
1077 err = qlcnic_issue_cmd(adapter,
1078 adapter->ahw.pci_func,
1079 adapter->fw_hal_version,
1080 *arg1,
1081 0,
1082 0,
1083 QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG);
1084
1085 if (err == QLCNIC_RCODE_SUCCESS) {
1086 *arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
1087 *arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
1088 dev_info(&adapter->pdev->dev,
1089 "eSwitch port config for pci func%d\n", pci_func);
1090 } else {
1091 dev_err(&adapter->pdev->dev,
1092 "Failed to get eswitch port config%d\n", pci_func);
1093 }
1094 return err;
1095}
1096/* Configure eSwitch port
1097op_mode = 0 for setting default port behavior
1098op_mode = 1 for setting vlan id
1099op_mode = 2 for deleting vlan id
1100op_type = 0 for vlan_id
1101op_type = 1 for port vlan_id
1102*/
1103int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
1104 struct qlcnic_esw_func_cfg *esw_cfg)
1105{
1106 int err = -EIO;
1107 u32 arg1, arg2 = 0;
1108 u8 pci_func;
1109
1110 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
1111 return err;
1112 pci_func = esw_cfg->pci_func;
1113 arg1 = (adapter->npars[pci_func].phy_port & BIT_0);
1114 arg1 |= (pci_func << 8);
1115
1116 if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
1117 return err;
1118 arg1 &= ~(0x0ff << 8);
1119 arg1 |= (pci_func << 8);
1120 arg1 &= ~(BIT_2 | BIT_3);
1121 switch (esw_cfg->op_mode) {
1122 case QLCNIC_PORT_DEFAULTS:
1123 arg1 |= (BIT_4 | BIT_6 | BIT_7);
1124 arg2 |= (BIT_0 | BIT_1);
1125 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
1126 arg2 |= (BIT_2 | BIT_3);
1127 if (!(esw_cfg->discard_tagged))
1128 arg1 &= ~BIT_4;
1129 if (!(esw_cfg->promisc_mode))
1130 arg1 &= ~BIT_6;
1131 if (!(esw_cfg->mac_learning))
1132 arg1 &= ~BIT_7;
1133 if (!(esw_cfg->mac_anti_spoof))
1134 arg2 &= ~BIT_0;
1135 if (!(esw_cfg->offload_flags & BIT_0))
1136 arg2 &= ~(BIT_1 | BIT_2 | BIT_3);
1137 if (!(esw_cfg->offload_flags & BIT_1))
1138 arg2 &= ~BIT_2;
1139 if (!(esw_cfg->offload_flags & BIT_2))
1140 arg2 &= ~BIT_3;
1141 break;
1142 case QLCNIC_ADD_VLAN:
1143 arg1 |= (BIT_2 | BIT_5);
1144 arg1 |= (esw_cfg->vlan_id << 16);
1145 break;
1146 case QLCNIC_DEL_VLAN:
1147 arg1 |= (BIT_3 | BIT_5);
1148 arg1 &= ~(0x0ffff << 16);
1149 default:
1150 return err;
1151 }
1152
1153 err = qlcnic_issue_cmd(adapter,
1154 adapter->ahw.pci_func,
1155 adapter->fw_hal_version,
1156 arg1,
1157 arg2,
1158 0,
1159 QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH);
1160
1161 if (err != QLCNIC_RCODE_SUCCESS) {
1162 dev_err(&adapter->pdev->dev,
1163 "Failed to configure eswitch port%d\n", pci_func);
1164 } else {
1165 dev_info(&adapter->pdev->dev,
1166 "Configured eSwitch for port %d\n", pci_func);
1167 }
1168
1169 return err;
1170}
1171
1172int
1173qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
1174 struct qlcnic_esw_func_cfg *esw_cfg)
1175{
1176 u32 arg1, arg2;
1177 u8 phy_port;
1178 if (adapter->op_mode == QLCNIC_MGMT_FUNC)
1179 phy_port = adapter->npars[esw_cfg->pci_func].phy_port;
1180 else
1181 phy_port = adapter->physical_port;
1182 arg1 = phy_port;
1183 arg1 |= (esw_cfg->pci_func << 8);
1184 if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
1185 return -EIO;
1186
1187 esw_cfg->discard_tagged = !!(arg1 & BIT_4);
1188 esw_cfg->host_vlan_tag = !!(arg1 & BIT_5);
1189 esw_cfg->promisc_mode = !!(arg1 & BIT_6);
1190 esw_cfg->mac_learning = !!(arg1 & BIT_7);
1191 esw_cfg->vlan_id = LSW(arg1 >> 16);
1192 esw_cfg->mac_anti_spoof = (arg2 & 0x1);
1193 esw_cfg->offload_flags = ((arg2 >> 1) & 0x7);
1194
1195 return 0;
1196}
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 39db4df0f650..eae03b5b0323 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -775,6 +775,7 @@ struct qlcnic_legacy_intr_set {
775#define QLCNIC_DRV_OP_MODE 0x1b2170 775#define QLCNIC_DRV_OP_MODE 0x1b2170
776#define QLCNIC_MSIX_BASE 0x132110 776#define QLCNIC_MSIX_BASE 0x132110
777#define QLCNIC_MAX_PCI_FUNC 8 777#define QLCNIC_MAX_PCI_FUNC 8
778#define QLCNIC_MAX_VLAN_FILTERS 64
778 779
779/* PCI function operational mode */ 780/* PCI function operational mode */
780enum { 781enum {
@@ -783,6 +784,12 @@ enum {
783 QLCNIC_NON_PRIV_FUNC = 2 784 QLCNIC_NON_PRIV_FUNC = 2
784}; 785};
785 786
787enum {
788 QLCNIC_PORT_DEFAULTS = 0,
789 QLCNIC_ADD_VLAN = 1,
790 QLCNIC_DEL_VLAN = 2
791};
792
786#define QLC_DEV_DRV_DEFAULT 0x11111111 793#define QLC_DEV_DRV_DEFAULT 0x11111111
787 794
788#define LSB(x) ((uint8_t)(x)) 795#define LSB(x) ((uint8_t)(x))
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index c6f19c961c3d..7bb32859b928 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -506,7 +506,6 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
506 adapter->npars[pfn].active = pci_info[i].active; 506 adapter->npars[pfn].active = pci_info[i].active;
507 adapter->npars[pfn].type = pci_info[i].type; 507 adapter->npars[pfn].type = pci_info[i].type;
508 adapter->npars[pfn].phy_port = pci_info[i].default_port; 508 adapter->npars[pfn].phy_port = pci_info[i].default_port;
509 adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN;
510 adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; 509 adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
511 adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; 510 adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
512 } 511 }
@@ -758,47 +757,64 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
758} 757}
759 758
760static int 759static int
760qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
761 struct qlcnic_npar_info *npar, int pci_func)
762{
763 struct qlcnic_esw_func_cfg esw_cfg;
764 esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS;
765 esw_cfg.pci_func = pci_func;
766 esw_cfg.vlan_id = npar->pvid;
767 esw_cfg.mac_learning = npar->mac_learning;
768 esw_cfg.discard_tagged = npar->discard_tagged;
769 esw_cfg.mac_anti_spoof = npar->mac_anti_spoof;
770 esw_cfg.offload_flags = npar->offload_flags;
771 esw_cfg.promisc_mode = npar->promisc_mode;
772 if (qlcnic_config_switch_port(adapter, &esw_cfg))
773 return -EIO;
774
775 esw_cfg.op_mode = QLCNIC_ADD_VLAN;
776 if (qlcnic_config_switch_port(adapter, &esw_cfg))
777 return -EIO;
778
779 return 0;
780}
781
782static int
761qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) 783qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
762{ 784{
763 int i, err = 0; 785 int i, err;
764 struct qlcnic_npar_info *npar; 786 struct qlcnic_npar_info *npar;
765 struct qlcnic_info nic_info; 787 struct qlcnic_info nic_info;
766 788
767 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 789 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
768 !adapter->need_fw_reset) 790 !adapter->need_fw_reset || adapter->op_mode != QLCNIC_MGMT_FUNC)
769 return 0; 791 return 0;
770 792
771 if (adapter->op_mode == QLCNIC_MGMT_FUNC) { 793 /* Set the NPAR config data after FW reset */
772 /* Set the NPAR config data after FW reset */ 794 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
773 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { 795 npar = &adapter->npars[i];
774 npar = &adapter->npars[i]; 796 if (npar->type != QLCNIC_TYPE_NIC)
775 if (npar->type != QLCNIC_TYPE_NIC) 797 continue;
776 continue; 798 err = qlcnic_get_nic_info(adapter, &nic_info, i);
777 err = qlcnic_get_nic_info(adapter, &nic_info, i); 799 if (err)
778 if (err) 800 return err;
779 goto err_out; 801 nic_info.min_tx_bw = npar->min_bw;
780 nic_info.min_tx_bw = npar->min_bw; 802 nic_info.max_tx_bw = npar->max_bw;
781 nic_info.max_tx_bw = npar->max_bw; 803 err = qlcnic_set_nic_info(adapter, &nic_info);
782 err = qlcnic_set_nic_info(adapter, &nic_info); 804 if (err)
783 if (err) 805 return err;
784 goto err_out;
785
786 if (npar->enable_pm) {
787 err = qlcnic_config_port_mirroring(adapter,
788 npar->dest_npar, 1, i);
789 if (err)
790 goto err_out;
791 806
792 } 807 if (npar->enable_pm) {
793 npar->mac_learning = DEFAULT_MAC_LEARN; 808 err = qlcnic_config_port_mirroring(adapter,
794 npar->host_vlan_tag = 0; 809 npar->dest_npar, 1, i);
795 npar->promisc_mode = 0; 810 if (err)
796 npar->discard_tagged = 0; 811 return err;
797 npar->vlan_id = 0;
798 } 812 }
813 err = qlcnic_reset_eswitch_config(adapter, npar, i);
814 if (err)
815 return err;
799 } 816 }
800err_out: 817 return 0;
801 return err;
802} 818}
803 819
804static int 820static int
@@ -863,12 +879,10 @@ wait_init:
863 879
864 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 880 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
865 qlcnic_idc_debug_info(adapter, 1); 881 qlcnic_idc_debug_info(adapter, 1);
866
867 qlcnic_check_options(adapter);
868 if (qlcnic_reset_npar_config(adapter)) 882 if (qlcnic_reset_npar_config(adapter))
869 goto err_out; 883 goto err_out;
870 qlcnic_dev_set_npar_ready(adapter); 884 qlcnic_dev_set_npar_ready(adapter);
871 885 qlcnic_check_options(adapter);
872 adapter->need_fw_reset = 0; 886 adapter->need_fw_reset = 0;
873 887
874 qlcnic_release_firmware(adapter); 888 qlcnic_release_firmware(adapter);
@@ -3082,9 +3096,6 @@ validate_pm_config(struct qlcnic_adapter *adapter,
3082 if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) 3096 if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC)
3083 return QL_STATUS_INVALID_PARAM; 3097 return QL_STATUS_INVALID_PARAM;
3084 3098
3085 if (!IS_VALID_MODE(pm_cfg[i].action))
3086 return QL_STATUS_INVALID_PARAM;
3087
3088 s_esw_id = adapter->npars[src_pci_func].phy_port; 3099 s_esw_id = adapter->npars[src_pci_func].phy_port;
3089 d_esw_id = adapter->npars[dest_pci_func].phy_port; 3100 d_esw_id = adapter->npars[dest_pci_func].phy_port;
3090 3101
@@ -3118,7 +3129,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
3118 return ret; 3129 return ret;
3119 for (i = 0; i < count; i++) { 3130 for (i = 0; i < count; i++) {
3120 pci_func = pm_cfg[i].pci_func; 3131 pci_func = pm_cfg[i].pci_func;
3121 action = pm_cfg[i].action; 3132 action = !!pm_cfg[i].action;
3122 id = adapter->npars[pci_func].phy_port; 3133 id = adapter->npars[pci_func].phy_port;
3123 ret = qlcnic_config_port_mirroring(adapter, id, 3134 ret = qlcnic_config_port_mirroring(adapter, id,
3124 action, pci_func); 3135 action, pci_func);
@@ -3129,7 +3140,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
3129 for (i = 0; i < count; i++) { 3140 for (i = 0; i < count; i++) {
3130 pci_func = pm_cfg[i].pci_func; 3141 pci_func = pm_cfg[i].pci_func;
3131 id = adapter->npars[pci_func].phy_port; 3142 id = adapter->npars[pci_func].phy_port;
3132 adapter->npars[pci_func].enable_pm = pm_cfg[i].action; 3143 adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action;
3133 adapter->npars[pci_func].dest_npar = id; 3144 adapter->npars[pci_func].dest_npar = id;
3134 } 3145 }
3135 return size; 3146 return size;
@@ -3161,30 +3172,38 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj,
3161 3172
3162static int 3173static int
3163validate_esw_config(struct qlcnic_adapter *adapter, 3174validate_esw_config(struct qlcnic_adapter *adapter,
3164 struct qlcnic_esw_func_cfg *esw_cfg, int count) 3175 struct qlcnic_esw_func_cfg *esw_cfg, int count)
3165{ 3176{
3166 u8 pci_func; 3177 u8 pci_func;
3167 int i; 3178 int i;
3168
3169 for (i = 0; i < count; i++) { 3179 for (i = 0; i < count; i++) {
3170 pci_func = esw_cfg[i].pci_func; 3180 pci_func = esw_cfg[i].pci_func;
3171 if (pci_func >= QLCNIC_MAX_PCI_FUNC) 3181 if (pci_func >= QLCNIC_MAX_PCI_FUNC)
3172 return QL_STATUS_INVALID_PARAM; 3182 return QL_STATUS_INVALID_PARAM;
3173 3183
3174 if (adapter->npars[i].type != QLCNIC_TYPE_NIC) 3184 if (adapter->op_mode == QLCNIC_MGMT_FUNC)
3175 return QL_STATUS_INVALID_PARAM; 3185 if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
3186 return QL_STATUS_INVALID_PARAM;
3176 3187
3177 if (esw_cfg->host_vlan_tag == 1) 3188 switch (esw_cfg[i].op_mode) {
3189 case QLCNIC_PORT_DEFAULTS:
3190 break;
3191 case QLCNIC_ADD_VLAN:
3178 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) 3192 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
3179 return QL_STATUS_INVALID_PARAM; 3193 return QL_STATUS_INVALID_PARAM;
3180 3194 if (!esw_cfg[i].op_type)
3181 if (!IS_VALID_MODE(esw_cfg[i].promisc_mode) 3195 return QL_STATUS_INVALID_PARAM;
3182 || !IS_VALID_MODE(esw_cfg[i].host_vlan_tag) 3196 break;
3183 || !IS_VALID_MODE(esw_cfg[i].mac_learning) 3197 case QLCNIC_DEL_VLAN:
3184 || !IS_VALID_MODE(esw_cfg[i].discard_tagged)) 3198 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
3199 return QL_STATUS_INVALID_PARAM;
3200 if (!esw_cfg[i].op_type)
3201 return QL_STATUS_INVALID_PARAM;
3202 break;
3203 default:
3185 return QL_STATUS_INVALID_PARAM; 3204 return QL_STATUS_INVALID_PARAM;
3205 }
3186 } 3206 }
3187
3188 return 0; 3207 return 0;
3189} 3208}
3190 3209
@@ -3195,8 +3214,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
3195 struct device *dev = container_of(kobj, struct device, kobj); 3214 struct device *dev = container_of(kobj, struct device, kobj);
3196 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 3215 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
3197 struct qlcnic_esw_func_cfg *esw_cfg; 3216 struct qlcnic_esw_func_cfg *esw_cfg;
3217 struct qlcnic_npar_info *npar;
3198 int count, rem, i, ret; 3218 int count, rem, i, ret;
3199 u8 id, pci_func; 3219 u8 pci_func;
3200 3220
3201 count = size / sizeof(struct qlcnic_esw_func_cfg); 3221 count = size / sizeof(struct qlcnic_esw_func_cfg);
3202 rem = size % sizeof(struct qlcnic_esw_func_cfg); 3222 rem = size % sizeof(struct qlcnic_esw_func_cfg);
@@ -3209,28 +3229,28 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
3209 return ret; 3229 return ret;
3210 3230
3211 for (i = 0; i < count; i++) { 3231 for (i = 0; i < count; i++) {
3212 pci_func = esw_cfg[i].pci_func; 3232 if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
3213 id = adapter->npars[pci_func].phy_port; 3233 return QL_STATUS_INVALID_PARAM;
3214 ret = qlcnic_config_switch_port(adapter, id,
3215 esw_cfg[i].host_vlan_tag,
3216 esw_cfg[i].discard_tagged,
3217 esw_cfg[i].promisc_mode,
3218 esw_cfg[i].mac_learning,
3219 esw_cfg[i].pci_func,
3220 esw_cfg[i].vlan_id);
3221 if (ret)
3222 return ret;
3223 } 3234 }
3224 3235
3225 for (i = 0; i < count; i++) { 3236 for (i = 0; i < count; i++) {
3226 pci_func = esw_cfg[i].pci_func; 3237 pci_func = esw_cfg[i].pci_func;
3227 adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode; 3238 npar = &adapter->npars[pci_func];
3228 adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning; 3239 switch (esw_cfg[i].op_mode) {
3229 adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id; 3240 case QLCNIC_PORT_DEFAULTS:
3230 adapter->npars[pci_func].discard_tagged = 3241 npar->promisc_mode = esw_cfg[i].promisc_mode;
3231 esw_cfg[i].discard_tagged; 3242 npar->mac_learning = esw_cfg[i].mac_learning;
3232 adapter->npars[pci_func].host_vlan_tag = 3243 npar->offload_flags = esw_cfg[i].offload_flags;
3233 esw_cfg[i].host_vlan_tag; 3244 npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
3245 npar->discard_tagged = esw_cfg[i].discard_tagged;
3246 break;
3247 case QLCNIC_ADD_VLAN:
3248 npar->pvid = esw_cfg[i].vlan_id;
3249 break;
3250 case QLCNIC_DEL_VLAN:
3251 npar->pvid = 0;
3252 break;
3253 }
3234 } 3254 }
3235 3255
3236 return size; 3256 return size;
@@ -3243,7 +3263,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
3243 struct device *dev = container_of(kobj, struct device, kobj); 3263 struct device *dev = container_of(kobj, struct device, kobj);
3244 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 3264 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
3245 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; 3265 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
3246 int i; 3266 u8 i;
3247 3267
3248 if (size != sizeof(esw_cfg)) 3268 if (size != sizeof(esw_cfg))
3249 return QL_STATUS_INVALID_PARAM; 3269 return QL_STATUS_INVALID_PARAM;
@@ -3251,12 +3271,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
3251 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { 3271 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
3252 if (adapter->npars[i].type != QLCNIC_TYPE_NIC) 3272 if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
3253 continue; 3273 continue;
3254 3274 esw_cfg[i].pci_func = i;
3255 esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag; 3275 if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]))
3256 esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode; 3276 return QL_STATUS_INVALID_PARAM;
3257 esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged;
3258 esw_cfg[i].vlan_id = adapter->npars[i].vlan_id;
3259 esw_cfg[i].mac_learning = adapter->npars[i].mac_learning;
3260 } 3277 }
3261 memcpy(buf, &esw_cfg, size); 3278 memcpy(buf, &esw_cfg, size);
3262 3279
@@ -3580,15 +3597,16 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
3580 dev_info(dev, "failed to create crb sysfs entry\n"); 3597 dev_info(dev, "failed to create crb sysfs entry\n");
3581 if (device_create_bin_file(dev, &bin_attr_mem)) 3598 if (device_create_bin_file(dev, &bin_attr_mem))
3582 dev_info(dev, "failed to create mem sysfs entry\n"); 3599 dev_info(dev, "failed to create mem sysfs entry\n");
3583 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 3600 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
3584 adapter->op_mode != QLCNIC_MGMT_FUNC) 3601 return;
3602 if (device_create_bin_file(dev, &bin_attr_esw_config))
3603 dev_info(dev, "failed to create esw config sysfs entry");
3604 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
3585 return; 3605 return;
3586 if (device_create_bin_file(dev, &bin_attr_pci_config)) 3606 if (device_create_bin_file(dev, &bin_attr_pci_config))
3587 dev_info(dev, "failed to create pci config sysfs entry"); 3607 dev_info(dev, "failed to create pci config sysfs entry");
3588 if (device_create_bin_file(dev, &bin_attr_npar_config)) 3608 if (device_create_bin_file(dev, &bin_attr_npar_config))
3589 dev_info(dev, "failed to create npar config sysfs entry"); 3609 dev_info(dev, "failed to create npar config sysfs entry");
3590 if (device_create_bin_file(dev, &bin_attr_esw_config))
3591 dev_info(dev, "failed to create esw config sysfs entry");
3592 if (device_create_bin_file(dev, &bin_attr_pm_config)) 3610 if (device_create_bin_file(dev, &bin_attr_pm_config))
3593 dev_info(dev, "failed to create pm config sysfs entry"); 3611 dev_info(dev, "failed to create pm config sysfs entry");
3594 if (device_create_bin_file(dev, &bin_attr_esw_stats)) 3612 if (device_create_bin_file(dev, &bin_attr_esw_stats))
@@ -3607,12 +3625,13 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
3607 device_remove_file(dev, &dev_attr_diag_mode); 3625 device_remove_file(dev, &dev_attr_diag_mode);
3608 device_remove_bin_file(dev, &bin_attr_crb); 3626 device_remove_bin_file(dev, &bin_attr_crb);
3609 device_remove_bin_file(dev, &bin_attr_mem); 3627 device_remove_bin_file(dev, &bin_attr_mem);
3610 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 3628 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
3611 adapter->op_mode != QLCNIC_MGMT_FUNC) 3629 return;
3630 device_remove_bin_file(dev, &bin_attr_esw_config);
3631 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
3612 return; 3632 return;
3613 device_remove_bin_file(dev, &bin_attr_pci_config); 3633 device_remove_bin_file(dev, &bin_attr_pci_config);
3614 device_remove_bin_file(dev, &bin_attr_npar_config); 3634 device_remove_bin_file(dev, &bin_attr_npar_config);
3615 device_remove_bin_file(dev, &bin_attr_esw_config);
3616 device_remove_bin_file(dev, &bin_attr_pm_config); 3635 device_remove_bin_file(dev, &bin_attr_pm_config);
3617 device_remove_bin_file(dev, &bin_attr_esw_stats); 3636 device_remove_bin_file(dev, &bin_attr_esw_stats);
3618} 3637}