ethdev: add pre-defined meter policy API
[dpdk.git] / drivers / net / mlx5 / mlx5_flow_meter.c
index 714b382..af0a1c1 100644 (file)
@@ -329,7 +329,6 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev,
        cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
        cap->meter_srtcm_rfc2697_n_max = qattr->flow_meter_old ? cap->n_max : 0;
        cap->meter_rate_max = 1ULL << 40; /* 1 Tera tokens per sec. */
-       cap->policer_action_drop_supported = 1;
        cap->stats_mask = RTE_MTR_STATS_N_BYTES_DROPPED |
                          RTE_MTR_STATS_N_PKTS_DROPPED;
        return 0;
@@ -436,90 +435,6 @@ mlx5_flow_meter_profile_delete(struct rte_eth_dev *dev,
        return 0;
 }
 
-/**
- * Convert wrong color setting action to verbose error.
- *
- * @param[in] action
- *   Policy color action.
- *
- * @return
- *   Verbose meter color error type.
- */
-static inline enum rte_mtr_error_type
-action2error(enum rte_mtr_policer_action action)
-{
-       switch (action) {
-       case MTR_POLICER_ACTION_COLOR_GREEN:
-               return RTE_MTR_ERROR_TYPE_POLICER_ACTION_GREEN;
-       case MTR_POLICER_ACTION_COLOR_YELLOW:
-               return RTE_MTR_ERROR_TYPE_POLICER_ACTION_YELLOW;
-       case MTR_POLICER_ACTION_COLOR_RED:
-               return RTE_MTR_ERROR_TYPE_POLICER_ACTION_RED;
-       default:
-               break;
-       }
-       return RTE_MTR_ERROR_TYPE_UNSPECIFIED;
-}
-
-/**
- * Check meter validation.
- *
- * @param[in] priv
- *   Pointer to mlx5 private data structure.
- * @param[in] meter_id
- *   Meter id.
- * @param[in] params
- *   Pointer to rte meter parameters.
- * @param[out] error
- *   Pointer to rte meter error structure.
- *
- * @return
- *   0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,
-                        struct rte_mtr_params *params,
-                        struct rte_mtr_error *error)
-{
-       /* Meter must use global drop action. */
-       if (!priv->sh->dr_drop_action)
-               return -rte_mtr_error_set(error, ENOTSUP,
-                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
-                                         NULL,
-                                         "No drop action ready for meter.");
-       /* Meter params must not be NULL. */
-       if (params == NULL)
-               return -rte_mtr_error_set(error, EINVAL,
-                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
-                                         NULL, "Meter object params null.");
-       /* Previous meter color is not supported. */
-       if (params->use_prev_mtr_color)
-               return -rte_mtr_error_set(error, ENOTSUP,
-                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
-                                         NULL,
-                                         "Previous meter color "
-                                         "not supported.");
-       /* Validate policer settings. */
-       if (params->action[RTE_COLOR_RED] != MTR_POLICER_ACTION_DROP)
-               return -rte_mtr_error_set
-                               (error, ENOTSUP,
-                                action2error(params->action[RTE_COLOR_RED]),
-                                NULL,
-                                "Red color only supports drop action.");
-       if (params->action[RTE_COLOR_GREEN] != MTR_POLICER_ACTION_COLOR_GREEN)
-               return -rte_mtr_error_set
-                               (error, ENOTSUP,
-                                action2error(params->action[RTE_COLOR_GREEN]),
-                                NULL,
-                                "Green color only supports recolor green action.");
-       /* Validate meter id. */
-       if (mlx5_flow_meter_find(priv, meter_id, NULL))
-               return -rte_mtr_error_set(error, EEXIST,
-                                         RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
-                                         "Meter object already exists.");
-       return 0;
-}
-
 /**
  * Modify the flow meter action.
  *
@@ -629,167 +544,14 @@ static void
 mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter_info *fm,
                                uint64_t stats_mask)
 {
-       fm->green_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_GREEN) ? 1 : 0;
-       fm->green_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_GREEN) ? 1 : 0;
-       fm->red_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_RED) ? 1 : 0;
-       fm->red_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_RED) ? 1 : 0;
        fm->bytes_dropped =
                (stats_mask & RTE_MTR_STATS_N_BYTES_DROPPED) ? 1 : 0;
        fm->pkts_dropped = (stats_mask & RTE_MTR_STATS_N_PKTS_DROPPED) ? 1 : 0;
 }
 
-/**
- * Create meter rules.
- *
- * @param[in] dev
- *   Pointer to Ethernet device.
- * @param[in] meter_id
- *   Meter id.
- * @param[in] params
- *   Pointer to rte meter parameters.
- * @param[in] shared
- *   Meter shared with other flow or not.
- * @param[out] error
- *   Pointer to rte meter error structure.
- *
- * @return
- *   0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
-                      struct rte_mtr_params *params, int shared,
-                      struct rte_mtr_error *error)
-{
-       struct mlx5_priv *priv = dev->data->dev_private;
-       struct mlx5_legacy_flow_meters *fms = &priv->flow_meters;
-       struct mlx5_flow_meter_profile *fmp;
-       struct mlx5_legacy_flow_meter *legacy_fm;
-       struct mlx5_flow_meter_info *fm;
-       const struct rte_flow_attr attr = {
-                               .ingress = 1,
-                               .egress = 1,
-                               .transfer = priv->config.dv_esw_en ? 1 : 0,
-                       };
-       struct mlx5_indexed_pool_config flow_ipool_cfg = {
-               .size = 0,
-               .trunk_size = 64,
-               .need_lock = 1,
-               .type = "mlx5_flow_mtr_flow_id_pool",
-       };
-       struct mlx5_aso_mtr *aso_mtr;
-       union mlx5_l3t_data data;
-       uint32_t mtr_idx;
-       int ret;
-       uint8_t mtr_id_bits;
-       uint8_t mtr_reg_bits = priv->mtr_reg_share ?
-                               MLX5_MTR_IDLE_BITS_IN_COLOR_REG : MLX5_REG_BITS;
-
-       if (!priv->mtr_en)
-               return -rte_mtr_error_set(error, ENOTSUP,
-                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
-                                         "Meter is not supported");
-       /* Validate the parameters. */
-       ret = mlx5_flow_meter_validate(priv, meter_id, params, error);
-       if (ret)
-               return ret;
-       /* Meter profile must exist. */
-       fmp = mlx5_flow_meter_profile_find(priv, params->meter_profile_id);
-       if (fmp == NULL)
-               return -rte_mtr_error_set(error, ENOENT,
-                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
-                                         NULL, "Meter profile id not valid.");
-       /* Allocate the flow meter memory. */
-       if (priv->sh->meter_aso_en) {
-               mtr_idx = mlx5_flow_mtr_alloc(dev);
-               if (!mtr_idx)
-                       return -rte_mtr_error_set(error, ENOMEM,
-                               RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
-                               "Memory alloc failed for meter.");
-               aso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx);
-               fm = &aso_mtr->fm;
-       } else {
-               legacy_fm = mlx5_ipool_zmalloc
-                               (priv->sh->ipool[MLX5_IPOOL_MTR], &mtr_idx);
-               if (legacy_fm == NULL)
-                       return -rte_mtr_error_set(error, ENOMEM,
-                               RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
-                               "Memory alloc failed for meter.");
-               legacy_fm->idx = mtr_idx;
-               fm = &legacy_fm->fm;
-       }
-       mtr_id_bits = MLX5_REG_BITS - __builtin_clz(mtr_idx);
-       if ((mtr_id_bits + priv->max_mtr_flow_bits) > mtr_reg_bits) {
-               DRV_LOG(ERR, "Meter number exceeds max limit.");
-               goto error;
-       }
-       if (mtr_id_bits > priv->max_mtr_bits)
-               priv->max_mtr_bits = mtr_id_bits;
-       /* Fill the flow meter parameters. */
-       fm->meter_id = meter_id;
-       fm->profile = fmp;
-       memcpy(fm->action, params->action, sizeof(params->action));
-       mlx5_flow_meter_stats_enable_update(fm, params->stats_mask);
-       /* Alloc policer counters. */
-       if (fm->green_bytes || fm->green_pkts) {
-               fm->policer_stats.pass_cnt = mlx5_counter_alloc(dev);
-               if (!fm->policer_stats.pass_cnt)
-                       goto error;
-       }
-       if (fm->red_bytes || fm->red_pkts ||
-           fm->bytes_dropped || fm->pkts_dropped) {
-               fm->policer_stats.drop_cnt = mlx5_counter_alloc(dev);
-               if (!fm->policer_stats.drop_cnt)
-                       goto error;
-       }
-       fm->mfts = mlx5_flow_create_mtr_tbls(dev);
-       if (!fm->mfts)
-               goto error;
-       ret = mlx5_flow_prepare_policer_rules(dev, fm, &attr);
-       if (ret)
-               goto error;
-       /* Add to the flow meter list. */
-       if (!priv->sh->meter_aso_en)
-               TAILQ_INSERT_TAIL(fms, legacy_fm, next);
-       fm->active_state = 1; /* Config meter starts as active. */
-       fm->is_enable = 1;
-       fm->shared = !!shared;
-       __atomic_add_fetch(&fm->profile->ref_cnt, 1, __ATOMIC_RELAXED);
-       fm->flow_ipool = mlx5_ipool_create(&flow_ipool_cfg);
-       if (!fm->flow_ipool)
-               goto error;
-       rte_spinlock_init(&fm->sl);
-       /* If ASO meter supported, allocate ASO flow meter. */
-       if (priv->sh->meter_aso_en) {
-               aso_mtr = container_of(fm, struct mlx5_aso_mtr, fm);
-               ret = mlx5_aso_meter_update_by_wqe(priv->sh, aso_mtr);
-               if (ret)
-                       goto error;
-               data.dword = mtr_idx;
-               if (mlx5_l3t_set_entry(priv->mtr_idx_tbl, meter_id, &data))
-                       goto error;
-       }
-       return 0;
-error:
-       mlx5_flow_destroy_policer_rules(dev, fm, &attr);
-       mlx5_flow_destroy_mtr_tbls(dev, fm->mfts);
-       /* Free policer counters. */
-       if (fm->policer_stats.pass_cnt)
-               mlx5_counter_free(dev, fm->policer_stats.pass_cnt);
-       if (fm->policer_stats.drop_cnt)
-               mlx5_counter_free(dev, fm->policer_stats.drop_cnt);
-       if (priv->sh->meter_aso_en)
-               mlx5_flow_mtr_free(dev, mtr_idx);
-       else
-               mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], mtr_idx);
-       return -rte_mtr_error_set(error, -ret,
-                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
-                                 NULL, "Failed to create devx meter.");
-}
-
 static int
 mlx5_flow_meter_params_flush(struct rte_eth_dev *dev,
                        struct mlx5_flow_meter_info *fm,
-                       const struct rte_flow_attr *attr,
                        uint32_t mtr_idx)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
@@ -810,15 +572,12 @@ mlx5_flow_meter_params_flush(struct rte_eth_dev *dev,
                legacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm);
                TAILQ_REMOVE(fms, legacy_fm, next);
        }
-       /* Free policer counters. */
-       if (fm->policer_stats.pass_cnt)
-               mlx5_counter_free(dev, fm->policer_stats.pass_cnt);
-       if (fm->policer_stats.drop_cnt)
-               mlx5_counter_free(dev, fm->policer_stats.drop_cnt);
+       /* Free drop counters. */
+       if (fm->drop_cnt)
+               mlx5_counter_free(dev, fm->drop_cnt);
        /* Free meter flow table. */
        if (fm->flow_ipool)
                mlx5_ipool_destroy(fm->flow_ipool);
-       mlx5_flow_destroy_policer_rules(dev, fm, attr);
        mlx5_flow_destroy_mtr_tbls(dev, fm->mfts);
        if (priv->sh->meter_aso_en)
                mlx5_flow_mtr_free(dev, mtr_idx);
@@ -847,11 +606,6 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_flow_meter_info *fm;
-       const struct rte_flow_attr attr = {
-                               .ingress = 1,
-                               .egress = 1,
-                               .transfer = priv->config.dv_esw_en ? 1 : 0,
-                       };
        uint32_t mtr_idx = 0;
 
        if (!priv->mtr_en)
@@ -876,7 +630,7 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,
                                "Fail to delete ASO Meter in index table.");
        }
        /* Destroy the meter profile. */
-       if (mlx5_flow_meter_params_flush(dev, fm, &attr, mtr_idx))
+       if (mlx5_flow_meter_params_flush(dev, fm, mtr_idx))
                return -rte_mtr_error_set(error, EINVAL,
                                        RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
                                        NULL, "MTR object meter profile invalid.");
@@ -1102,13 +856,6 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_flow_meter_info *fm;
-       const struct rte_flow_attr attr = {
-                               .ingress = 1,
-                               .egress = 1,
-                               .transfer = priv->config.dv_esw_en ? 1 : 0,
-                       };
-       bool need_updated = false;
-       struct mlx5_flow_policer_stats old_policer_stats;
 
        if (!priv->mtr_en)
                return -rte_mtr_error_set(error, ENOTSUP,
@@ -1120,69 +867,6 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,
                return -rte_mtr_error_set(error, ENOENT,
                                          RTE_MTR_ERROR_TYPE_MTR_ID,
                                          NULL, "Meter object id not valid.");
-       old_policer_stats.pass_cnt = 0;
-       old_policer_stats.drop_cnt = 0;
-       if (!!((RTE_MTR_STATS_N_PKTS_GREEN |
-                               RTE_MTR_STATS_N_BYTES_GREEN) & stats_mask) !=
-               !!fm->policer_stats.pass_cnt) {
-               need_updated = true;
-               if (fm->policer_stats.pass_cnt) {
-                       old_policer_stats.pass_cnt = fm->policer_stats.pass_cnt;
-                       fm->policer_stats.pass_cnt = 0;
-               } else {
-                       fm->policer_stats.pass_cnt =
-                               mlx5_counter_alloc(dev);
-                       if (!fm->policer_stats.pass_cnt)
-                               return -rte_mtr_error_set(error, ENOMEM,
-                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
-                                         "Counter alloc failed for meter.");
-               }
-       }
-       if (!!((RTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_BYTES_RED |
-               RTE_MTR_STATS_N_PKTS_DROPPED | RTE_MTR_STATS_N_BYTES_DROPPED) &
-               stats_mask) !=
-               !!fm->policer_stats.drop_cnt) {
-               need_updated = true;
-               if (fm->policer_stats.drop_cnt) {
-                       old_policer_stats.drop_cnt = fm->policer_stats.drop_cnt;
-                       fm->policer_stats.drop_cnt = 0;
-               } else {
-                       fm->policer_stats.drop_cnt =
-                               mlx5_counter_alloc(dev);
-                       if (!fm->policer_stats.drop_cnt)
-                               return -rte_mtr_error_set(error, ENOMEM,
-                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
-                                         "Counter alloc failed for meter.");
-               }
-       }
-       if (need_updated) {
-               if (mlx5_flow_prepare_policer_rules(dev, fm, &attr)) {
-                       if (fm->policer_stats.pass_cnt &&
-                               fm->policer_stats.pass_cnt !=
-                               old_policer_stats.pass_cnt)
-                               mlx5_counter_free(dev,
-                                       fm->policer_stats.pass_cnt);
-                       fm->policer_stats.pass_cnt =
-                                       old_policer_stats.pass_cnt;
-                       if (fm->policer_stats.drop_cnt &&
-                               fm->policer_stats.drop_cnt !=
-                               old_policer_stats.drop_cnt)
-                               mlx5_counter_free(dev,
-                                       fm->policer_stats.drop_cnt);
-                       fm->policer_stats.pass_cnt =
-                                       old_policer_stats.pass_cnt;
-                       return -rte_mtr_error_set(error, ENOTSUP,
-                               RTE_MTR_ERROR_TYPE_UNSPECIFIED,
-                               NULL, "Failed to create meter policer rules.");
-               }
-               /* Free old policer counters. */
-               if (old_policer_stats.pass_cnt)
-                       mlx5_counter_free(dev,
-                               old_policer_stats.pass_cnt);
-               if (old_policer_stats.drop_cnt)
-                       mlx5_counter_free(dev,
-                               old_policer_stats.drop_cnt);
-       }
        mlx5_flow_meter_stats_enable_update(fm, stats_mask);
        return 0;
 }
@@ -1216,7 +900,6 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_flow_meter_info *fm;
-       struct mlx5_flow_policer_stats *ps;
        uint64_t pkts;
        uint64_t bytes;
        int ret = 0;
@@ -1231,35 +914,14 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,
                return -rte_mtr_error_set(error, ENOENT,
                                          RTE_MTR_ERROR_TYPE_MTR_ID,
                                          NULL, "Meter object id not valid.");
-       ps = &fm->policer_stats;
        *stats_mask = 0;
-       if (fm->green_bytes)
-               *stats_mask |= RTE_MTR_STATS_N_BYTES_GREEN;
-       if (fm->green_pkts)
-               *stats_mask |= RTE_MTR_STATS_N_PKTS_GREEN;
-       if (fm->red_bytes)
-               *stats_mask |= RTE_MTR_STATS_N_BYTES_RED;
-       if (fm->red_pkts)
-               *stats_mask |= RTE_MTR_STATS_N_PKTS_RED;
        if (fm->bytes_dropped)
                *stats_mask |= RTE_MTR_STATS_N_BYTES_DROPPED;
        if (fm->pkts_dropped)
                *stats_mask |= RTE_MTR_STATS_N_PKTS_DROPPED;
        memset(stats, 0, sizeof(*stats));
-       if (ps->pass_cnt) {
-               ret = mlx5_counter_query(dev, ps->pass_cnt, clear, &pkts,
-                                                &bytes);
-               if (ret)
-                       goto error;
-               /* If need to read the packets, set it. */
-               if (fm->green_pkts)
-                       stats->n_pkts[RTE_COLOR_GREEN] = pkts;
-               /* If need to read the bytes, set it. */
-               if (fm->green_bytes)
-                       stats->n_bytes[RTE_COLOR_GREEN] = bytes;
-       }
-       if (ps->drop_cnt) {
-               ret = mlx5_counter_query(dev, ps->drop_cnt, clear, &pkts,
+       if (fm->drop_cnt) {
+               ret = mlx5_counter_query(dev, fm->drop_cnt, clear, &pkts,
                                                 &bytes);
                if (ret)
                        goto error;
@@ -1273,20 +935,18 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,
        return 0;
 error:
        return -rte_mtr_error_set(error, ret, RTE_MTR_ERROR_TYPE_STATS, NULL,
-                                "Failed to read policer counters.");
+                                "Failed to read meter drop counters.");
 }
 
 static const struct rte_mtr_ops mlx5_flow_mtr_ops = {
        .capabilities_get = mlx5_flow_mtr_cap_get,
        .meter_profile_add = mlx5_flow_meter_profile_add,
        .meter_profile_delete = mlx5_flow_meter_profile_delete,
-       .create = mlx5_flow_meter_create,
        .destroy = mlx5_flow_meter_destroy,
        .meter_enable = mlx5_flow_meter_enable,
        .meter_disable = mlx5_flow_meter_disable,
        .meter_profile_update = mlx5_flow_meter_profile_update,
        .meter_dscp_table_update = NULL,
-       .policer_actions_update = NULL,
        .stats_update = mlx5_flow_meter_stats_update,
        .stats_read = mlx5_flow_meter_stats_read,
 };
@@ -1344,12 +1004,11 @@ mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id,
                aso_mtr = mlx5_aso_meter_by_idx(priv, data.dword);
                /* Remove reference taken by the mlx5_l3t_get_entry. */
                mlx5_l3t_clear_entry(priv->mtr_idx_tbl, meter_id);
-               MLX5_ASSERT(meter_id == aso_mtr->fm.meter_id);
                rte_spinlock_unlock(&mtrmng->mtrsl);
                return &aso_mtr->fm;
        }
        TAILQ_FOREACH(legacy_fm, fms, next)
-               if (meter_id == legacy_fm->fm.meter_id) {
+               if (meter_id == legacy_fm->meter_id) {
                        if (mtr_idx)
                                *mtr_idx = legacy_fm->idx;
                        return &legacy_fm->fm;
@@ -1517,11 +1176,6 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)
        struct mlx5_legacy_flow_meter *legacy_fm;
        struct mlx5_flow_meter_info *fm;
        struct mlx5_aso_mtr_pool *mtr_pool;
-       const struct rte_flow_attr attr = {
-                               .ingress = 1,
-                               .egress = 1,
-                               .transfer = priv->config.dv_esw_en ? 1 : 0,
-                       };
        void *tmp;
        uint32_t i, offset, mtr_idx;
 
@@ -1533,9 +1187,8 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)
                                offset++) {
                                fm = &mtr_pool->mtrs[offset].fm;
                                mtr_idx = MLX5_MAKE_MTR_IDX(i, offset);
-                               if (fm->meter_id != UINT32_MAX &&
-                                       mlx5_flow_meter_params_flush(dev,
-                                               fm, &attr, mtr_idx))
+                               if (mlx5_flow_meter_params_flush(dev,
+                                               fm, mtr_idx))
                                        return -rte_mtr_error_set
                                        (error, EINVAL,
                                        RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
@@ -1545,7 +1198,7 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)
        } else {
                TAILQ_FOREACH_SAFE(legacy_fm, fms, next, tmp) {
                        fm = &legacy_fm->fm;
-                       if (mlx5_flow_meter_params_flush(dev, fm, &attr, 0))
+                       if (mlx5_flow_meter_params_flush(dev, fm, 0))
                                return -rte_mtr_error_set(error, EINVAL,
                                        RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
                                        NULL, "MTR object meter profile invalid.");