aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-11-25 11:11:35 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-26 18:59:36 -0500
commit55edc6e6ff728681ebc10d418222740705376664 (patch)
tree66136e674adde15b9668f13d4e0486482b7f1851
parent1dfc5ceacd00365a9089e98643f4b26253d5a6aa (diff)
sfc: Split MAC stats DMA initiation and completion
From: Steve Hodgson <shodgson@solarflare.com> Currently we initiate MAC stats DMA and busy-wait for completion when stats are requested. We can improve on this with a periodic timer to initiate and poll for stats, and opportunistically poll when stats are requested. Since efx_nic::stats_disable_count and efx_stats_{disable,enable}() are Falcon-specific, rename them and move them accordingly. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/sfc/efx.c48
-rw-r--r--drivers/net/sfc/efx.h2
-rw-r--r--drivers/net/sfc/falcon.c131
-rw-r--r--drivers/net/sfc/falcon.h12
-rw-r--r--drivers/net/sfc/falcon_boards.c10
-rw-r--r--drivers/net/sfc/falcon_gmac.c5
-rw-r--r--drivers/net/sfc/falcon_xmac.c13
-rw-r--r--drivers/net/sfc/net_driver.h2
-rw-r--r--drivers/net/sfc/tenxpress.c4
9 files changed, 139 insertions, 88 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 155aa1cca366..41ca5dbb4c44 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -637,6 +637,7 @@ void __efx_reconfigure_port(struct efx_nic *efx)
637 netif_addr_unlock_bh(efx->net_dev); 637 netif_addr_unlock_bh(efx->net_dev);
638 } 638 }
639 639
640 falcon_stop_nic_stats(efx);
640 falcon_deconfigure_mac_wrapper(efx); 641 falcon_deconfigure_mac_wrapper(efx);
641 642
642 /* Reconfigure the PHY, disabling transmit in mac level loopback. */ 643 /* Reconfigure the PHY, disabling transmit in mac level loopback. */
@@ -651,6 +652,8 @@ void __efx_reconfigure_port(struct efx_nic *efx)
651 652
652 efx->mac_op->reconfigure(efx); 653 efx->mac_op->reconfigure(efx);
653 654
655 falcon_start_nic_stats(efx);
656
654 /* Inform kernel of loss/gain of carrier */ 657 /* Inform kernel of loss/gain of carrier */
655 efx_link_status_changed(efx); 658 efx_link_status_changed(efx);
656 return; 659 return;
@@ -749,7 +752,6 @@ static int efx_init_port(struct efx_nic *efx)
749 efx->mac_op->reconfigure(efx); 752 efx->mac_op->reconfigure(efx);
750 753
751 efx->port_initialized = true; 754 efx->port_initialized = true;
752 efx_stats_enable(efx);
753 755
754 mutex_unlock(&efx->mac_lock); 756 mutex_unlock(&efx->mac_lock);
755 return 0; 757 return 0;
@@ -802,7 +804,6 @@ static void efx_fini_port(struct efx_nic *efx)
802 if (!efx->port_initialized) 804 if (!efx->port_initialized)
803 return; 805 return;
804 806
805 efx_stats_disable(efx);
806 efx->phy_op->fini(efx); 807 efx->phy_op->fini(efx);
807 efx->port_initialized = false; 808 efx->port_initialized = false;
808 809
@@ -1158,6 +1159,8 @@ static void efx_start_all(struct efx_nic *efx)
1158 if (efx->state == STATE_RUNNING) 1159 if (efx->state == STATE_RUNNING)
1159 queue_delayed_work(efx->workqueue, &efx->monitor_work, 1160 queue_delayed_work(efx->workqueue, &efx->monitor_work,
1160 efx_monitor_interval); 1161 efx_monitor_interval);
1162
1163 falcon_start_nic_stats(efx);
1161} 1164}
1162 1165
1163/* Flush all delayed work. Should only be called when no more delayed work 1166/* Flush all delayed work. Should only be called when no more delayed work
@@ -1195,6 +1198,8 @@ static void efx_stop_all(struct efx_nic *efx)
1195 if (!efx->port_enabled) 1198 if (!efx->port_enabled)
1196 return; 1199 return;
1197 1200
1201 falcon_stop_nic_stats(efx);
1202
1198 /* Disable interrupts and wait for ISR to complete */ 1203 /* Disable interrupts and wait for ISR to complete */
1199 falcon_disable_interrupts(efx); 1204 falcon_disable_interrupts(efx);
1200 if (efx->legacy_irq) 1205 if (efx->legacy_irq)
@@ -1438,20 +1443,6 @@ static int efx_net_stop(struct net_device *net_dev)
1438 return 0; 1443 return 0;
1439} 1444}
1440 1445
1441void efx_stats_disable(struct efx_nic *efx)
1442{
1443 spin_lock(&efx->stats_lock);
1444 ++efx->stats_disable_count;
1445 spin_unlock(&efx->stats_lock);
1446}
1447
1448void efx_stats_enable(struct efx_nic *efx)
1449{
1450 spin_lock(&efx->stats_lock);
1451 --efx->stats_disable_count;
1452 spin_unlock(&efx->stats_lock);
1453}
1454
1455/* Context: process, dev_base_lock or RTNL held, non-blocking. */ 1446/* Context: process, dev_base_lock or RTNL held, non-blocking. */
1456static struct net_device_stats *efx_net_stats(struct net_device *net_dev) 1447static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
1457{ 1448{
@@ -1459,17 +1450,9 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
1459 struct efx_mac_stats *mac_stats = &efx->mac_stats; 1450 struct efx_mac_stats *mac_stats = &efx->mac_stats;
1460 struct net_device_stats *stats = &net_dev->stats; 1451 struct net_device_stats *stats = &net_dev->stats;
1461 1452
1462 /* Update stats if possible, but do not wait if another thread 1453 spin_lock_bh(&efx->stats_lock);
1463 * is updating them or if MAC stats fetches are temporarily 1454 falcon_update_nic_stats(efx);
1464 * disabled; slightly stale stats are acceptable. 1455 spin_unlock_bh(&efx->stats_lock);
1465 */
1466 if (!spin_trylock(&efx->stats_lock))
1467 return stats;
1468 if (!efx->stats_disable_count) {
1469 efx->mac_op->update_stats(efx);
1470 falcon_update_nic_stats(efx);
1471 }
1472 spin_unlock(&efx->stats_lock);
1473 1456
1474 stats->rx_packets = mac_stats->rx_packets; 1457 stats->rx_packets = mac_stats->rx_packets;
1475 stats->tx_packets = mac_stats->tx_packets; 1458 stats->tx_packets = mac_stats->tx_packets;
@@ -1726,7 +1709,6 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method,
1726{ 1709{
1727 EFX_ASSERT_RESET_SERIALISED(efx); 1710 EFX_ASSERT_RESET_SERIALISED(efx);
1728 1711
1729 efx_stats_disable(efx);
1730 efx_stop_all(efx); 1712 efx_stop_all(efx);
1731 mutex_lock(&efx->mac_lock); 1713 mutex_lock(&efx->mac_lock);
1732 mutex_lock(&efx->spi_lock); 1714 mutex_lock(&efx->spi_lock);
@@ -1776,10 +1758,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method,
1776 mutex_unlock(&efx->spi_lock); 1758 mutex_unlock(&efx->spi_lock);
1777 mutex_unlock(&efx->mac_lock); 1759 mutex_unlock(&efx->mac_lock);
1778 1760
1779 if (ok) { 1761 if (ok)
1780 efx_start_all(efx); 1762 efx_start_all(efx);
1781 efx_stats_enable(efx);
1782 }
1783 return rc; 1763 return rc;
1784} 1764}
1785 1765
@@ -1977,7 +1957,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
1977 efx->rx_checksum_enabled = true; 1957 efx->rx_checksum_enabled = true;
1978 spin_lock_init(&efx->netif_stop_lock); 1958 spin_lock_init(&efx->netif_stop_lock);
1979 spin_lock_init(&efx->stats_lock); 1959 spin_lock_init(&efx->stats_lock);
1980 efx->stats_disable_count = 1;
1981 mutex_init(&efx->mac_lock); 1960 mutex_init(&efx->mac_lock);
1982 efx->mac_op = &efx_dummy_mac_operations; 1961 efx->mac_op = &efx_dummy_mac_operations;
1983 efx->phy_op = &efx_dummy_phy_operations; 1962 efx->phy_op = &efx_dummy_phy_operations;
@@ -2219,9 +2198,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
2219 goto fail4; 2198 goto fail4;
2220 } 2199 }
2221 2200
2222 /* Switch to the running state before we expose the device to 2201 /* Switch to the running state before we expose the device to the OS,
2223 * the OS. This is to ensure that the initial gathering of 2202 * so that dev_open()|efx_start_all() will actually start the device */
2224 * MAC stats succeeds. */
2225 efx->state = STATE_RUNNING; 2203 efx->state = STATE_RUNNING;
2226 2204
2227 rc = efx_register_netdev(efx); 2205 rc = efx_register_netdev(efx);
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 7acf82108a4f..01b93f93d316 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -60,8 +60,6 @@ extern void efx_process_channel_now(struct efx_channel *channel);
60#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1) 60#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1)
61 61
62/* Ports */ 62/* Ports */
63extern void efx_stats_disable(struct efx_nic *efx);
64extern void efx_stats_enable(struct efx_nic *efx);
65extern void efx_reconfigure_port(struct efx_nic *efx); 63extern void efx_reconfigure_port(struct efx_nic *efx);
66extern void __efx_reconfigure_port(struct efx_nic *efx); 64extern void __efx_reconfigure_port(struct efx_nic *efx);
67 65
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 9eec88502101..3ab2daff6b48 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -36,8 +36,6 @@
36 ************************************************************************** 36 **************************************************************************
37 */ 37 */
38 38
39static int disable_dma_stats;
40
41/* This is set to 16 for a good reason. In summary, if larger than 39/* This is set to 16 for a good reason. In summary, if larger than
42 * 16, the descriptor cache holds more than a default socket 40 * 16, the descriptor cache holds more than a default socket
43 * buffer's worth of packets (for UDP we can only have at most one 41 * buffer's worth of packets (for UDP we can only have at most one
@@ -1890,7 +1888,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
1890 1888
1891 /* MAC stats will fail whilst the TX fifo is draining. Serialise 1889 /* MAC stats will fail whilst the TX fifo is draining. Serialise
1892 * the drain sequence with the statistics fetch */ 1890 * the drain sequence with the statistics fetch */
1893 efx_stats_disable(efx); 1891 falcon_stop_nic_stats(efx);
1894 1892
1895 efx_reado(efx, &reg, FR_AB_MAC_CTRL); 1893 efx_reado(efx, &reg, FR_AB_MAC_CTRL);
1896 EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, 1); 1894 EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, 1);
@@ -1920,13 +1918,13 @@ static int falcon_reset_macs(struct efx_nic *efx)
1920 udelay(10); 1918 udelay(10);
1921 } 1919 }
1922 1920
1923 efx_stats_enable(efx);
1924
1925 /* If we've reset the EM block and the link is up, then 1921 /* If we've reset the EM block and the link is up, then
1926 * we'll have to kick the XAUI link so the PHY can recover */ 1922 * we'll have to kick the XAUI link so the PHY can recover */
1927 if (efx->link_state.up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) 1923 if (efx->link_state.up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx))
1928 falcon_reset_xaui(efx); 1924 falcon_reset_xaui(efx);
1929 1925
1926 falcon_start_nic_stats(efx);
1927
1930 return 0; 1928 return 0;
1931} 1929}
1932 1930
@@ -2010,25 +2008,19 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
2010 efx_writeo(efx, &reg, FR_AZ_RX_CFG); 2008 efx_writeo(efx, &reg, FR_AZ_RX_CFG);
2011} 2009}
2012 2010
2013int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) 2011static void falcon_stats_request(struct efx_nic *efx)
2014{ 2012{
2013 struct falcon_nic_data *nic_data = efx->nic_data;
2015 efx_oword_t reg; 2014 efx_oword_t reg;
2016 u32 *dma_done;
2017 int i;
2018 2015
2019 if (disable_dma_stats) 2016 WARN_ON(nic_data->stats_pending);
2020 return 0; 2017 WARN_ON(nic_data->stats_disable_count);
2021 2018
2022 /* Statistics fetch will fail if the MAC is in TX drain */ 2019 if (nic_data->stats_dma_done == NULL)
2023 if (falcon_rev(efx) >= FALCON_REV_B0) { 2020 return; /* no mac selected */
2024 efx_oword_t temp;
2025 efx_reado(efx, &temp, FR_AB_MAC_CTRL);
2026 if (EFX_OWORD_FIELD(temp, FRF_BB_TXFIFO_DRAIN_EN))
2027 return 0;
2028 }
2029 2021
2030 dma_done = (efx->stats_buffer.addr + done_offset); 2022 *nic_data->stats_dma_done = FALCON_STATS_NOT_DONE;
2031 *dma_done = FALCON_STATS_NOT_DONE; 2023 nic_data->stats_pending = true;
2032 wmb(); /* ensure done flag is clear */ 2024 wmb(); /* ensure done flag is clear */
2033 2025
2034 /* Initiate DMA transfer of stats */ 2026 /* Initiate DMA transfer of stats */
@@ -2038,17 +2030,37 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
2038 efx->stats_buffer.dma_addr); 2030 efx->stats_buffer.dma_addr);
2039 efx_writeo(efx, &reg, FR_AB_MAC_STAT_DMA); 2031 efx_writeo(efx, &reg, FR_AB_MAC_STAT_DMA);
2040 2032
2041 /* Wait for transfer to complete */ 2033 mod_timer(&nic_data->stats_timer, round_jiffies_up(jiffies + HZ / 2));
2042 for (i = 0; i < 400; i++) { 2034}
2043 if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) { 2035
2044 rmb(); /* Ensure the stats are valid. */ 2036static void falcon_stats_complete(struct efx_nic *efx)
2045 return 0; 2037{
2046 } 2038 struct falcon_nic_data *nic_data = efx->nic_data;
2047 udelay(10); 2039
2040 if (!nic_data->stats_pending)
2041 return;
2042
2043 nic_data->stats_pending = 0;
2044 if (*nic_data->stats_dma_done == FALCON_STATS_DONE) {
2045 rmb(); /* read the done flag before the stats */
2046 efx->mac_op->update_stats(efx);
2047 } else {
2048 EFX_ERR(efx, "timed out waiting for statistics\n");
2048 } 2049 }
2050}
2049 2051
2050 EFX_ERR(efx, "timed out waiting for statistics\n"); 2052static void falcon_stats_timer_func(unsigned long context)
2051 return -ETIMEDOUT; 2053{
2054 struct efx_nic *efx = (struct efx_nic *)context;
2055 struct falcon_nic_data *nic_data = efx->nic_data;
2056
2057 spin_lock(&efx->stats_lock);
2058
2059 falcon_stats_complete(efx);
2060 if (nic_data->stats_disable_count == 0)
2061 falcon_stats_request(efx);
2062
2063 spin_unlock(&efx->stats_lock);
2052} 2064}
2053 2065
2054/************************************************************************** 2066/**************************************************************************
@@ -2206,10 +2218,12 @@ static void falcon_clock_mac(struct efx_nic *efx)
2206int falcon_switch_mac(struct efx_nic *efx) 2218int falcon_switch_mac(struct efx_nic *efx)
2207{ 2219{
2208 struct efx_mac_operations *old_mac_op = efx->mac_op; 2220 struct efx_mac_operations *old_mac_op = efx->mac_op;
2221 struct falcon_nic_data *nic_data = efx->nic_data;
2222 unsigned int stats_done_offset;
2209 int rc = 0; 2223 int rc = 0;
2210 2224
2211 /* Don't try to fetch MAC stats while we're switching MACs */ 2225 /* Don't try to fetch MAC stats while we're switching MACs */
2212 efx_stats_disable(efx); 2226 falcon_stop_nic_stats(efx);
2213 2227
2214 /* Internal loopbacks override the phy speed setting */ 2228 /* Internal loopbacks override the phy speed setting */
2215 if (efx->loopback_mode == LOOPBACK_GMAC) { 2229 if (efx->loopback_mode == LOOPBACK_GMAC) {
@@ -2224,6 +2238,12 @@ int falcon_switch_mac(struct efx_nic *efx)
2224 efx->mac_op = (EFX_IS10G(efx) ? 2238 efx->mac_op = (EFX_IS10G(efx) ?
2225 &falcon_xmac_operations : &falcon_gmac_operations); 2239 &falcon_xmac_operations : &falcon_gmac_operations);
2226 2240
2241 if (EFX_IS10G(efx))
2242 stats_done_offset = XgDmaDone_offset;
2243 else
2244 stats_done_offset = GDmaDone_offset;
2245 nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset;
2246
2227 if (old_mac_op == efx->mac_op) 2247 if (old_mac_op == efx->mac_op)
2228 goto out; 2248 goto out;
2229 2249
@@ -2235,7 +2255,7 @@ int falcon_switch_mac(struct efx_nic *efx)
2235 2255
2236 rc = falcon_reset_macs(efx); 2256 rc = falcon_reset_macs(efx);
2237out: 2257out:
2238 efx_stats_enable(efx); 2258 falcon_start_nic_stats(efx);
2239 return rc; 2259 return rc;
2240} 2260}
2241 2261
@@ -2900,6 +2920,10 @@ int falcon_probe_nic(struct efx_nic *efx)
2900 goto fail6; 2920 goto fail6;
2901 } 2921 }
2902 2922
2923 nic_data->stats_disable_count = 1;
2924 setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func,
2925 (unsigned long)efx);
2926
2903 return 0; 2927 return 0;
2904 2928
2905 fail6: 2929 fail6:
@@ -3125,11 +3149,58 @@ void falcon_remove_nic(struct efx_nic *efx)
3125 3149
3126void falcon_update_nic_stats(struct efx_nic *efx) 3150void falcon_update_nic_stats(struct efx_nic *efx)
3127{ 3151{
3152 struct falcon_nic_data *nic_data = efx->nic_data;
3128 efx_oword_t cnt; 3153 efx_oword_t cnt;
3129 3154
3155 if (nic_data->stats_disable_count)
3156 return;
3157
3130 efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP); 3158 efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP);
3131 efx->n_rx_nodesc_drop_cnt += 3159 efx->n_rx_nodesc_drop_cnt +=
3132 EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT); 3160 EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT);
3161
3162 if (nic_data->stats_pending &&
3163 *nic_data->stats_dma_done == FALCON_STATS_DONE) {
3164 nic_data->stats_pending = false;
3165 rmb(); /* read the done flag before the stats */
3166 efx->mac_op->update_stats(efx);
3167 }
3168}
3169
3170void falcon_start_nic_stats(struct efx_nic *efx)
3171{
3172 struct falcon_nic_data *nic_data = efx->nic_data;
3173
3174 spin_lock_bh(&efx->stats_lock);
3175 if (--nic_data->stats_disable_count == 0)
3176 falcon_stats_request(efx);
3177 spin_unlock_bh(&efx->stats_lock);
3178}
3179
3180void falcon_stop_nic_stats(struct efx_nic *efx)
3181{
3182 struct falcon_nic_data *nic_data = efx->nic_data;
3183 int i;
3184
3185 might_sleep();
3186
3187 spin_lock_bh(&efx->stats_lock);
3188 ++nic_data->stats_disable_count;
3189 spin_unlock_bh(&efx->stats_lock);
3190
3191 del_timer_sync(&nic_data->stats_timer);
3192
3193 /* Wait enough time for the most recent transfer to
3194 * complete. */
3195 for (i = 0; i < 4 && nic_data->stats_pending; i++) {
3196 if (*nic_data->stats_dma_done == FALCON_STATS_DONE)
3197 break;
3198 msleep(1);
3199 }
3200
3201 spin_lock_bh(&efx->stats_lock);
3202 falcon_stats_complete(efx);
3203 spin_unlock_bh(&efx->stats_lock);
3133} 3204}
3134 3205
3135/************************************************************************** 3206/**************************************************************************
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index b331889ca46c..61fab0a00cc3 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -75,10 +75,18 @@ struct falcon_board {
75 * struct falcon_nic_data - Falcon NIC state 75 * struct falcon_nic_data - Falcon NIC state
76 * @pci_dev2: Secondary function of Falcon A 76 * @pci_dev2: Secondary function of Falcon A
77 * @board: Board state and functions 77 * @board: Board state and functions
78 * @stats_disable_count: Nest count for disabling statistics fetches
79 * @stats_pending: Is there a pending DMA of MAC statistics.
80 * @stats_timer: A timer for regularly fetching MAC statistics.
81 * @stats_dma_done: Pointer to the flag which indicates DMA completion.
78 */ 82 */
79struct falcon_nic_data { 83struct falcon_nic_data {
80 struct pci_dev *pci_dev2; 84 struct pci_dev *pci_dev2;
81 struct falcon_board board; 85 struct falcon_board board;
86 unsigned int stats_disable_count;
87 bool stats_pending;
88 struct timer_list stats_timer;
89 u32 *stats_dma_done;
82}; 90};
83 91
84static inline struct falcon_board *falcon_board(struct efx_nic *efx) 92static inline struct falcon_board *falcon_board(struct efx_nic *efx)
@@ -128,8 +136,6 @@ extern void falcon_remove_port(struct efx_nic *efx);
128/* MAC/PHY */ 136/* MAC/PHY */
129extern int falcon_switch_mac(struct efx_nic *efx); 137extern int falcon_switch_mac(struct efx_nic *efx);
130extern bool falcon_xaui_link_ok(struct efx_nic *efx); 138extern bool falcon_xaui_link_ok(struct efx_nic *efx);
131extern int falcon_dma_stats(struct efx_nic *efx,
132 unsigned int done_offset);
133extern void falcon_drain_tx_fifo(struct efx_nic *efx); 139extern void falcon_drain_tx_fifo(struct efx_nic *efx);
134extern void falcon_deconfigure_mac_wrapper(struct efx_nic *efx); 140extern void falcon_deconfigure_mac_wrapper(struct efx_nic *efx);
135extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); 141extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx);
@@ -154,6 +160,8 @@ extern int falcon_flush_queues(struct efx_nic *efx);
154extern int falcon_reset_hw(struct efx_nic *efx, enum reset_type method); 160extern int falcon_reset_hw(struct efx_nic *efx, enum reset_type method);
155extern void falcon_remove_nic(struct efx_nic *efx); 161extern void falcon_remove_nic(struct efx_nic *efx);
156extern void falcon_update_nic_stats(struct efx_nic *efx); 162extern void falcon_update_nic_stats(struct efx_nic *efx);
163extern void falcon_start_nic_stats(struct efx_nic *efx);
164extern void falcon_stop_nic_stats(struct efx_nic *efx);
157extern void falcon_set_multicast_hash(struct efx_nic *efx); 165extern void falcon_set_multicast_hash(struct efx_nic *efx);
158extern int falcon_reset_xaui(struct efx_nic *efx); 166extern int falcon_reset_xaui(struct efx_nic *efx);
159 167
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index ac1258ea677c..72d1c7834e6b 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -347,14 +347,14 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
347 * MAC stats accordingly. */ 347 * MAC stats accordingly. */
348 efx->phy_mode = new_mode; 348 efx->phy_mode = new_mode;
349 if (new_mode & PHY_MODE_SPECIAL) 349 if (new_mode & PHY_MODE_SPECIAL)
350 efx_stats_disable(efx); 350 falcon_stop_nic_stats(efx);
351 if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001) 351 if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001)
352 err = sfe4001_poweron(efx); 352 err = sfe4001_poweron(efx);
353 else 353 else
354 err = sfn4111t_reset(efx); 354 err = sfn4111t_reset(efx);
355 efx_reconfigure_port(efx); 355 efx_reconfigure_port(efx);
356 if (!(new_mode & PHY_MODE_SPECIAL)) 356 if (!(new_mode & PHY_MODE_SPECIAL))
357 efx_stats_enable(efx); 357 falcon_start_nic_stats(efx);
358 } 358 }
359 rtnl_unlock(); 359 rtnl_unlock();
360 360
@@ -441,7 +441,7 @@ static int sfe4001_init(struct efx_nic *efx)
441 if (efx->phy_mode & PHY_MODE_SPECIAL) { 441 if (efx->phy_mode & PHY_MODE_SPECIAL) {
442 /* PHY won't generate a 156.25 MHz clock and MAC stats fetch 442 /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
443 * will fail. */ 443 * will fail. */
444 efx_stats_disable(efx); 444 falcon_stop_nic_stats(efx);
445 } 445 }
446 rc = sfe4001_poweron(efx); 446 rc = sfe4001_poweron(efx);
447 if (rc) 447 if (rc)
@@ -504,7 +504,7 @@ static void sfn4111t_init_phy(struct efx_nic *efx)
504 return; 504 return;
505 505
506 efx->phy_mode = PHY_MODE_SPECIAL; 506 efx->phy_mode = PHY_MODE_SPECIAL;
507 efx_stats_disable(efx); 507 falcon_stop_nic_stats(efx);
508 } 508 }
509 509
510 sfn4111t_reset(efx); 510 sfn4111t_reset(efx);
@@ -531,7 +531,7 @@ static int sfn4111t_init(struct efx_nic *efx)
531 if (efx->phy_mode & PHY_MODE_SPECIAL) 531 if (efx->phy_mode & PHY_MODE_SPECIAL)
532 /* PHY may not generate a 156.25 MHz clock and MAC 532 /* PHY may not generate a 156.25 MHz clock and MAC
533 * stats fetch will fail. */ 533 * stats fetch will fail. */
534 efx_stats_disable(efx); 534 falcon_stop_nic_stats(efx);
535 535
536 return 0; 536 return 0;
537 537
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c
index 967f3fb397c9..2aeb3fc02786 100644
--- a/drivers/net/sfc/falcon_gmac.c
+++ b/drivers/net/sfc/falcon_gmac.c
@@ -130,11 +130,6 @@ static void falcon_update_stats_gmac(struct efx_nic *efx)
130 struct efx_mac_stats *mac_stats = &efx->mac_stats; 130 struct efx_mac_stats *mac_stats = &efx->mac_stats;
131 unsigned long old_rx_pause, old_tx_pause; 131 unsigned long old_rx_pause, old_tx_pause;
132 unsigned long new_rx_pause, new_tx_pause; 132 unsigned long new_rx_pause, new_tx_pause;
133 int rc;
134
135 rc = falcon_dma_stats(efx, GDmaDone_offset);
136 if (rc)
137 return;
138 133
139 /* Pause frames are erroneously counted as errors (SFC bug 3269) */ 134 /* Pause frames are erroneously counted as errors (SFC bug 3269) */
140 old_rx_pause = mac_stats->rx_pause; 135 old_rx_pause = mac_stats->rx_pause;
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index cf24513900e7..e57545de60ff 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -60,9 +60,13 @@ static void falcon_setup_xaui(struct efx_nic *efx)
60 60
61int falcon_reset_xaui(struct efx_nic *efx) 61int falcon_reset_xaui(struct efx_nic *efx)
62{ 62{
63 struct falcon_nic_data *nic_data = efx->nic_data;
63 efx_oword_t reg; 64 efx_oword_t reg;
64 int count; 65 int count;
65 66
67 /* Don't fetch MAC statistics over an XMAC reset */
68 WARN_ON(nic_data->stats_disable_count == 0);
69
66 /* Start reset sequence */ 70 /* Start reset sequence */
67 EFX_POPULATE_OWORD_1(reg, FRF_AB_XX_RST_XX_EN, 1); 71 EFX_POPULATE_OWORD_1(reg, FRF_AB_XX_RST_XX_EN, 1);
68 efx_writeo(efx, &reg, FR_AB_XX_PWR_RST); 72 efx_writeo(efx, &reg, FR_AB_XX_PWR_RST);
@@ -250,6 +254,8 @@ static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
250 /* XAUI link is expected to be down */ 254 /* XAUI link is expected to be down */
251 return; 255 return;
252 256
257 falcon_stop_nic_stats(efx);
258
253 while (!efx->mac_up && tries) { 259 while (!efx->mac_up && tries) {
254 EFX_LOG(efx, "bashing xaui\n"); 260 EFX_LOG(efx, "bashing xaui\n");
255 falcon_reset_xaui(efx); 261 falcon_reset_xaui(efx);
@@ -258,6 +264,8 @@ static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
258 efx->mac_up = falcon_xaui_link_ok(efx); 264 efx->mac_up = falcon_xaui_link_ok(efx);
259 --tries; 265 --tries;
260 } 266 }
267
268 falcon_start_nic_stats(efx);
261} 269}
262 270
263static void falcon_reconfigure_xmac(struct efx_nic *efx) 271static void falcon_reconfigure_xmac(struct efx_nic *efx)
@@ -276,11 +284,6 @@ static void falcon_reconfigure_xmac(struct efx_nic *efx)
276static void falcon_update_stats_xmac(struct efx_nic *efx) 284static void falcon_update_stats_xmac(struct efx_nic *efx)
277{ 285{
278 struct efx_mac_stats *mac_stats = &efx->mac_stats; 286 struct efx_mac_stats *mac_stats = &efx->mac_stats;
279 int rc;
280
281 rc = falcon_dma_stats(efx, XgDmaDone_offset);
282 if (rc)
283 return;
284 287
285 /* Update MAC stats from DMAed values */ 288 /* Update MAC stats from DMAed values */
286 FALCON_STAT(efx, XgRxOctets, rx_bytes); 289 FALCON_STAT(efx, XgRxOctets, rx_bytes);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index d0755ab056fe..262aeabdcab7 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -717,7 +717,6 @@ union efx_multicast_hash {
717 * &struct net_device_stats. 717 * &struct net_device_stats.
718 * @stats_buffer: DMA buffer for statistics 718 * @stats_buffer: DMA buffer for statistics
719 * @stats_lock: Statistics update lock. Serialises statistics fetches 719 * @stats_lock: Statistics update lock. Serialises statistics fetches
720 * @stats_disable_count: Nest count for disabling statistics fetches
721 * @mac_op: MAC interface 720 * @mac_op: MAC interface
722 * @mac_address: Permanent MAC address 721 * @mac_address: Permanent MAC address
723 * @phy_type: PHY type 722 * @phy_type: PHY type
@@ -799,7 +798,6 @@ struct efx_nic {
799 struct efx_mac_stats mac_stats; 798 struct efx_mac_stats mac_stats;
800 struct efx_buffer stats_buffer; 799 struct efx_buffer stats_buffer;
801 spinlock_t stats_lock; 800 spinlock_t stats_lock;
802 unsigned int stats_disable_count;
803 801
804 struct efx_mac_operations *mac_op; 802 struct efx_mac_operations *mac_op;
805 unsigned char mac_address[ETH_ALEN]; 803 unsigned char mac_address[ETH_ALEN];
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index a95402d601c7..e6232fe26072 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -374,7 +374,7 @@ static int tenxpress_special_reset(struct efx_nic *efx)
374 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so 374 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
375 * a special software reset can glitch the XGMAC sufficiently for stats 375 * a special software reset can glitch the XGMAC sufficiently for stats
376 * requests to fail. */ 376 * requests to fail. */
377 efx_stats_disable(efx); 377 falcon_stop_nic_stats(efx);
378 378
379 /* Initiate reset */ 379 /* Initiate reset */
380 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); 380 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
@@ -396,7 +396,7 @@ static int tenxpress_special_reset(struct efx_nic *efx)
396 /* Wait for the XGXS state machine to churn */ 396 /* Wait for the XGXS state machine to churn */
397 mdelay(10); 397 mdelay(10);
398out: 398out:
399 efx_stats_enable(efx); 399 falcon_start_nic_stats(efx);
400 return rc; 400 return rc;
401} 401}
402 402