aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic
diff options
context:
space:
mode:
authorRoopa Prabhu <roprabhu@cisco.com>2010-12-08 08:54:03 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-10 18:42:22 -0500
commit29639059a0122d95b34b5475bd9fee3910b401a3 (patch)
treed79443299bf4aeacc8047a87945fea5cc65159ae /drivers/net/enic
parent0b1c00fc3e9f8d658e0632da7e7ee57bed779ec7 (diff)
enic: Use VF mac set by IFLA_VF_MAC in port profile provisioning data
This patch adds support in enic 802.1Qbh port profile provisioning code to use the mac address set by IFLA_VF_MAC. For now we handle this mac as a special case for a VM mac address sent to us by libvirt. The VM mac address is sent to the switch along with the rest of the port profile provisioning data. This patch also adds calls to register and deregister the mac address during port profile association/deassociation. Signed-off-by: Roopa Prabhu <roprabhu@cisco.com> Signed-off-by: David Wang <dwang2@cisco.com> Signed-off-by: Christian Benvenuti <benve@cisco.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/enic')
-rw-r--r--drivers/net/enic/enic.h1
-rw-r--r--drivers/net/enic/enic_main.c79
2 files changed, 57 insertions, 23 deletions
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index bd473a9d739a..577067eef652 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -62,6 +62,7 @@ struct enic_port_profile {
62 u8 instance_uuid[PORT_UUID_MAX]; 62 u8 instance_uuid[PORT_UUID_MAX];
63 u8 host_uuid[PORT_UUID_MAX]; 63 u8 host_uuid[PORT_UUID_MAX];
64 u8 vf_mac[ETH_ALEN]; 64 u8 vf_mac[ETH_ALEN];
65 u8 mac_addr[ETH_ALEN];
65}; 66};
66 67
67/* Per-instance private data structure */ 68/* Per-instance private data structure */
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index ddeffb5192ae..21be989e6a14 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1278,9 +1278,14 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac)
1278 VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, 1278 VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
1279 strlen(enic->pp.name) + 1, enic->pp.name); 1279 strlen(enic->pp.name) + 1, enic->pp.name);
1280 1280
1281 vic_provinfo_add_tlv(vp, 1281 if (!is_zero_ether_addr(enic->pp.mac_addr))
1282 VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, 1282 vic_provinfo_add_tlv(vp,
1283 ETH_ALEN, mac); 1283 VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
1284 ETH_ALEN, enic->pp.mac_addr);
1285 else
1286 vic_provinfo_add_tlv(vp,
1287 VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
1288 ETH_ALEN, mac);
1284 1289
1285 if (enic->pp.set & ENIC_SET_INSTANCE) { 1290 if (enic->pp.set & ENIC_SET_INSTANCE) {
1286 sprintf(uuid_str, "%pUB", enic->pp.instance_uuid); 1291 sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
@@ -1300,16 +1305,18 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac)
1300 vic_provinfo_free(vp); 1305 vic_provinfo_free(vp);
1301 if (err) 1306 if (err)
1302 return err; 1307 return err;
1308
1309 enic->pp.set |= ENIC_SET_APPLIED;
1303 break; 1310 break;
1304 1311
1305 case PORT_REQUEST_DISASSOCIATE: 1312 case PORT_REQUEST_DISASSOCIATE:
1313 enic->pp.set &= ~ENIC_SET_APPLIED;
1306 break; 1314 break;
1307 1315
1308 default: 1316 default:
1309 return -EINVAL; 1317 return -EINVAL;
1310 } 1318 }
1311 1319
1312 enic->pp.set |= ENIC_SET_APPLIED;
1313 return 0; 1320 return 0;
1314} 1321}
1315 1322
@@ -1317,29 +1324,31 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
1317 struct nlattr *port[]) 1324 struct nlattr *port[])
1318{ 1325{
1319 struct enic *enic = netdev_priv(netdev); 1326 struct enic *enic = netdev_priv(netdev);
1327 struct enic_port_profile new_pp;
1328 int err = 0;
1320 1329
1321 memset(&enic->pp, 0, sizeof(enic->pp)); 1330 memset(&new_pp, 0, sizeof(new_pp));
1322 1331
1323 if (port[IFLA_PORT_REQUEST]) { 1332 if (port[IFLA_PORT_REQUEST]) {
1324 enic->pp.set |= ENIC_SET_REQUEST; 1333 new_pp.set |= ENIC_SET_REQUEST;
1325 enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); 1334 new_pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
1326 } 1335 }
1327 1336
1328 if (port[IFLA_PORT_PROFILE]) { 1337 if (port[IFLA_PORT_PROFILE]) {
1329 enic->pp.set |= ENIC_SET_NAME; 1338 new_pp.set |= ENIC_SET_NAME;
1330 memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]), 1339 memcpy(new_pp.name, nla_data(port[IFLA_PORT_PROFILE]),
1331 PORT_PROFILE_MAX); 1340 PORT_PROFILE_MAX);
1332 } 1341 }
1333 1342
1334 if (port[IFLA_PORT_INSTANCE_UUID]) { 1343 if (port[IFLA_PORT_INSTANCE_UUID]) {
1335 enic->pp.set |= ENIC_SET_INSTANCE; 1344 new_pp.set |= ENIC_SET_INSTANCE;
1336 memcpy(enic->pp.instance_uuid, 1345 memcpy(new_pp.instance_uuid,
1337 nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); 1346 nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
1338 } 1347 }
1339 1348
1340 if (port[IFLA_PORT_HOST_UUID]) { 1349 if (port[IFLA_PORT_HOST_UUID]) {
1341 enic->pp.set |= ENIC_SET_HOST; 1350 new_pp.set |= ENIC_SET_HOST;
1342 memcpy(enic->pp.host_uuid, 1351 memcpy(new_pp.host_uuid,
1343 nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); 1352 nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
1344 } 1353 }
1345 1354
@@ -1347,21 +1356,39 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
1347 if (vf != PORT_SELF_VF) 1356 if (vf != PORT_SELF_VF)
1348 return -EOPNOTSUPP; 1357 return -EOPNOTSUPP;
1349 1358
1350 if (!(enic->pp.set & ENIC_SET_REQUEST)) 1359 if (!(new_pp.set & ENIC_SET_REQUEST))
1351 return -EOPNOTSUPP; 1360 return -EOPNOTSUPP;
1352 1361
1353 if (enic->pp.request == PORT_REQUEST_ASSOCIATE) { 1362 if (new_pp.request == PORT_REQUEST_ASSOCIATE) {
1354 1363 /* Special case handling */
1355 /* If the interface mac addr hasn't been assigned, 1364 if (!is_zero_ether_addr(enic->pp.vf_mac))
1356 * assign a random mac addr before setting port- 1365 memcpy(new_pp.mac_addr, enic->pp.vf_mac, ETH_ALEN);
1357 * profile.
1358 */
1359 1366
1360 if (is_zero_ether_addr(netdev->dev_addr)) 1367 if (is_zero_ether_addr(netdev->dev_addr))
1361 random_ether_addr(netdev->dev_addr); 1368 random_ether_addr(netdev->dev_addr);
1369 } else if (new_pp.request == PORT_REQUEST_DISASSOCIATE) {
1370 if (!is_zero_ether_addr(enic->pp.mac_addr))
1371 enic_dev_del_addr(enic, enic->pp.mac_addr);
1362 } 1372 }
1363 1373
1364 return enic_set_port_profile(enic, netdev->dev_addr); 1374 memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile));
1375
1376 err = enic_set_port_profile(enic, netdev->dev_addr);
1377 if (err)
1378 goto set_port_profile_cleanup;
1379
1380 if (!is_zero_ether_addr(enic->pp.mac_addr))
1381 enic_dev_add_addr(enic, enic->pp.mac_addr);
1382
1383set_port_profile_cleanup:
1384 memset(enic->pp.vf_mac, 0, ETH_ALEN);
1385
1386 if (err || enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
1387 memset(netdev->dev_addr, 0, ETH_ALEN);
1388 memset(enic->pp.mac_addr, 0, ETH_ALEN);
1389 }
1390
1391 return err;
1365} 1392}
1366 1393
1367static int enic_get_vf_port(struct net_device *netdev, int vf, 1394static int enic_get_vf_port(struct net_device *netdev, int vf,
@@ -1941,7 +1968,10 @@ static int enic_open(struct net_device *netdev)
1941 for (i = 0; i < enic->rq_count; i++) 1968 for (i = 0; i < enic->rq_count; i++)
1942 vnic_rq_enable(&enic->rq[i]); 1969 vnic_rq_enable(&enic->rq[i]);
1943 1970
1944 enic_dev_add_station_addr(enic); 1971 if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
1972 enic_dev_add_addr(enic, enic->pp.mac_addr);
1973 else
1974 enic_dev_add_station_addr(enic);
1945 enic_set_rx_mode(netdev); 1975 enic_set_rx_mode(netdev);
1946 1976
1947 netif_wake_queue(netdev); 1977 netif_wake_queue(netdev);
@@ -1989,7 +2019,10 @@ static int enic_stop(struct net_device *netdev)
1989 2019
1990 netif_carrier_off(netdev); 2020 netif_carrier_off(netdev);
1991 netif_tx_disable(netdev); 2021 netif_tx_disable(netdev);
1992 enic_dev_del_station_addr(enic); 2022 if (enic_is_dynamic(enic) && !is_zero_ether_addr(enic->pp.mac_addr))
2023 enic_dev_del_addr(enic, enic->pp.mac_addr);
2024 else
2025 enic_dev_del_station_addr(enic);
1993 2026
1994 for (i = 0; i < enic->wq_count; i++) { 2027 for (i = 0; i < enic->wq_count; i++) {
1995 err = vnic_wq_disable(&enic->wq[i]); 2028 err = vnic_wq_disable(&enic->wq[i]);