From: Igor Romanov <igor.roma...@oktetlabs.ru> The MCDIs will be used to control counter Rx queue packet flow.
Signed-off-by: Igor Romanov <igor.roma...@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <andrew.rybche...@oktetlabs.ru> Reviewed-by: Andy Moreton <amore...@xilinx.com> Reviewed-by: Ivan Malov <ivan.ma...@oktetlabs.ru> --- 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 955f1d4353..0b3131161b 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -2766,6 +2766,144 @@ efx_mae_counters_free( 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.30.2