aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/efx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r--drivers/net/sfc/efx.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index d5930863691c..0d47d6ffe68a 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -560,6 +560,12 @@ void __efx_reconfigure_port(struct efx_nic *efx)
560 EFX_LOG(efx, "reconfiguring MAC from PHY settings on CPU %d\n", 560 EFX_LOG(efx, "reconfiguring MAC from PHY settings on CPU %d\n",
561 raw_smp_processor_id()); 561 raw_smp_processor_id());
562 562
563 /* Serialise the promiscuous flag with efx_set_multicast_list. */
564 if (efx_dev_registered(efx)) {
565 netif_addr_lock_bh(efx->net_dev);
566 netif_addr_unlock_bh(efx->net_dev);
567 }
568
563 falcon_reconfigure_xmac(efx); 569 falcon_reconfigure_xmac(efx);
564 570
565 /* Inform kernel of loss/gain of carrier */ 571 /* Inform kernel of loss/gain of carrier */
@@ -1410,26 +1416,19 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
1410 return 0; 1416 return 0;
1411} 1417}
1412 1418
1413/* Context: netif_tx_lock held, BHs disabled. */ 1419/* Context: netif_addr_lock held, BHs disabled. */
1414static void efx_set_multicast_list(struct net_device *net_dev) 1420static void efx_set_multicast_list(struct net_device *net_dev)
1415{ 1421{
1416 struct efx_nic *efx = netdev_priv(net_dev); 1422 struct efx_nic *efx = netdev_priv(net_dev);
1417 struct dev_mc_list *mc_list = net_dev->mc_list; 1423 struct dev_mc_list *mc_list = net_dev->mc_list;
1418 union efx_multicast_hash *mc_hash = &efx->multicast_hash; 1424 union efx_multicast_hash *mc_hash = &efx->multicast_hash;
1419 bool promiscuous; 1425 bool promiscuous = !!(net_dev->flags & IFF_PROMISC);
1426 bool changed = (efx->promiscuous != promiscuous);
1420 u32 crc; 1427 u32 crc;
1421 int bit; 1428 int bit;
1422 int i; 1429 int i;
1423 1430
1424 /* Set per-MAC promiscuity flag and reconfigure MAC if necessary */ 1431 efx->promiscuous = promiscuous;
1425 promiscuous = !!(net_dev->flags & IFF_PROMISC);
1426 if (efx->promiscuous != promiscuous) {
1427 efx->promiscuous = promiscuous;
1428 /* Close the window between efx_stop_port() and efx_flush_all()
1429 * by only queuing work when the port is enabled. */
1430 if (efx->port_enabled)
1431 queue_work(efx->workqueue, &efx->reconfigure_work);
1432 }
1433 1432
1434 /* Build multicast hash table */ 1433 /* Build multicast hash table */
1435 if (promiscuous || (net_dev->flags & IFF_ALLMULTI)) { 1434 if (promiscuous || (net_dev->flags & IFF_ALLMULTI)) {
@@ -1444,6 +1443,13 @@ static void efx_set_multicast_list(struct net_device *net_dev)
1444 } 1443 }
1445 } 1444 }
1446 1445
1446 if (!efx->port_enabled)
1447 /* Delay pushing settings until efx_start_port() */
1448 return;
1449
1450 if (changed)
1451 queue_work(efx->workqueue, &efx->reconfigure_work);
1452
1447 /* Create and activate new global multicast hash table */ 1453 /* Create and activate new global multicast hash table */
1448 falcon_set_multicast_hash(efx); 1454 falcon_set_multicast_hash(efx);
1449} 1455}