diff options
author | Rajesh Borundia <rajesh.borundia@qlogic.com> | 2010-08-19 01:08:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-19 19:52:38 -0400 |
commit | 4e8acb011f0e9e86e29b53ff051e699ba0c5726d (patch) | |
tree | a8f74029aa29ce99403f283a6c33368bda0762b9 /drivers/net/qlcnic/qlcnic_ctx.c | |
parent | 251b036a22f530aff26cf70f5cdb0cf64a072e46 (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/qlcnic/qlcnic_ctx.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_ctx.c | 174 |
1 files changed, 130 insertions, 44 deletions
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 */ | ||
947 | int 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 | |||
987 | int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, | 945 | int 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 | |||
1070 | static 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 | ||
1097 | op_mode = 0 for setting default port behavior | ||
1098 | op_mode = 1 for setting vlan id | ||
1099 | op_mode = 2 for deleting vlan id | ||
1100 | op_type = 0 for vlan_id | ||
1101 | op_type = 1 for port vlan_id | ||
1102 | */ | ||
1103 | int 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 | |||
1172 | int | ||
1173 | qlcnic_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 | } | ||