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

Generated by: LCOV version 1.14