From 238306cf9affe2efe6c3204e53e7a1955d370f50 Mon Sep 17 00:00:00 2001 From: Igor Romanov Date: Fri, 2 Jul 2021 11:39:43 +0300 Subject: [PATCH] common/sfc_efx/base: support counter in action set User will be able to associate counter with MAE action set to collect counter packets and bytes for a specific action set. 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 | 21 ++++ drivers/common/sfc_efx/base/efx_impl.h | 3 + drivers/common/sfc_efx/base/efx_mae.c | 133 ++++++++++++++++++++++++- drivers/common/sfc_efx/version.map | 3 + 4 files changed, 157 insertions(+), 3 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index cc173d13c6..628e61e065 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4306,6 +4306,15 @@ extern __checkReturn efx_rc_t efx_mae_action_set_populate_encap( __in efx_mae_actions_t *spec); +/* + * Use efx_mae_action_set_fill_in_counter_id() to set ID of a counter + * in the specification prior to action set allocation. + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_action_set_populate_count( + __in efx_mae_actions_t *spec); + LIBEFX_API extern __checkReturn efx_rc_t efx_mae_action_set_populate_flag( @@ -4410,6 +4419,18 @@ typedef struct efx_counter_s { uint32_t id; } efx_counter_t; +LIBEFX_API +extern __checkReturn unsigned int +efx_mae_action_set_get_nb_count( + __in const efx_mae_actions_t *spec); + +/* See description before efx_mae_action_set_populate_count(). */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_action_set_fill_in_counter_id( + __in efx_mae_actions_t *spec, + __in const efx_counter_t *counter_idp); + /* Action set ID */ typedef struct efx_mae_aset_id_s { uint32_t id; diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index 9dbf6d450c..992edbabe3 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -1734,6 +1734,7 @@ typedef enum efx_mae_action_e { EFX_MAE_ACTION_DECAP, EFX_MAE_ACTION_VLAN_POP, EFX_MAE_ACTION_VLAN_PUSH, + EFX_MAE_ACTION_COUNT, EFX_MAE_ACTION_ENCAP, /* @@ -1764,6 +1765,7 @@ typedef struct efx_mae_action_vlan_push_s { typedef struct efx_mae_actions_rsrc_s { efx_mae_eh_id_t emar_eh_id; + efx_counter_t emar_counter_id; } efx_mae_actions_rsrc_t; struct efx_mae_actions_s { @@ -1774,6 +1776,7 @@ struct efx_mae_actions_s { unsigned int ema_n_vlan_tags_to_push; efx_mae_action_vlan_push_t ema_vlan_push_descs[ EFX_MAE_VLAN_PUSH_MAX_NTAGS]; + unsigned int ema_n_count_actions; uint32_t ema_mark_value; efx_mport_sel_t ema_deliver_mport; diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 6481a4ec42..10a96ac22a 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -1191,6 +1191,7 @@ efx_mae_action_set_spec_init( } spec->ema_rsrc.emar_eh_id.id = EFX_MAE_RSRC_ID_INVALID; + spec->ema_rsrc.emar_counter_id.id = EFX_MAE_RSRC_ID_INVALID; *specp = spec; @@ -1358,6 +1359,50 @@ fail1: return (rc); } +static __checkReturn efx_rc_t +efx_mae_action_set_add_count( + __in efx_mae_actions_t *spec, + __in size_t arg_size, + __in_bcount(arg_size) const uint8_t *arg) +{ + efx_rc_t rc; + + EFX_STATIC_ASSERT(EFX_MAE_RSRC_ID_INVALID == + MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_NULL); + + /* + * Preparing an action set spec to update a counter requires + * two steps: first add this action to the action spec, and then + * add the counter ID to the spec. This allows validity checking + * and resource allocation to be done separately. + * Mark the counter ID as invalid in the spec to ensure that the + * caller must also invoke efx_mae_action_set_fill_in_counter_id() + * before action set allocation. + */ + spec->ema_rsrc.emar_counter_id.id = EFX_MAE_RSRC_ID_INVALID; + + /* Nothing else is supposed to take place over here. */ + if (arg_size != 0) { + rc = EINVAL; + goto fail1; + } + + if (arg != NULL) { + rc = EINVAL; + goto fail2; + } + + ++(spec->ema_n_count_actions); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + static __checkReturn efx_rc_t efx_mae_action_set_add_flag( __in efx_mae_actions_t *spec, @@ -1466,6 +1511,9 @@ static const efx_mae_action_desc_t efx_mae_actions[EFX_MAE_NACTIONS] = { [EFX_MAE_ACTION_ENCAP] = { .emad_add = efx_mae_action_set_add_encap }, + [EFX_MAE_ACTION_COUNT] = { + .emad_add = efx_mae_action_set_add_count + }, [EFX_MAE_ACTION_FLAG] = { .emad_add = efx_mae_action_set_add_flag }, @@ -1481,6 +1529,12 @@ static const uint32_t efx_mae_action_ordered_map = (1U << EFX_MAE_ACTION_DECAP) | (1U << EFX_MAE_ACTION_VLAN_POP) | (1U << EFX_MAE_ACTION_VLAN_PUSH) | + /* + * HW will conduct action COUNT after + * the matching packet has been modified by + * length-affecting actions except for ENCAP. + */ + (1U << EFX_MAE_ACTION_COUNT) | (1U << EFX_MAE_ACTION_ENCAP) | (1U << EFX_MAE_ACTION_FLAG) | (1U << EFX_MAE_ACTION_MARK) | @@ -1497,7 +1551,8 @@ static const uint32_t efx_mae_action_nonstrict_map = static const uint32_t efx_mae_action_repeat_map = (1U << EFX_MAE_ACTION_VLAN_POP) | - (1U << EFX_MAE_ACTION_VLAN_PUSH); + (1U << EFX_MAE_ACTION_VLAN_PUSH) | + (1U << EFX_MAE_ACTION_COUNT); /* * Add an action to an action set. @@ -1620,6 +1675,20 @@ efx_mae_action_set_populate_encap( EFX_MAE_ACTION_ENCAP, 0, NULL)); } + __checkReturn efx_rc_t +efx_mae_action_set_populate_count( + __in efx_mae_actions_t *spec) +{ + /* + * There is no argument to pass counter ID, thus, one does not + * need to allocate a counter while parsing application input. + * This is useful since building an action set may be done simply to + * validate a rule, whilst resource allocation usually consumes time. + */ + return (efx_mae_action_set_spec_populate(spec, + EFX_MAE_ACTION_COUNT, 0, NULL)); +} + __checkReturn efx_rc_t efx_mae_action_set_populate_flag( __in efx_mae_actions_t *spec) @@ -2306,8 +2375,6 @@ efx_mae_action_set_alloc( */ MCDI_IN_SET_DWORD(req, MAE_ACTION_SET_ALLOC_IN_COUNTER_LIST_ID, EFX_MAE_RSRC_ID_INVALID); - MCDI_IN_SET_DWORD(req, - MAE_ACTION_SET_ALLOC_IN_COUNTER_ID, EFX_MAE_RSRC_ID_INVALID); if ((spec->ema_actions & (1U << EFX_MAE_ACTION_DECAP)) != 0) { MCDI_IN_SET_DWORD_FIELD(req, MAE_ACTION_SET_ALLOC_IN_FLAGS, @@ -2344,6 +2411,8 @@ efx_mae_action_set_alloc( MCDI_IN_SET_DWORD(req, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID, spec->ema_rsrc.emar_eh_id.id); + MCDI_IN_SET_DWORD(req, MAE_ACTION_SET_ALLOC_IN_COUNTER_ID, + spec->ema_rsrc.emar_counter_id.id); if ((spec->ema_actions & (1U << EFX_MAE_ACTION_FLAG)) != 0) { MCDI_IN_SET_DWORD_FIELD(req, MAE_ACTION_SET_ALLOC_IN_FLAGS, @@ -2388,6 +2457,64 @@ efx_mae_action_set_alloc( return (0); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn unsigned int +efx_mae_action_set_get_nb_count( + __in const efx_mae_actions_t *spec) +{ + return (spec->ema_n_count_actions); +} + + __checkReturn efx_rc_t +efx_mae_action_set_fill_in_counter_id( + __in efx_mae_actions_t *spec, + __in const efx_counter_t *counter_idp) +{ + efx_rc_t rc; + + if ((spec->ema_actions & (1U << EFX_MAE_ACTION_COUNT)) == 0) { + /* + * Invalid to add counter ID if spec does not have COUNT action. + */ + rc = EINVAL; + goto fail1; + } + + if (spec->ema_n_count_actions != 1) { + /* + * Having multiple COUNT actions in the spec requires a counter + * list to be used. This API must only be used for a single + * counter per spec. Turn down the request as inappropriate. + */ + rc = EINVAL; + goto fail2; + } + + if (spec->ema_rsrc.emar_counter_id.id != EFX_MAE_RSRC_ID_INVALID) { + /* The caller attempts to indicate counter ID twice. */ + rc = EALREADY; + goto fail3; + } + + if (counter_idp->id == EFX_MAE_RSRC_ID_INVALID) { + rc = EINVAL; + goto fail4; + } + + spec->ema_rsrc.emar_counter_id.id = counter_idp->id; + + return (0); + fail4: EFSYS_PROBE(fail4); fail3: diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 622f5d4cf5..0c5bcdfa84 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -89,8 +89,11 @@ INTERNAL { efx_mae_action_rule_insert; efx_mae_action_rule_remove; efx_mae_action_set_alloc; + efx_mae_action_set_fill_in_counter_id; efx_mae_action_set_fill_in_eh_id; efx_mae_action_set_free; + efx_mae_action_set_get_nb_count; + efx_mae_action_set_populate_count; efx_mae_action_set_populate_decap; efx_mae_action_set_populate_deliver; efx_mae_action_set_populate_drop; -- 2.20.1