diff options
author | Edward Cree <ecree@solarflare.com> | 2020-06-29 14:34:20 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-06-29 17:37:48 -0700 |
commit | d3142c193dca9a2f6878f4128ce1aaf221bb3f99 (patch) | |
tree | 8722218c1475c4f51a49cebd78e68bc703d2863d /drivers/net/ethernet/sfc/nic.c | |
parent | de5f32e2b6301c1f6780b3ae9c2740a5e422e2da (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.c | 45 |
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 |