diff options
-rw-r--r-- | drivers/net/ethernet/sfc/falcon_xmac.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena.c | 8 |
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 | ||
352 | void falcon_poll_xmac(struct efx_nic *efx) | 352 | void 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); | |||
294 | extern int falcon_reconfigure_xmac(struct efx_nic *efx); | 294 | extern int falcon_reconfigure_xmac(struct efx_nic *efx); |
295 | extern void falcon_update_stats_xmac(struct efx_nic *efx); | 295 | extern 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 | */ | ||
309 | static 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 */ |
298 | extern int efx_nic_init_interrupt(struct efx_nic *efx); | 316 | extern int efx_nic_init_interrupt(struct efx_nic *efx); |
299 | extern void efx_nic_enable_interrupts(struct efx_nic *efx); | 317 | extern 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); |