aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/sfc/nic.c
diff options
context:
space:
mode:
authorEdward Cree <ecree@solarflare.com>2020-06-29 14:34:20 +0100
committerDavid S. Miller <davem@davemloft.net>2020-06-29 17:37:48 -0700
commitd3142c193dca9a2f6878f4128ce1aaf221bb3f99 (patch)
tree8722218c1475c4f51a49cebd78e68bc703d2863d /drivers/net/ethernet/sfc/nic.c
parentde5f32e2b6301c1f6780b3ae9c2740a5e422e2da (diff)
sfc: refactor EF10 stats handling
Separate the generation-count handling from the format conversion, to make it easier to re-use both for EF100. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/sfc/nic.c')
-rw-r--r--drivers/net/ethernet/sfc/nic.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index b0baa70fbba7..ac6630510324 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -20,6 +20,8 @@
#include "farch_regs.h"
#include "io.h"
#include "workarounds.h"
+#include "mcdi_port_common.h"
+#include "mcdi_pcol.h"
/**************************************************************************
*
@@ -471,6 +473,49 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
}
/**
+ * efx_nic_copy_stats - Copy stats from the DMA buffer in to an
+ * intermediate buffer. This is used to get a consistent
+ * set of stats while the DMA buffer can be written at any time
+ * by the NIC.
+ * @efx: The associated NIC.
+ * @dest: Destination buffer. Must be the same size as the DMA buffer.
+ */
+int efx_nic_copy_stats(struct efx_nic *efx, __le64 *dest)
+{
+ __le64 *dma_stats = efx->stats_buffer.addr;
+ __le64 generation_start, generation_end;
+ int rc = 0, retry;
+
+ if (!dest)
+ return 0;
+
+ if (!dma_stats)
+ goto return_zeroes;
+
+ /* If we're unlucky enough to read statistics during the DMA, wait
+ * up to 10ms for it to finish (typically takes <500us)
+ */
+ for (retry = 0; retry < 100; ++retry) {
+ generation_end = dma_stats[efx->num_mac_stats - 1];
+ if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
+ goto return_zeroes;
+ rmb();
+ memcpy(dest, dma_stats, efx->num_mac_stats * sizeof(__le64));
+ rmb();
+ generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
+ if (generation_end == generation_start)
+ return 0; /* return good data */
+ udelay(100);
+ }
+
+ rc = -EIO;
+
+return_zeroes:
+ memset(dest, 0, efx->num_mac_stats * sizeof(u64));
+ return rc;
+}
+
+/**
* efx_nic_update_stats - Convert statistics DMA buffer to array of u64
* @desc: Array of &struct efx_hw_stat_desc describing the DMA buffer
* layout. DMA widths of 0, 16, 32 and 64 are supported; where