diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index a390a4b53c..93f5c0e4d4 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -362,6 +362,7 @@ Limitations
   - Green color is not supported with drop action.
   - Yellow detection is not supported.
   - Red color must be with drop action.
+  - meter srTCMp algorithm is supported.
 
 Statistics
 ----------
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 2790995dcc..16fa1b6c4d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -742,8 +742,13 @@ struct mlx5_flow_meter_info {
 	/**< Flow meter action. */
 };
 
-/* RFC2697 parameter structure. */
-struct mlx5_flow_meter_srtcm_rfc2697_prm {
+/* PPS(packets per second) map to BPS(Bytes per second).
+ * HW treat packet as 128bytes in PPS mode
+ */
+#define MLX5_MTRS_PPS_MAP_BPS_SHIFT 7
+
+/* RFC2697/PPS parameter structure. */
+struct mlx5_flow_meter_srtcm_prm {
 	rte_be32_t cbs_cir;
 	/*
 	 * bit 24-28: cbs_exponent, bit 16-23 cbs_mantissa,
@@ -763,8 +768,8 @@ struct mlx5_flow_meter_profile {
 	uint32_t id; /**< Profile id. */
 	struct rte_mtr_meter_profile profile; /**< Profile detail. */
 	union {
-		struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;
-		/**< srtcm_rfc2697 struct. */
+		struct mlx5_flow_meter_srtcm_prm srtcm_prm;
+		/**< srtcm_rfc2697/srtcm_pps struct. */
 	};
 	uint32_t ref_cnt; /**< Use count. */
 };
diff --git a/drivers/net/mlx5/mlx5_flow_aso.c b/drivers/net/mlx5/mlx5_flow_aso.c
index c9280b1f9d..3f3ba7e8fa 100644
--- a/drivers/net/mlx5/mlx5_flow_aso.c
+++ b/drivers/net/mlx5/mlx5_flow_aso.c
@@ -244,7 +244,6 @@ mlx5_aso_mtr_init_sq(struct mlx5_aso_sq *sq)
 	volatile struct mlx5_aso_wqe *restrict wqe;
 	int i;
 	int size = 1 << sq->log_desc_n;
-	uint32_t idx;
 
 	/* All the next fields state should stay constant. */
 	for (i = 0, wqe = &sq->wqes[0]; i < size; ++i, ++wqe) {
@@ -257,11 +256,6 @@ mlx5_aso_mtr_init_sq(struct mlx5_aso_sq *sq)
 			 (BYTEWISE_64BYTE << ASO_CSEG_DATA_MASK_MODE_OFFSET));
 		wqe->general_cseg.flags = RTE_BE32(MLX5_COMP_ALWAYS <<
 							 MLX5_COMP_MODE_OFFSET);
-		for (idx = 0; idx < MLX5_ASO_METERS_PER_WQE;
-			idx++)
-			wqe->aso_dseg.mtrs[idx].v_bo_sc_bbog_mm =
-				RTE_BE32((1 << ASO_DSEG_VALID_OFFSET) |
-				(MLX5_FLOW_COLOR_GREEN << ASO_DSEG_SC_OFFSET));
 	}
 }
 
@@ -744,6 +738,7 @@ mlx5_aso_mtr_sq_enqueue_single(struct mlx5_aso_sq *sq,
 {
 	volatile struct mlx5_aso_wqe *wqe = NULL;
 	struct mlx5_flow_meter_info *fm = NULL;
+	struct mlx5_flow_meter_profile *fmp;
 	uint16_t size = 1 << sq->log_desc_n;
 	uint16_t mask = size - 1;
 	uint16_t res = size - (uint16_t)(sq->head - sq->tail);
@@ -781,6 +776,16 @@ mlx5_aso_mtr_sq_enqueue_single(struct mlx5_aso_sq *sq,
 			RTE_BE32(MLX5_IFC_FLOW_METER_DISABLE_CBS_CIR_VAL);
 		wqe->aso_dseg.mtrs[dseg_idx].ebs_eir = 0;
 	}
+	fmp = fm->profile;
+	if (fmp->profile.alg == RTE_MTR_SRTCMP)
+		wqe->aso_dseg.mtrs[dseg_idx].v_bo_sc_bbog_mm =
+				RTE_BE32((1 << ASO_DSEG_VALID_OFFSET) |
+				(MLX5_FLOW_COLOR_GREEN << ASO_DSEG_SC_OFFSET) |
+				(MLX5_METER_MODE_PKT << ASO_DSEG_MTR_MODE));
+	else
+		wqe->aso_dseg.mtrs[dseg_idx].v_bo_sc_bbog_mm =
+				RTE_BE32((1 << ASO_DSEG_VALID_OFFSET) |
+				(MLX5_FLOW_COLOR_GREEN << ASO_DSEG_SC_OFFSET));
 	sq->head++;
 	sq->pi += 2;/* Each WQE contains 2 WQEBB's. */
 	rte_io_wmb();
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 49f6229ae6..cf2fe8c173 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -33,7 +33,7 @@ mlx5_flow_meter_action_create(struct mlx5_priv *priv,
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
 	struct mlx5dv_dr_flow_meter_attr mtr_init;
 	uint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)];
-	struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm =
+	struct mlx5_flow_meter_srtcm_prm *srtcm =
 						     &fm->profile->srtcm_prm;
 	uint32_t cbs_cir = rte_be_to_cpu_32(srtcm->cbs_cir);
 	uint32_t ebs_eir = rte_be_to_cpu_32(srtcm->ebs_eir);
@@ -157,6 +157,32 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
 					      "Invalid metering parameters.");
 		}
 	}
+	if (priv->sh->meter_aso_en &&
+		profile->alg == RTE_MTR_SRTCMP) {
+		if (priv->config.hca_attr.qos.srtcm_sup) {
+			/* Verify support for flow meter parameters. */
+			if (profile->srtcmp.cir > 0 &&
+			    (profile->srtcmp.cir <<
+					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+						<= MLX5_SRTCM_CIR_MAX &&
+			    profile->srtcmp.cbs > 0 &&
+			    (profile->srtcmp.cbs <<
+					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+						<= MLX5_SRTCM_CBS_MAX &&
+			    (profile->srtcmp.ebs <<
+					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+						<= MLX5_SRTCM_EBS_MAX)
+				return 0;
+			else
+				return -rte_mtr_error_set
+					     (error, ENOTSUP,
+					      RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+					      NULL,
+					      profile->srtcmp.ebs ?
+					      "Metering value ebs must be 0." :
+					      "Invalid metering parameters.");
+		}
+	}
 	return -rte_mtr_error_set(error, ENOTSUP,
 				  RTE_MTR_ERROR_TYPE_METER_PROFILE,
 				  NULL, "Metering algorithm not supported.");
@@ -238,19 +264,35 @@ mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp)
  */
 static int
 mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
-			  struct rte_mtr_error *error)
+			struct mlx5_priv *priv, struct rte_mtr_error *error)
 {
-	struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm = &fmp->srtcm_prm;
+	struct mlx5_flow_meter_srtcm_prm *srtcm = &fmp->srtcm_prm;
 	uint8_t man, exp;
 	uint32_t cbs_exp, cbs_man, cir_exp, cir_man;
 	uint32_t ebs_exp, ebs_man;
+	uint64_t cir, cbs, ebs;
 
-	if (fmp->profile.alg != RTE_MTR_SRTCM_RFC2697)
-		return -rte_mtr_error_set(error, ENOTSUP,
+	if (fmp->profile.alg == RTE_MTR_SRTCM_RFC2697) {
+		cir = fmp->profile.srtcm_rfc2697.cir;
+		cbs = fmp->profile.srtcm_rfc2697.cbs;
+		ebs = fmp->profile.srtcm_rfc2697.ebs;
+	} else {
+		if (priv->sh->meter_aso_en &&
+			fmp->profile.alg == RTE_MTR_SRTCMP) {
+			cir = fmp->profile.srtcmp.cir <<
+				MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+			cbs = fmp->profile.srtcmp.cbs <<
+				MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+			ebs = fmp->profile.srtcmp.ebs <<
+				MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+		} else {
+			return -rte_mtr_error_set(error, ENOTSUP,
 				RTE_MTR_ERROR_TYPE_METER_PROFILE,
 				NULL, "Metering algorithm not supported.");
+		}
+	}
 	/* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */
-	mlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,
+	mlx5_flow_meter_cir_man_exp_calc(cir,
 				    &man, &exp);
 	/* Check if cir mantissa is too large. */
 	if (exp > ASO_DSEG_CIR_EXP_MASK)
@@ -261,7 +303,7 @@ mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
 	cir_man = man;
 	cir_exp = exp;
 	 /* cbs = cbs_mantissa * 2^cbs_exponent */
-	mlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.cbs,
+	mlx5_flow_meter_xbs_man_exp_calc(cbs,
 				    &man, &exp);
 	/* Check if cbs mantissa is too large. */
 	if (exp > ASO_DSEG_EXP_MASK)
@@ -275,7 +317,7 @@ mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
 				cbs_man << ASO_DSEG_CBS_MAN_OFFSET |
 				cir_exp << ASO_DSEG_CIR_EXP_OFFSET |
 				cir_man);
-	mlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.ebs,
+	mlx5_flow_meter_xbs_man_exp_calc(ebs,
 				    &man, &exp);
 	/* Check if ebs mantissa is too large. */
 	if (exp > ASO_DSEG_EXP_MASK)
@@ -316,11 +358,14 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev,
 					  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
 					  "Meter is not supported");
 	memset(cap, 0, sizeof(*cap));
-	if (priv->sh->meter_aso_en)
+	if (priv->sh->meter_aso_en) {
 	    /* 2 meters per one ASO cache line. */
 		cap->n_max = 1 << (qattr->log_max_num_meter_aso + 1);
-	else
+		cap->meter_srtcmp_n_max = qattr->srtcm_sup ? cap->n_max : 0;
+	} else {
 		cap->n_max = 1 << qattr->log_max_flow_meter;
+		cap->meter_srtcmp_n_max = 0;
+	}
 	cap->n_shared_max = cap->n_max;
 	cap->identical = 1;
 	cap->shared_identical = 1;
@@ -382,7 +427,7 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,
 	fmp->id = meter_profile_id;
 	fmp->profile = *profile;
 	/* Fill the flow meter parameters for the PRM. */
-	ret = mlx5_flow_meter_param_fill(fmp, error);
+	ret = mlx5_flow_meter_param_fill(fmp, priv, error);
 	if (ret)
 		goto error;
 	/* Add to list. */
@@ -539,7 +584,7 @@ mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,
 static int
 mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
 		struct mlx5_flow_meter_info *fm,
-		const struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm,
+		const struct mlx5_flow_meter_srtcm_prm *srtcm,
 		uint64_t modify_bits, uint32_t active_state, uint32_t is_enable)
 {
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
@@ -899,7 +944,7 @@ mlx5_flow_meter_modify_state(struct mlx5_priv *priv,
 			     uint32_t new_state,
 			     struct rte_mtr_error *error)
 {
-	static const struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm = {
+	static const struct mlx5_flow_meter_srtcm_prm srtcm = {
 		.cbs_cir = RTE_BE32(MLX5_IFC_FLOW_METER_DISABLE_CBS_CIR_VAL),
 		.ebs_eir = 0,
 	};
