Doing so is required to disambiguate counters of different types supported by the match-action engine (MAE) on EF100.
Currently, the code only supports action rule counters, but MAE may also support conntrack assistance counters. Add type-aware allocate and free MCDI handlers and extend reporting of counter limits accordingly. Signed-off-by: Ivan Malov <ivan.ma...@arknetworks.am> Reviewed-by: Andy Moreton <amore...@xilinx.com> --- drivers/common/sfc_efx/base/efx.h | 39 +++++++- drivers/common/sfc_efx/base/efx_impl.h | 2 +- drivers/common/sfc_efx/base/efx_mae.c | 120 ++++++++++++++++++++----- drivers/common/sfc_efx/version.map | 2 + 4 files changed, 140 insertions(+), 23 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index a296d34f29..5a2e05134a 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4191,7 +4191,10 @@ typedef struct efx_mae_limits_s { uint32_t eml_max_n_outer_prios; uint32_t eml_encap_types_supported; uint32_t eml_encap_header_size_limit; - uint32_t eml_max_n_counters; + union { + uint32_t eml_max_n_counters; + uint32_t eml_max_n_action_counters; + }; } efx_mae_limits_t; LIBEFX_API @@ -4780,6 +4783,14 @@ efx_mae_action_set_fill_in_eh_id( __in efx_mae_actions_t *spec, __in const efx_mae_eh_id_t *eh_idp); +/* + * Counter types that may be supported by the match-action engine. + * Each counter type maintains its own counter ID namespace in FW. + */ +typedef enum efx_counter_type_e { + EFX_COUNTER_TYPE_ACTION = 0, +} efx_counter_type_t; + typedef struct efx_counter_s { uint32_t id; } efx_counter_t; @@ -4809,6 +4820,8 @@ efx_mae_action_set_alloc( __out efx_mae_aset_id_t *aset_idp); /* + * Allocates MAE counter(s) of type EFX_COUNTER_TYPE_ACTION. + * * Generation count has two purposes: * * 1) Distinguish between counter packets that belong to freed counter @@ -4832,6 +4845,20 @@ efx_mae_counters_alloc( __out_ecount(n_counters) efx_counter_t *countersp, __out_opt uint32_t *gen_countp); +/* + * Allocates MAE counter(s) of the specified type. Other + * than that, behaves like efx_mae_counters_alloc(). + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_counters_alloc_type( + __in efx_nic_t *enp, + __in efx_counter_type_t type, + __in uint32_t n_counters, + __out uint32_t *n_allocatedp, + __out_ecount(n_counters) efx_counter_t *countersp, + __out_opt uint32_t *gen_countp); + LIBEFX_API extern __checkReturn efx_rc_t efx_mae_counters_free( @@ -4841,6 +4868,16 @@ efx_mae_counters_free( __in_ecount(n_counters) const efx_counter_t *countersp, __out_opt uint32_t *gen_countp); +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_counters_free_type( + __in efx_nic_t *enp, + __in efx_counter_type_t type, + __in uint32_t n_counters, + __out uint32_t *n_freedp, + __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) diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index e978ad0de8..f6b472c160 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -841,7 +841,7 @@ typedef struct efx_mae_s { /** Outer rule match field capabilities. */ efx_mae_field_cap_t *em_outer_rule_field_caps; size_t em_outer_rule_field_caps_size; - uint32_t em_max_ncounters; + uint32_t em_max_n_action_counters; } efx_mae_t; #endif /* EFSYS_OPT_MAE */ diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index aaea38c933..4078146741 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -67,8 +67,8 @@ efx_mae_get_capabilities( maep->em_max_nfields = MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_MATCH_FIELD_COUNT); - maep->em_max_ncounters = - MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_COUNTERS); + maep->em_max_n_action_counters = + MCDI_OUT_DWORD(req, MAE_GET_CAPS_OUT_AR_COUNTERS); return (0); @@ -374,7 +374,7 @@ efx_mae_get_limits( emlp->eml_encap_types_supported = maep->em_encap_types_supported; emlp->eml_encap_header_size_limit = MC_CMD_MAE_ENCAP_HEADER_ALLOC_IN_HDR_DATA_MAXNUM_MCDI2; - emlp->eml_max_n_counters = maep->em_max_ncounters; + emlp->eml_max_n_action_counters = maep->em_max_n_action_counters; return (0); @@ -3256,55 +3256,70 @@ efx_mae_action_set_fill_in_counter_id( } __checkReturn efx_rc_t -efx_mae_counters_alloc( +efx_mae_counters_alloc_type( __in efx_nic_t *enp, + __in efx_counter_type_t type, __in uint32_t n_counters, __out uint32_t *n_allocatedp, __out_ecount(n_counters) efx_counter_t *countersp, __out_opt uint32_t *gen_countp) { EFX_MCDI_DECLARE_BUF(payload, - MC_CMD_MAE_COUNTER_ALLOC_IN_LEN, + MC_CMD_MAE_COUNTER_ALLOC_V2_IN_LEN, MC_CMD_MAE_COUNTER_ALLOC_OUT_LENMAX_MCDI2); efx_mae_t *maep = enp->en_maep; + uint32_t max_n_counters; uint32_t n_allocated; efx_mcdi_req_t req; unsigned int i; efx_rc_t rc; - if (n_counters > maep->em_max_ncounters || + EFX_STATIC_ASSERT(EFX_COUNTER_TYPE_ACTION == MAE_COUNTER_TYPE_AR); + + switch (type) { + case EFX_COUNTER_TYPE_ACTION: + max_n_counters = maep->em_max_n_action_counters; + break; + default: + rc = EINVAL; + goto fail1; + } + + if (n_counters > max_n_counters || n_counters < MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_MINNUM || n_counters > MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_MAXNUM_MCDI2) { rc = EINVAL; - goto fail1; + goto fail2; } req.emr_cmd = MC_CMD_MAE_COUNTER_ALLOC; req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_MAE_COUNTER_ALLOC_IN_LEN; + req.emr_in_length = MC_CMD_MAE_COUNTER_ALLOC_V2_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_MAE_COUNTER_ALLOC_OUT_LEN(n_counters); MCDI_IN_SET_DWORD(req, MAE_COUNTER_ALLOC_IN_REQUESTED_COUNT, n_counters); + MCDI_IN_SET_DWORD(req, MAE_COUNTER_ALLOC_V2_IN_COUNTER_TYPE, type); + efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail2; + goto fail3; } if (req.emr_out_length_used < MC_CMD_MAE_COUNTER_ALLOC_OUT_LENMIN) { rc = EMSGSIZE; - goto fail3; + goto fail4; } n_allocated = MCDI_OUT_DWORD(req, MAE_COUNTER_ALLOC_OUT_COUNTER_ID_COUNT); if (n_allocated < MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_MINNUM) { rc = EFAULT; - goto fail4; + goto fail5; } for (i = 0; i < n_allocated; i++) { @@ -3321,6 +3336,8 @@ efx_mae_counters_alloc( return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -3334,33 +3351,67 @@ efx_mae_counters_alloc( } __checkReturn efx_rc_t -efx_mae_counters_free( +efx_mae_counters_alloc( __in efx_nic_t *enp, __in uint32_t n_counters, + __out uint32_t *n_allocatedp, + __out_ecount(n_counters) efx_counter_t *countersp, + __out_opt uint32_t *gen_countp) +{ + efx_rc_t rc; + + rc = efx_mae_counters_alloc_type(enp, EFX_COUNTER_TYPE_ACTION, + n_counters, n_allocatedp, + countersp, gen_countp); + if (rc != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_counters_free_type( + __in efx_nic_t *enp, + __in efx_counter_type_t type, + __in uint32_t n_counters, __out uint32_t *n_freedp, __in_ecount(n_counters) const efx_counter_t *countersp, __out_opt uint32_t *gen_countp) { EFX_MCDI_DECLARE_BUF(payload, - MC_CMD_MAE_COUNTER_FREE_IN_LENMAX_MCDI2, + MC_CMD_MAE_COUNTER_FREE_V2_IN_LEN, MC_CMD_MAE_COUNTER_FREE_OUT_LENMAX_MCDI2); efx_mae_t *maep = enp->en_maep; + uint32_t max_n_counters; efx_mcdi_req_t req; uint32_t n_freed; unsigned int i; efx_rc_t rc; - if (n_counters > maep->em_max_ncounters || - n_counters < MC_CMD_MAE_COUNTER_FREE_IN_FREE_COUNTER_ID_MINNUM || - n_counters > - MC_CMD_MAE_COUNTER_FREE_IN_FREE_COUNTER_ID_MAXNUM_MCDI2) { + switch (type) { + case EFX_COUNTER_TYPE_ACTION: + max_n_counters = maep->em_max_n_action_counters; + break; + default: rc = EINVAL; goto fail1; } + if (n_counters > max_n_counters || + n_counters < MC_CMD_MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID_MINNUM || + n_counters > + MC_CMD_MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID_MAXNUM_MCDI2) { + rc = EINVAL; + goto fail2; + } + req.emr_cmd = MC_CMD_MAE_COUNTER_FREE; req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_MAE_COUNTER_FREE_IN_LEN(n_counters); + req.emr_in_length = MC_CMD_MAE_COUNTER_FREE_V2_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_MAE_COUNTER_FREE_OUT_LEN(n_counters); @@ -3371,23 +3422,25 @@ efx_mae_counters_free( MCDI_IN_SET_DWORD(req, MAE_COUNTER_FREE_IN_COUNTER_ID_COUNT, n_counters); + MCDI_IN_SET_DWORD(req, MAE_COUNTER_FREE_V2_IN_COUNTER_TYPE, type); + efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail2; + goto fail3; } if (req.emr_out_length_used < MC_CMD_MAE_COUNTER_FREE_OUT_LENMIN) { rc = EMSGSIZE; - goto fail3; + goto fail4; } n_freed = MCDI_OUT_DWORD(req, MAE_COUNTER_FREE_OUT_COUNTER_ID_COUNT); if (n_freed < MC_CMD_MAE_COUNTER_FREE_OUT_FREED_COUNTER_ID_MINNUM) { rc = EFAULT; - goto fail4; + goto fail5; } if (gen_countp != NULL) { @@ -3399,6 +3452,8 @@ efx_mae_counters_free( return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -3411,6 +3466,29 @@ efx_mae_counters_free( return (rc); } + __checkReturn efx_rc_t +efx_mae_counters_free( + __in efx_nic_t *enp, + __in uint32_t n_counters, + __out uint32_t *n_freedp, + __in_ecount(n_counters) const efx_counter_t *countersp, + __out_opt uint32_t *gen_countp) +{ + efx_rc_t rc; + + rc = efx_mae_counters_free_type(enp, EFX_COUNTER_TYPE_ACTION, + n_counters, n_freedp, + countersp, gen_countp); + if (rc != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + __checkReturn efx_rc_t efx_mae_counters_stream_start( __in efx_nic_t *enp, diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 1ff760a024..e550b64be6 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -113,7 +113,9 @@ INTERNAL { efx_mae_action_set_spec_init; efx_mae_action_set_specs_equal; efx_mae_counters_alloc; + efx_mae_counters_alloc_type; efx_mae_counters_free; + efx_mae_counters_free_type; efx_mae_counters_stream_give_credits; efx_mae_counters_stream_start; efx_mae_counters_stream_stop; -- 2.30.2