aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h3
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c118
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.c192
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.h15
4 files changed, 232 insertions, 96 deletions
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 8c5cfb53b178..fe0c29acdbe6 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -96,7 +96,7 @@ struct enic {
96#ifdef CONFIG_PCI_IOV 96#ifdef CONFIG_PCI_IOV
97 u32 num_vfs; 97 u32 num_vfs;
98#endif 98#endif
99 struct enic_port_profile pp; 99 struct enic_port_profile *pp;
100 100
101 /* work queue cache line section */ 101 /* work queue cache line section */
102 ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; 102 ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
@@ -130,5 +130,6 @@ static inline struct device *enic_get_dev(struct enic *enic)
130void enic_reset_addr_lists(struct enic *enic); 130void enic_reset_addr_lists(struct enic *enic);
131int enic_sriov_enabled(struct enic *enic); 131int enic_sriov_enabled(struct enic *enic);
132int enic_is_valid_vf(struct enic *enic, int vf); 132int enic_is_valid_vf(struct enic *enic, int vf);
133int enic_is_dynamic(struct enic *enic);
133 134
134#endif /* _ENIC_H_ */ 135#endif /* _ENIC_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 59ba590c0526..aeab6cd44fcf 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -122,7 +122,7 @@ static const struct enic_stat enic_rx_stats[] = {
122static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats); 122static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats);
123static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats); 123static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats);
124 124
125static int enic_is_dynamic(struct enic *enic) 125int enic_is_dynamic(struct enic *enic)
126{ 126{
127 return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN; 127 return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
128} 128}
@@ -1054,15 +1054,15 @@ static void enic_tx_timeout(struct net_device *netdev)
1054static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) 1054static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
1055{ 1055{
1056 struct enic *enic = netdev_priv(netdev); 1056 struct enic *enic = netdev_priv(netdev);
1057 struct enic_port_profile *pp;
1058 int err;
1057 1059
1058 if (vf != PORT_SELF_VF) 1060 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
1059 return -EOPNOTSUPP; 1061 if (err)
1062 return err;
1060 1063
1061 /* Ignore the vf argument for now. We can assume the request
1062 * is coming on a vf.
1063 */
1064 if (is_valid_ether_addr(mac)) { 1064 if (is_valid_ether_addr(mac)) {
1065 memcpy(enic->pp.vf_mac, mac, ETH_ALEN); 1065 memcpy(pp->vf_mac, mac, ETH_ALEN);
1066 return 0; 1066 return 0;
1067 } else 1067 } else
1068 return -EINVAL; 1068 return -EINVAL;
@@ -1073,71 +1073,74 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
1073{ 1073{
1074 struct enic *enic = netdev_priv(netdev); 1074 struct enic *enic = netdev_priv(netdev);
1075 struct enic_port_profile prev_pp; 1075 struct enic_port_profile prev_pp;
1076 struct enic_port_profile *pp;
1076 int err = 0, restore_pp = 1; 1077 int err = 0, restore_pp = 1;
1077 1078
1078 /* don't support VFs, yet */ 1079 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
1079 if (vf != PORT_SELF_VF) 1080 if (err)
1080 return -EOPNOTSUPP; 1081 return err;
1081 1082
1082 if (!port[IFLA_PORT_REQUEST]) 1083 if (!port[IFLA_PORT_REQUEST])
1083 return -EOPNOTSUPP; 1084 return -EOPNOTSUPP;
1084 1085
1085 memcpy(&prev_pp, &enic->pp, sizeof(enic->pp)); 1086 memcpy(&prev_pp, pp, sizeof(*enic->pp));
1086 memset(&enic->pp, 0, sizeof(enic->pp)); 1087 memset(pp, 0, sizeof(*enic->pp));
1087 1088
1088 enic->pp.set |= ENIC_SET_REQUEST; 1089 pp->set |= ENIC_SET_REQUEST;
1089 enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); 1090 pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]);
1090 1091
1091 if (port[IFLA_PORT_PROFILE]) { 1092 if (port[IFLA_PORT_PROFILE]) {
1092 enic->pp.set |= ENIC_SET_NAME; 1093 pp->set |= ENIC_SET_NAME;
1093 memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]), 1094 memcpy(pp->name, nla_data(port[IFLA_PORT_PROFILE]),
1094 PORT_PROFILE_MAX); 1095 PORT_PROFILE_MAX);
1095 } 1096 }
1096 1097
1097 if (port[IFLA_PORT_INSTANCE_UUID]) { 1098 if (port[IFLA_PORT_INSTANCE_UUID]) {
1098 enic->pp.set |= ENIC_SET_INSTANCE; 1099 pp->set |= ENIC_SET_INSTANCE;
1099 memcpy(enic->pp.instance_uuid, 1100 memcpy(pp->instance_uuid,
1100 nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); 1101 nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
1101 } 1102 }
1102 1103
1103 if (port[IFLA_PORT_HOST_UUID]) { 1104 if (port[IFLA_PORT_HOST_UUID]) {
1104 enic->pp.set |= ENIC_SET_HOST; 1105 pp->set |= ENIC_SET_HOST;
1105 memcpy(enic->pp.host_uuid, 1106 memcpy(pp->host_uuid,
1106 nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); 1107 nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
1107 } 1108 }
1108 1109
1109 /* Special case handling: mac came from IFLA_VF_MAC */ 1110 /* Special case handling: mac came from IFLA_VF_MAC */
1110 if (!is_zero_ether_addr(prev_pp.vf_mac)) 1111 if (!is_zero_ether_addr(prev_pp.vf_mac))
1111 memcpy(enic->pp.mac_addr, prev_pp.vf_mac, ETH_ALEN); 1112 memcpy(pp->mac_addr, prev_pp.vf_mac, ETH_ALEN);
1112 1113
1113 if (is_zero_ether_addr(netdev->dev_addr)) 1114 if (vf == PORT_SELF_VF && is_zero_ether_addr(netdev->dev_addr))
1114 random_ether_addr(netdev->dev_addr); 1115 random_ether_addr(netdev->dev_addr);
1115 1116
1116 err = enic_process_set_pp_request(enic, &prev_pp, &restore_pp); 1117 err = enic_process_set_pp_request(enic, vf, &prev_pp, &restore_pp);
1117 if (err) { 1118 if (err) {
1118 if (restore_pp) { 1119 if (restore_pp) {
1119 /* Things are still the way they were: Implicit 1120 /* Things are still the way they were: Implicit
1120 * DISASSOCIATE failed 1121 * DISASSOCIATE failed
1121 */ 1122 */
1122 memcpy(&enic->pp, &prev_pp, sizeof(enic->pp)); 1123 memcpy(pp, &prev_pp, sizeof(*pp));
1123 } else { 1124 } else {
1124 memset(&enic->pp, 0, sizeof(enic->pp)); 1125 memset(pp, 0, sizeof(*pp));
1125 memset(netdev->dev_addr, 0, ETH_ALEN); 1126 if (vf == PORT_SELF_VF)
1127 memset(netdev->dev_addr, 0, ETH_ALEN);
1126 } 1128 }
1127 } else { 1129 } else {
1128 /* Set flag to indicate that the port assoc/disassoc 1130 /* Set flag to indicate that the port assoc/disassoc
1129 * request has been sent out to fw 1131 * request has been sent out to fw
1130 */ 1132 */
1131 enic->pp.set |= ENIC_PORT_REQUEST_APPLIED; 1133 pp->set |= ENIC_PORT_REQUEST_APPLIED;
1132 1134
1133 /* If DISASSOCIATE, clean up all assigned/saved macaddresses */ 1135 /* If DISASSOCIATE, clean up all assigned/saved macaddresses */
1134 if (enic->pp.request == PORT_REQUEST_DISASSOCIATE) { 1136 if (pp->request == PORT_REQUEST_DISASSOCIATE) {
1135 memset(enic->pp.mac_addr, 0, ETH_ALEN); 1137 memset(pp->mac_addr, 0, ETH_ALEN);
1136 memset(netdev->dev_addr, 0, ETH_ALEN); 1138 if (vf == PORT_SELF_VF)
1139 memset(netdev->dev_addr, 0, ETH_ALEN);
1137 } 1140 }
1138 } 1141 }
1139 1142
1140 memset(enic->pp.vf_mac, 0, ETH_ALEN); 1143 memset(pp->vf_mac, 0, ETH_ALEN);
1141 1144
1142 return err; 1145 return err;
1143} 1146}
@@ -1147,26 +1150,31 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
1147{ 1150{
1148 struct enic *enic = netdev_priv(netdev); 1151 struct enic *enic = netdev_priv(netdev);
1149 u16 response = PORT_PROFILE_RESPONSE_SUCCESS; 1152 u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
1153 struct enic_port_profile *pp;
1150 int err; 1154 int err;
1151 1155
1152 if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED)) 1156 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
1157 if (err)
1158 return err;
1159
1160 if (!(pp->set & ENIC_PORT_REQUEST_APPLIED))
1153 return -ENODATA; 1161 return -ENODATA;
1154 1162
1155 err = enic_process_get_pp_request(enic, enic->pp.request, &response); 1163 err = enic_process_get_pp_request(enic, vf, pp->request, &response);
1156 if (err) 1164 if (err)
1157 return err; 1165 return err;
1158 1166
1159 NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request); 1167 NLA_PUT_U16(skb, IFLA_PORT_REQUEST, pp->request);
1160 NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response); 1168 NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
1161 if (enic->pp.set & ENIC_SET_NAME) 1169 if (pp->set & ENIC_SET_NAME)
1162 NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, 1170 NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
1163 enic->pp.name); 1171 pp->name);
1164 if (enic->pp.set & ENIC_SET_INSTANCE) 1172 if (pp->set & ENIC_SET_INSTANCE)
1165 NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, 1173 NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
1166 enic->pp.instance_uuid); 1174 pp->instance_uuid);
1167 if (enic->pp.set & ENIC_SET_HOST) 1175 if (pp->set & ENIC_SET_HOST)
1168 NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, 1176 NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
1169 enic->pp.host_uuid); 1177 pp->host_uuid);
1170 1178
1171 return 0; 1179 return 0;
1172 1180
@@ -1600,10 +1608,9 @@ static int enic_open(struct net_device *netdev)
1600 for (i = 0; i < enic->rq_count; i++) 1608 for (i = 0; i < enic->rq_count; i++)
1601 vnic_rq_enable(&enic->rq[i]); 1609 vnic_rq_enable(&enic->rq[i]);
1602 1610
1603 if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr)) 1611 if (!enic_is_dynamic(enic))
1604 enic_dev_add_addr(enic, enic->pp.mac_addr);
1605 else
1606 enic_dev_add_station_addr(enic); 1612 enic_dev_add_station_addr(enic);
1613
1607 enic_set_rx_mode(netdev); 1614 enic_set_rx_mode(netdev);
1608 1615
1609 netif_wake_queue(netdev); 1616 netif_wake_queue(netdev);
@@ -1651,9 +1658,8 @@ static int enic_stop(struct net_device *netdev)
1651 1658
1652 netif_carrier_off(netdev); 1659 netif_carrier_off(netdev);
1653 netif_tx_disable(netdev); 1660 netif_tx_disable(netdev);
1654 if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr)) 1661
1655 enic_dev_del_addr(enic, enic->pp.mac_addr); 1662 if (!enic_is_dynamic(enic))
1656 else
1657 enic_dev_del_station_addr(enic); 1663 enic_dev_del_station_addr(enic);
1658 1664
1659 for (i = 0; i < enic->wq_count; i++) { 1665 for (i = 0; i < enic->wq_count; i++) {
@@ -2143,6 +2149,9 @@ static const struct net_device_ops enic_netdev_ops = {
2143 .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, 2149 .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
2144 .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid, 2150 .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
2145 .ndo_tx_timeout = enic_tx_timeout, 2151 .ndo_tx_timeout = enic_tx_timeout,
2152 .ndo_set_vf_port = enic_set_vf_port,
2153 .ndo_get_vf_port = enic_get_vf_port,
2154 .ndo_set_vf_mac = enic_set_vf_mac,
2146#ifdef CONFIG_NET_POLL_CONTROLLER 2155#ifdef CONFIG_NET_POLL_CONTROLLER
2147 .ndo_poll_controller = enic_poll_controller, 2156 .ndo_poll_controller = enic_poll_controller,
2148#endif 2157#endif
@@ -2254,6 +2263,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
2254 int using_dac = 0; 2263 int using_dac = 0;
2255 unsigned int i; 2264 unsigned int i;
2256 int err; 2265 int err;
2266 int num_pps = 1;
2257#ifdef CONFIG_PCI_IOV 2267#ifdef CONFIG_PCI_IOV
2258 int pos = 0; 2268 int pos = 0;
2259#endif 2269#endif
@@ -2363,17 +2373,26 @@ static int __devinit enic_probe(struct pci_dev *pdev,
2363 goto err_out_vnic_unregister; 2373 goto err_out_vnic_unregister;
2364 } 2374 }
2365 enic->priv_flags |= ENIC_SRIOV_ENABLED; 2375 enic->priv_flags |= ENIC_SRIOV_ENABLED;
2376 num_pps = enic->num_vfs;
2366 } 2377 }
2367 } 2378 }
2368 2379
2369#endif 2380#endif
2381 /* Allocate structure for port profiles */
2382 enic->pp = kzalloc(num_pps * sizeof(*enic->pp), GFP_KERNEL);
2383 if (!enic->pp) {
2384 pr_err("port profile alloc failed, aborting\n");
2385 err = -ENOMEM;
2386 goto err_out_disable_sriov;
2387 }
2388
2370 /* Issue device open to get device in known state 2389 /* Issue device open to get device in known state
2371 */ 2390 */
2372 2391
2373 err = enic_dev_open(enic); 2392 err = enic_dev_open(enic);
2374 if (err) { 2393 if (err) {
2375 dev_err(dev, "vNIC dev open failed, aborting\n"); 2394 dev_err(dev, "vNIC dev open failed, aborting\n");
2376 goto err_out_disable_sriov; 2395 goto err_out_free_pp;
2377 } 2396 }
2378 2397
2379 /* Setup devcmd lock 2398 /* Setup devcmd lock
@@ -2497,6 +2516,8 @@ err_out_dev_deinit:
2497 enic_dev_deinit(enic); 2516 enic_dev_deinit(enic);
2498err_out_dev_close: 2517err_out_dev_close:
2499 vnic_dev_close(enic->vdev); 2518 vnic_dev_close(enic->vdev);
2519err_out_free_pp:
2520 kfree(enic->pp);
2500err_out_disable_sriov: 2521err_out_disable_sriov:
2501#ifdef CONFIG_PCI_IOV 2522#ifdef CONFIG_PCI_IOV
2502 if (enic_sriov_enabled(enic)) { 2523 if (enic_sriov_enabled(enic)) {
@@ -2537,6 +2558,7 @@ static void __devexit enic_remove(struct pci_dev *pdev)
2537 enic->priv_flags &= ~ENIC_SRIOV_ENABLED; 2558 enic->priv_flags &= ~ENIC_SRIOV_ENABLED;
2538 } 2559 }
2539#endif 2560#endif
2561 kfree(enic->pp);
2540 vnic_dev_unregister(enic->vdev); 2562 vnic_dev_unregister(enic->vdev);
2541 enic_iounmap(enic); 2563 enic_iounmap(enic);
2542 pci_release_regions(pdev); 2564 pci_release_regions(pdev);
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index ffaa75dd1ded..22bf03a1829e 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -29,10 +29,47 @@
29#include "enic_res.h" 29#include "enic_res.h"
30#include "enic.h" 30#include "enic.h"
31#include "enic_dev.h" 31#include "enic_dev.h"
32#include "enic_pp.h"
32 33
33static int enic_set_port_profile(struct enic *enic) 34/*
35 * Checks validity of vf index that came in
36 * port profile request
37 */
38int enic_is_valid_pp_vf(struct enic *enic, int vf, int *err)
39{
40 if (vf != PORT_SELF_VF) {
41#ifdef CONFIG_PCI_IOV
42 if (enic_sriov_enabled(enic)) {
43 if (vf < 0 || vf >= enic->num_vfs) {
44 *err = -EINVAL;
45 goto err_out;
46 }
47 } else {
48 *err = -EOPNOTSUPP;
49 goto err_out;
50 }
51#else
52 *err = -EOPNOTSUPP;
53 goto err_out;
54#endif
55 }
56
57 if (vf == PORT_SELF_VF && !enic_is_dynamic(enic)) {
58 *err = -EOPNOTSUPP;
59 goto err_out;
60 }
61
62 *err = 0;
63 return 1;
64
65err_out:
66 return 0;
67}
68
69static int enic_set_port_profile(struct enic *enic, int vf)
34{ 70{
35 struct net_device *netdev = enic->netdev; 71 struct net_device *netdev = enic->netdev;
72 struct enic_port_profile *pp;
36 struct vic_provinfo *vp; 73 struct vic_provinfo *vp;
37 const u8 oui[3] = VIC_PROVINFO_CISCO_OUI; 74 const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
38 const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX); 75 const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
@@ -41,7 +78,11 @@ static int enic_set_port_profile(struct enic *enic)
41 u8 *client_mac; 78 u8 *client_mac;
42 int err; 79 int err;
43 80
44 if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name)) 81 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
82 if (err)
83 return err;
84
85 if (!(pp->set & ENIC_SET_NAME) || !strlen(pp->name))
45 return -EINVAL; 86 return -EINVAL;
46 87
47 vp = vic_provinfo_alloc(GFP_KERNEL, oui, 88 vp = vic_provinfo_alloc(GFP_KERNEL, oui,
@@ -51,12 +92,18 @@ static int enic_set_port_profile(struct enic *enic)
51 92
52 VIC_PROVINFO_ADD_TLV(vp, 93 VIC_PROVINFO_ADD_TLV(vp,
53 VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR, 94 VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
54 strlen(enic->pp.name) + 1, enic->pp.name); 95 strlen(pp->name) + 1, pp->name);
55 96
56 if (!is_zero_ether_addr(enic->pp.mac_addr)) 97 if (!is_zero_ether_addr(pp->mac_addr)) {
57 client_mac = enic->pp.mac_addr; 98 client_mac = pp->mac_addr;
58 else 99 } else if (vf == PORT_SELF_VF) {
59 client_mac = netdev->dev_addr; 100 client_mac = netdev->dev_addr;
101 } else {
102 netdev_err(netdev, "Cannot find pp mac address "
103 "for VF %d\n", vf);
104 err = -EINVAL;
105 goto add_tlv_failure;
106 }
60 107
61 VIC_PROVINFO_ADD_TLV(vp, 108 VIC_PROVINFO_ADD_TLV(vp,
62 VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR, 109 VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
@@ -67,15 +114,15 @@ static int enic_set_port_profile(struct enic *enic)
67 VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR, 114 VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
68 sizeof(client_mac_str), client_mac_str); 115 sizeof(client_mac_str), client_mac_str);
69 116
70 if (enic->pp.set & ENIC_SET_INSTANCE) { 117 if (pp->set & ENIC_SET_INSTANCE) {
71 sprintf(uuid_str, "%pUB", enic->pp.instance_uuid); 118 sprintf(uuid_str, "%pUB", pp->instance_uuid);
72 VIC_PROVINFO_ADD_TLV(vp, 119 VIC_PROVINFO_ADD_TLV(vp,
73 VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR, 120 VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
74 sizeof(uuid_str), uuid_str); 121 sizeof(uuid_str), uuid_str);
75 } 122 }
76 123
77 if (enic->pp.set & ENIC_SET_HOST) { 124 if (pp->set & ENIC_SET_HOST) {
78 sprintf(uuid_str, "%pUB", enic->pp.host_uuid); 125 sprintf(uuid_str, "%pUB", pp->host_uuid);
79 VIC_PROVINFO_ADD_TLV(vp, 126 VIC_PROVINFO_ADD_TLV(vp,
80 VIC_GENERIC_PROV_TLV_HOST_UUID_STR, 127 VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
81 sizeof(uuid_str), uuid_str); 128 sizeof(uuid_str), uuid_str);
@@ -85,7 +132,9 @@ static int enic_set_port_profile(struct enic *enic)
85 VIC_GENERIC_PROV_TLV_OS_TYPE, 132 VIC_GENERIC_PROV_TLV_OS_TYPE,
86 sizeof(os_type), &os_type); 133 sizeof(os_type), &os_type);
87 134
88 err = enic_dev_status_to_errno(enic_dev_init_prov2(enic, vp)); 135 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_init_prov2, (u8 *)vp,
136 vic_provinfo_size(vp));
137 err = enic_dev_status_to_errno(err);
89 138
90add_tlv_failure: 139add_tlv_failure:
91 vic_provinfo_free(vp); 140 vic_provinfo_free(vp);
@@ -93,15 +142,16 @@ add_tlv_failure:
93 return err; 142 return err;
94} 143}
95 144
96static int enic_unset_port_profile(struct enic *enic) 145static int enic_unset_port_profile(struct enic *enic, int vf)
97{ 146{
98 int err; 147 int err;
99 148
100 err = enic_vnic_dev_deinit(enic); 149 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_deinit);
101 if (err) 150 if (err)
102 return enic_dev_status_to_errno(err); 151 return enic_dev_status_to_errno(err);
103 152
104 enic_reset_addr_lists(enic); 153 if (vf == PORT_SELF_VF)
154 enic_reset_addr_lists(enic);
105 155
106 return 0; 156 return 0;
107} 157}
@@ -115,17 +165,18 @@ static int enic_are_pp_different(struct enic_port_profile *pp1,
115 !!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN); 165 !!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN);
116} 166}
117 167
118static int enic_pp_preassociate(struct enic *enic, 168static int enic_pp_preassociate(struct enic *enic, int vf,
119 struct enic_port_profile *prev_pp, int *restore_pp); 169 struct enic_port_profile *prev_pp, int *restore_pp);
120static int enic_pp_disassociate(struct enic *enic, 170static int enic_pp_disassociate(struct enic *enic, int vf,
121 struct enic_port_profile *prev_pp, int *restore_pp); 171 struct enic_port_profile *prev_pp, int *restore_pp);
122static int enic_pp_preassociate_rr(struct enic *enic, 172static int enic_pp_preassociate_rr(struct enic *enic, int vf,
123 struct enic_port_profile *prev_pp, int *restore_pp); 173 struct enic_port_profile *prev_pp, int *restore_pp);
124static int enic_pp_associate(struct enic *enic, 174static int enic_pp_associate(struct enic *enic, int vf,
125 struct enic_port_profile *prev_pp, int *restore_pp); 175 struct enic_port_profile *prev_pp, int *restore_pp);
126 176
127static int (*enic_pp_handlers[])(struct enic *enic, 177static int (*enic_pp_handlers[])(struct enic *enic, int vf,
128 struct enic_port_profile *prev_state, int *restore_pp) = { 178 struct enic_port_profile *prev_state,
179 int *restore_pp) = {
129 [PORT_REQUEST_PREASSOCIATE] = enic_pp_preassociate, 180 [PORT_REQUEST_PREASSOCIATE] = enic_pp_preassociate,
130 [PORT_REQUEST_PREASSOCIATE_RR] = enic_pp_preassociate_rr, 181 [PORT_REQUEST_PREASSOCIATE_RR] = enic_pp_preassociate_rr,
131 [PORT_REQUEST_ASSOCIATE] = enic_pp_associate, 182 [PORT_REQUEST_ASSOCIATE] = enic_pp_associate,
@@ -135,28 +186,49 @@ static int (*enic_pp_handlers[])(struct enic *enic,
135static const int enic_pp_handlers_count = 186static const int enic_pp_handlers_count =
136 sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers); 187 sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers);
137 188
138static int enic_pp_preassociate(struct enic *enic, 189static int enic_pp_preassociate(struct enic *enic, int vf,
139 struct enic_port_profile *prev_pp, int *restore_pp) 190 struct enic_port_profile *prev_pp, int *restore_pp)
140{ 191{
141 return -EOPNOTSUPP; 192 return -EOPNOTSUPP;
142} 193}
143 194
144static int enic_pp_disassociate(struct enic *enic, 195static int enic_pp_disassociate(struct enic *enic, int vf,
145 struct enic_port_profile *prev_pp, int *restore_pp) 196 struct enic_port_profile *prev_pp, int *restore_pp)
146{ 197{
147 return enic_unset_port_profile(enic); 198 struct net_device *netdev = enic->netdev;
199 struct enic_port_profile *pp;
200 int err;
201
202 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
203 if (err)
204 return err;
205
206 /* Deregister mac addresses */
207 if (!is_zero_ether_addr(pp->mac_addr))
208 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
209 pp->mac_addr);
210 else if (!is_zero_ether_addr(netdev->dev_addr))
211 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
212 netdev->dev_addr);
213
214 return enic_unset_port_profile(enic, vf);
148} 215}
149 216
150static int enic_pp_preassociate_rr(struct enic *enic, 217static int enic_pp_preassociate_rr(struct enic *enic, int vf,
151 struct enic_port_profile *prev_pp, int *restore_pp) 218 struct enic_port_profile *prev_pp, int *restore_pp)
152{ 219{
220 struct enic_port_profile *pp;
153 int err; 221 int err;
154 int active = 0; 222 int active = 0;
155 223
156 if (enic->pp.request != PORT_REQUEST_ASSOCIATE) { 224 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
225 if (err)
226 return err;
227
228 if (pp->request != PORT_REQUEST_ASSOCIATE) {
157 /* If pre-associate is not part of an associate. 229 /* If pre-associate is not part of an associate.
158 We always disassociate first */ 230 We always disassociate first */
159 err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic, 231 err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic, vf,
160 prev_pp, restore_pp); 232 prev_pp, restore_pp);
161 if (err) 233 if (err)
162 return err; 234 return err;
@@ -166,29 +238,39 @@ static int enic_pp_preassociate_rr(struct enic *enic,
166 238
167 *restore_pp = 0; 239 *restore_pp = 0;
168 240
169 err = enic_set_port_profile(enic); 241 err = enic_set_port_profile(enic, vf);
170 if (err) 242 if (err)
171 return err; 243 return err;
172 244
173 /* If pre-associate is not part of an associate. */ 245 /* If pre-associate is not part of an associate. */
174 if (enic->pp.request != PORT_REQUEST_ASSOCIATE) 246 if (pp->request != PORT_REQUEST_ASSOCIATE) {
175 err = enic_dev_status_to_errno(enic_dev_enable2(enic, active)); 247 /* Enable device as standby */
248 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_enable2,
249 active);
250 err = enic_dev_status_to_errno(err);
251 }
176 252
177 return err; 253 return err;
178} 254}
179 255
180static int enic_pp_associate(struct enic *enic, 256static int enic_pp_associate(struct enic *enic, int vf,
181 struct enic_port_profile *prev_pp, int *restore_pp) 257 struct enic_port_profile *prev_pp, int *restore_pp)
182{ 258{
259 struct net_device *netdev = enic->netdev;
260 struct enic_port_profile *pp;
183 int err; 261 int err;
184 int active = 1; 262 int active = 1;
185 263
264 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
265 if (err)
266 return err;
267
186 /* Check if a pre-associate was called before */ 268 /* Check if a pre-associate was called before */
187 if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR || 269 if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR ||
188 (prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR && 270 (prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR &&
189 enic_are_pp_different(prev_pp, &enic->pp))) { 271 enic_are_pp_different(prev_pp, pp))) {
190 err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE]( 272 err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](
191 enic, prev_pp, restore_pp); 273 enic, vf, prev_pp, restore_pp);
192 if (err) 274 if (err)
193 return err; 275 return err;
194 276
@@ -196,28 +278,48 @@ static int enic_pp_associate(struct enic *enic,
196 } 278 }
197 279
198 err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR]( 280 err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR](
199 enic, prev_pp, restore_pp); 281 enic, vf, prev_pp, restore_pp);
200 if (err) 282 if (err)
201 return err; 283 return err;
202 284
203 *restore_pp = 0; 285 *restore_pp = 0;
204 286
205 return enic_dev_status_to_errno(enic_dev_enable2(enic, active)); 287 /* Enable device as active */
288 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_enable2, active);
289 err = enic_dev_status_to_errno(err);
290 if (err)
291 return err;
292
293 /* Register mac address */
294 if (!is_zero_ether_addr(pp->mac_addr))
295 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
296 pp->mac_addr);
297 else if (!is_zero_ether_addr(netdev->dev_addr))
298 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
299 netdev->dev_addr);
300
301 return 0;
206} 302}
207 303
208int enic_process_set_pp_request(struct enic *enic, 304int enic_process_set_pp_request(struct enic *enic, int vf,
209 struct enic_port_profile *prev_pp, int *restore_pp) 305 struct enic_port_profile *prev_pp, int *restore_pp)
210{ 306{
211 if (enic->pp.request < enic_pp_handlers_count 307 struct enic_port_profile *pp;
212 && enic_pp_handlers[enic->pp.request]) 308 int err;
213 return enic_pp_handlers[enic->pp.request](enic, 309
214 prev_pp, restore_pp); 310 ENIC_PP_BY_INDEX(enic, vf, pp, &err);
215 else 311 if (err)
312 return err;
313
314 if (pp->request >= enic_pp_handlers_count
315 || !enic_pp_handlers[pp->request])
216 return -EOPNOTSUPP; 316 return -EOPNOTSUPP;
317
318 return enic_pp_handlers[pp->request](enic, vf, prev_pp, restore_pp);
217} 319}
218 320
219int enic_process_get_pp_request(struct enic *enic, int request, 321int enic_process_get_pp_request(struct enic *enic, int vf,
220 u16 *response) 322 int request, u16 *response)
221{ 323{
222 int err, status = ERR_SUCCESS; 324 int err, status = ERR_SUCCESS;
223 325
@@ -225,11 +327,13 @@ int enic_process_get_pp_request(struct enic *enic, int request,
225 327
226 case PORT_REQUEST_PREASSOCIATE_RR: 328 case PORT_REQUEST_PREASSOCIATE_RR:
227 case PORT_REQUEST_ASSOCIATE: 329 case PORT_REQUEST_ASSOCIATE:
228 err = enic_dev_enable2_done(enic, &status); 330 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
331 vnic_dev_enable2_done, &status);
229 break; 332 break;
230 333
231 case PORT_REQUEST_DISASSOCIATE: 334 case PORT_REQUEST_DISASSOCIATE:
232 err = enic_dev_deinit_done(enic, &status); 335 ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
336 vnic_dev_deinit_done, &status);
233 break; 337 break;
234 338
235 default: 339 default:
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.h b/drivers/net/ethernet/cisco/enic/enic_pp.h
index 699e365a944d..a09ff392c1c6 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.h
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.h
@@ -19,9 +19,18 @@
19#ifndef _ENIC_PP_H_ 19#ifndef _ENIC_PP_H_
20#define _ENIC_PP_H_ 20#define _ENIC_PP_H_
21 21
22int enic_process_set_pp_request(struct enic *enic, 22#define ENIC_PP_BY_INDEX(enic, vf, pp, err) \
23 do { \
24 if (enic_is_valid_pp_vf(enic, vf, err)) \
25 pp = (vf == PORT_SELF_VF) ? enic->pp : enic->pp + vf; \
26 else \
27 pp = NULL; \
28 } while (0)
29
30int enic_process_set_pp_request(struct enic *enic, int vf,
23 struct enic_port_profile *prev_pp, int *restore_pp); 31 struct enic_port_profile *prev_pp, int *restore_pp);
24int enic_process_get_pp_request(struct enic *enic, int request, 32int enic_process_get_pp_request(struct enic *enic, int vf,
25 u16 *response); 33 int request, u16 *response);
34int enic_is_valid_pp_vf(struct enic *enic, int vf, int *err);
26 35
27#endif /* _ENIC_PP_H_ */ 36#endif /* _ENIC_PP_H_ */