From: Jay Ding <jay.d...@broadcom.com>

1. Implement Thor2 meter template tables
2. Add Thor2 meter support in ULP
3. Make rte_mtr API implementation device independent
   to adapt Thor2 meter hw change
4. Fix the round issue in xir calculation

Signed-off-by: Jay Ding <jay.d...@broadcom.com>
Reviewed-by: Michael Baucom <michael.bau...@broadcom.com>
Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapa...@broadcom.com>
---
 drivers/net/bnxt/tf_ulp/bnxt_ulp.h       |  12 +-
 drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c | 273 +++++++----------------
 drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c    | 113 +++++++++-
 drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c   |  47 +++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c |  12 +-
 5 files changed, 246 insertions(+), 211 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h 
b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h
index d62a9df5f0..4868339478 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.h
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.h
@@ -12,6 +12,7 @@
 
 #include "rte_version.h"
 #include "rte_ethdev.h"
+#include "rte_mtr.h"
 
 #include "bnxt.h"
 #include "ulp_template_db_enum.h"
@@ -231,6 +232,10 @@ struct bnxt_ulp_core_ops {
        int32_t
        (*ulp_vfr_session_fid_rem)(struct bnxt_ulp_context *ulp_ctx,
                                  uint16_t rep_fid);
+
+       int32_t
+       (*ulp_mtr_cap_get)(struct bnxt *bp,
+                          struct rte_mtr_capabilities *cap);
 };
 
 extern const struct bnxt_ulp_core_ops bnxt_ulp_tf_core_ops;
@@ -566,9 +571,6 @@ bnxt_ulp_cntxt_ecpri_udp_port_set(struct bnxt_ulp_context 
*ulp_ctx,
 unsigned int
 bnxt_ulp_cntxt_ecpri_udp_port_get(struct bnxt_ulp_context *ulp_ctx);
 
-int32_t
-bnxt_flow_meter_init(struct bnxt *bp);
-
 uint32_t
 bnxt_ulp_cntxt_convert_dev_id(uint32_t ulp_dev_id);
 
@@ -618,4 +620,8 @@ bnxt_ulp_vfr_session_fid_add(struct bnxt_ulp_context 
*ulp_ctx,
 int32_t
 bnxt_ulp_vfr_session_fid_rem(struct bnxt_ulp_context *ulp_ctx,
                             uint16_t vfr_fid);
+
+int32_t
+bnxt_flow_mtr_init(struct bnxt *bp __rte_unused);
+
 #endif /* _BNXT_ULP_H_ */
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c 
b/drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c
index 61d006fc08..37b5cc4dfb 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_meter.c
@@ -40,122 +40,24 @@
 /**
  * Meter init status
  */
-int bnxt_meter_initialized;
+int bnxt_mtr_initialized;
 
-/**
- * Internal api to config global config.
- * returns 0 on success.
- */
-static int32_t
-bnxt_meter_global_cfg_update(struct bnxt *bp,
-                            enum tf_dir dir,
-                            enum tf_global_config_type type,
-                            uint32_t offset,
-                            uint32_t value,
-                            uint32_t set_flag)
-{
-       uint32_t global_cfg = 0;
-       struct tf_global_cfg_parms parms = { 0 };
-       struct tf *tfp;
-       int32_t rc = 0;
-
-       parms.dir = dir,
-       parms.type = type,
-       parms.offset = offset,
-       parms.config = (uint8_t *)&global_cfg,
-       parms.config_sz_in_bytes = sizeof(global_cfg);
-
-       tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
-       rc = tf_get_global_cfg(tfp, &parms);
-       if (rc) {
-               BNXT_DRV_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
-                            type, rc);
-               return rc;
-       }
-
-       if (set_flag)
-               global_cfg |= value;
-       else
-               global_cfg &= ~value;
-
-       rc = tf_set_global_cfg(tfp, &parms);
-       if (rc) {
-               BNXT_DRV_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
-                            type, rc);
-               return rc;
-       }
-       return rc;
-}
-
-/**
- * When a port is initialized by dpdk. This functions is called
- * to enable the meter and initializes the meter global configurations.
- */
-#define BNXT_THOR_FMTCR_NUM_MET_MET_1K (0x7UL << 20)
-#define BNXT_THOR_FMTCR_CNTRS_ENABLE (0x1UL << 25)
-#define BNXT_THOR_FMTCR_INTERVAL_1K (1024)
 int32_t
-bnxt_flow_meter_init(struct bnxt *bp)
+bnxt_flow_mtr_init(struct bnxt *bp __rte_unused)
 {
-       int rc = 0;
-
-       /*
-        * Enable metering. Set the meter global configuration register.
-        * Set number of meter to 1K. Disable the drop counter for now.
-        */
-       rc = bnxt_meter_global_cfg_update(bp, TF_DIR_RX, TF_METER_CFG,
-                                         0,
-                                         BNXT_THOR_FMTCR_NUM_MET_MET_1K,
-                                         1);
-       if (rc) {
-               BNXT_DRV_DBG(ERR, "Failed to set rx meter configuration\n");
-               goto jump_to_error;
-       }
-
-       rc = bnxt_meter_global_cfg_update(bp, TF_DIR_TX, TF_METER_CFG,
-                                       0,
-                                       BNXT_THOR_FMTCR_NUM_MET_MET_1K,
-                                       1);
-       if (rc) {
-               BNXT_DRV_DBG(ERR, "Failed to set tx meter configuration\n");
-               goto jump_to_error;
-       }
-
        /*
-        * Set meter refresh rate to 1024 clock cycle. This value works for
-        * most bit rates especially for high rates.
-        */
-       rc = bnxt_meter_global_cfg_update(bp, TF_DIR_RX, TF_METER_INTERVAL_CFG,
-                                         0,
-                                         BNXT_THOR_FMTCR_INTERVAL_1K,
-                                         1);
-       if (rc) {
-               BNXT_DRV_DBG(ERR, "Failed to set rx meter interval\n");
-               goto jump_to_error;
-       }
-
-       rc = bnxt_meter_global_cfg_update(bp, TF_DIR_TX, TF_METER_INTERVAL_CFG,
-                                         0,
-                                         BNXT_THOR_FMTCR_INTERVAL_1K,
-                                         1);
-       if (rc) {
-               BNXT_DRV_DBG(ERR, "Failed to set tx meter interval\n");
-               goto jump_to_error;
-       }
-
-       bnxt_meter_initialized = 1;
+        ** Enable metering. The meter refresh interval is set to 1K
+        ** in FW. The meters is set to drop packet and meter cache is
+        ** enabled by HW default.
+        **/
+       bnxt_mtr_initialized = 1;
        BNXT_DRV_DBG(DEBUG, "Bnxt flow meter has been initialized\n");
-       return rc;
-
-jump_to_error:
-       return rc;
+       return 0;
 }
 
 /**
  * Get meter capabilities.
  */
-#define MAX_FLOW_PER_METER 1024
-#define MAX_METER_RATE_100GBPS ((1ULL << 30) * 100 / 8)
 static int
 bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
                      struct rte_mtr_capabilities *cap,
@@ -163,11 +65,9 @@ bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
 {
        struct bnxt *bp = dev->data->dev_private;
        uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
-       struct tf_get_session_info_parms iparms;
-       struct tf *tfp;
        int32_t rc = 0;
 
-       if (!bnxt_meter_initialized)
+       if (!bnxt_mtr_initialized)
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED,
                                          NULL,
@@ -180,35 +80,12 @@ bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
                                          NULL,
                                          "Unable to get device id from ulp");
 
-       /* Get number of meter reserved for this session */
-       memset(&iparms, 0, sizeof(iparms));
-       tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
-       rc = tf_get_session_info(tfp, &iparms);
-       if (rc != 0)
+       rc = bp->ulp_ctx->ops->ulp_mtr_cap_get(bp, cap);
+       if (rc)
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED,
                                          NULL,
-                                         "Failed to get session resource 
info");
-
-       memset(cap, 0, sizeof(struct rte_mtr_capabilities));
-
-       cap->n_max = 
iparms.session_info.tbl[TF_DIR_RX].info[TF_TBL_TYPE_METER_INST].stride;
-       if (!cap->n_max)
-               return -rte_mtr_error_set(error, ENOTSUP,
-                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
-                                         "Meter is not supported");
-
-       cap->srtcm_rfc2697_byte_mode_supported = 1;
-       cap->n_shared_max = cap->n_max;
-       /* No meter is identical */
-       cap->identical = 1;
-       cap->shared_identical = 1;
-       cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
-       cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
-       cap->meter_srtcm_rfc2697_n_max = cap->n_max;
-       cap->meter_rate_max = MAX_METER_RATE_100GBPS;
-       /* No stats supported now */
-       cap->stats_mask = 0;
+                                         "Unable to get meter capabilities");
 
        return 0;
 }
@@ -218,9 +95,8 @@ bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
  */
 #define BNXT_CPU_CLOCK 800
 #define MEGA 1000000
-#define NUM_BIT_PER_BYTE 8
 static inline void
-bnxt_ulp_flow_meter_xir_calc(int64_t xir, uint32_t *reg)
+bnxt_ulp_flow_mtr_xir_calc(int64_t xir, uint32_t *reg)
 {
        int64_t temp;
        uint16_t m = 0;
@@ -248,7 +124,7 @@ bnxt_ulp_flow_meter_xir_calc(int64_t xir, uint32_t *reg)
         *   = round(b*2^(38-e) - 2^11)
         *
         */
-       m = xir * (1 << (38 - e)) / BNXT_CPU_CLOCK / MEGA - (1 << 11);
+       m = (xir * (1 << (38 - e)) / BNXT_CPU_CLOCK / (MEGA / 10) + 5) / 10  - 
(1 << 11);
        *reg = ((m & 0x7FF) << 6) | (e & 0x3F);
        swap = (uint8_t *)reg;
        *reg = swap[0] << 16 | swap[1] << 8 | swap[2];
@@ -258,7 +134,7 @@ bnxt_ulp_flow_meter_xir_calc(int64_t xir, uint32_t *reg)
  * Calculate mantissa and exponent for cbs / ebs reg.
  */
 static inline void
-bnxt_ulp_flow_meter_xbs_calc(int64_t xbs, uint16_t *reg)
+bnxt_ulp_flow_mtr_xbs_calc(int64_t xbs, uint16_t *reg)
 {
        uint16_t m = 0;
        uint16_t e = 0;
@@ -288,7 +164,7 @@ bnxt_ulp_flow_meter_xbs_calc(int64_t xbs, uint16_t *reg)
  * Parse the meter profile.
  */
 static inline int
-bnxt_ulp_meter_profile_parse(struct ulp_rte_act_prop *act_prop,
+bnxt_ulp_mtr_profile_parse(struct ulp_rte_act_prop *act_prop,
                             const struct rte_mtr_meter_profile *profile,
                             struct rte_mtr_error *error)
 {
@@ -357,22 +233,22 @@ bnxt_ulp_meter_profile_parse(struct ulp_rte_act_prop 
*act_prop,
                                          NULL,
                                          "PIR must be equal to or greater than 
CIR");
 
-       bnxt_ulp_flow_meter_xir_calc(cir, &cir_reg);
+       bnxt_ulp_flow_mtr_xir_calc(cir, &cir_reg);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_CIR],
               &cir_reg,
               BNXT_ULP_ACT_PROP_SZ_METER_PROF_CIR);
 
-       bnxt_ulp_flow_meter_xir_calc(eir, &eir_reg);
+       bnxt_ulp_flow_mtr_xir_calc(eir, &eir_reg);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_EIR],
               &eir_reg,
               BNXT_ULP_ACT_PROP_SZ_METER_PROF_EIR);
 
-       bnxt_ulp_flow_meter_xbs_calc(cbs, &cbs_reg);
+       bnxt_ulp_flow_mtr_xbs_calc(cbs, &cbs_reg);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_CBS],
               &cbs_reg,
               BNXT_ULP_ACT_PROP_SZ_METER_PROF_CBS);
 
-       bnxt_ulp_flow_meter_xbs_calc(ebs, &ebs_reg);
+       bnxt_ulp_flow_mtr_xbs_calc(ebs, &ebs_reg);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_EBS],
               &ebs_reg,
               BNXT_ULP_ACT_PROP_SZ_METER_PROF_EBS);
@@ -392,8 +268,8 @@ bnxt_ulp_meter_profile_parse(struct ulp_rte_act_prop 
*act_prop,
  * Add MTR profile.
  */
 static int
-bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
-                           uint32_t meter_profile_id,
+bnxt_flow_mtr_profile_add(struct rte_eth_dev *dev,
+                           uint32_t mtr_profile_id,
                            struct rte_mtr_meter_profile *profile,
                            struct rte_mtr_error *error)
 {
@@ -406,7 +282,7 @@ bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
        int ret;
        uint32_t tmp_profile_id;
 
-       if (!bnxt_meter_initialized)
+       if (!bnxt_mtr_initialized)
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED,
                                          NULL,
@@ -426,12 +302,12 @@ bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
        /* not direction from rte_mtr. Set ingress by default */
        params.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
 
-       tmp_profile_id = tfp_cpu_to_be_32(meter_profile_id);
+       tmp_profile_id = tfp_cpu_to_be_32(mtr_profile_id);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_ID],
               &tmp_profile_id,
               BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);
 
-       ret = bnxt_ulp_meter_profile_parse(act_prop, profile, error);
+       ret = bnxt_ulp_mtr_profile_parse(act_prop, profile, error);
        if (ret)
                goto parse_error;
 
@@ -478,8 +354,8 @@ bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
  * Delete meter profile.
  */
 static int
-bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
-                              uint32_t meter_profile_id,
+bnxt_flow_mtr_profile_delete(struct rte_eth_dev *dev,
+                              uint32_t mtr_profile_id,
                               struct rte_mtr_error *error)
 {
        struct bnxt_ulp_context *ulp_ctx;
@@ -491,7 +367,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
        int ret;
        uint32_t tmp_profile_id;
 
-       if (!bnxt_meter_initialized)
+       if (!bnxt_mtr_initialized)
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED,
                                          NULL,
@@ -512,7 +388,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
        /* not direction from rte_mtr. Set ingress by default */
        params.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
 
-       tmp_profile_id = tfp_cpu_to_be_32(meter_profile_id);
+       tmp_profile_id = tfp_cpu_to_be_32(mtr_profile_id);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_ID],
               &tmp_profile_id,
               BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);
@@ -547,7 +423,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
                goto parse_error;
 
        BNXT_DRV_DBG(DEBUG, "Bnxt flow meter profile %d deleted\n",
-                    meter_profile_id);
+                    mtr_profile_id);
 
        return 0;
 
@@ -562,7 +438,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
  * Create meter.
  */
 static int
-bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
+bnxt_flow_mtr_create(struct rte_eth_dev *dev, uint32_t mtr_id,
                       struct rte_mtr_params *params, int shared __rte_unused,
                       struct rte_mtr_error *error)
 {
@@ -572,11 +448,11 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t 
meter_id,
        struct bnxt_ulp_mapper_parms mparms = { 0 };
        uint32_t act_tid;
        uint16_t func_id;
-       bool meter_en = params->meter_enable ? true : false;
+       bool mtr_en = params->meter_enable ? true : false;
        int ret;
-       uint32_t tmp_meter_id, tmp_profile_id;
+       uint32_t tmp_mtr_id, tmp_profile_id;
 
-       if (!bnxt_meter_initialized)
+       if (!bnxt_mtr_initialized)
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED,
                                          NULL,
@@ -596,9 +472,9 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t 
meter_id,
        /* not direction from rte_mtr. Set ingress by default */
        pparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
 
-       tmp_meter_id = tfp_cpu_to_be_32(meter_id);
+       tmp_mtr_id = tfp_cpu_to_be_32(mtr_id);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],
-              &tmp_meter_id,
+              &tmp_mtr_id,
               BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);
 
        tmp_profile_id = tfp_cpu_to_be_32(params->meter_profile_id);
@@ -607,7 +483,7 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t 
meter_id,
               BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);
 
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL],
-              &meter_en,
+              &mtr_en,
               BNXT_ULP_ACT_PROP_SZ_METER_INST_MTR_VAL);
 
        ret = ulp_matcher_action_match(&pparams, &act_tid);
@@ -639,7 +515,7 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t 
meter_id,
        if (ret)
                goto parse_error;
 
-       BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is created\n", meter_id);
+       BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is created\n", mtr_id);
 
        return 0;
 parse_error:
@@ -653,8 +529,8 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t 
meter_id,
  * Destroy meter.
  */
 static int
-bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
-                       uint32_t meter_id,
+bnxt_flow_mtr_destroy(struct rte_eth_dev *dev,
+                       uint32_t mtr_id,
                        struct rte_mtr_error *error)
 {
        struct bnxt_ulp_context *ulp_ctx;
@@ -664,9 +540,9 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
        uint32_t act_tid;
        uint16_t func_id;
        int ret;
-       uint32_t tmp_meter_id;
+       uint32_t tmp_mtr_id;
 
-       if (!bnxt_meter_initialized)
+       if (!bnxt_mtr_initialized)
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED,
                                          NULL,
@@ -687,9 +563,9 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
        /* not direction from rte_mtr. Set ingress by default */
        pparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
 
-       tmp_meter_id = tfp_cpu_to_be_32(meter_id);
+       tmp_mtr_id = tfp_cpu_to_be_32(mtr_id);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],
-              &tmp_meter_id,
+              &tmp_mtr_id,
               BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);
 
        ret = ulp_matcher_action_match(&pparams, &act_tid);
@@ -721,7 +597,7 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
        if (ret)
                goto parse_error;
 
-       BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is deleted\n", meter_id);
+       BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is deleted\n", mtr_id);
 
        return 0;
 parse_error:
@@ -735,8 +611,8 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
  * Set meter valid/invalid.
  */
 static int
-bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
-                          uint32_t meter_id,
+bnxt_flow_mtr_enable_set(struct rte_eth_dev *dev,
+                          uint32_t mtr_id,
                           uint8_t val,
                           struct rte_mtr_error *error)
 {
@@ -747,9 +623,9 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
        uint32_t act_tid;
        uint16_t func_id;
        int ret;
-       uint32_t tmp_meter_id;
+       uint32_t tmp_mtr_id;
 
-       if (!bnxt_meter_initialized)
+       if (!bnxt_mtr_initialized)
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED,
                                          NULL,
@@ -770,9 +646,9 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
        /* not direction from rte_mtr. Set ingress by default */
        pparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
 
-       tmp_meter_id = tfp_cpu_to_be_32(meter_id);
+       tmp_mtr_id = tfp_cpu_to_be_32(mtr_id);
        memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],
-              &tmp_meter_id,
+              &tmp_mtr_id,
               BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);
        act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL_UPDATE] 
= 1;
        act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL] = val;
@@ -807,7 +683,7 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
                goto parse_error;
 
        BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is %s\n",
-                    meter_id, val ? "enabled" : "disabled");
+                    mtr_id, val ? "enabled" : "disabled");
 
        return 0;
 parse_error:
@@ -821,31 +697,31 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
  * Enable flow meter.
  */
 static int
-bnxt_flow_meter_enable(struct rte_eth_dev *dev,
-                      uint32_t meter_id,
+bnxt_flow_mtr_enable(struct rte_eth_dev *dev,
+                      uint32_t mtr_id,
                       struct rte_mtr_error *error)
 {
-       return bnxt_flow_meter_enable_set(dev, meter_id, 1, error);
+       return bnxt_flow_mtr_enable_set(dev, mtr_id, 1, error);
 }
 
 /**
  * Disable flow meter.
  */
 static int
-bnxt_flow_meter_disable(struct rte_eth_dev *dev,
-                       uint32_t meter_id,
+bnxt_flow_mtr_disable(struct rte_eth_dev *dev,
+                       uint32_t mtr_id,
                        struct rte_mtr_error *error)
 {
-       return bnxt_flow_meter_enable_set(dev, meter_id, 0, error);
+       return bnxt_flow_mtr_enable_set(dev, mtr_id, 0, error);
 }
 
 /**
  * Update meter profile.
  */
 static int
-bnxt_flow_meter_profile_update(struct rte_eth_dev *dev __rte_unused,
-                              uint32_t meter_id __rte_unused,
-                              uint32_t meter_profile_id __rte_unused,
+bnxt_flow_mtr_profile_update(struct rte_eth_dev *dev __rte_unused,
+                              uint32_t mtr_id __rte_unused,
+                              uint32_t mtr_profile_id __rte_unused,
                               struct rte_mtr_error *error)
 {
        return -rte_mtr_error_set(error, ENOTSUP,
@@ -858,8 +734,8 @@ bnxt_flow_meter_profile_update(struct rte_eth_dev *dev 
__rte_unused,
  * Udate meter stats mask.
  */
 static int
-bnxt_flow_meter_stats_update(struct rte_eth_dev *dev __rte_unused,
-                            uint32_t meter_id __rte_unused,
+bnxt_flow_mtr_stats_update(struct rte_eth_dev *dev __rte_unused,
+                            uint32_t mtr_id __rte_unused,
                             uint64_t stats_mask __rte_unused,
                             struct rte_mtr_error *error)
 {
@@ -873,8 +749,8 @@ bnxt_flow_meter_stats_update(struct rte_eth_dev *dev 
__rte_unused,
  * Read meter statistics.
  */
 static int
-bnxt_flow_meter_stats_read(struct rte_eth_dev *dev __rte_unused,
-                          uint32_t meter_id __rte_unused,
+bnxt_flow_mtr_stats_read(struct rte_eth_dev *dev __rte_unused,
+                          uint32_t mtr_id __rte_unused,
                           struct rte_mtr_stats *stats __rte_unused,
                           uint64_t *stats_mask __rte_unused,
                           int clear __rte_unused,
@@ -888,19 +764,19 @@ bnxt_flow_meter_stats_read(struct rte_eth_dev *dev 
__rte_unused,
 
 static const struct rte_mtr_ops bnxt_flow_mtr_ops = {
        .capabilities_get = bnxt_flow_mtr_cap_get,
-       .meter_profile_add = bnxt_flow_meter_profile_add,
-       .meter_profile_delete = bnxt_flow_meter_profile_delete,
+       .meter_profile_add = bnxt_flow_mtr_profile_add,
+       .meter_profile_delete = bnxt_flow_mtr_profile_delete,
        .meter_policy_validate = NULL,
        .meter_policy_add = NULL,
        .meter_policy_delete = NULL,
-       .create = bnxt_flow_meter_create,
-       .destroy = bnxt_flow_meter_destroy,
-       .meter_enable = bnxt_flow_meter_enable,
-       .meter_disable = bnxt_flow_meter_disable,
-       .meter_profile_update = bnxt_flow_meter_profile_update,
+       .create = bnxt_flow_mtr_create,
+       .destroy = bnxt_flow_mtr_destroy,
+       .meter_enable = bnxt_flow_mtr_enable,
+       .meter_disable = bnxt_flow_mtr_disable,
+       .meter_profile_update = bnxt_flow_mtr_profile_update,
        .meter_dscp_table_update = NULL,
-       .stats_update = bnxt_flow_meter_stats_update,
-       .stats_read = bnxt_flow_meter_stats_read,
+       .stats_update = bnxt_flow_mtr_stats_update,
+       .stats_read = bnxt_flow_mtr_stats_read,
 };
 
 /**
@@ -910,5 +786,6 @@ int
 bnxt_flow_meter_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
 {
        *(const struct rte_mtr_ops **)arg = &bnxt_flow_mtr_ops;
+
        return 0;
 }
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c 
b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c
index eb8ecdbace..c7a712b8c8 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c
@@ -9,6 +9,8 @@
 #include <rte_flow_driver.h>
 #include <rte_tailq.h>
 #include <rte_spinlock.h>
+#include <rte_mtr.h>
+#include <rte_version.h>
 
 #include "bnxt.h"
 #include "bnxt_ulp.h"
@@ -1316,6 +1318,65 @@ ulp_tf_global_cfg_update(struct bnxt *bp,
        return rc;
 }
 
+/**
+ * When a port is initialized by dpdk. This functions is called
+ * to enable the meter and initializes the meter global configurations.
+ */
+#define BNXT_THOR_FMTCR_NUM_MET_MET_1K (0x7UL << 20)
+#define BNXT_THOR_FMTCR_CNTRS_ENABLE (0x1UL << 25)
+#define BNXT_THOR_FMTCR_INTERVAL_1K (1024)
+static int32_t
+ulp_tf_flow_mtr_init(struct bnxt *bp)
+{
+       int rc = 0;
+
+       /*
+        * Enable metering. Set the meter global configuration register.
+        * Set number of meter to 1K. Disable the drop counter for now.
+        */
+       rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_CFG,
+                                     0,
+                                     BNXT_THOR_FMTCR_NUM_MET_MET_1K,
+                                     1);
+       if (rc) {
+               BNXT_DRV_DBG(ERR, "Failed to set rx meter configuration\n");
+               goto jump_to_error;
+       }
+
+       rc = ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_METER_CFG,
+                                     0,
+                                     BNXT_THOR_FMTCR_NUM_MET_MET_1K,
+                                     1);
+       if (rc) {
+               BNXT_DRV_DBG(ERR, "Failed to set tx meter configuration\n");
+               goto jump_to_error;
+       }
+
+       /*
+        * Set meter refresh rate to 1024 clock cycle. This value works for
+        * most bit rates especially for high rates.
+        */
+       rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_INTERVAL_CFG,
+                                     0,
+                                     BNXT_THOR_FMTCR_INTERVAL_1K,
+                                     1);
+       if (rc) {
+               BNXT_DRV_DBG(ERR, "Failed to set rx meter interval\n");
+               goto jump_to_error;
+       }
+
+       rc = bnxt_flow_mtr_init(bp);
+       if (rc) {
+               BNXT_DRV_DBG(ERR, "Failed to config meter\n");
+               goto jump_to_error;
+       }
+
+       return rc;
+
+jump_to_error:
+       return rc;
+}
+
 /*
  * When a port is deinit'ed by dpdk. This function is called
  * and this function clears the ULP context and rest of the
@@ -1498,7 +1559,7 @@ ulp_tf_init(struct bnxt *bp,
        }
 
        if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR) {
-               rc = bnxt_flow_meter_init(bp);
+               rc = ulp_tf_flow_mtr_init(bp);
                if (rc) {
                        BNXT_DRV_DBG(ERR, "Failed to config meter\n");
                        goto jump_to_error;
@@ -1513,11 +1574,59 @@ ulp_tf_init(struct bnxt *bp,
        return rc;
 }
 
+/**
+ * Get meter capabilities.
+ */
+#define MAX_FLOW_PER_METER 1024
+#define MAX_METER_RATE_100GBPS ((1ULL << 30) * 100 / 8)
+static int
+ulp_tf_mtr_cap_get(struct bnxt *bp,
+                  struct rte_mtr_capabilities *cap)
+{
+       struct tf_get_session_info_parms iparms;
+       struct tf *tfp;
+       int32_t rc = 0;
+
+       /* Get number of meter reserved for this session */
+       memset(&iparms, 0, sizeof(iparms));
+       tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
+       rc = tf_get_session_info(tfp, &iparms);
+       if (rc != 0) {
+               BNXT_DRV_DBG(ERR, "Failed to get session resource info\n");
+               return rc;
+       }
+
+       memset(cap, 0, sizeof(struct rte_mtr_capabilities));
+
+       cap->n_max = 
iparms.session_info.tbl[TF_DIR_RX].info[TF_TBL_TYPE_METER_INST].stride;
+       if (!cap->n_max) {
+               BNXT_DRV_DBG(ERR, "Meter is not supported\n");
+               return -EINVAL;
+       }
+
+#if (RTE_VERSION_NUM(21, 05, 0, 0) <= RTE_VERSION)
+       cap->srtcm_rfc2697_byte_mode_supported = 1;
+#endif
+       cap->n_shared_max = cap->n_max;
+       /* No meter is identical */
+       cap->identical = 1;
+       cap->shared_identical = 1;
+       cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
+       cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
+       cap->meter_srtcm_rfc2697_n_max = cap->n_max;
+       cap->meter_rate_max = MAX_METER_RATE_100GBPS;
+       /* No stats supported now */
+       cap->stats_mask = 0;
+
+       return 0;
+}
+
 const struct bnxt_ulp_core_ops bnxt_ulp_tf_core_ops = {
        .ulp_ctx_attach = ulp_tf_ctx_attach,
        .ulp_ctx_detach = ulp_tf_ctx_detach,
        .ulp_deinit =  ulp_tf_deinit,
        .ulp_init =  ulp_tf_init,
        .ulp_vfr_session_fid_add = NULL,
-       .ulp_vfr_session_fid_rem = NULL
+       .ulp_vfr_session_fid_rem = NULL,
+       .ulp_mtr_cap_get = ulp_tf_mtr_cap_get
 };
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c 
b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c
index 2011ab6599..42ad944b2c 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c
@@ -9,6 +9,8 @@
 #include <rte_flow_driver.h>
 #include <rte_tailq.h>
 #include <rte_spinlock.h>
+#include <rte_mtr.h>
+#include <rte_version.h>
 
 #include "bnxt.h"
 #include "bnxt_ulp.h"
@@ -1017,6 +1019,20 @@ ulp_tfc_init(struct bnxt *bp,
                goto jump_to_error;
        }
 
+       rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
+       if (rc) {
+               BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
+               return rc;
+       }
+
+       if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR2) {
+               rc = bnxt_flow_mtr_init(bp);
+               if (rc) {
+                       BNXT_DRV_DBG(ERR, "Failed to config meter\n");
+                       goto jump_to_error;
+               }
+       }
+
        BNXT_DRV_DBG(DEBUG, "ulp ctx has been initialized\n");
        return rc;
 
@@ -1025,11 +1041,40 @@ ulp_tfc_init(struct bnxt *bp,
        return rc;
 }
 
+/**
+ * Get meter capabilities.
+ */
+#define MAX_FLOW_PER_METER 1024
+#define MAX_NUM_METER 1024
+#define MAX_METER_RATE_200GBPS ((1ULL << 31) * 100 / 8)
+static int
+ulp_tfc_mtr_cap_get(struct bnxt *bp __rte_unused,
+                   struct rte_mtr_capabilities *cap)
+{
+#if (RTE_VERSION_NUM(21, 05, 0, 0) <= RTE_VERSION)
+       cap->srtcm_rfc2697_byte_mode_supported = 1;
+#endif
+       cap->n_max = MAX_NUM_METER;
+       cap->n_shared_max = cap->n_max;
+       /* No meter is identical */
+       cap->identical = 1;
+       cap->shared_identical = 1;
+       cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
+       cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
+       cap->meter_srtcm_rfc2697_n_max = cap->n_max;
+       cap->meter_rate_max = MAX_METER_RATE_200GBPS;
+       /* No stats supported now */
+       cap->stats_mask = 0;
+
+       return 0;
+}
+
 const struct bnxt_ulp_core_ops bnxt_ulp_tfc_core_ops = {
        .ulp_ctx_attach = ulp_tfc_ctx_attach,
        .ulp_ctx_detach = ulp_tfc_ctx_detach,
        .ulp_deinit =  ulp_tfc_deinit,
        .ulp_init =  ulp_tfc_init,
        .ulp_vfr_session_fid_add = ulp_tfc_vfr_session_fid_add,
-       .ulp_vfr_session_fid_rem = ulp_tfc_vfr_session_fid_rem
+       .ulp_vfr_session_fid_rem = ulp_tfc_vfr_session_fid_rem,
+       .ulp_mtr_cap_get = ulp_tfc_mtr_cap_get
 };
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c 
b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index b647b2b83f..d313b7da07 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -3401,13 +3401,11 @@ ulp_rte_meter_act_handler(const struct rte_flow_action 
*action_item,
        }
 
        meter = action_item->conf;
-       if (meter) {
-               /* validate the mtr_id and update the reference counter */
-               tmp_meter_id = tfp_cpu_to_be_32(meter->mtr_id);
-               memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER],
-                      &tmp_meter_id,
-                      BNXT_ULP_ACT_PROP_SZ_METER);
-       }
+       /* validate the mtr_id and update the reference counter */
+       tmp_meter_id = tfp_cpu_to_be_32(meter->mtr_id);
+       memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER],
+              &tmp_meter_id,
+              BNXT_ULP_ACT_PROP_SZ_METER);
 
        /* set the meter action header bit */
        ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_METER);
-- 
2.39.3

Reply via email to