[34/47] net/bnxt: tf_ulp: add rte_mtr support for Thor2

Message ID 20240830140049.1715230-35-sriharsha.basavapatna@broadcom.com (mailing list archive)
State Superseded
Delegated to: Ajit Khaparde
Headers
Series TruFlow update for Thor2 |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Sriharsha Basavapatna Aug. 30, 2024, 2 p.m. UTC
From: Jay Ding <jay.ding@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.ding@broadcom.com>
Reviewed-by: Michael Baucom <michael.baucom@broadcom.com>
Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@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(-)
  

Patch

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);