From d3142c193dca9a2f6878f4128ce1aaf221bb3f99 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Mon, 29 Jun 2020 14:34:20 +0100 Subject: 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 Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/nic.c | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'drivers/net/ethernet/sfc/nic.c') 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" /************************************************************************** * @@ -470,6 +472,49 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, return visible; } +/** + * 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 -- cgit v1.2.3 From 20e1026cbed4af3fcf15779ec3edecf990ee8d4e Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Tue, 30 Jun 2020 13:13:47 +0100 Subject: sfc: move definition of EFX_MC_STATS_GENERATION_INVALID Saves a whole #include from nic.c. Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/mcdi_port_common.h | 2 -- drivers/net/ethernet/sfc/nic.c | 1 - drivers/net/ethernet/sfc/nic_common.h | 2 ++ 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net/ethernet/sfc/nic.c') diff --git a/drivers/net/ethernet/sfc/mcdi_port_common.h b/drivers/net/ethernet/sfc/mcdi_port_common.h index f6f81cbeb07e..9dbeee83266f 100644 --- a/drivers/net/ethernet/sfc/mcdi_port_common.h +++ b/drivers/net/ethernet/sfc/mcdi_port_common.h @@ -28,8 +28,6 @@ struct efx_mcdi_phy_data { u32 forced_cap; }; -#define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1)) - int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg); void efx_link_set_advertising(struct efx_nic *efx, const unsigned long *advertising); diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index ac6630510324..d994d136bb03 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -20,7 +20,6 @@ #include "farch_regs.h" #include "io.h" #include "workarounds.h" -#include "mcdi_port_common.h" #include "mcdi_pcol.h" /************************************************************************** diff --git a/drivers/net/ethernet/sfc/nic_common.h b/drivers/net/ethernet/sfc/nic_common.h index 8d0d163afc0d..197ecac5e005 100644 --- a/drivers/net/ethernet/sfc/nic_common.h +++ b/drivers/net/ethernet/sfc/nic_common.h @@ -263,6 +263,8 @@ void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer); size_t efx_nic_get_regs_len(struct efx_nic *efx); void efx_nic_get_regs(struct efx_nic *efx, void *buf); +#define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1)) + size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, const unsigned long *mask, u8 *names); int efx_nic_copy_stats(struct efx_nic *efx, __le64 *dest); -- cgit v1.2.3