LCOV - code coverage report
Current view: top level - drivers/net/nfp - nfp_mtr.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 332 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 28 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 231 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2022 Corigine, Inc.
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "nfp_mtr.h"
       7                 :            : 
       8                 :            : #include <rte_alarm.h>
       9                 :            : #include <rte_malloc.h>
      10                 :            : #include <rte_mtr_driver.h>
      11                 :            : 
      12                 :            : #include "flower/nfp_flower_representor.h"
      13                 :            : #include "nfp_logs.h"
      14                 :            : 
      15                 :            : #define NFP_MAX_POLICY_CNT             NFP_MAX_MTR_CNT
      16                 :            : #define NFP_MAX_PROFILE_CNT            NFP_MAX_MTR_CNT
      17                 :            : 
      18                 :            : #define NFP_FL_QOS_PPS          RTE_BIT32(15)
      19                 :            : #define NFP_FL_QOS_METER        RTE_BIT32(10)
      20                 :            : #define NFP_FL_QOS_RFC2697      RTE_BIT32(0)
      21                 :            : 
      22                 :            : /* Alarm timeout value in microseconds */
      23                 :            : #define NFP_METER_STATS_INTERVAL 1000000  /* 1 second */
      24                 :            : 
      25                 :            : /**
      26                 :            :  * Callback to get MTR capabilities.
      27                 :            :  *
      28                 :            :  * @param[in] dev
      29                 :            :  *   Pointer to the device (unused).
      30                 :            :  * @param[out] cap
      31                 :            :  *   Pointer to the meter object capabilities.
      32                 :            :  * @param[out] error
      33                 :            :  *   Pointer to the error (unused).
      34                 :            :  *
      35                 :            :  * @returns
      36                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
      37                 :            :  */
      38                 :            : static int
      39                 :          0 : nfp_mtr_cap_get(struct rte_eth_dev *dev __rte_unused,
      40                 :            :                 struct rte_mtr_capabilities *cap,
      41                 :            :                 struct rte_mtr_error *error)
      42                 :            : {
      43         [ #  # ]:          0 :         if (cap == NULL) {
      44                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
      45                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
      46                 :            :                                 NULL, "NULL pointer for capabilitie argument.");
      47                 :            :         }
      48                 :            : 
      49                 :            :         memset(cap, 0, sizeof(struct rte_mtr_capabilities));
      50                 :            : 
      51                 :          0 :         cap->n_max                               = NFP_MAX_MTR_CNT;
      52                 :          0 :         cap->n_shared_max                        = NFP_MAX_MTR_CNT;
      53                 :          0 :         cap->identical                           = 1;
      54                 :          0 :         cap->shared_identical                    = 1;
      55                 :          0 :         cap->chaining_n_mtrs_per_flow_max        = 1;
      56                 :          0 :         cap->meter_srtcm_rfc2697_n_max           = NFP_MAX_MTR_CNT;
      57                 :          0 :         cap->meter_trtcm_rfc2698_n_max           = NFP_MAX_MTR_CNT;
      58                 :          0 :         cap->meter_rate_max                      = UINT64_MAX;
      59                 :          0 :         cap->meter_policy_n_max                  = NFP_MAX_POLICY_CNT;
      60                 :          0 :         cap->srtcm_rfc2697_byte_mode_supported   = 1;
      61                 :          0 :         cap->srtcm_rfc2697_packet_mode_supported = 1;
      62                 :          0 :         cap->trtcm_rfc2698_byte_mode_supported   = 1;
      63                 :          0 :         cap->trtcm_rfc2698_packet_mode_supported = 1;
      64                 :          0 :         cap->stats_mask = RTE_MTR_STATS_N_PKTS_GREEN |
      65                 :            :                         RTE_MTR_STATS_N_PKTS_DROPPED |
      66                 :            :                         RTE_MTR_STATS_N_BYTES_GREEN |
      67                 :            :                         RTE_MTR_STATS_N_BYTES_DROPPED;
      68                 :            : 
      69                 :          0 :         return 0;
      70                 :            : }
      71                 :            : 
      72                 :            : static int
      73                 :          0 : nfp_mtr_profile_validate(uint32_t mtr_profile_id,
      74                 :            :                 struct rte_mtr_meter_profile *profile,
      75                 :            :                 struct rte_mtr_error *error)
      76                 :            : {
      77                 :            :         /* Profile must not be NULL. */
      78         [ #  # ]:          0 :         if (profile == NULL) {
      79                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
      80                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
      81                 :            :                                 NULL, "Meter profile is null.");
      82                 :            :         }
      83                 :            : 
      84                 :            :         /* Meter profile ID must be valid. */
      85         [ #  # ]:          0 :         if (mtr_profile_id >= NFP_MAX_PROFILE_CNT) {
      86                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
      87                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
      88                 :            :                                 NULL, "Meter profile id not valid.");
      89                 :            :         }
      90                 :            : 
      91      [ #  #  # ]:          0 :         switch (profile->alg) {
      92                 :            :         case RTE_MTR_SRTCM_RFC2697:
      93                 :            :         case RTE_MTR_TRTCM_RFC2698:
      94                 :            :                 return 0;
      95                 :            :         case RTE_MTR_TRTCM_RFC4115:
      96                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
      97                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
      98                 :            :                                 NULL, "Unsupported metering algorithm.");
      99                 :            :         default:
     100                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     101                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
     102                 :            :                                 NULL, "Unknown metering algorithm.");
     103                 :            :         }
     104                 :            : }
     105                 :            : 
     106                 :            : static void
     107                 :          0 : nfp_mtr_profile_config_2698(uint32_t mtr_profile_id,
     108                 :            :                 struct rte_mtr_meter_profile *profile,
     109                 :            :                 struct nfp_profile_conf *conf)
     110                 :            : {
     111         [ #  # ]:          0 :         if (profile->packet_mode != 0)
     112                 :          0 :                 conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_PPS);
     113                 :            : 
     114                 :          0 :         conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_METER);
     115         [ #  # ]:          0 :         conf->head.profile_id = rte_cpu_to_be_32(mtr_profile_id);
     116                 :            : 
     117         [ #  # ]:          0 :         conf->bkt_tkn_c = rte_cpu_to_be_32(profile->trtcm_rfc2698.cbs);
     118         [ #  # ]:          0 :         conf->bkt_tkn_p = rte_cpu_to_be_32(profile->trtcm_rfc2698.pbs);
     119         [ #  # ]:          0 :         conf->cbs = rte_cpu_to_be_32(profile->trtcm_rfc2698.cbs);
     120         [ #  # ]:          0 :         conf->pbs = rte_cpu_to_be_32(profile->trtcm_rfc2698.pbs);
     121         [ #  # ]:          0 :         conf->cir = rte_cpu_to_be_32(profile->trtcm_rfc2698.cir);
     122         [ #  # ]:          0 :         conf->pir = rte_cpu_to_be_32(profile->trtcm_rfc2698.pir);
     123                 :          0 : }
     124                 :            : 
     125                 :            : static void
     126                 :          0 : nfp_mtr_profile_config_2697(uint32_t mtr_profile_id,
     127                 :            :                 struct rte_mtr_meter_profile *profile,
     128                 :            :                 struct nfp_profile_conf *conf)
     129                 :            : {
     130         [ #  # ]:          0 :         if (profile->packet_mode != 0)
     131                 :          0 :                 conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_PPS);
     132                 :            : 
     133                 :          0 :         conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_RFC2697);
     134                 :          0 :         conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_METER);
     135         [ #  # ]:          0 :         conf->head.profile_id = rte_cpu_to_be_32(mtr_profile_id);
     136                 :            : 
     137         [ #  # ]:          0 :         conf->bkt_tkn_c = rte_cpu_to_be_32(profile->srtcm_rfc2697.cbs);
     138         [ #  # ]:          0 :         conf->bkt_tkn_p = rte_cpu_to_be_32(profile->srtcm_rfc2697.ebs);
     139         [ #  # ]:          0 :         conf->cbs = rte_cpu_to_be_32(profile->srtcm_rfc2697.cbs);
     140         [ #  # ]:          0 :         conf->pbs = rte_cpu_to_be_32(profile->srtcm_rfc2697.ebs);
     141         [ #  # ]:          0 :         conf->cir = rte_cpu_to_be_32(profile->srtcm_rfc2697.cir);
     142         [ #  # ]:          0 :         conf->pir = rte_cpu_to_be_32(profile->srtcm_rfc2697.cir);
     143                 :          0 : }
     144                 :            : 
     145                 :            : static int
     146                 :          0 : nfp_mtr_profile_conf_mod(uint32_t mtr_profile_id,
     147                 :            :                 struct rte_mtr_meter_profile *profile,
     148                 :            :                 struct nfp_profile_conf *conf)
     149                 :            : {
     150   [ #  #  #  # ]:          0 :         switch (profile->alg) {
     151                 :          0 :         case RTE_MTR_SRTCM_RFC2697:
     152                 :          0 :                 nfp_mtr_profile_config_2697(mtr_profile_id, profile, conf);
     153                 :          0 :                 return 0;
     154                 :          0 :         case RTE_MTR_TRTCM_RFC2698:
     155                 :          0 :                 nfp_mtr_profile_config_2698(mtr_profile_id, profile, conf);
     156                 :          0 :                 return 0;
     157                 :            :         case RTE_MTR_TRTCM_RFC4115:
     158                 :            :                 return -ENOTSUP;
     159                 :          0 :         default:
     160                 :          0 :                 return -EINVAL;
     161                 :            :         }
     162                 :            : }
     163                 :            : 
     164                 :            : static int
     165                 :            : nfp_mtr_profile_conf_insert(uint32_t mtr_profile_id,
     166                 :            :                 struct rte_mtr_meter_profile *profile,
     167                 :            :                 struct nfp_mtr_profile *mtr_profile)
     168                 :            : {
     169                 :          0 :         mtr_profile->profile_id = mtr_profile_id;
     170                 :          0 :         mtr_profile->in_use = false;
     171                 :            : 
     172                 :          0 :         return nfp_mtr_profile_conf_mod(mtr_profile_id, profile,
     173                 :            :                         &mtr_profile->conf);
     174                 :            : }
     175                 :            : 
     176                 :            : static struct nfp_mtr_profile *
     177                 :            : nfp_mtr_profile_search(struct nfp_mtr_priv *priv, uint32_t mtr_profile_id)
     178                 :            : {
     179                 :            :         struct nfp_mtr_profile *mtr_profile;
     180                 :            : 
     181   [ #  #  #  #  :          0 :         LIST_FOREACH(mtr_profile, &priv->profiles, next)
             #  #  #  # ]
     182   [ #  #  #  #  :          0 :                 if (mtr_profile->profile_id == mtr_profile_id)
             #  #  #  # ]
     183                 :            :                         break;
     184                 :            : 
     185                 :            :         return mtr_profile;
     186                 :            : }
     187                 :            : 
     188                 :            : static int
     189                 :          0 : nfp_mtr_profile_insert(struct nfp_app_fw_flower *app_fw_flower,
     190                 :            :                 struct rte_mtr_meter_profile *profile,
     191                 :            :                 uint32_t mtr_profile_id,
     192                 :            :                 struct rte_mtr_error *error)
     193                 :            : {
     194                 :            :         int ret;
     195                 :            :         struct nfp_mtr_priv *priv;
     196                 :            :         struct nfp_mtr_profile *mtr_profile;
     197                 :            : 
     198                 :          0 :         priv = app_fw_flower->mtr_priv;
     199                 :            : 
     200                 :            :         /* Meter profile memory allocation. */
     201                 :          0 :         mtr_profile = rte_zmalloc(NULL, sizeof(struct nfp_mtr_profile), 0);
     202         [ #  # ]:          0 :         if (mtr_profile == NULL) {
     203                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     204                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     205                 :            :                                 NULL, "Meter profile alloc failed.");
     206                 :            :         }
     207                 :            : 
     208                 :            :         ret = nfp_mtr_profile_conf_insert(mtr_profile_id,
     209                 :            :                         profile, mtr_profile);
     210         [ #  # ]:          0 :         if (ret != 0) {
     211                 :            :                 rte_mtr_error_set(error, EINVAL,
     212                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     213                 :            :                                 NULL, "Insert profile config failed.");
     214                 :          0 :                 goto free_profile;
     215                 :            :         }
     216                 :            : 
     217                 :          0 :         ret = nfp_flower_cmsg_qos_add(app_fw_flower, &mtr_profile->conf);
     218         [ #  # ]:          0 :         if (ret != 0) {
     219                 :            :                 rte_mtr_error_set(error, EINVAL,
     220                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     221                 :            :                                 NULL, "Add meter to firmware failed.");
     222                 :          0 :                 goto free_profile;
     223                 :            :         }
     224                 :            : 
     225                 :            :         /* Insert profile into profile list */
     226         [ #  # ]:          0 :         LIST_INSERT_HEAD(&priv->profiles, mtr_profile, next);
     227                 :            : 
     228                 :          0 :         return 0;
     229                 :            : 
     230                 :          0 : free_profile:
     231                 :          0 :         rte_free(mtr_profile);
     232                 :            : 
     233                 :          0 :         return ret;
     234                 :            : }
     235                 :            : 
     236                 :            : static int
     237                 :          0 : nfp_mtr_profile_mod(struct nfp_app_fw_flower *app_fw_flower,
     238                 :            :                 struct rte_mtr_meter_profile *profile,
     239                 :            :                 struct nfp_mtr_profile *mtr_profile,
     240                 :            :                 struct rte_mtr_error *error)
     241                 :            : {
     242                 :            :         int ret;
     243                 :            :         struct nfp_profile_conf old_conf;
     244                 :            : 
     245                 :            :         /* Get the old profile config */
     246         [ #  # ]:          0 :         rte_memcpy(&old_conf, &mtr_profile->conf, sizeof(old_conf));
     247                 :            : 
     248                 :            :         memset(&mtr_profile->conf, 0, sizeof(struct nfp_profile_conf));
     249                 :            : 
     250                 :          0 :         ret = nfp_mtr_profile_conf_mod(mtr_profile->profile_id,
     251                 :            :                         profile, &mtr_profile->conf);
     252         [ #  # ]:          0 :         if (ret != 0) {
     253                 :            :                 rte_mtr_error_set(error, EINVAL,
     254                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     255                 :            :                                 NULL, "Mod profile config failed.");
     256                 :          0 :                 goto rollback;
     257                 :            :         }
     258                 :            : 
     259                 :          0 :         ret = nfp_flower_cmsg_qos_add(app_fw_flower, &mtr_profile->conf);
     260         [ #  # ]:          0 :         if (ret != 0) {
     261                 :            :                 rte_mtr_error_set(error, EINVAL,
     262                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     263                 :            :                                 NULL, "Mod meter to firmware failed.");
     264                 :          0 :                 goto rollback;
     265                 :            :         }
     266                 :            : 
     267                 :            :         return 0;
     268                 :            : 
     269         [ #  # ]:          0 : rollback:
     270                 :            :         rte_memcpy(&mtr_profile->conf, &old_conf, sizeof(old_conf));
     271                 :            : 
     272                 :            :         return ret;
     273                 :            : }
     274                 :            : 
     275                 :            : /**
     276                 :            :  * Callback to add MTR profile.
     277                 :            :  *
     278                 :            :  * @param[in] dev
     279                 :            :  *   Pointer to Ethernet device.
     280                 :            :  * @param[in] mtr_profile_id
     281                 :            :  *   Meter profile id.
     282                 :            :  * @param[in] profile
     283                 :            :  *   Pointer to meter profile detail.
     284                 :            :  * @param[out] error
     285                 :            :  *   Pointer to the error structure.
     286                 :            :  *
     287                 :            :  * @return
     288                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     289                 :            :  */
     290                 :            : static int
     291                 :          0 : nfp_mtr_profile_add(struct rte_eth_dev *dev,
     292                 :            :                 uint32_t mtr_profile_id,
     293                 :            :                 struct rte_mtr_meter_profile *profile,
     294                 :            :                 struct rte_mtr_error *error)
     295                 :            : {
     296                 :            :         int ret;
     297                 :            :         struct nfp_mtr_priv *priv;
     298                 :            :         struct nfp_mtr_profile *mtr_profile;
     299                 :            :         struct nfp_app_fw_flower *app_fw_flower;
     300                 :            :         struct nfp_flower_representor *representor;
     301                 :            : 
     302                 :          0 :         representor = dev->data->dev_private;
     303                 :          0 :         app_fw_flower = representor->app_fw_flower;
     304                 :          0 :         priv = app_fw_flower->mtr_priv;
     305                 :            : 
     306                 :            :         /* Check input params */
     307                 :          0 :         ret = nfp_mtr_profile_validate(mtr_profile_id, profile, error);
     308         [ #  # ]:          0 :         if (ret != 0)
     309                 :            :                 return ret;
     310                 :            : 
     311                 :            :         /* Check if mtr profile id exist */
     312                 :            :         mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
     313         [ #  # ]:          0 :         if (mtr_profile == NULL) {
     314                 :          0 :                 ret = nfp_mtr_profile_insert(app_fw_flower,
     315                 :            :                                 profile, mtr_profile_id, error);
     316                 :            :         } else {
     317                 :          0 :                 ret = nfp_mtr_profile_mod(app_fw_flower,
     318                 :            :                                 profile, mtr_profile, error);
     319                 :            :         }
     320                 :            : 
     321                 :            :         return ret;
     322                 :            : }
     323                 :            : 
     324                 :            : /**
     325                 :            :  * Callback to delete MTR profile.
     326                 :            :  *
     327                 :            :  * @param[in] dev
     328                 :            :  *   Pointer to Ethernet device.
     329                 :            :  * @param[in] mtr_profile_id
     330                 :            :  *   Meter profile id.
     331                 :            :  * @param[out] error
     332                 :            :  *   Pointer to the error structure.
     333                 :            :  *
     334                 :            :  * @return
     335                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     336                 :            :  */
     337                 :            : static int
     338                 :          0 : nfp_mtr_profile_delete(struct rte_eth_dev *dev,
     339                 :            :                 uint32_t mtr_profile_id,
     340                 :            :                 struct rte_mtr_error *error)
     341                 :            : {
     342                 :            :         int ret;
     343                 :            :         struct nfp_mtr_priv *priv;
     344                 :            :         struct nfp_mtr_profile *mtr_profile;
     345                 :            :         struct nfp_app_fw_flower *app_fw_flower;
     346                 :            :         struct nfp_flower_representor *representor;
     347                 :            : 
     348                 :          0 :         representor = dev->data->dev_private;
     349                 :          0 :         app_fw_flower = representor->app_fw_flower;
     350                 :          0 :         priv = app_fw_flower->mtr_priv;
     351                 :            : 
     352                 :            :         /* Check if mtr profile id exist */
     353                 :            :         mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
     354         [ #  # ]:          0 :         if (mtr_profile == NULL) {
     355                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     356                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     357                 :            :                                 NULL, "Request meter profile not exist.");
     358                 :            :         }
     359                 :            : 
     360         [ #  # ]:          0 :         if (mtr_profile->in_use) {
     361                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     362                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
     363                 :            :                                 NULL, "Request meter profile is been used.");
     364                 :            :         }
     365                 :            : 
     366                 :          0 :         ret = nfp_flower_cmsg_qos_delete(app_fw_flower, &mtr_profile->conf);
     367         [ #  # ]:          0 :         if (ret != 0) {
     368                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     369                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     370                 :            :                                 NULL, "Delete meter from firmware failed.");
     371                 :            :         }
     372                 :            : 
     373                 :            :         /* Remove profile from profile list */
     374         [ #  # ]:          0 :         LIST_REMOVE(mtr_profile, next);
     375                 :          0 :         rte_free(mtr_profile);
     376                 :            : 
     377                 :          0 :         return 0;
     378                 :            : }
     379                 :            : 
     380                 :            : static struct nfp_mtr_policy *
     381                 :            : nfp_mtr_policy_search(struct nfp_mtr_priv *priv, uint32_t mtr_policy_id)
     382                 :            : {
     383                 :            :         struct nfp_mtr_policy *mtr_policy;
     384                 :            : 
     385   [ #  #  #  #  :          0 :         LIST_FOREACH(mtr_policy, &priv->policies, next)
                   #  # ]
     386   [ #  #  #  #  :          0 :                 if (mtr_policy->policy_id == mtr_policy_id)
                   #  # ]
     387                 :            :                         break;
     388                 :            : 
     389                 :            :         return mtr_policy;
     390                 :            : }
     391                 :            : 
     392                 :            : static int
     393                 :          0 : nfp_mtr_policy_validate(uint32_t mtr_policy_id,
     394                 :            :                 struct rte_mtr_meter_policy_params *policy,
     395                 :            :                 struct rte_mtr_error *error)
     396                 :            : {
     397                 :            :         const struct rte_flow_action *action;
     398                 :            : 
     399                 :            :         /* Policy must not be NULL */
     400         [ #  # ]:          0 :         if (policy == NULL) {
     401                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     402                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY,
     403                 :            :                                 NULL, "Meter policy is null.");
     404                 :            :         }
     405                 :            : 
     406                 :            :         /* Meter policy ID must be valid. */
     407         [ #  # ]:          0 :         if (mtr_policy_id >= NFP_MAX_POLICY_CNT) {
     408                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     409                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     410                 :            :                                 NULL, "Meter policy id not valid.");
     411                 :            :         }
     412                 :            : 
     413                 :            :         /* Check green action
     414                 :            :          * Actions equal NULL means end action
     415                 :            :          */
     416                 :          0 :         action = policy->actions[RTE_COLOR_GREEN];
     417   [ #  #  #  # ]:          0 :         if (action != NULL && action->type != RTE_FLOW_ACTION_TYPE_VOID) {
     418                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     419                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY,
     420                 :            :                                 NULL, "Green action must be void or end.");
     421                 :            :         }
     422                 :            : 
     423                 :            :         /* Check yellow action
     424                 :            :          * Actions equal NULL means end action
     425                 :            :          */
     426                 :          0 :         action = policy->actions[RTE_COLOR_YELLOW];
     427   [ #  #  #  # ]:          0 :         if (action != NULL && action->type != RTE_FLOW_ACTION_TYPE_VOID) {
     428                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     429                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY,
     430                 :            :                                 NULL, "Yellow action must be void or end.");
     431                 :            :         }
     432                 :            : 
     433                 :            :         /* Check red action */
     434                 :          0 :         action = policy->actions[RTE_COLOR_RED];
     435   [ #  #  #  # ]:          0 :         if (action == NULL || action->type != RTE_FLOW_ACTION_TYPE_DROP) {
     436                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     437                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY,
     438                 :            :                                 NULL, "Red action must be drop.");
     439                 :            :         }
     440                 :            : 
     441                 :            :         return 0;
     442                 :            : }
     443                 :            : 
     444                 :            : /**
     445                 :            :  * Callback to add MTR policy.
     446                 :            :  *
     447                 :            :  * @param[in] dev
     448                 :            :  *   Pointer to Ethernet device.
     449                 :            :  * @param[in] mtr_policy_id
     450                 :            :  *   Meter policy id.
     451                 :            :  * @param[in] policy
     452                 :            :  *   Pointer to meter policy detail.
     453                 :            :  * @param[out] error
     454                 :            :  *   Pointer to the error structure.
     455                 :            :  *
     456                 :            :  * @return
     457                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     458                 :            :  */
     459                 :            : static int
     460                 :          0 : nfp_mtr_policy_add(struct rte_eth_dev *dev,
     461                 :            :                 uint32_t mtr_policy_id,
     462                 :            :                 struct rte_mtr_meter_policy_params *policy,
     463                 :            :                 struct rte_mtr_error *error)
     464                 :            : {
     465                 :            :         int ret;
     466                 :            :         struct nfp_mtr_priv *priv;
     467                 :            :         struct nfp_mtr_policy *mtr_policy;
     468                 :            :         struct nfp_flower_representor *representor;
     469                 :            : 
     470                 :          0 :         representor = dev->data->dev_private;
     471                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     472                 :            : 
     473                 :            :         /* Check if mtr policy id exist */
     474                 :            :         mtr_policy = nfp_mtr_policy_search(priv, mtr_policy_id);
     475         [ #  # ]:          0 :         if (mtr_policy != NULL) {
     476                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     477                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     478                 :            :                                 NULL, "Meter policy already exist.");
     479                 :            :         }
     480                 :            : 
     481                 :            :         /* Check input params */
     482                 :          0 :         ret = nfp_mtr_policy_validate(mtr_policy_id, policy, error);
     483         [ #  # ]:          0 :         if (ret != 0)
     484                 :            :                 return ret;
     485                 :            : 
     486                 :            :         /* Meter policy memory alloc */
     487                 :          0 :         mtr_policy = rte_zmalloc(NULL, sizeof(struct nfp_mtr_policy), 0);
     488         [ #  # ]:          0 :         if (mtr_policy == NULL) {
     489                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     490                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     491                 :            :                                 NULL, "Meter policy alloc failed.");
     492                 :            :         }
     493                 :            : 
     494                 :          0 :         mtr_policy->policy_id = mtr_policy_id;
     495         [ #  # ]:          0 :         rte_memcpy(&mtr_policy->policy, policy,
     496                 :            :                         sizeof(struct rte_mtr_meter_policy_params));
     497                 :            : 
     498                 :            :         /* Insert policy into policy list */
     499         [ #  # ]:          0 :         LIST_INSERT_HEAD(&priv->policies, mtr_policy, next);
     500                 :            : 
     501                 :          0 :         return 0;
     502                 :            : }
     503                 :            : 
     504                 :            : /**
     505                 :            :  * Callback to delete MTR policy.
     506                 :            :  *
     507                 :            :  * @param[in] dev
     508                 :            :  *   Pointer to Ethernet device.
     509                 :            :  * @param[in] mtr_policy_id
     510                 :            :  *   Meter policy id.
     511                 :            :  * @param[out] error
     512                 :            :  *   Pointer to the error structure.
     513                 :            :  *
     514                 :            :  * @return
     515                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     516                 :            :  */
     517                 :            : static int
     518                 :          0 : nfp_mtr_policy_delete(struct rte_eth_dev *dev,
     519                 :            :                 uint32_t mtr_policy_id,
     520                 :            :                 struct rte_mtr_error *error)
     521                 :            : {
     522                 :            :         struct nfp_mtr_priv *priv;
     523                 :            :         struct nfp_mtr_policy *mtr_policy;
     524                 :            :         struct nfp_flower_representor *representor;
     525                 :            : 
     526                 :          0 :         representor = dev->data->dev_private;
     527                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     528                 :            : 
     529                 :            :         /* Check if mtr policy id exist */
     530                 :            :         mtr_policy = nfp_mtr_policy_search(priv, mtr_policy_id);
     531         [ #  # ]:          0 :         if (mtr_policy == NULL) {
     532                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     533                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     534                 :            :                                 NULL, "Request meter policy not exist.");
     535                 :            :         }
     536                 :            : 
     537         [ #  # ]:          0 :         if (mtr_policy->ref_cnt > 0) {
     538                 :          0 :                 return -rte_mtr_error_set(error, EBUSY,
     539                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY,
     540                 :            :                                 NULL, "Request mtr policy is been used.");
     541                 :            :         }
     542                 :            : 
     543                 :            :         /* Remove profile from profile list */
     544         [ #  # ]:          0 :         LIST_REMOVE(mtr_policy, next);
     545                 :          0 :         rte_free(mtr_policy);
     546                 :            : 
     547                 :          0 :         return 0;
     548                 :            : }
     549                 :            : 
     550                 :            : struct nfp_mtr *
     551                 :          0 : nfp_mtr_find_by_mtr_id(struct nfp_mtr_priv *priv, uint32_t mtr_id)
     552                 :            : {
     553                 :            :         struct nfp_mtr *mtr;
     554                 :            : 
     555         [ #  # ]:          0 :         LIST_FOREACH(mtr, &priv->mtrs, next)
     556         [ #  # ]:          0 :                 if (mtr->mtr_id == mtr_id)
     557                 :            :                         break;
     558                 :            : 
     559                 :          0 :         return mtr;
     560                 :            : }
     561                 :            : 
     562                 :            : struct nfp_mtr *
     563                 :          0 : nfp_mtr_find_by_profile_id(struct nfp_mtr_priv *priv, uint32_t profile_id)
     564                 :            : {
     565                 :            :         struct nfp_mtr *mtr;
     566                 :            : 
     567         [ #  # ]:          0 :         LIST_FOREACH(mtr, &priv->mtrs, next)
     568         [ #  # ]:          0 :                 if (mtr->mtr_profile->profile_id == profile_id)
     569                 :            :                         break;
     570                 :            : 
     571                 :          0 :         return mtr;
     572                 :            : }
     573                 :            : 
     574                 :            : static int
     575                 :          0 : nfp_mtr_stats_mask_validate(uint64_t stats_mask, struct rte_mtr_error *error)
     576                 :            : {
     577         [ #  # ]:          0 :         if ((stats_mask & RTE_MTR_STATS_N_PKTS_YELLOW) != 0) {
     578                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     579                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     580                 :            :                                 NULL, "RTE_MTR_STATS_N_PKTS_YELLOW not support.");
     581                 :            :         }
     582                 :            : 
     583         [ #  # ]:          0 :         if ((stats_mask & RTE_MTR_STATS_N_PKTS_RED) != 0) {
     584                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     585                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     586                 :            :                                 NULL, "RTE_MTR_STATS_N_PKTS_RED not support.");
     587                 :            :         }
     588                 :            : 
     589         [ #  # ]:          0 :         if ((stats_mask & RTE_MTR_STATS_N_BYTES_YELLOW) != 0) {
     590                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     591                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     592                 :            :                                 NULL, "RTE_MTR_STATS_N_BYTES_YELLOW not support.");
     593                 :            :         }
     594                 :            : 
     595         [ #  # ]:          0 :         if ((stats_mask & RTE_MTR_STATS_N_BYTES_RED) != 0) {
     596                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     597                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     598                 :            :                                 NULL, "RTE_MTR_STATS_N_BYTES_RED not support.");
     599                 :            :         }
     600                 :            : 
     601                 :            :         return 0;
     602                 :            : }
     603                 :            : 
     604                 :            : static int
     605                 :          0 : nfp_mtr_validate(uint32_t meter_id,
     606                 :            :                 struct rte_mtr_params *params,
     607                 :            :                 struct rte_mtr_error *error)
     608                 :            : {
     609                 :            :         /* Params must not be NULL */
     610         [ #  # ]:          0 :         if (params == NULL) {
     611                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     612                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     613                 :            :                                 NULL, "Meter params is null.");
     614                 :            :         }
     615                 :            : 
     616                 :            :         /* Meter policy ID must be valid. */
     617         [ #  # ]:          0 :         if (meter_id >= NFP_MAX_MTR_CNT) {
     618                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     619                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     620                 :            :                                 NULL, "Meter id not valid.");
     621                 :            :         }
     622                 :            : 
     623         [ #  # ]:          0 :         if (params->use_prev_mtr_color != 0) {
     624                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     625                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     626                 :            :                                 NULL, "Feature use_prev_mtr_color not support.");
     627                 :            :         }
     628                 :            : 
     629                 :          0 :         return nfp_mtr_stats_mask_validate(params->stats_mask, error);
     630                 :            : }
     631                 :            : 
     632                 :            : static void
     633                 :            : nfp_mtr_config(uint32_t mtr_id,
     634                 :            :                 int shared,
     635                 :            :                 struct rte_mtr_params *params,
     636                 :            :                 struct nfp_mtr_profile *mtr_profile,
     637                 :            :                 struct nfp_mtr_policy *mtr_policy,
     638                 :            :                 struct nfp_mtr *mtr)
     639                 :            : {
     640                 :          0 :         mtr->mtr_id = mtr_id;
     641                 :            : 
     642         [ #  # ]:          0 :         if (shared != 0)
     643                 :          0 :                 mtr->shared = true;
     644                 :            : 
     645         [ #  # ]:          0 :         if (params->meter_enable != 0)
     646                 :          0 :                 mtr->enable = true;
     647                 :            : 
     648                 :          0 :         mtr->mtr_profile = mtr_profile;
     649                 :          0 :         mtr->mtr_policy = mtr_policy;
     650                 :          0 :         mtr->stats_mask = params->stats_mask;
     651                 :            : }
     652                 :            : 
     653                 :            : /**
     654                 :            :  * Create meter rules.
     655                 :            :  *
     656                 :            :  * @param[in] dev
     657                 :            :  *   Pointer to Ethernet device.
     658                 :            :  * @param[in] mtr_id
     659                 :            :  *   Meter id.
     660                 :            :  * @param[in] params
     661                 :            :  *   Pointer to rte meter parameters.
     662                 :            :  * @param[in] shared
     663                 :            :  *   Meter shared with other flow or not.
     664                 :            :  * @param[out] error
     665                 :            :  *   Pointer to rte meter error structure.
     666                 :            :  *
     667                 :            :  * @return
     668                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     669                 :            :  */
     670                 :            : static int
     671                 :          0 : nfp_mtr_create(struct rte_eth_dev *dev,
     672                 :            :                 uint32_t mtr_id,
     673                 :            :                 struct rte_mtr_params *params,
     674                 :            :                 int shared,
     675                 :            :                 struct rte_mtr_error *error)
     676                 :            : {
     677                 :            :         int ret;
     678                 :            :         struct nfp_mtr *mtr;
     679                 :            :         struct nfp_mtr_priv *priv;
     680                 :            :         struct nfp_mtr_policy *mtr_policy;
     681                 :            :         struct nfp_mtr_profile *mtr_profile;
     682                 :            :         struct nfp_flower_representor *representor;
     683                 :            : 
     684                 :          0 :         representor = dev->data->dev_private;
     685                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     686                 :            : 
     687                 :            :         /* Check if meter id exist */
     688                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
     689         [ #  # ]:          0 :         if (mtr != NULL) {
     690                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     691                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     692                 :            :                                 NULL, "Meter already exist.");
     693                 :            :         }
     694                 :            : 
     695                 :            :         /* Check input meter params */
     696                 :          0 :         ret = nfp_mtr_validate(mtr_id, params, error);
     697         [ #  # ]:          0 :         if (ret != 0)
     698                 :            :                 return ret;
     699                 :            : 
     700                 :          0 :         mtr_profile = nfp_mtr_profile_search(priv, params->meter_profile_id);
     701         [ #  # ]:          0 :         if (mtr_profile == NULL) {
     702                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     703                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     704                 :            :                                 NULL, "Request meter profile not exist.");
     705                 :            :         }
     706                 :            : 
     707         [ #  # ]:          0 :         if (mtr_profile->in_use) {
     708                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     709                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     710                 :            :                                 NULL, "Request meter profile is been used.");
     711                 :            :         }
     712                 :            : 
     713                 :          0 :         mtr_policy = nfp_mtr_policy_search(priv, params->meter_policy_id);
     714         [ #  # ]:          0 :         if (mtr_policy == NULL) {
     715                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     716                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     717                 :            :                                 NULL, "Request meter policy not exist.");
     718                 :            :         }
     719                 :            : 
     720                 :            :         /* Meter param memory alloc */
     721                 :          0 :         mtr = rte_zmalloc(NULL, sizeof(struct nfp_mtr), 0);
     722         [ #  # ]:          0 :         if (mtr == NULL) {
     723                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     724                 :            :                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     725                 :            :                                 NULL, "Meter param alloc failed.");
     726                 :            :         }
     727                 :            : 
     728                 :            :         nfp_mtr_config(mtr_id, shared, params, mtr_profile, mtr_policy, mtr);
     729                 :            : 
     730                 :            :         /* Update profile/policy status */
     731                 :          0 :         mtr->mtr_policy->ref_cnt++;
     732                 :          0 :         mtr->mtr_profile->in_use = true;
     733                 :            : 
     734                 :            :         /* Insert mtr into mtr list */
     735         [ #  # ]:          0 :         LIST_INSERT_HEAD(&priv->mtrs, mtr, next);
     736                 :            : 
     737                 :          0 :         return 0;
     738                 :            : }
     739                 :            : 
     740                 :            : /**
     741                 :            :  * Destroy meter rules.
     742                 :            :  *
     743                 :            :  * @param[in] dev
     744                 :            :  *   Pointer to Ethernet device.
     745                 :            :  * @param[in] mtr_id
     746                 :            :  *   Meter id.
     747                 :            :  * @param[out] error
     748                 :            :  *   Pointer to rte meter error structure.
     749                 :            :  *
     750                 :            :  * @return
     751                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     752                 :            :  */
     753                 :            : static int
     754                 :          0 : nfp_mtr_destroy(struct rte_eth_dev *dev,
     755                 :            :                 uint32_t mtr_id,
     756                 :            :                 struct rte_mtr_error *error)
     757                 :            : {
     758                 :            :         struct nfp_mtr *mtr;
     759                 :            :         struct nfp_mtr_priv *priv;
     760                 :            :         struct nfp_flower_representor *representor;
     761                 :            : 
     762                 :          0 :         representor = dev->data->dev_private;
     763                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     764                 :            : 
     765                 :            :         /* Check if meter id exist */
     766                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
     767         [ #  # ]:          0 :         if (mtr == NULL) {
     768                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     769                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     770                 :            :                                 NULL, "Request meter not exist.");
     771                 :            :         }
     772                 :            : 
     773         [ #  # ]:          0 :         if (mtr->ref_cnt > 0) {
     774                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     775                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     776                 :            :                                 NULL, "Meter object is being used.");
     777                 :            :         }
     778                 :            : 
     779                 :            :         /* Update profile/policy status */
     780                 :          0 :         mtr->mtr_policy->ref_cnt--;
     781                 :          0 :         mtr->mtr_profile->in_use = false;
     782                 :            : 
     783                 :            :         /* Remove mtr from mtr list */
     784         [ #  # ]:          0 :         LIST_REMOVE(mtr, next);
     785                 :          0 :         rte_free(mtr);
     786                 :            : 
     787                 :          0 :         return 0;
     788                 :            : }
     789                 :            : 
     790                 :            : /**
     791                 :            :  * Enable meter object.
     792                 :            :  *
     793                 :            :  * @param[in] dev
     794                 :            :  *   Pointer to the device.
     795                 :            :  * @param[in] mtr_id
     796                 :            :  *   Id of the meter.
     797                 :            :  * @param[out] error
     798                 :            :  *   Pointer to the error.
     799                 :            :  *
     800                 :            :  * @returns
     801                 :            :  *   0 in success, negative value otherwise and rte_errno is set..
     802                 :            :  */
     803                 :            : static int
     804                 :          0 : nfp_mtr_enable(struct rte_eth_dev *dev,
     805                 :            :                 uint32_t mtr_id,
     806                 :            :                 struct rte_mtr_error *error)
     807                 :            : {
     808                 :            :         struct nfp_mtr *mtr;
     809                 :            :         struct nfp_mtr_priv *priv;
     810                 :            :         struct nfp_flower_representor *representor;
     811                 :            : 
     812                 :          0 :         representor = dev->data->dev_private;
     813                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     814                 :            : 
     815                 :            :         /* Check if meter id exist */
     816                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
     817         [ #  # ]:          0 :         if (mtr == NULL) {
     818                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     819                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     820                 :            :                                 NULL, "Request meter not exist.");
     821                 :            :         }
     822                 :            : 
     823                 :          0 :         mtr->enable = true;
     824                 :            : 
     825                 :          0 :         return 0;
     826                 :            : }
     827                 :            : 
     828                 :            : /**
     829                 :            :  * Disable meter object.
     830                 :            :  *
     831                 :            :  * @param[in] dev
     832                 :            :  *   Pointer to the device.
     833                 :            :  * @param[in] mtr_id
     834                 :            :  *   Id of the meter.
     835                 :            :  * @param[out] error
     836                 :            :  *   Pointer to the error.
     837                 :            :  *
     838                 :            :  * @returns
     839                 :            :  *   0 on success, negative value otherwise and rte_errno is set..
     840                 :            :  */
     841                 :            : static int
     842                 :          0 : nfp_mtr_disable(struct rte_eth_dev *dev,
     843                 :            :                 uint32_t mtr_id,
     844                 :            :                 struct rte_mtr_error *error)
     845                 :            : {
     846                 :            :         struct nfp_mtr *mtr;
     847                 :            :         struct nfp_mtr_priv *priv;
     848                 :            :         struct nfp_flower_representor *representor;
     849                 :            : 
     850                 :          0 :         representor = dev->data->dev_private;
     851                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     852                 :            : 
     853                 :            :         /* Check if meter id exist */
     854                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
     855         [ #  # ]:          0 :         if (mtr == NULL) {
     856                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     857                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     858                 :            :                                 NULL, "Request meter not exist.");
     859                 :            :         }
     860                 :            : 
     861         [ #  # ]:          0 :         if (mtr->ref_cnt > 0) {
     862                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     863                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     864                 :            :                                 NULL, "Can not disable a used meter.");
     865                 :            :         }
     866                 :            : 
     867                 :          0 :         mtr->enable = false;
     868                 :            : 
     869                 :          0 :         return 0;
     870                 :            : }
     871                 :            : 
     872                 :            : /**
     873                 :            :  * Callback to update meter profile.
     874                 :            :  *
     875                 :            :  * @param[in] dev
     876                 :            :  *   Pointer to Ethernet device.
     877                 :            :  * @param[in] mtr_id
     878                 :            :  *   Meter id.
     879                 :            :  * @param[in] mtr_profile_id
     880                 :            :  *   To be updated meter profile id.
     881                 :            :  * @param[out] error
     882                 :            :  *   Pointer to rte meter error structure.
     883                 :            :  *
     884                 :            :  * @return
     885                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     886                 :            :  */
     887                 :            : static int
     888                 :          0 : nfp_mtr_profile_update(struct rte_eth_dev *dev,
     889                 :            :                 uint32_t mtr_id,
     890                 :            :                 uint32_t mtr_profile_id,
     891                 :            :                 struct rte_mtr_error *error)
     892                 :            : {
     893                 :            :         struct nfp_mtr *mtr;
     894                 :            :         struct nfp_mtr_priv *priv;
     895                 :            :         struct nfp_mtr_profile *mtr_profile;
     896                 :            :         struct nfp_flower_representor *representor;
     897                 :            : 
     898                 :          0 :         representor = dev->data->dev_private;
     899                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     900                 :            : 
     901                 :            :         /* Check if meter id exist */
     902                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
     903         [ #  # ]:          0 :         if (mtr == NULL) {
     904                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     905                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     906                 :            :                                 NULL, "Request meter not exist.");
     907                 :            :         }
     908                 :            : 
     909         [ #  # ]:          0 :         if (mtr->ref_cnt > 0) {
     910                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     911                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     912                 :            :                                 NULL, "Request meter is been used.");
     913                 :            :         }
     914                 :            : 
     915         [ #  # ]:          0 :         if (mtr->mtr_profile->profile_id == mtr_profile_id)
     916                 :            :                 return 0;
     917                 :            : 
     918                 :            :         mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
     919         [ #  # ]:          0 :         if (mtr_profile == NULL) {
     920                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     921                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     922                 :            :                                 NULL, "Request meter profile not exist.");
     923                 :            :         }
     924                 :            : 
     925         [ #  # ]:          0 :         if (mtr_profile->in_use) {
     926                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     927                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     928                 :            :                                 NULL, "Request meter profile is been used.");
     929                 :            :         }
     930                 :            : 
     931                 :          0 :         mtr_profile->in_use = true;
     932                 :          0 :         mtr->mtr_profile->in_use = false;
     933                 :          0 :         mtr->mtr_profile = mtr_profile;
     934                 :            : 
     935                 :          0 :         return 0;
     936                 :            : }
     937                 :            : 
     938                 :            : /**
     939                 :            :  * Callback to update meter stats mask.
     940                 :            :  *
     941                 :            :  * @param[in] dev
     942                 :            :  *   Pointer to Ethernet device.
     943                 :            :  * @param[in] mtr_id
     944                 :            :  *   Meter id.
     945                 :            :  * @param[in] stats_mask
     946                 :            :  *   To be updated stats_mask.
     947                 :            :  * @param[out] error
     948                 :            :  *   Pointer to rte meter error structure.
     949                 :            :  *
     950                 :            :  * @return
     951                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
     952                 :            :  */
     953                 :            : static int
     954                 :          0 : nfp_mtr_stats_update(struct rte_eth_dev *dev,
     955                 :            :                 uint32_t mtr_id,
     956                 :            :                 uint64_t stats_mask,
     957                 :            :                 struct rte_mtr_error *error)
     958                 :            : {
     959                 :            :         int ret;
     960                 :            :         struct nfp_mtr *mtr;
     961                 :            :         struct nfp_mtr_priv *priv;
     962                 :            :         struct nfp_flower_representor *representor;
     963                 :            : 
     964                 :          0 :         representor = dev->data->dev_private;
     965                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
     966                 :            : 
     967                 :            :         /* Check if meter id exist */
     968                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
     969         [ #  # ]:          0 :         if (mtr == NULL) {
     970                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     971                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
     972                 :            :                                 NULL, "Request meter id not exist.");
     973                 :            :         }
     974                 :            : 
     975                 :          0 :         ret = nfp_mtr_stats_mask_validate(stats_mask, error);
     976         [ #  # ]:          0 :         if (ret != 0)
     977                 :            :                 return ret;
     978                 :            : 
     979                 :          0 :         mtr->stats_mask = stats_mask;
     980                 :            : 
     981                 :          0 :         return 0;
     982                 :            : }
     983                 :            : 
     984                 :            : /**
     985                 :            :  * Callback to read meter statistics.
     986                 :            :  *
     987                 :            :  * @param[in] dev
     988                 :            :  *   Pointer to Ethernet device.
     989                 :            :  * @param[in] mtr_id
     990                 :            :  *   Meter id.
     991                 :            :  * @param[out] stats
     992                 :            :  *   Pointer to store the statistics.
     993                 :            :  * @param[out] stats_mask
     994                 :            :  *   Pointer to store the stats_mask.
     995                 :            :  * @param[in] clear
     996                 :            :  *   Statistic to be cleared after read or not.
     997                 :            :  * @param[out] error
     998                 :            :  *   Pointer to rte meter error structure.
     999                 :            :  *
    1000                 :            :  * @return
    1001                 :            :  *   0 on success, a negative value otherwise and rte_errno is set.
    1002                 :            :  */
    1003                 :            : static int
    1004                 :          0 : nfp_mtr_stats_read(struct rte_eth_dev *dev,
    1005                 :            :                 uint32_t mtr_id,
    1006                 :            :                 struct rte_mtr_stats *stats,
    1007                 :            :                 uint64_t *stats_mask,
    1008                 :            :                 int clear,
    1009                 :            :                 struct rte_mtr_error *error)
    1010                 :            : {
    1011                 :            :         struct nfp_mtr *mtr;
    1012                 :            :         struct nfp_mtr_priv *priv;
    1013                 :            :         struct nfp_mtr_stats curr;
    1014                 :            :         struct nfp_mtr_stats *prev;
    1015                 :            :         struct nfp_flower_representor *representor;
    1016                 :            : 
    1017                 :          0 :         representor = dev->data->dev_private;
    1018                 :          0 :         priv = representor->app_fw_flower->mtr_priv;
    1019                 :            : 
    1020                 :            :         /* Check if meter id exist */
    1021                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
    1022         [ #  # ]:          0 :         if (mtr == NULL) {
    1023                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
    1024                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID,
    1025                 :            :                                 NULL, "Request meter not exist.");
    1026                 :            :         }
    1027                 :            : 
    1028                 :          0 :         *stats_mask = mtr->stats_mask;
    1029                 :            : 
    1030                 :          0 :         rte_spinlock_lock(&priv->mtr_stats_lock);
    1031         [ #  # ]:          0 :         rte_memcpy(&curr, &mtr->mtr_stats.curr, sizeof(curr));
    1032                 :            :         rte_spinlock_unlock(&priv->mtr_stats_lock);
    1033                 :            : 
    1034                 :            :         prev = &mtr->mtr_stats.prev;
    1035                 :            : 
    1036                 :          0 :         stats->n_pkts[RTE_COLOR_GREEN] = curr.pass_pkts - prev->pass_pkts;
    1037                 :          0 :         stats->n_bytes[RTE_COLOR_GREEN] = curr.pass_bytes - prev->pass_bytes;
    1038                 :          0 :         stats->n_pkts_dropped = curr.drop_pkts - prev->drop_pkts;
    1039                 :          0 :         stats->n_bytes_dropped = curr.drop_bytes - prev->drop_bytes;
    1040                 :            : 
    1041         [ #  # ]:          0 :         if (clear != 0) {
    1042                 :          0 :                 prev->pass_pkts = curr.pass_pkts;
    1043                 :          0 :                 prev->pass_bytes = curr.pass_bytes;
    1044                 :          0 :                 prev->drop_pkts = curr.drop_pkts;
    1045                 :          0 :                 prev->drop_bytes = curr.drop_bytes;
    1046                 :            :         }
    1047                 :            : 
    1048                 :            :         return 0;
    1049                 :            : }
    1050                 :            : 
    1051                 :            : static const struct rte_mtr_ops nfp_mtr_ops = {
    1052                 :            :         .capabilities_get      = nfp_mtr_cap_get,
    1053                 :            :         .meter_profile_add     = nfp_mtr_profile_add,
    1054                 :            :         .meter_profile_delete  = nfp_mtr_profile_delete,
    1055                 :            :         .meter_policy_add      = nfp_mtr_policy_add,
    1056                 :            :         .meter_policy_delete   = nfp_mtr_policy_delete,
    1057                 :            :         .create                = nfp_mtr_create,
    1058                 :            :         .destroy               = nfp_mtr_destroy,
    1059                 :            :         .meter_enable          = nfp_mtr_enable,
    1060                 :            :         .meter_disable         = nfp_mtr_disable,
    1061                 :            :         .meter_profile_update  = nfp_mtr_profile_update,
    1062                 :            :         .stats_update          = nfp_mtr_stats_update,
    1063                 :            :         .stats_read            = nfp_mtr_stats_read,
    1064                 :            : };
    1065                 :            : 
    1066                 :            : int
    1067         [ #  # ]:          0 : nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg)
    1068                 :            : {
    1069         [ #  # ]:          0 :         if (!rte_eth_dev_is_repr(dev)) {
    1070                 :          0 :                 PMD_DRV_LOG(ERR, "Port is not a representor.");
    1071                 :          0 :                 return -EINVAL;
    1072                 :            :         }
    1073                 :            : 
    1074                 :          0 :         *(const struct rte_mtr_ops **)arg = &nfp_mtr_ops;
    1075                 :            : 
    1076                 :          0 :         return 0;
    1077                 :            : }
    1078                 :            : 
    1079                 :            : static void
    1080                 :          0 : nfp_mtr_stats_request(void *arg)
    1081                 :            : {
    1082                 :            :         struct nfp_mtr *mtr;
    1083                 :            :         struct nfp_app_fw_flower *app_fw_flower = arg;
    1084                 :            : 
    1085         [ #  # ]:          0 :         LIST_FOREACH(mtr, &app_fw_flower->mtr_priv->mtrs, next)
    1086                 :          0 :                 nfp_flower_cmsg_qos_stats(app_fw_flower, &mtr->mtr_profile->conf.head);
    1087                 :            : 
    1088                 :          0 :         rte_eal_alarm_set(NFP_METER_STATS_INTERVAL, nfp_mtr_stats_request, arg);
    1089                 :          0 : }
    1090                 :            : 
    1091                 :            : int
    1092                 :          0 : nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev)
    1093                 :            : {
    1094                 :            :         int ret;
    1095                 :            :         struct nfp_mtr_priv *priv;
    1096                 :            :         struct nfp_app_fw_flower *app_fw_flower;
    1097                 :            : 
    1098                 :          0 :         priv = rte_zmalloc("nfp_app_mtr_priv", sizeof(struct nfp_mtr_priv), 0);
    1099         [ #  # ]:          0 :         if (priv == NULL) {
    1100                 :          0 :                 PMD_INIT_LOG(ERR, "NFP app mtr priv creation failed.");
    1101                 :          0 :                 return -ENOMEM;
    1102                 :            :         }
    1103                 :            : 
    1104                 :          0 :         app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
    1105                 :          0 :         app_fw_flower->mtr_priv = priv;
    1106                 :            : 
    1107                 :          0 :         ret = rte_eal_alarm_set(NFP_METER_STATS_INTERVAL, nfp_mtr_stats_request,
    1108                 :            :                         (void *)app_fw_flower);
    1109         [ #  # ]:          0 :         if (ret < 0) {
    1110                 :          0 :                 PMD_INIT_LOG(ERR, "NFP mtr timer init failed.");
    1111                 :          0 :                 rte_free(priv);
    1112                 :          0 :                 return ret;
    1113                 :            :         }
    1114                 :            : 
    1115                 :          0 :         LIST_INIT(&priv->mtrs);
    1116                 :          0 :         LIST_INIT(&priv->profiles);
    1117                 :          0 :         LIST_INIT(&priv->policies);
    1118                 :            : 
    1119                 :            :         rte_spinlock_init(&priv->mtr_stats_lock);
    1120                 :            : 
    1121                 :          0 :         return 0;
    1122                 :            : }
    1123                 :            : 
    1124                 :            : void
    1125                 :          0 : nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
    1126                 :            : {
    1127                 :            :         struct nfp_mtr *mtr;
    1128                 :            :         struct nfp_mtr_priv *priv;
    1129                 :            :         struct nfp_mtr_policy *mtr_policy;
    1130                 :            :         struct nfp_mtr_profile *mtr_profile;
    1131                 :            :         struct nfp_app_fw_flower *app_fw_flower;
    1132                 :            : 
    1133                 :          0 :         app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
    1134                 :          0 :         priv = app_fw_flower->mtr_priv;
    1135                 :            : 
    1136                 :          0 :         rte_eal_alarm_cancel(nfp_mtr_stats_request, (void *)app_fw_flower);
    1137                 :            : 
    1138         [ #  # ]:          0 :         LIST_FOREACH(mtr, &priv->mtrs, next) {
    1139         [ #  # ]:          0 :                 LIST_REMOVE(mtr, next);
    1140                 :          0 :                 rte_free(mtr);
    1141                 :            :         }
    1142                 :            : 
    1143         [ #  # ]:          0 :         LIST_FOREACH(mtr_profile, &priv->profiles, next) {
    1144         [ #  # ]:          0 :                 LIST_REMOVE(mtr_profile, next);
    1145                 :          0 :                 rte_free(mtr_profile);
    1146                 :            :         }
    1147                 :            : 
    1148         [ #  # ]:          0 :         LIST_FOREACH(mtr_policy, &priv->policies, next) {
    1149         [ #  # ]:          0 :                 LIST_REMOVE(mtr_policy, next);
    1150                 :          0 :                 rte_free(mtr_policy);
    1151                 :            :         }
    1152                 :            : 
    1153                 :          0 :         rte_free(priv);
    1154                 :          0 : }
    1155                 :            : 
    1156                 :            : int
    1157                 :          0 : nfp_mtr_update_ref_cnt(struct nfp_mtr_priv *priv,
    1158                 :            :                 uint32_t mtr_id,
    1159                 :            :                 bool add)
    1160                 :            : {
    1161                 :            :         struct nfp_mtr *mtr;
    1162                 :            : 
    1163                 :          0 :         mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
    1164         [ #  # ]:          0 :         if (mtr == NULL)
    1165                 :            :                 return -EINVAL;
    1166                 :            : 
    1167         [ #  # ]:          0 :         mtr->ref_cnt += add ? 1 : -1;
    1168                 :            : 
    1169                 :          0 :         return 0;
    1170                 :            : }

Generated by: LCOV version 1.14