if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
if (priv->config.hca_attr.qos.flow_meter_old) {
/* Verify support for flow meter parameters. */
- if (profile->srtcm_rfc2697.cir > 0 &&
- profile->srtcm_rfc2697.cir <= MLX5_SRTCM_CIR_MAX &&
- profile->srtcm_rfc2697.cbs > 0 &&
- profile->srtcm_rfc2697.cbs <= MLX5_SRTCM_CBS_MAX &&
- profile->srtcm_rfc2697.ebs <= MLX5_SRTCM_EBS_MAX)
- return 0;
- else
+ if (priv->sh->meter_aso_en && profile->packet_mode) {
+ if (profile->srtcm_rfc2697.cir > 0 &&
+ (profile->srtcm_rfc2697.cir <<
+ MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+ <= MLX5_SRTCM_CIR_MAX &&
+ profile->srtcm_rfc2697.cbs > 0 &&
+ (profile->srtcm_rfc2697.cbs <<
+ MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+ <= MLX5_SRTCM_CBS_MAX &&
+ (profile->srtcm_rfc2697.ebs <<
+ MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+ <= MLX5_SRTCM_EBS_MAX)
+ return 0;
return -rte_mtr_error_set
(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_MTR_PARAMS,
profile->srtcm_rfc2697.ebs ?
"Metering value ebs must be 0." :
"Invalid metering parameters.");
+ }
+ if (profile->srtcm_rfc2697.cir > 0 &&
+ profile->srtcm_rfc2697.cir <=
+ MLX5_SRTCM_CIR_MAX &&
+ profile->srtcm_rfc2697.cbs > 0 &&
+ profile->srtcm_rfc2697.cbs <=
+ MLX5_SRTCM_CBS_MAX &&
+ profile->srtcm_rfc2697.ebs <=
+ MLX5_SRTCM_EBS_MAX)
+ return 0;
+ return -rte_mtr_error_set(error, ENOTSUP,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+ NULL,
+ profile->srtcm_rfc2697.ebs ?
+ "Metering value ebs must be 0." :
+ "Invalid metering parameters.");
}
}
return -rte_mtr_error_set(error, ENOTSUP,
*/
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;
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,
RTE_MTR_ERROR_TYPE_METER_PROFILE,
NULL, "Metering algorithm not supported.");
+ if (!priv->sh->meter_aso_en && fmp->profile.packet_mode)
+ return -rte_mtr_error_set(error, ENOTSUP,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE,
+ NULL, "Metering algorithm packet mode not supported.");
+ if (priv->sh->meter_aso_en && fmp->profile.packet_mode) {
+ cir = fmp->profile.srtcm_rfc2697.cir <<
+ MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+ cbs = fmp->profile.srtcm_rfc2697.cbs <<
+ MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+ ebs = fmp->profile.srtcm_rfc2697.ebs <<
+ MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+ } else {
+ cir = fmp->profile.srtcm_rfc2697.cir;
+ cbs = fmp->profile.srtcm_rfc2697.cbs;
+ ebs = fmp->profile.srtcm_rfc2697.ebs;
+ }
/* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */
- mlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,
- &man, &exp);
+ mlx5_flow_meter_cir_man_exp_calc(cir, &man, &exp);
/* Check if cir mantissa is too large. */
if (exp > ASO_DSEG_CIR_EXP_MASK)
return -rte_mtr_error_set(error, ENOTSUP,
cir_man = man;
cir_exp = exp;
/* cbs = cbs_mantissa * 2^cbs_exponent */
- mlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.cbs,
- &man, &exp);
+ mlx5_flow_meter_xbs_man_exp_calc(cbs, &man, &exp);
/* Check if cbs mantissa is too large. */
if (exp > ASO_DSEG_EXP_MASK)
return -rte_mtr_error_set(error, ENOTSUP,
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,
- &man, &exp);
+ mlx5_flow_meter_xbs_man_exp_calc(ebs, &man, &exp);
/* Check if ebs mantissa is too large. */
if (exp > ASO_DSEG_EXP_MASK)
return -rte_mtr_error_set(error, ENOTSUP,
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->srtcm_rfc2697_packet_mode_supported = 1;
+ } else {
cap->n_max = 1 << qattr->log_max_flow_meter;
+ cap->srtcm_rfc2697_packet_mode_supported = 0;
+ }
+ cap->srtcm_rfc2697_byte_mode_supported = 1;
cap->n_shared_max = cap->n_max;
cap->identical = 1;
cap->shared_identical = 1;
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. */
__mlx5_flow_meter_policy_delete(struct rte_eth_dev *dev,
uint32_t policy_id,
struct mlx5_flow_meter_policy *mtr_policy,
- struct rte_mtr_error *error)
+ struct rte_mtr_error *error,
+ bool clear_l3t)
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_meter_sub_policy *sub_policy;
}
}
}
- if (priv->sh->mtrmng->policy_idx_tbl) {
+ if (priv->sh->mtrmng->policy_idx_tbl && clear_l3t) {
if (mlx5_l3t_clear_entry(priv->sh->mtrmng->policy_idx_tbl,
policy_id)) {
rte_spinlock_unlock(&mtr_policy->sl);
policy->actions, error);
if (ret)
goto policy_add_err;
- if (!is_rss) {
+ if (!is_rss && !mtr_policy->is_queue) {
/* Create policy rules in HW. */
ret = mlx5_flow_create_policy_rules(dev, mtr_policy);
if (ret)
policy_add_err:
if (mtr_policy) {
ret = __mlx5_flow_meter_policy_delete(dev, policy_id,
- mtr_policy, error);
+ mtr_policy, error, false);
mlx5_free(mtr_policy);
if (ret)
return ret;
RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
"Meter policy id is invalid. ");
ret = __mlx5_flow_meter_policy_delete(dev, policy_id, mtr_policy,
- error);
+ error, true);
if (ret)
return ret;
mlx5_free(mtr_policy);
#endif
}
+/**
+ * Flush meter with Rx queue configuration.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ */
+void
+mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_flow_meter_sub_policy *sub_policy;
+ struct mlx5_flow_meter_policy *mtr_policy;
+ void *entry;
+ uint32_t i, policy_idx;
+
+ if (!priv->mtr_en)
+ return;
+ if (priv->sh->mtrmng->policy_idx_tbl && priv->sh->refcnt == 1) {
+ MLX5_L3T_FOREACH(priv->sh->mtrmng->policy_idx_tbl,
+ i, entry) {
+ policy_idx = *(uint32_t *)entry;
+ sub_policy = mlx5_ipool_get
+ (priv->sh->ipool[MLX5_IPOOL_MTR_POLICY],
+ policy_idx);
+ if (!sub_policy || !sub_policy->main_policy)
+ continue;
+ mtr_policy = sub_policy->main_policy;
+ if (mtr_policy->is_queue || mtr_policy->is_rss)
+ mlx5_flow_destroy_sub_policy_with_rxq(dev,
+ mtr_policy);
+ }
+ }
+}
+
/**
* Flush meter configuration.
*
"meter policy invalid.");
if (__mlx5_flow_meter_policy_delete(dev, i,
sub_policy->main_policy,
- error))
+ error, true))
return -rte_mtr_error_set(error,
EINVAL,
RTE_MTR_ERROR_TYPE_METER_POLICY_ID,