aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/falcon_xmac.c12
-rw-r--r--drivers/net/ethernet/sfc/nic.h18
-rw-r--r--drivers/net/ethernet/sfc/siena.c8
3 files changed, 28 insertions, 10 deletions
diff --git a/drivers/net/ethernet/sfc/falcon_xmac.c b/drivers/net/ethernet/sfc/falcon_xmac.c
index 6106ef15dee3..8333865d4c95 100644
--- a/drivers/net/ethernet/sfc/falcon_xmac.c
+++ b/drivers/net/ethernet/sfc/falcon_xmac.c
@@ -341,12 +341,12 @@ void falcon_update_stats_xmac(struct efx_nic *efx)
341 FALCON_STAT(efx, XgTxIpSrcErrPkt, tx_ip_src_error); 341 FALCON_STAT(efx, XgTxIpSrcErrPkt, tx_ip_src_error);
342 342
343 /* Update derived statistics */ 343 /* Update derived statistics */
344 mac_stats->tx_good_bytes = 344 efx_update_diff_stat(&mac_stats->tx_good_bytes,
345 (mac_stats->tx_bytes - mac_stats->tx_bad_bytes - 345 mac_stats->tx_bytes - mac_stats->tx_bad_bytes -
346 mac_stats->tx_control * 64); 346 mac_stats->tx_control * 64);
347 mac_stats->rx_bad_bytes = 347 efx_update_diff_stat(&mac_stats->rx_bad_bytes,
348 (mac_stats->rx_bytes - mac_stats->rx_good_bytes - 348 mac_stats->rx_bytes - mac_stats->rx_good_bytes -
349 mac_stats->rx_control * 64); 349 mac_stats->rx_control * 64);
350} 350}
351 351
352void falcon_poll_xmac(struct efx_nic *efx) 352void falcon_poll_xmac(struct efx_nic *efx)
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index f48ccf6bb3b9..bab5cd9f5740 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -294,6 +294,24 @@ extern bool falcon_xmac_check_fault(struct efx_nic *efx);
294extern int falcon_reconfigure_xmac(struct efx_nic *efx); 294extern int falcon_reconfigure_xmac(struct efx_nic *efx);
295extern void falcon_update_stats_xmac(struct efx_nic *efx); 295extern void falcon_update_stats_xmac(struct efx_nic *efx);
296 296
297/* Some statistics are computed as A - B where A and B each increase
298 * linearly with some hardware counter(s) and the counters are read
299 * asynchronously. If the counters contributing to B are always read
300 * after those contributing to A, the computed value may be lower than
301 * the true value by some variable amount, and may decrease between
302 * subsequent computations.
303 *
304 * We should never allow statistics to decrease or to exceed the true
305 * value. Since the computed value will never be greater than the
306 * true value, we can achieve this by only storing the computed value
307 * when it increases.
308 */
309static inline void efx_update_diff_stat(u64 *stat, u64 diff)
310{
311 if ((s64)(diff - *stat) > 0)
312 *stat = diff;
313}
314
297/* Interrupts and test events */ 315/* Interrupts and test events */
298extern int efx_nic_init_interrupt(struct efx_nic *efx); 316extern int efx_nic_init_interrupt(struct efx_nic *efx);
299extern void efx_nic_enable_interrupts(struct efx_nic *efx); 317extern void efx_nic_enable_interrupts(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 2354886293db..6bafd216e55e 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -458,8 +458,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
458 458
459 MAC_STAT(tx_bytes, TX_BYTES); 459 MAC_STAT(tx_bytes, TX_BYTES);
460 MAC_STAT(tx_bad_bytes, TX_BAD_BYTES); 460 MAC_STAT(tx_bad_bytes, TX_BAD_BYTES);
461 mac_stats->tx_good_bytes = (mac_stats->tx_bytes - 461 efx_update_diff_stat(&mac_stats->tx_good_bytes,
462 mac_stats->tx_bad_bytes); 462 mac_stats->tx_bytes - mac_stats->tx_bad_bytes);
463 MAC_STAT(tx_packets, TX_PKTS); 463 MAC_STAT(tx_packets, TX_PKTS);
464 MAC_STAT(tx_bad, TX_BAD_FCS_PKTS); 464 MAC_STAT(tx_bad, TX_BAD_FCS_PKTS);
465 MAC_STAT(tx_pause, TX_PAUSE_PKTS); 465 MAC_STAT(tx_pause, TX_PAUSE_PKTS);
@@ -492,8 +492,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
492 MAC_STAT(tx_ip_src_error, TX_IP_SRC_ERR_PKTS); 492 MAC_STAT(tx_ip_src_error, TX_IP_SRC_ERR_PKTS);
493 MAC_STAT(rx_bytes, RX_BYTES); 493 MAC_STAT(rx_bytes, RX_BYTES);
494 MAC_STAT(rx_bad_bytes, RX_BAD_BYTES); 494 MAC_STAT(rx_bad_bytes, RX_BAD_BYTES);
495 mac_stats->rx_good_bytes = (mac_stats->rx_bytes - 495 efx_update_diff_stat(&mac_stats->rx_good_bytes,
496 mac_stats->rx_bad_bytes); 496 mac_stats->rx_bytes - mac_stats->rx_bad_bytes);
497 MAC_STAT(rx_packets, RX_PKTS); 497 MAC_STAT(rx_packets, RX_PKTS);
498 MAC_STAT(rx_good, RX_GOOD_PKTS); 498 MAC_STAT(rx_good, RX_GOOD_PKTS);
499 MAC_STAT(rx_bad, RX_BAD_FCS_PKTS); 499 MAC_STAT(rx_bad, RX_BAD_FCS_PKTS);