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

Reply via email to