From c0a77efb9cc31f473815619fef2ff1b18bc9345a Mon Sep 17 00:00:00 2001 From: Igor Romanov Date: Fri, 2 Jul 2021 11:39:42 +0300 Subject: [PATCH] common/sfc_efx/base: add counter stream MCDI wrappers The MCDIs will be used to control counter Rx queue packet flow. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/common/sfc_efx/base/efx.h | 32 ++++++ drivers/common/sfc_efx/base/efx_mae.c | 138 ++++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 3 + 3 files changed, 173 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index d0f8bc10b3..cc173d13c6 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4455,6 +4455,38 @@ efx_mae_counters_free( __in_ecount(n_counters) const efx_counter_t *countersp, __out_opt uint32_t *gen_countp); +/* When set, include counters with a value of zero */ +#define EFX_MAE_COUNTERS_STREAM_IN_ZERO_SQUASH_DISABLE (1U << 0) + +/* + * Set if credit-based flow control is used. In this case the driver + * must call efx_mae_counters_stream_give_credits() to notify the + * packetiser of descriptors written. + */ +#define EFX_MAE_COUNTERS_STREAM_OUT_USES_CREDITS (1U << 0) + +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_counters_stream_start( + __in efx_nic_t *enp, + __in uint16_t rxq_id, + __in uint16_t packet_size, + __in uint32_t flags_in, + __out uint32_t *flags_out); + +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_counters_stream_stop( + __in efx_nic_t *enp, + __in uint16_t rxq_id, + __out_opt uint32_t *gen_countp); + +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_counters_stream_give_credits( + __in efx_nic_t *enp, + __in uint32_t n_credits); + LIBEFX_API extern __checkReturn efx_rc_t efx_mae_action_set_free( diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 8f9f9f417d..6481a4ec42 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -2551,6 +2551,144 @@ fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_counters_stream_start( + __in efx_nic_t *enp, + __in uint16_t rxq_id, + __in uint16_t packet_size, + __in uint32_t flags_in, + __out uint32_t *flags_out) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_MAE_COUNTERS_STREAM_START_IN_LEN, + MC_CMD_MAE_COUNTERS_STREAM_START_OUT_LEN); + efx_rc_t rc; + + EFX_STATIC_ASSERT(EFX_MAE_COUNTERS_STREAM_IN_ZERO_SQUASH_DISABLE == + 1U << MC_CMD_MAE_COUNTERS_STREAM_START_IN_ZERO_SQUASH_DISABLE_LBN); + + EFX_STATIC_ASSERT(EFX_MAE_COUNTERS_STREAM_OUT_USES_CREDITS == + 1U << MC_CMD_MAE_COUNTERS_STREAM_START_OUT_USES_CREDITS_LBN); + + req.emr_cmd = MC_CMD_MAE_COUNTERS_STREAM_START; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_COUNTERS_STREAM_START_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_COUNTERS_STREAM_START_OUT_LEN; + + MCDI_IN_SET_WORD(req, MAE_COUNTERS_STREAM_START_IN_QID, rxq_id); + MCDI_IN_SET_WORD(req, MAE_COUNTERS_STREAM_START_IN_PACKET_SIZE, + packet_size); + MCDI_IN_SET_DWORD(req, MAE_COUNTERS_STREAM_START_IN_FLAGS, flags_in); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < + MC_CMD_MAE_COUNTERS_STREAM_START_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + *flags_out = MCDI_OUT_DWORD(req, MAE_COUNTERS_STREAM_START_OUT_FLAGS); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_counters_stream_stop( + __in efx_nic_t *enp, + __in uint16_t rxq_id, + __out_opt uint32_t *gen_countp) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_MAE_COUNTERS_STREAM_STOP_IN_LEN, + MC_CMD_MAE_COUNTERS_STREAM_STOP_OUT_LEN); + efx_rc_t rc; + + req.emr_cmd = MC_CMD_MAE_COUNTERS_STREAM_STOP; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_COUNTERS_STREAM_STOP_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_COUNTERS_STREAM_STOP_OUT_LEN; + + MCDI_IN_SET_WORD(req, MAE_COUNTERS_STREAM_STOP_IN_QID, rxq_id); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < + MC_CMD_MAE_COUNTERS_STREAM_STOP_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + if (gen_countp != NULL) { + *gen_countp = MCDI_OUT_DWORD(req, + MAE_COUNTERS_STREAM_STOP_OUT_GENERATION_COUNT); + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_counters_stream_give_credits( + __in efx_nic_t *enp, + __in uint32_t n_credits) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS_IN_LEN, + MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS_OUT_LEN); + efx_rc_t rc; + + req.emr_cmd = MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS_OUT_LEN; + + MCDI_IN_SET_DWORD(req, MAE_COUNTERS_STREAM_GIVE_CREDITS_IN_NUM_CREDITS, + n_credits); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); } diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 30b243a1e7..622f5d4cf5 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -104,6 +104,9 @@ INTERNAL { efx_mae_action_set_specs_equal; efx_mae_counters_alloc; efx_mae_counters_free; + efx_mae_counters_stream_give_credits; + efx_mae_counters_stream_start; + efx_mae_counters_stream_stop; efx_mae_encap_header_alloc; efx_mae_encap_header_free; efx_mae_fini; -- 2.20.1