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.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index b0e53087bda0..ab0e09bf154d 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -685,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx)
685 efx->mac_op->reconfigure(efx); 685 efx->mac_op->reconfigure(efx);
686 686
687 efx->port_initialized = true; 687 efx->port_initialized = true;
688 efx->stats_enabled = true; 688 efx_stats_enable(efx);
689 return 0; 689 return 0;
690 690
691fail: 691fail:
@@ -734,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx)
734 if (!efx->port_initialized) 734 if (!efx->port_initialized)
735 return; 735 return;
736 736
737 efx_stats_disable(efx);
737 efx->phy_op->fini(efx); 738 efx->phy_op->fini(efx);
738 efx->port_initialized = false; 739 efx->port_initialized = false;
739 740
@@ -1360,6 +1361,20 @@ static int efx_net_stop(struct net_device *net_dev)
1360 return 0; 1361 return 0;
1361} 1362}
1362 1363
1364void efx_stats_disable(struct efx_nic *efx)
1365{
1366 spin_lock(&efx->stats_lock);
1367 ++efx->stats_disable_count;
1368 spin_unlock(&efx->stats_lock);
1369}
1370
1371void efx_stats_enable(struct efx_nic *efx)
1372{
1373 spin_lock(&efx->stats_lock);
1374 --efx->stats_disable_count;
1375 spin_unlock(&efx->stats_lock);
1376}
1377
1363/* Context: process, dev_base_lock or RTNL held, non-blocking. */ 1378/* Context: process, dev_base_lock or RTNL held, non-blocking. */
1364static struct net_device_stats *efx_net_stats(struct net_device *net_dev) 1379static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
1365{ 1380{
@@ -1368,12 +1383,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
1368 struct net_device_stats *stats = &net_dev->stats; 1383 struct net_device_stats *stats = &net_dev->stats;
1369 1384
1370 /* Update stats if possible, but do not wait if another thread 1385 /* Update stats if possible, but do not wait if another thread
1371 * is updating them (or resetting the NIC); slightly stale 1386 * is updating them or if MAC stats fetches are temporarily
1372 * stats are acceptable. 1387 * disabled; slightly stale stats are acceptable.
1373 */ 1388 */
1374 if (!spin_trylock(&efx->stats_lock)) 1389 if (!spin_trylock(&efx->stats_lock))
1375 return stats; 1390 return stats;
1376 if (efx->stats_enabled) { 1391 if (!efx->stats_disable_count) {
1377 efx->mac_op->update_stats(efx); 1392 efx->mac_op->update_stats(efx);
1378 falcon_update_nic_stats(efx); 1393 falcon_update_nic_stats(efx);
1379 } 1394 }
@@ -1626,12 +1641,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method,
1626{ 1641{
1627 EFX_ASSERT_RESET_SERIALISED(efx); 1642 EFX_ASSERT_RESET_SERIALISED(efx);
1628 1643
1629 /* The net_dev->get_stats handler is quite slow, and will fail 1644 efx_stats_disable(efx);
1630 * if a fetch is pending over reset. Serialise against it. */
1631 spin_lock(&efx->stats_lock);
1632 efx->stats_enabled = false;
1633 spin_unlock(&efx->stats_lock);
1634
1635 efx_stop_all(efx); 1645 efx_stop_all(efx);
1636 mutex_lock(&efx->mac_lock); 1646 mutex_lock(&efx->mac_lock);
1637 mutex_lock(&efx->spi_lock); 1647 mutex_lock(&efx->spi_lock);
@@ -1682,7 +1692,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method,
1682 1692
1683 if (ok) { 1693 if (ok) {
1684 efx_start_all(efx); 1694 efx_start_all(efx);
1685 efx->stats_enabled = true; 1695 efx_stats_enable(efx);
1686 } 1696 }
1687 return rc; 1697 return rc;
1688} 1698}
@@ -1888,6 +1898,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
1888 efx->rx_checksum_enabled = true; 1898 efx->rx_checksum_enabled = true;
1889 spin_lock_init(&efx->netif_stop_lock); 1899 spin_lock_init(&efx->netif_stop_lock);
1890 spin_lock_init(&efx->stats_lock); 1900 spin_lock_init(&efx->stats_lock);
1901 efx->stats_disable_count = 1;
1891 mutex_init(&efx->mac_lock); 1902 mutex_init(&efx->mac_lock);
1892 efx->mac_op = &efx_dummy_mac_operations; 1903 efx->mac_op = &efx_dummy_mac_operations;
1893 efx->phy_op = &efx_dummy_phy_operations; 1904 efx->phy_op = &efx_dummy_phy_operations;