aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/efx.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index c734fba8c99c..893cd78c3a6c 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1060,18 +1060,23 @@ static void efx_start_port(struct efx_nic *efx)
1060 mutex_lock(&efx->mac_lock); 1060 mutex_lock(&efx->mac_lock);
1061 efx->port_enabled = true; 1061 efx->port_enabled = true;
1062 1062
1063 /* efx_mac_work() might have been scheduled after efx_stop_port(), 1063 /* Ensure MAC ingress/egress is enabled */
1064 * and then cancelled by efx_flush_all() */
1065 efx->type->reconfigure_mac(efx); 1064 efx->type->reconfigure_mac(efx);
1066 1065
1067 mutex_unlock(&efx->mac_lock); 1066 mutex_unlock(&efx->mac_lock);
1068} 1067}
1069 1068
1070/* Prevent efx_mac_work() and efx_monitor() from working */ 1069/* Cancel work for MAC reconfiguration, periodic hardware monitoring
1070 * and the async self-test, wait for them to finish and prevent them
1071 * being scheduled again. This doesn't cover online resets, which
1072 * should only be cancelled when removing the device.
1073 */
1071static void efx_stop_port(struct efx_nic *efx) 1074static void efx_stop_port(struct efx_nic *efx)
1072{ 1075{
1073 netif_dbg(efx, ifdown, efx->net_dev, "stop port\n"); 1076 netif_dbg(efx, ifdown, efx->net_dev, "stop port\n");
1074 1077
1078 EFX_ASSERT_RESET_SERIALISED(efx);
1079
1075 mutex_lock(&efx->mac_lock); 1080 mutex_lock(&efx->mac_lock);
1076 efx->port_enabled = false; 1081 efx->port_enabled = false;
1077 mutex_unlock(&efx->mac_lock); 1082 mutex_unlock(&efx->mac_lock);
@@ -1079,6 +1084,10 @@ static void efx_stop_port(struct efx_nic *efx)
1079 /* Serialise against efx_set_multicast_list() */ 1084 /* Serialise against efx_set_multicast_list() */
1080 netif_addr_lock_bh(efx->net_dev); 1085 netif_addr_lock_bh(efx->net_dev);
1081 netif_addr_unlock_bh(efx->net_dev); 1086 netif_addr_unlock_bh(efx->net_dev);
1087
1088 cancel_delayed_work_sync(&efx->monitor_work);
1089 efx_selftest_async_cancel(efx);
1090 cancel_work_sync(&efx->mac_work);
1082} 1091}
1083 1092
1084static void efx_fini_port(struct efx_nic *efx) 1093static void efx_fini_port(struct efx_nic *efx)
@@ -1690,18 +1699,6 @@ static void efx_start_all(struct efx_nic *efx)
1690 spin_unlock_bh(&efx->stats_lock); 1699 spin_unlock_bh(&efx->stats_lock);
1691} 1700}
1692 1701
1693/* Flush all delayed work. Should only be called when no more delayed work
1694 * will be scheduled. This doesn't flush pending online resets (efx_reset),
1695 * since we're holding the rtnl_lock at this point. */
1696static void efx_flush_all(struct efx_nic *efx)
1697{
1698 /* Make sure the hardware monitor and event self-test are stopped */
1699 cancel_delayed_work_sync(&efx->monitor_work);
1700 efx_selftest_async_cancel(efx);
1701 /* Stop scheduled port reconfigurations */
1702 cancel_work_sync(&efx->mac_work);
1703}
1704
1705/* Quiesce the hardware and software data path, and regular activity 1702/* Quiesce the hardware and software data path, and regular activity
1706 * for the port without bringing the link down. Safe to call multiple 1703 * for the port without bringing the link down. Safe to call multiple
1707 * times with the NIC in almost any state, but interrupts should be 1704 * times with the NIC in almost any state, but interrupts should be
@@ -1725,9 +1722,6 @@ static void efx_stop_all(struct efx_nic *efx)
1725 efx->type->stop_stats(efx); 1722 efx->type->stop_stats(efx);
1726 efx_stop_port(efx); 1723 efx_stop_port(efx);
1727 1724
1728 /* Flush efx_mac_work(), refill_workqueue, monitor_work */
1729 efx_flush_all(efx);
1730
1731 /* Stop the kernel transmit interface. This is only valid if 1725 /* Stop the kernel transmit interface. This is only valid if
1732 * the device is stopped or detached; otherwise the watchdog 1726 * the device is stopped or detached; otherwise the watchdog
1733 * may fire immediately. 1727 * may fire immediately.