aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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]);