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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2021 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "cnxk_ethdev.h"
       6                 :            : #include <rte_mtr_driver.h>
       7                 :            : 
       8                 :            : #define NIX_MTR_COUNT_PER_FLOW 3  /* 1(leaf) + 1(mid) + 1(top) */
       9                 :            : 
      10                 :            : #define NIX_BPF_STATS_MASK_ALL                                                 \
      11                 :            :         {                                                                      \
      12                 :            :                 ROC_NIX_BPF_GREEN_PKT_F_PASS | ROC_NIX_BPF_GREEN_OCTS_F_PASS | \
      13                 :            :                         ROC_NIX_BPF_GREEN_PKT_F_DROP |                         \
      14                 :            :                         ROC_NIX_BPF_GREEN_OCTS_F_DROP |                        \
      15                 :            :                         ROC_NIX_BPF_YELLOW_PKT_F_PASS |                        \
      16                 :            :                         ROC_NIX_BPF_YELLOW_OCTS_F_PASS |                       \
      17                 :            :                         ROC_NIX_BPF_YELLOW_PKT_F_DROP |                        \
      18                 :            :                         ROC_NIX_BPF_YELLOW_OCTS_F_DROP |                       \
      19                 :            :                         ROC_NIX_BPF_RED_PKT_F_PASS |                           \
      20                 :            :                         ROC_NIX_BPF_RED_OCTS_F_PASS |                          \
      21                 :            :                         ROC_NIX_BPF_RED_PKT_F_DROP |                           \
      22                 :            :                         ROC_NIX_BPF_RED_OCTS_F_DROP                            \
      23                 :            :         }
      24                 :            : 
      25                 :            : static const enum roc_nix_bpf_level_flag lvl_map[] = {ROC_NIX_BPF_LEVEL_F_LEAF,
      26                 :            :                                                       ROC_NIX_BPF_LEVEL_F_MID,
      27                 :            :                                                       ROC_NIX_BPF_LEVEL_F_TOP};
      28                 :            : 
      29                 :            : static struct rte_mtr_capabilities mtr_capa = {
      30                 :            :         .n_shared_max = NIX_MTR_COUNT_PER_FLOW,
      31                 :            :         /* .identical = , */
      32                 :            :         .shared_identical = true,
      33                 :            :         /* .shared_n_flows_per_mtr_max = ,*/
      34                 :            :         .chaining_n_mtrs_per_flow_max = NIX_MTR_COUNT_PER_FLOW,
      35                 :            :         .chaining_use_prev_mtr_color_supported = true,
      36                 :            :         .chaining_use_prev_mtr_color_enforced = true,
      37                 :            :         .color_aware_srtcm_rfc2697_supported = true,
      38                 :            :         .color_aware_trtcm_rfc2698_supported = true,
      39                 :            :         .color_aware_trtcm_rfc4115_supported = true,
      40                 :            :         .srtcm_rfc2697_byte_mode_supported = true,
      41                 :            :         .srtcm_rfc2697_packet_mode_supported = true,
      42                 :            :         .trtcm_rfc2698_byte_mode_supported = true,
      43                 :            :         .trtcm_rfc2698_packet_mode_supported = true,
      44                 :            :         .trtcm_rfc4115_byte_mode_supported = true,
      45                 :            :         .trtcm_rfc4115_packet_mode_supported = true,
      46                 :            :         .stats_mask = RTE_MTR_STATS_N_PKTS_GREEN | RTE_MTR_STATS_N_PKTS_YELLOW |
      47                 :            :                       RTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_PKTS_DROPPED |
      48                 :            :                       RTE_MTR_STATS_N_BYTES_GREEN |
      49                 :            :                       RTE_MTR_STATS_N_BYTES_YELLOW | RTE_MTR_STATS_N_BYTES_RED |
      50                 :            :                       RTE_MTR_STATS_N_BYTES_DROPPED,
      51                 :            :         .input_color_proto_mask = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN |
      52                 :            :                         RTE_MTR_COLOR_IN_PROTO_INNER_VLAN |
      53                 :            :                         RTE_MTR_COLOR_IN_PROTO_OUTER_IP |
      54                 :            :                         RTE_MTR_COLOR_IN_PROTO_INNER_IP,
      55                 :            :         .separate_input_color_table_per_port = true};
      56                 :            : 
      57                 :            : static struct cnxk_meter_node *
      58                 :            : nix_mtr_find(struct cnxk_eth_dev *dev, uint32_t meter_id)
      59                 :            : {
      60                 :            :         struct cnxk_mtr *fms = &dev->mtr;
      61                 :            :         struct cnxk_meter_node *fm;
      62                 :            : 
      63   [ #  #  #  #  :          0 :         TAILQ_FOREACH(fm, fms, next)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
      64   [ #  #  #  #  :          0 :                 if (meter_id == fm->id)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
      65                 :            :                         return fm;
      66                 :            :         return NULL;
      67                 :            : }
      68                 :            : 
      69                 :            : static struct cnxk_mtr_profile_node *
      70                 :            : nix_mtr_profile_find(struct cnxk_eth_dev *dev, uint32_t profile_id)
      71                 :            : {
      72                 :            :         struct cnxk_mtr_profiles *fmps = &dev->mtr_profiles;
      73                 :            :         struct cnxk_mtr_profile_node *fmp;
      74                 :            : 
      75   [ #  #  #  #  :          0 :         TAILQ_FOREACH(fmp, fmps, next)
             #  #  #  # ]
      76   [ #  #  #  #  :          0 :                 if (profile_id == fmp->id)
             #  #  #  # ]
      77                 :            :                         return fmp;
      78                 :            : 
      79                 :            :         return NULL;
      80                 :            : }
      81                 :            : 
      82                 :            : static struct cnxk_mtr_policy_node *
      83                 :            : nix_mtr_policy_find(struct cnxk_eth_dev *dev, uint32_t meter_policy_id)
      84                 :            : {
      85                 :            :         struct cnxk_mtr_policy *fmps = &dev->mtr_policy;
      86                 :            :         struct cnxk_mtr_policy_node *fmp;
      87                 :            : 
      88   [ #  #  #  #  :          0 :         TAILQ_FOREACH(fmp, fmps, next)
          #  #  #  #  #  
                      # ]
      89   [ #  #  #  #  :          0 :                 if (meter_policy_id == fmp->id)
          #  #  #  #  #  
                      # ]
      90                 :            :                         return fmp;
      91                 :            :         return NULL;
      92                 :            : }
      93                 :            : 
      94                 :            : static int
      95                 :          0 : nix_mtr_profile_validate(struct cnxk_eth_dev *dev, uint32_t profile_id,
      96                 :            :                          struct rte_mtr_meter_profile *profile,
      97                 :            :                          struct rte_mtr_error *error)
      98                 :            : {
      99                 :            :         int rc = 0;
     100                 :            : 
     101                 :            :         PLT_SET_USED(dev);
     102                 :            : 
     103         [ #  # ]:          0 :         if (profile == NULL)
     104                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     105                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE,
     106                 :            :                                           NULL, "Meter profile is null.");
     107                 :            : 
     108         [ #  # ]:          0 :         if (profile_id == UINT32_MAX)
     109                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     110                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     111                 :            :                                           NULL, "Meter profile id not valid.");
     112                 :            : 
     113   [ #  #  #  # ]:          0 :         switch (profile->alg) {
     114                 :          0 :         case RTE_MTR_SRTCM_RFC2697:
     115         [ #  # ]:          0 :                 if (profile->srtcm_rfc2697.cir > mtr_capa.meter_rate_max)
     116                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     117                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     118                 :            :                                 "CIR exceeds max meter rate");
     119                 :            : 
     120         [ #  # ]:          0 :                 if (profile->srtcm_rfc2697.cbs > NIX_BPF_BURST_MAX)
     121                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     122                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     123                 :            :                                 "CBS exceeds max meter burst size");
     124                 :            : 
     125         [ #  # ]:          0 :                 if (profile->srtcm_rfc2697.ebs > NIX_BPF_BURST_MAX)
     126                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     127                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     128                 :            :                                 "EBS exceeds max meter burst size");
     129                 :            :                 break;
     130                 :            : 
     131                 :          0 :         case RTE_MTR_TRTCM_RFC2698:
     132         [ #  # ]:          0 :                 if (profile->trtcm_rfc2698.cir > mtr_capa.meter_rate_max)
     133                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     134                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     135                 :            :                                 "CIR exceeds max meter rate");
     136                 :            : 
     137         [ #  # ]:          0 :                 if (profile->trtcm_rfc2698.pir > mtr_capa.meter_rate_max)
     138                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     139                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     140                 :            :                                 "PIR exceeds max meter rate");
     141                 :            : 
     142         [ #  # ]:          0 :                 if (profile->trtcm_rfc2698.cbs > NIX_BPF_BURST_MAX)
     143                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     144                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     145                 :            :                                 "CBS exceeds max meter burst size");
     146                 :            : 
     147         [ #  # ]:          0 :                 if (profile->trtcm_rfc2698.pbs > NIX_BPF_BURST_MAX)
     148                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     149                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     150                 :            :                                 "PBS exceeds max meter burst size");
     151                 :            :                 break;
     152                 :            : 
     153                 :          0 :         case RTE_MTR_TRTCM_RFC4115:
     154                 :          0 :                 if ((profile->trtcm_rfc4115.cir + profile->trtcm_rfc4115.eir) >
     155         [ #  # ]:          0 :                     mtr_capa.meter_rate_max)
     156                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     157                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     158                 :            :                                 "PIR + EIR exceeds max rate");
     159                 :            : 
     160         [ #  # ]:          0 :                 if (profile->trtcm_rfc4115.cbs > NIX_BPF_BURST_MAX)
     161                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     162                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     163                 :            :                                 "CBS exceeds max meter burst size");
     164                 :            : 
     165         [ #  # ]:          0 :                 if (profile->trtcm_rfc4115.ebs > NIX_BPF_BURST_MAX)
     166                 :            :                         rc = -rte_mtr_error_set(error, EINVAL,
     167                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     168                 :            :                                 "PBS exceeds max meter burst size");
     169                 :            :                 break;
     170                 :            : 
     171                 :            :         default:
     172                 :            :                 rc = -rte_mtr_error_set(error, EINVAL,
     173                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     174                 :            :                                         "alg is invalid");
     175                 :          0 :                 break;
     176                 :            :         }
     177                 :            : 
     178                 :            :         return rc;
     179                 :            : }
     180                 :            : 
     181                 :            : static int
     182         [ #  # ]:          0 : cnxk_nix_mtr_capabilities_get(struct rte_eth_dev *dev,
     183                 :            :                               struct rte_mtr_capabilities *capa,
     184                 :            :                               struct rte_mtr_error *error)
     185                 :            : {
     186                 :            :         uint8_t lvl_mask = ROC_NIX_BPF_LEVEL_F_LEAF | ROC_NIX_BPF_LEVEL_F_MID |
     187                 :            :                            ROC_NIX_BPF_LEVEL_F_TOP;
     188                 :            :         struct cnxk_eth_dev *eth_dev = cnxk_eth_pmd_priv(dev);
     189                 :          0 :         uint16_t count[ROC_NIX_BPF_LEVEL_MAX] = {0};
     190                 :          0 :         struct roc_nix *nix = &eth_dev->nix;
     191                 :            :         uint32_t time_unit;
     192                 :            :         int rc, i;
     193                 :            : 
     194                 :            :         RTE_SET_USED(dev);
     195                 :            : 
     196         [ #  # ]:          0 :         if (!capa)
     197                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     198                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
     199                 :            :                                 "NULL input parameter");
     200                 :            : 
     201                 :          0 :         rc = roc_nix_bpf_count_get(nix, lvl_mask, count);
     202         [ #  # ]:          0 :         if (rc)
     203                 :            :                 return rc;
     204                 :            : 
     205         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++)
     206                 :          0 :                 mtr_capa.n_max += count[i];
     207                 :            : 
     208                 :          0 :         mtr_capa.meter_srtcm_rfc2697_n_max = mtr_capa.n_max;
     209                 :          0 :         mtr_capa.meter_trtcm_rfc2698_n_max = mtr_capa.n_max;
     210                 :          0 :         mtr_capa.meter_trtcm_rfc4115_n_max = mtr_capa.n_max;
     211                 :          0 :         mtr_capa.meter_policy_n_max = mtr_capa.n_max;
     212                 :            : 
     213                 :          0 :         rc = roc_nix_bpf_timeunit_get(nix, &time_unit);
     214         [ #  # ]:          0 :         if (rc)
     215                 :            :                 return rc;
     216                 :            : 
     217                 :          0 :         mtr_capa.meter_rate_max =
     218                 :          0 :                 NIX_BPF_RATE(time_unit, NIX_BPF_MAX_RATE_EXPONENT,
     219                 :          0 :                              NIX_BPF_MAX_RATE_MANTISSA, 0) /
     220                 :            :                 8;
     221                 :            : 
     222                 :          0 :         *capa = mtr_capa;
     223                 :          0 :         return 0;
     224                 :            : }
     225                 :            : 
     226                 :            : static int
     227                 :          0 : cnxk_nix_mtr_profile_add(struct rte_eth_dev *eth_dev, uint32_t profile_id,
     228                 :            :                          struct rte_mtr_meter_profile *profile,
     229                 :            :                          struct rte_mtr_error *error)
     230                 :            : {
     231                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     232                 :            :         struct cnxk_mtr_profiles *fmps = &dev->mtr_profiles;
     233                 :            :         struct cnxk_mtr_profile_node *fmp;
     234                 :            :         int ret;
     235                 :            : 
     236                 :            :         /* Check input params. */
     237                 :          0 :         ret = nix_mtr_profile_validate(dev, profile_id, profile, error);
     238         [ #  # ]:          0 :         if (ret)
     239                 :            :                 return ret;
     240                 :            : 
     241                 :            :         fmp = nix_mtr_profile_find(dev, profile_id);
     242         [ #  # ]:          0 :         if (fmp) {
     243                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     244                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     245                 :            :                                           NULL, "Profile already exist");
     246                 :            :         }
     247                 :            : 
     248                 :          0 :         fmp = plt_zmalloc(sizeof(struct cnxk_mtr_profile_node), ROC_ALIGN);
     249         [ #  # ]:          0 :         if (fmp == NULL)
     250                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     251                 :            :                                           RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
     252                 :            :                                           "Meter profile memory "
     253                 :            :                                           "alloc failed.");
     254                 :            : 
     255                 :          0 :         fmp->id = profile_id;
     256                 :          0 :         fmp->profile = *profile;
     257                 :            : 
     258                 :          0 :         TAILQ_INSERT_TAIL(fmps, fmp, next);
     259                 :            : 
     260                 :          0 :         return 0;
     261                 :            : }
     262                 :            : 
     263                 :            : static int
     264         [ #  # ]:          0 : cnxk_nix_mtr_profile_delete(struct rte_eth_dev *eth_dev, uint32_t profile_id,
     265                 :            :                             struct rte_mtr_error *error)
     266                 :            : {
     267                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     268                 :            :         struct cnxk_mtr_profile_node *fmp;
     269                 :            : 
     270         [ #  # ]:          0 :         if (profile_id == UINT32_MAX)
     271                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     272                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     273                 :            :                                           NULL, "Meter profile id not valid.");
     274                 :            : 
     275                 :            :         fmp = nix_mtr_profile_find(dev, profile_id);
     276         [ #  # ]:          0 :         if (fmp == NULL)
     277                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     278                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     279                 :            :                                           &profile_id,
     280                 :            :                                           "Meter profile is invalid.");
     281                 :            : 
     282         [ #  # ]:          0 :         if (fmp->ref_cnt)
     283                 :          0 :                 return -rte_mtr_error_set(error, EBUSY,
     284                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     285                 :            :                                           NULL, "Meter profile is in use.");
     286                 :            : 
     287         [ #  # ]:          0 :         TAILQ_REMOVE(&dev->mtr_profiles, fmp, next);
     288                 :          0 :         plt_free(fmp);
     289                 :          0 :         return 0;
     290                 :            : }
     291                 :            : 
     292                 :            : static int
     293                 :            : update_mtr_err(uint32_t act_color, struct rte_mtr_error *error, bool action)
     294                 :            : {
     295                 :            :         const char *str = NULL;
     296   [ #  #  #  #  :          0 :         switch (act_color) {
                   #  # ]
     297                 :            :         case RTE_COLOR_GREEN:
     298                 :            :                 if (action) {
     299                 :            :                         str = "Green action is not valid";
     300                 :          0 :                         goto notsup;
     301                 :            :                 } else {
     302                 :            :                         str = "Green action is null";
     303                 :          0 :                         goto notvalid;
     304                 :            :                 }
     305                 :            :                 break;
     306                 :            :         case RTE_COLOR_YELLOW:
     307                 :            :                 if (action) {
     308                 :            :                         str = "Yellow action is not valid";
     309                 :          0 :                         goto notsup;
     310                 :            :                 } else {
     311                 :            :                         str = "Yellow action is null";
     312                 :          0 :                         goto notvalid;
     313                 :            :                 }
     314                 :            :                 break;
     315                 :            :         case RTE_COLOR_RED:
     316                 :            :                 if (action) {
     317                 :            :                         str = "Red action is not valid";
     318                 :          0 :                         goto notsup;
     319                 :            :                 } else {
     320                 :            :                         str = "Red action is null";
     321                 :          0 :                         goto notvalid;
     322                 :            :                 }
     323                 :            :                 break;
     324                 :            :         }
     325         [ #  # ]:          0 : notsup:
     326                 :            :         return -rte_mtr_error_set(error, ENOTSUP,
     327                 :            :                                   RTE_MTR_ERROR_TYPE_METER_POLICY, NULL, str);
     328         [ #  # ]:          0 : notvalid:
     329                 :            :         return -rte_mtr_error_set(error, EINVAL,
     330                 :            :                                   RTE_MTR_ERROR_TYPE_METER_POLICY, NULL, str);
     331                 :            : }
     332                 :            : 
     333                 :            : static int
     334                 :          0 : cnxk_nix_mtr_policy_validate(struct rte_eth_dev *dev,
     335                 :            :                              struct rte_mtr_meter_policy_params *policy,
     336                 :            :                              struct rte_mtr_error *error)
     337                 :            : {
     338                 :          0 :         bool supported[RTE_COLORS] = {false, false, false};
     339                 :            :         const struct rte_flow_action *action;
     340                 :            :         uint32_t i;
     341                 :            : 
     342                 :            :         RTE_SET_USED(dev);
     343                 :            : 
     344         [ #  # ]:          0 :         if (!policy)
     345                 :            :                 return 0; /* Nothing to be validated */
     346                 :            : 
     347         [ #  # ]:          0 :         for (i = 0; i < RTE_COLORS; i++) {
     348         [ #  # ]:          0 :                 if (policy->actions[i]) {
     349                 :            :                         for (action = policy->actions[i];
     350         [ #  # ]:          0 :                              action->type != RTE_FLOW_ACTION_TYPE_END;
     351                 :          0 :                              action++) {
     352         [ #  # ]:          0 :                                 if (action->type == RTE_FLOW_ACTION_TYPE_METER)
     353                 :          0 :                                         supported[i] = true;
     354                 :            : 
     355         [ #  # ]:          0 :                                 if (action->type == RTE_FLOW_ACTION_TYPE_DROP)
     356                 :          0 :                                         supported[i] = true;
     357                 :            : 
     358         [ #  # ]:          0 :                                 if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
     359                 :          0 :                                         supported[i] = true;
     360                 :            : 
     361         [ #  # ]:          0 :                                 if (action->type == RTE_FLOW_ACTION_TYPE_SKIP_CMAN)
     362                 :          0 :                                         supported[i] = true;
     363                 :            : 
     364         [ #  # ]:          0 :                                 if (!supported[i])
     365                 :          0 :                                         return update_mtr_err(i, error, true);
     366                 :            :                         }
     367                 :            :                 } else {
     368                 :          0 :                         return update_mtr_err(i, error, false);
     369                 :            :                 }
     370                 :            :         }
     371                 :            : 
     372                 :            :         return 0;
     373                 :            : }
     374                 :            : 
     375                 :            : static void
     376                 :          0 : cnxk_fill_policy_actions(struct cnxk_mtr_policy_node *fmp,
     377                 :            :                          struct rte_mtr_meter_policy_params *policy)
     378                 :            : 
     379                 :            : {
     380                 :            :         const struct rte_flow_action_meter *mtr;
     381                 :            :         const struct rte_flow_action *action;
     382                 :            :         int i;
     383                 :            : 
     384         [ #  # ]:          0 :         for (i = 0; i < RTE_COLORS; i++) {
     385         [ #  # ]:          0 :                 if (policy->actions[i]) {
     386                 :            :                         for (action = policy->actions[i];
     387         [ #  # ]:          0 :                              action->type != RTE_FLOW_ACTION_TYPE_END;
     388                 :          0 :                              action++) {
     389         [ #  # ]:          0 :                                 if (action->type ==
     390                 :            :                                     RTE_FLOW_ACTION_TYPE_METER) {
     391                 :          0 :                                         fmp->actions[i].action_fate =
     392                 :            :                                                 action->type;
     393                 :          0 :                                         mtr = (const struct
     394                 :            :                                                rte_flow_action_meter *)
     395                 :            :                                                       action->conf;
     396                 :          0 :                                         fmp->actions[i].mtr_id = mtr->mtr_id;
     397                 :            :                                 }
     398                 :            : 
     399         [ #  # ]:          0 :                                 if (action->type == RTE_FLOW_ACTION_TYPE_DROP) {
     400                 :          0 :                                         fmp->actions[i].action_fate =
     401                 :            :                                                 action->type;
     402                 :            :                                 }
     403                 :            : 
     404         [ #  # ]:          0 :                                 if (action->type ==
     405                 :            :                                         RTE_FLOW_ACTION_TYPE_SKIP_CMAN)
     406                 :          0 :                                         fmp->actions[i].skip_red = true;
     407                 :            :                         }
     408                 :            :                 }
     409                 :            :         }
     410                 :          0 : }
     411                 :            : 
     412                 :            : static int
     413                 :          0 : cnxk_nix_mtr_policy_add(struct rte_eth_dev *eth_dev, uint32_t policy_id,
     414                 :            :                         struct rte_mtr_meter_policy_params *policy,
     415                 :            :                         struct rte_mtr_error *error)
     416                 :            : {
     417                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     418                 :            :         struct cnxk_mtr_policy *fmps = &dev->mtr_policy;
     419                 :            :         struct cnxk_mtr_policy_node *fmp;
     420                 :            :         int rc;
     421                 :            : 
     422                 :            :         fmp = nix_mtr_policy_find(dev, policy_id);
     423         [ #  # ]:          0 :         if (fmp) {
     424                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     425                 :            :                                           RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     426                 :            :                                           NULL, "Policy already exist");
     427                 :            :         }
     428                 :            : 
     429                 :          0 :         fmp = plt_zmalloc(sizeof(struct cnxk_mtr_policy_node), ROC_ALIGN);
     430         [ #  # ]:          0 :         if (fmp == NULL) {
     431                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     432                 :            :                                           RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
     433                 :            :                                           "Memory allocation failure");
     434                 :            :         } else {
     435                 :          0 :                 rc = cnxk_nix_mtr_policy_validate(eth_dev, policy, error);
     436         [ #  # ]:          0 :                 if (rc)
     437                 :          0 :                         goto exit;
     438                 :            :         }
     439                 :            : 
     440                 :          0 :         fmp->id = policy_id;
     441                 :          0 :         cnxk_fill_policy_actions(fmp, policy);
     442                 :          0 :         TAILQ_INSERT_TAIL(fmps, fmp, next);
     443                 :          0 :         return 0;
     444                 :            : 
     445                 :            : exit:
     446                 :          0 :         plt_free(fmp);
     447                 :          0 :         return rc;
     448                 :            : }
     449                 :            : 
     450                 :            : static int
     451                 :          0 : cnxk_nix_mtr_policy_delete(struct rte_eth_dev *eth_dev, uint32_t policy_id,
     452                 :            :                            struct rte_mtr_error *error)
     453                 :            : {
     454                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     455                 :            :         struct cnxk_mtr_policy_node *fmp;
     456                 :            : 
     457                 :            :         fmp = nix_mtr_policy_find(dev, policy_id);
     458         [ #  # ]:          0 :         if (fmp == NULL) {
     459                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     460                 :            :                                           RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     461                 :            :                                           NULL, "No policy found");
     462                 :            :         }
     463                 :            : 
     464         [ #  # ]:          0 :         if (fmp->ref_cnt)
     465                 :          0 :                 return -rte_mtr_error_set(error, EBUSY,
     466                 :            :                                           RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     467                 :            :                                           NULL, "Meter policy is in use.");
     468                 :            : 
     469         [ #  # ]:          0 :         TAILQ_REMOVE(&dev->mtr_policy, fmp, next);
     470                 :          0 :         plt_free(fmp);
     471                 :            : 
     472                 :          0 :         return 0;
     473                 :            : }
     474                 :            : 
     475                 :            : static int
     476         [ #  # ]:          0 : cnxk_nix_mtr_create(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     477                 :            :                     struct rte_mtr_params *params, int shared,
     478                 :            :                     struct rte_mtr_error *error)
     479                 :            : {
     480                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     481                 :            :         struct cnxk_mtr_profile_node *profile;
     482                 :            :         struct cnxk_mtr_policy_node *policy;
     483                 :            :         struct cnxk_mtr *fm = &dev->mtr;
     484                 :            :         enum rte_color *table = NULL;
     485                 :            :         struct cnxk_meter_node *mtr;
     486                 :            :         int i;
     487                 :            : 
     488                 :            :         RTE_SET_USED(shared);
     489                 :            : 
     490         [ #  # ]:          0 :         if (params == NULL)
     491                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     492                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
     493                 :            :                                           "Meter params are invalid.");
     494                 :            : 
     495                 :          0 :         profile = nix_mtr_profile_find(dev, params->meter_profile_id);
     496         [ #  # ]:          0 :         if (profile == NULL)
     497                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     498                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
     499         [ #  # ]:          0 :                                           &params->meter_profile_id,
     500                 :            :                                           "Meter profile is invalid.");
     501                 :            : 
     502                 :          0 :         policy = nix_mtr_policy_find(dev, params->meter_policy_id);
     503         [ #  # ]:          0 :         if (policy == NULL)
     504                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     505                 :            :                                           RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     506         [ #  # ]:          0 :                                           &params->meter_policy_id,
     507                 :            :                                           "Meter policy is invalid.");
     508                 :            : 
     509                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     510         [ #  # ]:          0 :         if (mtr) {
     511                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     512                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     513                 :            :                                           "Meter already exist");
     514                 :            :         }
     515                 :            : 
     516                 :          0 :         mtr = plt_zmalloc(sizeof(struct cnxk_meter_node), ROC_ALIGN);
     517         [ #  # ]:          0 :         if (mtr == NULL) {
     518                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     519                 :            :                                           RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
     520                 :            :                                           "Meter memory alloc failed.");
     521                 :            :         }
     522                 :            : 
     523                 :          0 :         mtr->id = mtr_id;
     524                 :          0 :         mtr->profile = profile;
     525                 :          0 :         mtr->policy = policy;
     526                 :          0 :         mtr->params = *params;
     527                 :          0 :         mtr->bpf_id = ROC_NIX_BPF_ID_INVALID;
     528                 :          0 :         mtr->prev_cnt = 0;
     529         [ #  # ]:          0 :         for (i = 0; i < MAX_PRV_MTR_NODES; i++)
     530                 :          0 :                 mtr->prev_id[i] = ROC_NIX_BPF_ID_INVALID;
     531                 :            : 
     532                 :          0 :         mtr->next_id = ROC_NIX_BPF_ID_INVALID;
     533                 :          0 :         mtr->is_next = false;
     534                 :          0 :         mtr->level = ROC_NIX_BPF_LEVEL_IDX_INVALID;
     535                 :            : 
     536                 :            :         /* populate dscp table for input coloring */
     537         [ #  # ]:          0 :         if (params->dscp_table) {
     538                 :          0 :                 table = (enum rte_color *)plt_zmalloc(sizeof(enum rte_color) *
     539                 :            :                         ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP, ROC_ALIGN);
     540         [ #  # ]:          0 :                 if (table == NULL) {
     541                 :          0 :                         plt_free(mtr);
     542                 :          0 :                         return -rte_mtr_error_set(error, ENOMEM,
     543                 :            :                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     544                 :            :                                         NULL, "Memory alloc failed.");
     545                 :            :                 }
     546                 :            : 
     547         [ #  # ]:          0 :                 for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
     548                 :          0 :                         table[i] = params->dscp_table[i];
     549                 :            : 
     550                 :          0 :                 mtr->params.dscp_table = table;
     551                 :            :         }
     552                 :            : 
     553                 :            : 
     554                 :            :         /* populate vlan table for input coloring */
     555         [ #  # ]:          0 :         if (params->vlan_table) {
     556                 :          0 :                 table = (enum rte_color *)plt_zmalloc(sizeof(enum rte_color) *
     557                 :            :                         ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN, ROC_ALIGN);
     558         [ #  # ]:          0 :                 if (table == NULL) {
     559                 :          0 :                         plt_free(mtr->params.dscp_table);
     560                 :          0 :                         plt_free(mtr);
     561                 :          0 :                         return -rte_mtr_error_set(error, ENOMEM,
     562                 :            :                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     563                 :            :                                         NULL, "Memory alloc failed.");
     564                 :            :                 }
     565                 :            : 
     566         [ #  # ]:          0 :                 for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
     567                 :          0 :                         table[i] = params->vlan_table[i];
     568                 :            : 
     569                 :          0 :                 mtr->params.vlan_table = table;
     570                 :            :         }
     571                 :            : 
     572                 :          0 :         profile->ref_cnt++;
     573                 :          0 :         policy->ref_cnt++;
     574                 :          0 :         TAILQ_INSERT_TAIL(fm, mtr, next);
     575                 :          0 :         return 0;
     576                 :            : }
     577                 :            : 
     578                 :            : static int
     579                 :          0 : cnxk_nix_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     580                 :            :                      struct rte_mtr_error *error)
     581                 :            : {
     582                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     583                 :          0 :         struct roc_nix_bpf_objs profs = {0};
     584                 :            :         struct cnxk_mtr *fm = &dev->mtr;
     585                 :          0 :         struct roc_nix *nix = &dev->nix;
     586                 :            :         struct cnxk_meter_node *mtr;
     587                 :            :         struct cnxk_meter_node *mid_mtr;
     588                 :            :         struct cnxk_meter_node *top_mtr;
     589                 :            :         int rc = 0;
     590                 :            : 
     591                 :          0 :         mtr = nix_mtr_find(dev, mtr_id);
     592         [ #  # ]:          0 :         if (mtr == NULL) {
     593                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     594                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, &mtr_id,
     595                 :            :                                           "Meter id is invalid.");
     596                 :            :         }
     597                 :            : 
     598         [ #  # ]:          0 :         if (mtr->ref_cnt) {
     599                 :          0 :                 return -rte_mtr_error_set(error, EADDRINUSE,
     600                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, &mtr_id,
     601                 :            :                                           "Meter id in use.");
     602                 :            :         }
     603                 :            : 
     604   [ #  #  #  # ]:          0 :         switch (lvl_map[mtr->level]) {
     605                 :          0 :         case ROC_NIX_BPF_LEVEL_F_LEAF:
     606         [ #  # ]:          0 :                 if (mtr->is_next) {
     607                 :          0 :                         rc = roc_nix_bpf_connect(nix, ROC_NIX_BPF_LEVEL_F_LEAF,
     608                 :          0 :                                                  mtr->bpf_id,
     609                 :            :                                                  ROC_NIX_BPF_ID_INVALID);
     610                 :            :                 }
     611                 :            :                 break;
     612                 :            :         case ROC_NIX_BPF_LEVEL_F_MID:
     613         [ #  # ]:          0 :                 while ((mtr->prev_cnt) + 1) {
     614                 :            :                         mid_mtr =
     615                 :          0 :                                 nix_mtr_find(dev, mtr->prev_id[mtr->prev_cnt]);
     616         [ #  # ]:          0 :                         if (mid_mtr == NULL) {
     617                 :          0 :                                 return -rte_mtr_error_set(error, ENOENT,
     618         [ #  # ]:          0 :                                           RTE_MTR_ERROR_TYPE_MTR_ID, &mtr->prev_id[mtr->prev_cnt],
     619                 :            :                                           "Mid meter id is invalid.");
     620                 :            :                         }
     621                 :          0 :                         rc = roc_nix_bpf_connect(nix, ROC_NIX_BPF_LEVEL_F_LEAF,
     622                 :          0 :                                                  mid_mtr->bpf_id,
     623                 :            :                                                  ROC_NIX_BPF_ID_INVALID);
     624                 :          0 :                         mtr->prev_cnt--;
     625                 :            :                 }
     626         [ #  # ]:          0 :                 if (mtr->is_next) {
     627                 :          0 :                         rc = roc_nix_bpf_connect(nix, ROC_NIX_BPF_LEVEL_F_MID,
     628                 :          0 :                                                  mtr->bpf_id,
     629                 :            :                                                  ROC_NIX_BPF_ID_INVALID);
     630                 :            :                 }
     631                 :            :                 break;
     632                 :            :         case ROC_NIX_BPF_LEVEL_F_TOP:
     633         [ #  # ]:          0 :                 while (mtr->prev_cnt) {
     634                 :            :                         top_mtr =
     635                 :          0 :                                 nix_mtr_find(dev, mtr->prev_id[mtr->prev_cnt]);
     636         [ #  # ]:          0 :                         if (top_mtr == NULL) {
     637                 :          0 :                                 return -rte_mtr_error_set(error, ENOENT,
     638         [ #  # ]:          0 :                                           RTE_MTR_ERROR_TYPE_MTR_ID, &mtr->prev_id[mtr->prev_cnt],
     639                 :            :                                           "Top meter id is invalid.");
     640                 :            :                         }
     641                 :          0 :                         rc = roc_nix_bpf_connect(nix, ROC_NIX_BPF_LEVEL_F_MID,
     642                 :          0 :                                                  top_mtr->bpf_id,
     643                 :            :                                                  ROC_NIX_BPF_ID_INVALID);
     644                 :          0 :                         mtr->prev_cnt--;
     645                 :            :                 }
     646                 :            :                 break;
     647                 :            :         default:
     648                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     649                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     650                 :            :                                           "Invalid meter level");
     651                 :            :         }
     652                 :            : 
     653         [ #  # ]:          0 :         if (rc)
     654                 :          0 :                 goto exit;
     655                 :            : 
     656                 :          0 :         profs.level = mtr->level;
     657                 :          0 :         profs.count = 1;
     658                 :          0 :         profs.ids[0] = mtr->bpf_id;
     659                 :          0 :         rc = roc_nix_bpf_free(nix, &profs, 1);
     660         [ #  # ]:          0 :         if (rc)
     661                 :          0 :                 goto exit;
     662                 :            : 
     663                 :          0 :         mtr->policy->ref_cnt--;
     664                 :          0 :         mtr->profile->ref_cnt--;
     665         [ #  # ]:          0 :         TAILQ_REMOVE(fm, mtr, next);
     666                 :            : 
     667         [ #  # ]:          0 :         if (mtr->params.dscp_table)
     668                 :          0 :                 plt_free(mtr->params.dscp_table);
     669                 :            : 
     670         [ #  # ]:          0 :         if (mtr->params.vlan_table)
     671                 :          0 :                 plt_free(mtr->params.vlan_table);
     672                 :            : 
     673                 :          0 :         plt_free(mtr);
     674                 :            : 
     675                 :            : exit:
     676                 :            :         return rc;
     677                 :            : }
     678                 :            : 
     679                 :            : static int
     680                 :          0 : cnxk_nix_mtr_enable(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     681                 :            :                     struct rte_mtr_error *error)
     682                 :            : {
     683                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     684                 :          0 :         struct roc_nix *nix = &dev->nix;
     685                 :            :         struct cnxk_meter_node *mtr;
     686                 :            :         struct roc_nix_rq *rq;
     687                 :            :         uint32_t i;
     688                 :            :         int rc = 0;
     689                 :            : 
     690                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     691         [ #  # ]:          0 :         if (mtr == NULL) {
     692                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     693                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     694                 :            :                                           "Meter id is invalid.");
     695                 :            :         }
     696                 :            : 
     697         [ #  # ]:          0 :         if (mtr->level != 0)
     698                 :            :                 return 0;
     699                 :            : 
     700         [ #  # ]:          0 :         for (i = 0; i < mtr->rq_num; i++) {
     701                 :          0 :                 rq = &dev->rqs[mtr->rq_id[i]];
     702                 :          0 :                 rc |= roc_nix_bpf_ena_dis(nix, mtr->bpf_id, rq, true);
     703                 :            :         }
     704                 :            : 
     705                 :            :         return rc;
     706                 :            : }
     707                 :            : 
     708                 :            : static int
     709                 :          0 : cnxk_nix_mtr_disable(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     710                 :            :                      struct rte_mtr_error *error)
     711                 :            : {
     712                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     713                 :          0 :         struct roc_nix *nix = &dev->nix;
     714                 :            :         struct cnxk_meter_node *mtr;
     715                 :            :         struct roc_nix_rq *rq;
     716                 :            :         uint32_t i;
     717                 :            :         int rc = 0;
     718                 :            : 
     719                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     720         [ #  # ]:          0 :         if (mtr == NULL) {
     721                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     722                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     723                 :            :                                           "Meter id is invalid.");
     724                 :            :         }
     725                 :            : 
     726         [ #  # ]:          0 :         if (mtr->level != 0)
     727                 :            :                 return 0;
     728                 :            : 
     729         [ #  # ]:          0 :         for (i = 0; i < mtr->rq_num; i++) {
     730                 :          0 :                 rq = &dev->rqs[mtr->rq_id[i]];
     731                 :          0 :                 rc |= roc_nix_bpf_ena_dis(nix, mtr->bpf_id, rq, false);
     732                 :            :         }
     733                 :            : 
     734                 :            :         return rc;
     735                 :            : }
     736                 :            : 
     737                 :            : static int
     738                 :          0 : cnxk_nix_mtr_dscp_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     739                 :            :                                enum rte_mtr_color_in_protocol proto,
     740                 :            :                                enum rte_color *dscp_table,
     741                 :            :                                struct rte_mtr_error *error)
     742                 :            : {
     743                 :            :         enum roc_nix_bpf_color nix_dscp_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP];
     744                 :          0 :         enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
     745                 :            :                                               ROC_NIX_BPF_COLOR_YELLOW,
     746                 :            :                                               ROC_NIX_BPF_COLOR_RED};
     747                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     748                 :            :         struct roc_nix_bpf_precolor table;
     749                 :          0 :         struct roc_nix *nix = &dev->nix;
     750                 :            :         struct cnxk_meter_node *mtr;
     751                 :            :         int rc, i;
     752                 :            : 
     753                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     754         [ #  # ]:          0 :         if (mtr == NULL) {
     755                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     756                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     757                 :            :                                           "Meter object not found");
     758                 :            :         }
     759                 :            : 
     760         [ #  # ]:          0 :         if (!dscp_table) {
     761         [ #  # ]:          0 :                 for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
     762                 :          0 :                         nix_dscp_tbl[i] = ROC_NIX_BPF_COLOR_GREEN;
     763                 :            :         } else {
     764         [ #  # ]:          0 :                 for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
     765                 :          0 :                         nix_dscp_tbl[i] = color_map[dscp_table[i]];
     766                 :            :         }
     767                 :            : 
     768                 :          0 :         table.count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP;
     769                 :            : 
     770      [ #  #  # ]:          0 :         switch (proto) {
     771                 :          0 :         case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
     772                 :          0 :                 table.mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
     773                 :          0 :                 break;
     774                 :          0 :         case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
     775                 :          0 :                 table.mode = ROC_NIX_BPF_PC_MODE_DSCP_INNER;
     776                 :          0 :                 break;
     777                 :            :         default:
     778                 :            :                 rc = -rte_mtr_error_set(error, EINVAL,
     779                 :            :                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
     780                 :            :                         "Invalid input color protocol");
     781                 :          0 :                 goto exit;
     782                 :            :         }
     783                 :            : 
     784         [ #  # ]:          0 :         if (dev->proto != proto) {
     785                 :            :                 rc = -rte_mtr_error_set(error, EINVAL,
     786                 :            :                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
     787                 :            :                         "input color protocol is not configured");
     788                 :          0 :                 goto exit;
     789                 :            :         }
     790                 :            : 
     791         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
     792                 :          0 :                 table.color[i] = nix_dscp_tbl[i];
     793                 :            : 
     794                 :          0 :         rc = roc_nix_bpf_pre_color_tbl_setup(nix, mtr->bpf_id,
     795                 :          0 :                                              lvl_map[mtr->level], &table);
     796         [ #  # ]:          0 :         if (rc) {
     797                 :            :                 rte_mtr_error_set(error, rc, RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     798                 :            :                                   NULL, NULL);
     799                 :          0 :                 goto exit;
     800                 :            :         }
     801                 :            : 
     802         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
     803                 :          0 :                 dev->precolor_tbl[i] = nix_dscp_tbl[i];
     804                 :            : 
     805                 :          0 : exit:
     806                 :            :         return rc;
     807                 :            : }
     808                 :            : 
     809                 :            : static int
     810                 :          0 : cnxk_nix_mtr_vlan_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     811                 :            :                                enum rte_mtr_color_in_protocol proto,
     812                 :            :                                enum rte_color *vlan_table,
     813                 :            :                                struct rte_mtr_error *error)
     814                 :            : {
     815                 :            :         enum roc_nix_bpf_color nix_vlan_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN];
     816                 :          0 :         enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
     817                 :            :                                               ROC_NIX_BPF_COLOR_YELLOW,
     818                 :            :                                               ROC_NIX_BPF_COLOR_RED};
     819                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     820                 :            :         struct roc_nix_bpf_precolor table;
     821                 :          0 :         struct roc_nix *nix = &dev->nix;
     822                 :            :         struct cnxk_meter_node *mtr;
     823                 :            :         int rc, i;
     824                 :            : 
     825                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     826         [ #  # ]:          0 :         if (mtr == NULL) {
     827                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     828                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     829                 :            :                                           "Meter object not found");
     830                 :            :         }
     831                 :            : 
     832         [ #  # ]:          0 :         if (!vlan_table) {
     833         [ #  # ]:          0 :                 for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
     834                 :          0 :                         nix_vlan_tbl[i] = ROC_NIX_BPF_COLOR_GREEN;
     835                 :            :         } else {
     836         [ #  # ]:          0 :                 for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
     837                 :          0 :                         nix_vlan_tbl[i] = color_map[vlan_table[i]];
     838                 :            :         }
     839                 :            : 
     840                 :          0 :         table.count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN;
     841                 :            : 
     842      [ #  #  # ]:          0 :         switch (proto) {
     843                 :          0 :         case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
     844                 :          0 :                 table.mode = ROC_NIX_BPF_PC_MODE_VLAN_OUTER;
     845                 :          0 :                 break;
     846                 :          0 :         case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
     847                 :          0 :                 table.mode = ROC_NIX_BPF_PC_MODE_VLAN_INNER;
     848                 :          0 :                 break;
     849                 :            :         default:
     850                 :            :                 rc = -rte_mtr_error_set(error, EINVAL,
     851                 :            :                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
     852                 :            :                         "Invalid input color protocol");
     853                 :          0 :                 goto exit;
     854                 :            :         }
     855                 :            : 
     856         [ #  # ]:          0 :         if (dev->proto != proto) {
     857                 :            :                 rc = -rte_mtr_error_set(error, EINVAL,
     858                 :            :                         RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
     859                 :            :                         "input color protocol is not configured");
     860                 :          0 :                 goto exit;
     861                 :            :         }
     862                 :            : 
     863         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
     864                 :          0 :                 table.color[i] = nix_vlan_tbl[i];
     865                 :            : 
     866                 :          0 :         rc = roc_nix_bpf_pre_color_tbl_setup(nix, mtr->bpf_id,
     867                 :          0 :                                              lvl_map[mtr->level], &table);
     868         [ #  # ]:          0 :         if (rc) {
     869                 :            :                 rte_mtr_error_set(error, rc, RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     870                 :            :                                   NULL, NULL);
     871                 :          0 :                 goto exit;
     872                 :            :         }
     873                 :            : 
     874         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
     875                 :          0 :                 dev->precolor_tbl[i] = nix_vlan_tbl[i];
     876                 :            : 
     877                 :          0 : exit:
     878                 :            :         return rc;
     879                 :            : }
     880                 :            : 
     881                 :            : static int
     882                 :          0 : cnxk_nix_mtr_in_proto_set(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     883                 :            :                           enum rte_mtr_color_in_protocol proto,
     884                 :            :                           uint32_t priority, struct rte_mtr_error *error)
     885                 :            : {
     886                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     887                 :            :         struct cnxk_meter_node *mtr;
     888                 :            : 
     889                 :            :         RTE_SET_USED(priority);
     890                 :            : 
     891                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     892         [ #  # ]:          0 :         if (mtr == NULL) {
     893                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     894                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     895                 :            :                                           "Meter object not found");
     896                 :            :         }
     897                 :            : 
     898                 :          0 :         dev->proto = proto;
     899                 :          0 :         return 0;
     900                 :            : }
     901                 :            : 
     902                 :            : static int
     903                 :          0 : cnxk_nix_mtr_in_proto_get(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     904                 :            :                           uint64_t *proto_mask, struct rte_mtr_error *error)
     905                 :            : {
     906                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     907                 :            :         struct cnxk_meter_node *mtr;
     908                 :            : 
     909                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     910         [ #  # ]:          0 :         if (mtr == NULL) {
     911                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     912                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     913                 :            :                                           "Meter object not found");
     914                 :            :         }
     915                 :            : 
     916                 :          0 :         *proto_mask = dev->proto;
     917                 :          0 :         return 0;
     918                 :            : }
     919                 :            : 
     920                 :            : static int
     921                 :          0 : cnxk_nix_mtr_in_proto_prio_get(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     922                 :            :                                enum rte_mtr_color_in_protocol proto,
     923                 :            :                                uint32_t *priority, struct rte_mtr_error *error)
     924                 :            : {
     925                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     926                 :            :         struct cnxk_meter_node *mtr;
     927                 :            : 
     928                 :            :         RTE_SET_USED(proto);
     929                 :            : 
     930                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     931         [ #  # ]:          0 :         if (mtr == NULL) {
     932                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     933                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     934                 :            :                                           "Meter object not found");
     935                 :            :         }
     936                 :            : 
     937                 :          0 :         plt_info("Only single priority supported i.e. 0");
     938                 :          0 :         *priority = 0;
     939                 :          0 :         return 0;
     940                 :            : }
     941                 :            : 
     942                 :            : static int
     943         [ #  # ]:          0 : cnxk_nix_mtr_stats_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     944                 :            :                           uint64_t stats_mask, struct rte_mtr_error *error)
     945                 :            : {
     946                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     947                 :            :         struct cnxk_meter_node *mtr;
     948                 :            : 
     949         [ #  # ]:          0 :         if (!stats_mask)
     950                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     951                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
     952                 :            :                                           "no bit is set to stats mask");
     953                 :            : 
     954                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     955         [ #  # ]:          0 :         if (mtr == NULL) {
     956                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     957                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     958                 :            :                                           "Meter object not found");
     959                 :            :         }
     960                 :            : 
     961                 :          0 :         mtr->params.stats_mask = stats_mask;
     962                 :          0 :         return 0;
     963                 :            : }
     964                 :            : 
     965                 :            : static int
     966         [ #  # ]:          0 : cnxk_nix_mtr_stats_read(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
     967                 :            :                         struct rte_mtr_stats *stats, uint64_t *stats_mask,
     968                 :            :                         int clear, struct rte_mtr_error *error)
     969                 :            : {
     970                 :            :         uint8_t yellow_pkt_pass, yellow_octs_pass, yellow_pkt_drop;
     971                 :            :         uint8_t green_octs_drop, yellow_octs_drop, red_octs_drop;
     972                 :            :         uint8_t green_pkt_pass, green_octs_pass, green_pkt_drop;
     973                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
     974                 :            :         uint8_t red_pkt_pass, red_octs_pass, red_pkt_drop;
     975                 :          0 :         uint64_t bpf_stats[ROC_NIX_BPF_STATS_MAX] = {0};
     976                 :            :         uint64_t mask = NIX_BPF_STATS_MASK_ALL;
     977                 :          0 :         struct roc_nix *nix = &dev->nix;
     978                 :            :         struct cnxk_meter_node *mtr;
     979                 :            :         int rc;
     980                 :            : 
     981         [ #  # ]:          0 :         if (!stats)
     982                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     983                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
     984                 :            :                                           "stats pointer is NULL");
     985                 :            : 
     986                 :            :         mtr = nix_mtr_find(dev, mtr_id);
     987         [ #  # ]:          0 :         if (mtr == NULL) {
     988                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     989                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
     990                 :            :                                           "Meter object not found");
     991                 :            :         }
     992                 :            : 
     993                 :          0 :         rc = roc_nix_bpf_stats_read(nix, mtr->bpf_id, mask, lvl_map[mtr->level],
     994                 :            :                                     bpf_stats);
     995         [ #  # ]:          0 :         if (rc) {
     996                 :            :                 rte_mtr_error_set(error, rc, RTE_MTR_ERROR_TYPE_UNSPECIFIED,
     997                 :            :                                   NULL, NULL);
     998                 :          0 :                 goto exit;
     999                 :            :         }
    1000                 :            : 
    1001                 :          0 :         green_pkt_pass = roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_GREEN_PKT_F_PASS);
    1002                 :            :         green_octs_pass =
    1003                 :          0 :                 roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_GREEN_OCTS_F_PASS);
    1004                 :          0 :         green_pkt_drop = roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_GREEN_PKT_F_DROP);
    1005                 :            :         green_octs_drop =
    1006                 :          0 :                 roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_GREEN_OCTS_F_DROP);
    1007                 :            :         yellow_pkt_pass =
    1008                 :          0 :                 roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_YELLOW_PKT_F_PASS);
    1009                 :            :         yellow_octs_pass =
    1010                 :          0 :                 roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_YELLOW_OCTS_F_PASS);
    1011                 :            :         yellow_pkt_drop =
    1012                 :          0 :                 roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_YELLOW_PKT_F_DROP);
    1013                 :            :         yellow_octs_drop =
    1014                 :          0 :                 roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_YELLOW_OCTS_F_DROP);
    1015                 :          0 :         red_pkt_pass = roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_RED_PKT_F_PASS);
    1016                 :          0 :         red_octs_pass = roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_RED_OCTS_F_PASS);
    1017                 :          0 :         red_pkt_drop = roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_RED_PKT_F_DROP);
    1018                 :          0 :         red_octs_drop = roc_nix_bpf_stats_to_idx(ROC_NIX_BPF_RED_OCTS_F_DROP);
    1019                 :            : 
    1020         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_PKTS_GREEN)
    1021                 :          0 :                 stats->n_pkts[RTE_COLOR_GREEN] = bpf_stats[green_pkt_pass];
    1022                 :            : 
    1023         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_PKTS_YELLOW)
    1024                 :          0 :                 stats->n_pkts[RTE_COLOR_YELLOW] = bpf_stats[yellow_pkt_pass];
    1025                 :            : 
    1026         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_PKTS_RED)
    1027                 :          0 :                 stats->n_pkts[RTE_COLOR_RED] = bpf_stats[red_pkt_pass];
    1028                 :            : 
    1029         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_BYTES_GREEN)
    1030                 :          0 :                 stats->n_bytes[RTE_COLOR_GREEN] = bpf_stats[green_octs_pass];
    1031                 :            : 
    1032         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_BYTES_YELLOW)
    1033                 :          0 :                 stats->n_bytes[RTE_COLOR_YELLOW] = bpf_stats[yellow_octs_pass];
    1034                 :            : 
    1035         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_BYTES_RED)
    1036                 :          0 :                 stats->n_bytes[RTE_COLOR_RED] = bpf_stats[red_octs_pass];
    1037                 :            : 
    1038         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_PKTS_DROPPED)
    1039                 :          0 :                 stats->n_pkts_dropped = bpf_stats[green_pkt_drop] +
    1040                 :          0 :                                         bpf_stats[yellow_pkt_drop] +
    1041                 :          0 :                                         bpf_stats[red_pkt_drop];
    1042                 :            : 
    1043         [ #  # ]:          0 :         if (mtr->params.stats_mask & RTE_MTR_STATS_N_BYTES_DROPPED)
    1044                 :          0 :                 stats->n_bytes_dropped = bpf_stats[green_octs_drop] +
    1045                 :          0 :                                          bpf_stats[yellow_octs_drop] +
    1046                 :          0 :                                          bpf_stats[red_octs_drop];
    1047                 :            : 
    1048         [ #  # ]:          0 :         if (stats_mask)
    1049                 :          0 :                 *stats_mask = mtr->params.stats_mask;
    1050                 :            : 
    1051         [ #  # ]:          0 :         if (clear) {
    1052                 :          0 :                 rc = roc_nix_bpf_stats_reset(nix, mtr->bpf_id, mask,
    1053                 :          0 :                                              lvl_map[mtr->level]);
    1054         [ #  # ]:          0 :                 if (rc) {
    1055                 :            :                         rte_mtr_error_set(error, rc,
    1056                 :            :                                           RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
    1057                 :            :                                           NULL);
    1058                 :          0 :                         goto exit;
    1059                 :            :                 }
    1060                 :            :         }
    1061                 :            : 
    1062                 :          0 : exit:
    1063                 :            :         return rc;
    1064                 :            : }
    1065                 :            : 
    1066                 :            : const struct rte_mtr_ops nix_mtr_ops = {
    1067                 :            :         .capabilities_get = cnxk_nix_mtr_capabilities_get,
    1068                 :            :         .meter_profile_add = cnxk_nix_mtr_profile_add,
    1069                 :            :         .meter_profile_delete = cnxk_nix_mtr_profile_delete,
    1070                 :            :         .meter_policy_validate = cnxk_nix_mtr_policy_validate,
    1071                 :            :         .meter_policy_add = cnxk_nix_mtr_policy_add,
    1072                 :            :         .meter_policy_delete = cnxk_nix_mtr_policy_delete,
    1073                 :            :         .create = cnxk_nix_mtr_create,
    1074                 :            :         .destroy = cnxk_nix_mtr_destroy,
    1075                 :            :         .meter_enable = cnxk_nix_mtr_enable,
    1076                 :            :         .meter_disable = cnxk_nix_mtr_disable,
    1077                 :            :         .meter_dscp_table_update = cnxk_nix_mtr_dscp_table_update,
    1078                 :            :         .meter_vlan_table_update = cnxk_nix_mtr_vlan_table_update,
    1079                 :            :         .in_proto_set = cnxk_nix_mtr_in_proto_set,
    1080                 :            :         .in_proto_get = cnxk_nix_mtr_in_proto_get,
    1081                 :            :         .in_proto_prio_get = cnxk_nix_mtr_in_proto_prio_get,
    1082                 :            :         .stats_update = cnxk_nix_mtr_stats_update,
    1083                 :            :         .stats_read = cnxk_nix_mtr_stats_read,
    1084                 :            : };
    1085                 :            : 
    1086                 :            : int
    1087                 :          0 : cnxk_nix_mtr_ops_get(struct rte_eth_dev *dev, void *ops)
    1088                 :            : {
    1089                 :            :         RTE_SET_USED(dev);
    1090                 :            : 
    1091                 :          0 :         *(const void **)ops = &nix_mtr_ops;
    1092                 :          0 :         return 0;
    1093                 :            : }
    1094                 :            : 
    1095                 :            : int
    1096                 :          0 : nix_mtr_validate(struct rte_eth_dev *eth_dev, uint32_t id)
    1097                 :            : {
    1098                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1099                 :            :         struct cnxk_mtr_profile_node *profile;
    1100                 :            :         struct cnxk_mtr_policy_node *policy;
    1101                 :            :         struct cnxk_meter_node *mtr;
    1102                 :            : 
    1103                 :            :         mtr = nix_mtr_find(dev, id);
    1104         [ #  # ]:          0 :         if (mtr == NULL)
    1105                 :            :                 return -EINVAL;
    1106                 :            : 
    1107                 :          0 :         profile = nix_mtr_profile_find(dev, mtr->params.meter_profile_id);
    1108         [ #  # ]:          0 :         if (profile == NULL)
    1109                 :            :                 return -EINVAL;
    1110                 :            : 
    1111                 :          0 :         policy = nix_mtr_policy_find(dev, mtr->params.meter_policy_id);
    1112         [ #  # ]:          0 :         if (policy == NULL)
    1113                 :          0 :                 return -EINVAL;
    1114                 :            : 
    1115                 :            :         return 0;
    1116                 :            : }
    1117                 :            : 
    1118                 :            : int
    1119                 :          0 : nix_mtr_policy_act_get(struct rte_eth_dev *eth_dev, uint32_t id,
    1120                 :            :                        struct cnxk_mtr_policy_node **policy_act)
    1121                 :            : {
    1122                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1123                 :            :         struct cnxk_mtr_policy_node *policy;
    1124                 :            :         struct cnxk_meter_node *mtr;
    1125                 :            : 
    1126                 :            :         mtr = nix_mtr_find(dev, id);
    1127         [ #  # ]:          0 :         if (mtr == NULL)
    1128                 :            :                 return -EINVAL;
    1129                 :            : 
    1130                 :          0 :         policy = nix_mtr_policy_find(dev, mtr->params.meter_policy_id);
    1131         [ #  # ]:          0 :         if (policy == NULL)
    1132                 :            :                 return -EINVAL;
    1133                 :            : 
    1134                 :          0 :         *policy_act = policy;
    1135                 :            : 
    1136                 :          0 :         return 0;
    1137                 :            : }
    1138                 :            : 
    1139                 :            : int
    1140                 :          0 : nix_mtr_rq_update(struct rte_eth_dev *eth_dev, uint32_t id, uint32_t queue_num,
    1141                 :            :                   const uint16_t *queue)
    1142                 :            : {
    1143                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1144                 :            :         struct cnxk_meter_node *mtr;
    1145                 :            :         uint32_t i;
    1146                 :            : 
    1147                 :            :         mtr = nix_mtr_find(dev, id);
    1148         [ #  # ]:          0 :         if (mtr == NULL)
    1149                 :            :                 return -EINVAL;
    1150                 :            : 
    1151                 :          0 :         mtr->rq_id = plt_zmalloc(queue_num * sizeof(uint32_t), ROC_ALIGN);
    1152         [ #  # ]:          0 :         if (mtr->rq_id == NULL)
    1153                 :            :                 return -ENOMEM;
    1154                 :            : 
    1155                 :          0 :         mtr->rq_num = queue_num;
    1156         [ #  # ]:          0 :         for (i = 0; i < queue_num; i++)
    1157                 :          0 :                 mtr->rq_id[i] = queue[i];
    1158                 :            : 
    1159                 :            :         return 0;
    1160                 :            : }
    1161                 :            : 
    1162                 :            : int
    1163                 :          0 : nix_mtr_chain_reset(struct rte_eth_dev *eth_dev, uint32_t cur_id)
    1164                 :            : {
    1165                 :          0 :         struct cnxk_meter_node *mtr[ROC_NIX_BPF_LEVEL_MAX] = {0};
    1166                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1167                 :            :         uint32_t mtr_id = cur_id;
    1168                 :            :         int i = 0, j = 0;
    1169                 :            : 
    1170         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {
    1171                 :          0 :                 mtr[i] = nix_mtr_find(dev, mtr_id);
    1172         [ #  # ]:          0 :                 if (mtr[i])
    1173                 :          0 :                         mtr_id = mtr[i]->next_id;
    1174                 :            :         }
    1175         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {
    1176         [ #  # ]:          0 :                 if (mtr[i]) {
    1177         [ #  # ]:          0 :                         for (j = 0; j < MAX_PRV_MTR_NODES; j++)
    1178                 :          0 :                                 mtr[i]->prev_id[i] = ROC_NIX_BPF_ID_INVALID;
    1179                 :          0 :                         mtr[i]->level = ROC_NIX_BPF_LEVEL_IDX_INVALID;
    1180                 :          0 :                         mtr[i]->next_id = ROC_NIX_BPF_ID_INVALID;
    1181                 :          0 :                         mtr[i]->is_next = false;
    1182                 :          0 :                         mtr[i]->prev_cnt = 0;
    1183                 :            :                 }
    1184                 :            :         }
    1185                 :          0 :         return 0;
    1186                 :            : }
    1187                 :            : 
    1188                 :            : int
    1189                 :          0 : nix_mtr_chain_update(struct rte_eth_dev *eth_dev, uint32_t cur_id,
    1190                 :            :                      uint32_t prev_id, uint32_t next_id)
    1191                 :            : {
    1192                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1193                 :            :         struct cnxk_meter_node *mtr;
    1194                 :            : 
    1195                 :            :         mtr = nix_mtr_find(dev, cur_id);
    1196         [ #  # ]:          0 :         if (mtr == NULL)
    1197                 :            :                 return -EINVAL;
    1198                 :            : 
    1199   [ #  #  #  # ]:          0 :         switch (lvl_map[mtr->level]) {
    1200                 :          0 :         case ROC_NIX_BPF_LEVEL_F_LEAF:
    1201                 :          0 :                 mtr->prev_id[mtr->prev_cnt] = ROC_NIX_BPF_ID_INVALID;
    1202                 :          0 :                 mtr->next_id = next_id;
    1203                 :          0 :                 mtr->is_next = true;
    1204                 :          0 :                 break;
    1205                 :          0 :         case ROC_NIX_BPF_LEVEL_F_MID:
    1206                 :          0 :                 mtr->prev_id[mtr->prev_cnt] = prev_id;
    1207                 :          0 :                 mtr->next_id = next_id;
    1208                 :          0 :                 mtr->is_next = true;
    1209                 :          0 :                 break;
    1210                 :          0 :         case ROC_NIX_BPF_LEVEL_F_TOP:
    1211                 :          0 :                 mtr->prev_id[mtr->prev_cnt] = prev_id;
    1212                 :          0 :                 mtr->next_id = ROC_NIX_BPF_ID_INVALID;
    1213                 :          0 :                 mtr->is_next = false;
    1214                 :          0 :                 break;
    1215                 :          0 :         default:
    1216                 :          0 :                 plt_err("Invalid meter level");
    1217                 :          0 :                 return -EINVAL;
    1218                 :            :         }
    1219                 :            : 
    1220                 :            :         return 0;
    1221                 :            : }
    1222                 :            : 
    1223                 :            : struct cnxk_meter_node *
    1224                 :          0 : nix_get_mtr(struct rte_eth_dev *eth_dev, uint32_t id)
    1225                 :            : {
    1226                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1227                 :            :         struct cnxk_meter_node *mtr;
    1228                 :            : 
    1229                 :            :         mtr = nix_mtr_find(dev, id);
    1230         [ #  # ]:          0 :         if (mtr == NULL)
    1231                 :          0 :                 return NULL;
    1232                 :            : 
    1233                 :            :         return mtr;
    1234                 :            : }
    1235                 :            : 
    1236                 :            : int
    1237                 :          0 : nix_mtr_level_update(struct rte_eth_dev *eth_dev, uint32_t id, uint32_t level)
    1238                 :            : {
    1239                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1240                 :            :         struct cnxk_meter_node *mtr;
    1241                 :            : 
    1242                 :            :         mtr = nix_mtr_find(dev, id);
    1243         [ #  # ]:          0 :         if (mtr == NULL)
    1244                 :            :                 return -EINVAL;
    1245                 :            : 
    1246                 :          0 :         mtr->level = level;
    1247                 :          0 :         return 0;
    1248                 :            : }
    1249                 :            : 
    1250                 :            : static void
    1251                 :          0 : nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)
    1252                 :            : {
    1253                 :          0 :         enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
    1254                 :            :                                               ROC_NIX_BPF_COLOR_YELLOW,
    1255                 :            :                                               ROC_NIX_BPF_COLOR_RED};
    1256                 :          0 :         enum roc_nix_bpf_algo alg_map[] = {
    1257                 :            :                 ROC_NIX_BPF_ALGO_NONE, ROC_NIX_BPF_ALGO_2697,
    1258                 :            :                 ROC_NIX_BPF_ALGO_2698, ROC_NIX_BPF_ALGO_4115};
    1259                 :          0 :         struct cnxk_mtr_profile_node *profile = mtr->profile;
    1260                 :          0 :         struct cnxk_mtr_policy_node *policy = mtr->policy;
    1261                 :            : 
    1262                 :          0 :         cfg->alg = alg_map[profile->profile.alg];
    1263                 :          0 :         cfg->lmode = profile->profile.packet_mode;
    1264                 :          0 :         cfg->icolor = color_map[mtr->params.default_input_color];
    1265                 :            : 
    1266                 :            :         switch (RTE_MTR_COLOR_IN_PROTO_OUTER_IP) {
    1267                 :            :         case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
    1268                 :          0 :                 cfg->pc_mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
    1269                 :          0 :                 cfg->tnl_ena = false;
    1270                 :            :                 break;
    1271                 :            :         case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
    1272                 :            :                 cfg->pc_mode = ROC_NIX_BPF_PC_MODE_DSCP_INNER;
    1273                 :            :                 cfg->tnl_ena = true;
    1274                 :            :                 break;
    1275                 :            :         case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
    1276                 :            :                 cfg->pc_mode = ROC_NIX_BPF_PC_MODE_VLAN_OUTER;
    1277                 :            :                 cfg->tnl_ena = false;
    1278                 :            :                 break;
    1279                 :            :         case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
    1280                 :            :                 cfg->pc_mode = ROC_NIX_BPF_PC_MODE_VLAN_INNER;
    1281                 :            :                 cfg->tnl_ena = true;
    1282                 :            :                 break;
    1283                 :            :         default:
    1284                 :            :                 break;
    1285                 :            :         }
    1286                 :            : 
    1287   [ #  #  #  # ]:          0 :         switch (cfg->alg) {
    1288                 :          0 :         case ROC_NIX_BPF_ALGO_2697:
    1289                 :          0 :                 cfg->algo2697.cir = profile->profile.srtcm_rfc2697.cir * 8;
    1290                 :          0 :                 cfg->algo2697.cbs = profile->profile.srtcm_rfc2697.cbs;
    1291                 :          0 :                 cfg->algo2697.ebs = profile->profile.srtcm_rfc2697.ebs;
    1292                 :          0 :                 break;
    1293                 :          0 :         case ROC_NIX_BPF_ALGO_2698:
    1294                 :          0 :                 cfg->algo2698.cir = profile->profile.trtcm_rfc2698.cir * 8;
    1295                 :          0 :                 cfg->algo2698.pir = profile->profile.trtcm_rfc2698.pir * 8;
    1296                 :          0 :                 cfg->algo2698.cbs = profile->profile.trtcm_rfc2698.cbs;
    1297                 :          0 :                 cfg->algo2698.pbs = profile->profile.trtcm_rfc2698.pbs;
    1298                 :          0 :                 break;
    1299                 :          0 :         case ROC_NIX_BPF_ALGO_4115:
    1300                 :          0 :                 cfg->algo4115.cir = profile->profile.trtcm_rfc4115.cir * 8;
    1301                 :          0 :                 cfg->algo4115.eir = profile->profile.trtcm_rfc4115.eir * 8;
    1302                 :          0 :                 cfg->algo4115.cbs = profile->profile.trtcm_rfc4115.cbs;
    1303                 :          0 :                 cfg->algo4115.ebs = profile->profile.trtcm_rfc4115.ebs;
    1304                 :          0 :                 break;
    1305                 :            :         default:
    1306                 :            :                 break;
    1307                 :            :         }
    1308                 :            : 
    1309                 :          0 :         cfg->action[ROC_NIX_BPF_COLOR_GREEN] = ROC_NIX_BPF_ACTION_PASS;
    1310                 :          0 :         cfg->action[ROC_NIX_BPF_COLOR_YELLOW] = ROC_NIX_BPF_ACTION_PASS;
    1311                 :          0 :         cfg->action[ROC_NIX_BPF_COLOR_RED] = ROC_NIX_BPF_ACTION_PASS;
    1312                 :            : 
    1313         [ #  # ]:          0 :         if (policy->actions[RTE_COLOR_GREEN].action_fate ==
    1314                 :            :             RTE_FLOW_ACTION_TYPE_DROP)
    1315                 :          0 :                 cfg->action[ROC_NIX_BPF_COLOR_GREEN] = ROC_NIX_BPF_ACTION_DROP;
    1316                 :            : 
    1317         [ #  # ]:          0 :         if (policy->actions[RTE_COLOR_YELLOW].action_fate ==
    1318                 :            :             RTE_FLOW_ACTION_TYPE_DROP)
    1319                 :          0 :                 cfg->action[ROC_NIX_BPF_COLOR_YELLOW] = ROC_NIX_BPF_ACTION_DROP;
    1320                 :            : 
    1321         [ #  # ]:          0 :         if (policy->actions[RTE_COLOR_RED].action_fate ==
    1322                 :            :             RTE_FLOW_ACTION_TYPE_DROP)
    1323                 :          0 :                 cfg->action[ROC_NIX_BPF_COLOR_RED] = ROC_NIX_BPF_ACTION_DROP;
    1324                 :          0 : }
    1325                 :            : 
    1326                 :            : static void
    1327                 :          0 : nix_mtr_config_red(struct cnxk_meter_node *mtr, struct roc_nix_rq *rq,
    1328                 :            :                    struct roc_nix_bpf_cfg *cfg)
    1329                 :            : {
    1330                 :          0 :         struct cnxk_mtr_policy_node *policy = mtr->policy;
    1331                 :            : 
    1332   [ #  #  #  # ]:          0 :         if ((rq->red_pass && rq->red_pass >= rq->red_drop) ||
    1333   [ #  #  #  # ]:          0 :            (rq->spb_red_pass && rq->spb_red_pass >= rq->spb_red_drop)       ||
    1334   [ #  #  #  # ]:          0 :            (rq->xqe_red_pass && rq->xqe_red_pass >= rq->xqe_red_drop)) {
    1335         [ #  # ]:          0 :                 if (policy->actions[RTE_COLOR_GREEN].action_fate ==
    1336                 :            :                         RTE_FLOW_ACTION_TYPE_DROP) {
    1337         [ #  # ]:          0 :                         if (policy->actions[RTE_COLOR_GREEN].skip_red)
    1338                 :          0 :                                 cfg->action[ROC_NIX_BPF_COLOR_GREEN] =
    1339                 :            :                                                 ROC_NIX_BPF_ACTION_DROP;
    1340                 :            :                         else
    1341                 :          0 :                                 cfg->action[ROC_NIX_BPF_COLOR_GREEN] =
    1342                 :            :                                                 ROC_NIX_BPF_ACTION_RED;
    1343                 :            :                 }
    1344         [ #  # ]:          0 :                 if (policy->actions[RTE_COLOR_YELLOW].action_fate ==
    1345                 :            :                         RTE_FLOW_ACTION_TYPE_DROP) {
    1346         [ #  # ]:          0 :                         if (policy->actions[RTE_COLOR_YELLOW].skip_red)
    1347                 :          0 :                                 cfg->action[ROC_NIX_BPF_COLOR_YELLOW] =
    1348                 :            :                                                 ROC_NIX_BPF_ACTION_DROP;
    1349                 :            :                         else
    1350                 :          0 :                                 cfg->action[ROC_NIX_BPF_COLOR_YELLOW] =
    1351                 :            :                                                 ROC_NIX_BPF_ACTION_RED;
    1352                 :            :                 }
    1353         [ #  # ]:          0 :                 if (policy->actions[RTE_COLOR_RED].action_fate ==
    1354                 :            :                         RTE_FLOW_ACTION_TYPE_DROP) {
    1355         [ #  # ]:          0 :                         if (policy->actions[RTE_COLOR_RED].skip_red)
    1356                 :          0 :                                 cfg->action[ROC_NIX_BPF_COLOR_RED] =
    1357                 :            :                                                 ROC_NIX_BPF_ACTION_DROP;
    1358                 :            :                         else
    1359                 :          0 :                                 cfg->action[ROC_NIX_BPF_COLOR_RED] =
    1360                 :            :                                                 ROC_NIX_BPF_ACTION_RED;
    1361                 :            :                 }
    1362                 :            :         }
    1363                 :          0 : }
    1364                 :            : 
    1365                 :            : static void
    1366                 :          0 : nix_precolor_table_map(struct cnxk_meter_node *mtr,
    1367                 :            :                        struct roc_nix_bpf_precolor *tbl,
    1368                 :            :                        enum rte_mtr_color_in_protocol proto)
    1369                 :            : {
    1370                 :          0 :         enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
    1371                 :            :                                               ROC_NIX_BPF_COLOR_YELLOW,
    1372                 :            :                                               ROC_NIX_BPF_COLOR_RED};
    1373                 :            :         int i;
    1374                 :            : 
    1375      [ #  #  # ]:          0 :         switch (proto) {
    1376                 :          0 :         case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
    1377                 :            :         case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
    1378                 :          0 :                 tbl->count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP;
    1379                 :          0 :                 tbl->mode = (proto == RTE_MTR_COLOR_IN_PROTO_OUTER_IP) ?
    1380         [ #  # ]:          0 :                                     ROC_NIX_BPF_PC_MODE_DSCP_OUTER :
    1381                 :            :                                     ROC_NIX_BPF_PC_MODE_DSCP_INNER;
    1382                 :            : 
    1383         [ #  # ]:          0 :                 for (i = 0; i < tbl->count; i++)
    1384                 :          0 :                         tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
    1385                 :            : 
    1386         [ #  # ]:          0 :                 if (mtr->params.dscp_table) {
    1387         [ #  # ]:          0 :                         for (i = 0; i < tbl->count; i++)
    1388                 :          0 :                                 tbl->color[i] =
    1389                 :          0 :                                         color_map[mtr->params.dscp_table[i]];
    1390                 :            :                 }
    1391                 :            :                 break;
    1392                 :          0 :         case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
    1393                 :            :         case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
    1394                 :          0 :                 tbl->count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN;
    1395                 :          0 :                 tbl->mode = (proto == RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN) ?
    1396                 :          0 :                                     ROC_NIX_BPF_PC_MODE_VLAN_OUTER :
    1397                 :            :                                     ROC_NIX_BPF_PC_MODE_VLAN_INNER;
    1398                 :            : 
    1399         [ #  # ]:          0 :                 for (i = 0; i < tbl->count; i++)
    1400                 :          0 :                         tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
    1401                 :            : 
    1402         [ #  # ]:          0 :                 if (mtr->params.vlan_table) {
    1403         [ #  # ]:          0 :                         for (i = 0; i < tbl->count; i++)
    1404                 :          0 :                                 tbl->color[i] =
    1405                 :          0 :                                         color_map[mtr->params.vlan_table[i]];
    1406                 :            :                 }
    1407                 :            :                 break;
    1408                 :            :         default:
    1409                 :            :                 break;
    1410                 :            :         }
    1411                 :          0 : }
    1412                 :            : 
    1413                 :            : int
    1414                 :          0 : nix_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t id,
    1415                 :            :                 struct rte_mtr_error *error)
    1416                 :            : {
    1417                 :          0 :         return cnxk_nix_mtr_destroy(eth_dev, id, error);
    1418                 :            : }
    1419                 :            : 
    1420                 :            : int
    1421                 :          0 : nix_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t id)
    1422                 :            : {
    1423                 :            :         enum roc_nix_bpf_level_flag lvl_flag = ROC_NIX_BPF_LEVEL_IDX_INVALID;
    1424                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1425                 :            :         struct cnxk_meter_node *base_mtr, *next_mtr;
    1426                 :          0 :         struct roc_nix *nix = &dev->nix;
    1427                 :            :         uint32_t cur_mtr_id = id;
    1428                 :            :         int rc, i;
    1429                 :            : 
    1430         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {
    1431                 :            :                 base_mtr = nix_mtr_find(dev, cur_mtr_id);
    1432         [ #  # ]:          0 :                 if (base_mtr) {
    1433                 :          0 :                         lvl_flag = lvl_map[base_mtr->level];
    1434         [ #  # ]:          0 :                         if (base_mtr->is_next) {
    1435                 :          0 :                                 next_mtr = nix_mtr_find(dev, base_mtr->next_id);
    1436         [ #  # ]:          0 :                                 if (next_mtr) {
    1437         [ #  # ]:          0 :                                         if (!base_mtr->is_used) {
    1438                 :          0 :                                                 rc = roc_nix_bpf_connect(nix,
    1439                 :            :                                                         lvl_flag,
    1440                 :          0 :                                                         base_mtr->bpf_id,
    1441                 :          0 :                                                         next_mtr->bpf_id);
    1442         [ #  # ]:          0 :                                                 if (rc)
    1443                 :          0 :                                                         return rc;
    1444                 :            :                                         }
    1445                 :            :                                 }
    1446                 :          0 :                                 cur_mtr_id = base_mtr->next_id;
    1447                 :            :                         }
    1448                 :            :                 }
    1449                 :            :         }
    1450                 :            :         return 0;
    1451                 :            : }
    1452                 :            : 
    1453                 :            : int
    1454                 :          0 : nix_mtr_configure(struct rte_eth_dev *eth_dev, uint32_t id)
    1455                 :            : {
    1456                 :          0 :         struct cnxk_meter_node *mtr[ROC_NIX_BPF_LEVEL_MAX] = {0};
    1457                 :            :         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
    1458                 :            :         struct roc_nix_bpf_objs profs[ROC_NIX_BPF_LEVEL_MAX];
    1459                 :            :         uint8_t idx0 = ROC_NIX_BPF_LEVEL_IDX_INVALID;
    1460                 :            :         uint8_t idx1 = ROC_NIX_BPF_LEVEL_IDX_INVALID;
    1461                 :            :         uint8_t idx2 = ROC_NIX_BPF_LEVEL_IDX_INVALID;
    1462                 :            :         uint16_t per_lvl_cnt[ROC_NIX_BPF_LEVEL_MAX];
    1463                 :          0 :         int num_mtr[ROC_NIX_BPF_LEVEL_MAX] = {0};
    1464                 :          0 :         struct roc_nix *nix = &dev->nix;
    1465                 :            :         struct roc_nix_bpf_precolor tbl;
    1466                 :            :         struct roc_nix_bpf_cfg cfg;
    1467                 :            :         struct roc_nix_rq *rq;
    1468                 :            :         uint8_t lvl_mask;
    1469                 :            :         uint32_t i;
    1470                 :            :         uint32_t j;
    1471                 :            :         int rc;
    1472                 :            : 
    1473                 :          0 :         mtr[0] = nix_mtr_find(dev, id);
    1474         [ #  # ]:          0 :         if (mtr[0] == NULL)
    1475                 :            :                 return -EINVAL;
    1476                 :            : 
    1477                 :          0 :         num_mtr[0] = 1;
    1478                 :          0 :         idx0 = roc_nix_bpf_level_to_idx(lvl_map[mtr[0]->level]);
    1479         [ #  # ]:          0 :         if (idx0 == ROC_NIX_BPF_LEVEL_IDX_INVALID)
    1480                 :            :                 return -EINVAL;
    1481                 :            : 
    1482                 :            :         lvl_mask = ROC_NIX_BPF_LEVEL_F_LEAF;
    1483         [ #  # ]:          0 :         if (mtr[0]->is_used)
    1484                 :          0 :                 per_lvl_cnt[idx0] = 0;
    1485                 :            :         else
    1486                 :          0 :                 per_lvl_cnt[idx0] = 1;
    1487                 :            : 
    1488         [ #  # ]:          0 :         if (mtr[0]->is_next) {
    1489                 :          0 :                 mtr[1] = nix_mtr_find(dev, mtr[0]->next_id);
    1490         [ #  # ]:          0 :                 if (mtr[1] == NULL)
    1491                 :            :                         return -EINVAL;
    1492                 :          0 :                 num_mtr[1] = 1;
    1493                 :          0 :                 idx1 = roc_nix_bpf_level_to_idx(lvl_map[mtr[1]->level]);
    1494         [ #  # ]:          0 :                 if (idx1 == ROC_NIX_BPF_LEVEL_IDX_INVALID)
    1495                 :            :                         return -EINVAL;
    1496                 :            : 
    1497                 :            :                 lvl_mask |= ROC_NIX_BPF_LEVEL_F_MID;
    1498         [ #  # ]:          0 :                 if (mtr[1]->is_used)
    1499                 :          0 :                         per_lvl_cnt[idx1] = 0;
    1500                 :            :                 else
    1501                 :          0 :                         per_lvl_cnt[idx1] = 1;
    1502                 :            :         }
    1503                 :            : 
    1504   [ #  #  #  # ]:          0 :         if (mtr[1] && mtr[1]->is_next) {
    1505                 :          0 :                 mtr[2] = nix_mtr_find(dev, mtr[1]->next_id);
    1506         [ #  # ]:          0 :                 if (mtr[2] == NULL)
    1507                 :            :                         return -EINVAL;
    1508                 :            : 
    1509                 :          0 :                 num_mtr[2] = 1;
    1510                 :          0 :                 idx2 = roc_nix_bpf_level_to_idx(lvl_map[mtr[2]->level]);
    1511         [ #  # ]:          0 :                 if (idx2 == ROC_NIX_BPF_LEVEL_IDX_INVALID)
    1512                 :            :                         return -EINVAL;
    1513                 :            : 
    1514                 :          0 :                 lvl_mask |= ROC_NIX_BPF_LEVEL_F_TOP;
    1515         [ #  # ]:          0 :                 if (mtr[2]->is_used)
    1516                 :          0 :                         per_lvl_cnt[idx2] = 0;
    1517                 :            :                 else
    1518                 :          0 :                         per_lvl_cnt[idx2] = 1;
    1519                 :            :         }
    1520                 :            : 
    1521                 :          0 :         rc = roc_nix_bpf_alloc(nix, lvl_mask, per_lvl_cnt, profs);
    1522         [ #  # ]:          0 :         if (rc)
    1523                 :            :                 return rc;
    1524         [ #  # ]:          0 :         if (mtr[0]->bpf_id == ROC_NIX_BPF_ID_INVALID)
    1525                 :          0 :                 mtr[0]->bpf_id = profs[idx0].ids[0];
    1526                 :            : 
    1527                 :            :         if (num_mtr[0])
    1528   [ #  #  #  # ]:          0 :                 if (mtr[0]->is_next && idx1 != ROC_NIX_BPF_LEVEL_IDX_INVALID)
    1529         [ #  # ]:          0 :                         if (mtr[1]->bpf_id == ROC_NIX_BPF_ID_INVALID)
    1530                 :          0 :                                 mtr[1]->bpf_id = profs[idx1].ids[0];
    1531                 :            : 
    1532         [ #  # ]:          0 :         if (num_mtr[1])
    1533   [ #  #  #  # ]:          0 :                 if (mtr[1]->is_next && idx2 != ROC_NIX_BPF_LEVEL_IDX_INVALID)
    1534         [ #  # ]:          0 :                         if (mtr[2]->bpf_id == ROC_NIX_BPF_ID_INVALID)
    1535                 :          0 :                                 mtr[2]->bpf_id = profs[idx2].ids[0];
    1536                 :            : 
    1537         [ #  # ]:          0 :         for (i = 0; i < ROC_NIX_BPF_LEVEL_MAX; i++) {
    1538         [ #  # ]:          0 :                 if (num_mtr[i]) {
    1539         [ #  # ]:          0 :                         if (!mtr[i]->is_used) {
    1540                 :            :                                 memset(&cfg, 0, sizeof(struct roc_nix_bpf_cfg));
    1541                 :          0 :                                 nix_mtr_config_map(mtr[i], &cfg);
    1542         [ #  # ]:          0 :                                 for (j = 0; j < mtr[i]->rq_num; j++) {
    1543                 :          0 :                                         rq = &dev->rqs[mtr[i]->rq_id[j]];
    1544                 :          0 :                                         nix_mtr_config_red(mtr[i], rq, &cfg);
    1545                 :            :                                 }
    1546                 :          0 :                                 rc = roc_nix_bpf_config(nix, mtr[i]->bpf_id,
    1547                 :          0 :                                                         lvl_map[mtr[i]->level],
    1548                 :            :                                                         &cfg);
    1549                 :            : 
    1550                 :            :                                 memset(&tbl, 0,
    1551                 :            :                                        sizeof(struct roc_nix_bpf_precolor));
    1552                 :          0 :                                 nix_precolor_table_map(mtr[i], &tbl,
    1553                 :            :                                                        dev->proto);
    1554                 :          0 :                                 rc = roc_nix_bpf_pre_color_tbl_setup(nix,
    1555                 :          0 :                                         mtr[i]->bpf_id, lvl_map[mtr[i]->level],
    1556                 :            :                                         &tbl);
    1557                 :            : 
    1558         [ #  # ]:          0 :                                 if (mtr[i]->params.meter_enable) {
    1559         [ #  # ]:          0 :                                         for (j = 0; j < mtr[i]->rq_num; j++) {
    1560                 :          0 :                                                 rq = &dev->rqs[mtr[i]->rq_id
    1561                 :          0 :                                                                        [j]];
    1562                 :          0 :                                                 rc = roc_nix_bpf_ena_dis(nix,
    1563                 :          0 :                                                         mtr[i]->bpf_id, rq,
    1564                 :            :                                                         true);
    1565                 :            :                                         }
    1566                 :            :                                 }
    1567                 :            :                         }
    1568                 :            :                 }
    1569                 :            :         }
    1570                 :            : 
    1571                 :            :         return rc;
    1572                 :            : }
    1573                 :            : 
    1574                 :            : int
    1575                 :          0 : nix_mtr_color_action_validate(struct rte_eth_dev *eth_dev, uint32_t id,
    1576                 :            :                               uint32_t *prev_id, uint32_t *next_id,
    1577                 :            :                               struct cnxk_mtr_policy_node *policy,
    1578                 :            :                               int *tree_level)
    1579                 :            : {
    1580                 :          0 :         uint32_t action_fate_red = policy->actions[RTE_COLOR_RED].action_fate;
    1581                 :          0 :         uint32_t action_fate_green =
    1582                 :            :                 policy->actions[RTE_COLOR_GREEN].action_fate;
    1583                 :          0 :         uint32_t action_fate_yellow =
    1584                 :            :                 policy->actions[RTE_COLOR_YELLOW].action_fate;
    1585                 :          0 :         uint32_t cur_mtr_id = *next_id;
    1586                 :            :         uint32_t next_mtr_id = 0xffff;
    1587                 :            :         uint32_t prev_mtr_id = 0xffff;
    1588                 :            :         struct cnxk_meter_node *mtr;
    1589                 :            : 
    1590         [ #  # ]:          0 :         if (action_fate_green == RTE_FLOW_ACTION_TYPE_METER)
    1591                 :          0 :                 next_mtr_id = policy->actions[RTE_COLOR_GREEN].mtr_id;
    1592                 :            : 
    1593         [ #  # ]:          0 :         if (action_fate_yellow == RTE_FLOW_ACTION_TYPE_METER)
    1594                 :          0 :                 next_mtr_id = policy->actions[RTE_COLOR_YELLOW].mtr_id;
    1595                 :            : 
    1596         [ #  # ]:          0 :         if (action_fate_red == RTE_FLOW_ACTION_TYPE_METER)
    1597                 :          0 :                 next_mtr_id = policy->actions[RTE_COLOR_RED].mtr_id;
    1598                 :            : 
    1599         [ #  # ]:          0 :         if (next_mtr_id != 0xffff) {
    1600   [ #  #  #  # ]:          0 :                 switch (*tree_level) {
    1601                 :          0 :                 case 0:
    1602                 :          0 :                         mtr = nix_get_mtr(eth_dev, cur_mtr_id);
    1603         [ #  # ]:          0 :                         if (mtr == NULL)
    1604                 :            :                                 return -EINVAL;
    1605         [ #  # ]:          0 :                         if (mtr->level == ROC_NIX_BPF_LEVEL_IDX_INVALID) {
    1606                 :          0 :                                 nix_mtr_level_update(eth_dev, cur_mtr_id, 0);
    1607                 :          0 :                                 nix_mtr_chain_update(eth_dev, cur_mtr_id, -1,
    1608                 :            :                                                      next_mtr_id);
    1609                 :            :                         } else {
    1610         [ #  # ]:          0 :                                 if (mtr->level == 0)
    1611                 :          0 :                                         mtr->is_used = true;
    1612                 :            :                                 else
    1613                 :            :                                         return -EINVAL;
    1614                 :            :                         }
    1615                 :          0 :                         (*tree_level)++;
    1616                 :          0 :                         *next_id = next_mtr_id;
    1617                 :          0 :                         break;
    1618                 :          0 :                 case 1:
    1619                 :          0 :                         mtr = nix_get_mtr(eth_dev, cur_mtr_id);
    1620         [ #  # ]:          0 :                         if (mtr == NULL)
    1621                 :            :                                 return -EINVAL;
    1622         [ #  # ]:          0 :                         if (mtr->level == ROC_NIX_BPF_LEVEL_IDX_INVALID) {
    1623                 :          0 :                                 nix_mtr_level_update(eth_dev, cur_mtr_id, 1);
    1624                 :            :                                 prev_mtr_id = id;
    1625                 :          0 :                                 nix_mtr_chain_update(eth_dev, cur_mtr_id,
    1626                 :            :                                                      prev_mtr_id, next_mtr_id);
    1627                 :            :                         } else {
    1628         [ #  # ]:          0 :                                 if (mtr->level == 1) {
    1629                 :          0 :                                         mtr->prev_cnt++;
    1630                 :            :                                         prev_mtr_id = id;
    1631                 :          0 :                                         nix_mtr_chain_update(eth_dev,
    1632                 :            :                                                 cur_mtr_id, prev_mtr_id,
    1633                 :            :                                                 next_mtr_id);
    1634                 :            : 
    1635                 :          0 :                                         mtr->is_used = true;
    1636                 :            :                                 } else {
    1637                 :            :                                         return -EINVAL;
    1638                 :            :                                 }
    1639                 :            :                         }
    1640                 :          0 :                         (*tree_level)++;
    1641                 :          0 :                         *next_id = next_mtr_id;
    1642                 :          0 :                         *prev_id = cur_mtr_id;
    1643                 :          0 :                         break;
    1644                 :          0 :                 case 2:
    1645                 :          0 :                         nix_mtr_chain_reset(eth_dev, id);
    1646                 :          0 :                         return -EINVAL;
    1647                 :            :                 }
    1648                 :            :         } else {
    1649   [ #  #  #  # ]:          0 :                 switch (*tree_level) {
    1650                 :          0 :                 case 0:
    1651                 :          0 :                         mtr = nix_get_mtr(eth_dev, cur_mtr_id);
    1652         [ #  # ]:          0 :                         if (mtr == NULL)
    1653                 :            :                                 return -EINVAL;
    1654         [ #  # ]:          0 :                         if (mtr->level == ROC_NIX_BPF_LEVEL_IDX_INVALID) {
    1655                 :          0 :                                 nix_mtr_level_update(eth_dev, cur_mtr_id, 0);
    1656                 :            :                         } else {
    1657         [ #  # ]:          0 :                                 if (mtr->level == 0)
    1658                 :          0 :                                         mtr->is_used = true;
    1659                 :            :                                 else
    1660                 :            :                                         return -EINVAL;
    1661                 :            :                         }
    1662                 :            :                         break;
    1663                 :          0 :                 case 1:
    1664                 :          0 :                         mtr = nix_get_mtr(eth_dev, cur_mtr_id);
    1665         [ #  # ]:          0 :                         if (mtr == NULL)
    1666                 :            :                                 return -EINVAL;
    1667         [ #  # ]:          0 :                         if (mtr->level == ROC_NIX_BPF_LEVEL_IDX_INVALID) {
    1668                 :          0 :                                 nix_mtr_level_update(eth_dev, cur_mtr_id, 1);
    1669                 :            :                                 prev_mtr_id = id;
    1670                 :          0 :                                 nix_mtr_chain_update(eth_dev, cur_mtr_id,
    1671                 :            :                                                      prev_mtr_id, -1);
    1672                 :            :                         } else {
    1673         [ #  # ]:          0 :                                 if (mtr->level == 1) {
    1674                 :          0 :                                         mtr->prev_cnt++;
    1675                 :            :                                         prev_mtr_id = id;
    1676                 :          0 :                                         nix_mtr_chain_update(eth_dev,
    1677                 :            :                                                              cur_mtr_id,
    1678                 :            :                                                              prev_mtr_id, -1);
    1679                 :          0 :                                         mtr->is_used = true;
    1680                 :            :                                 } else {
    1681                 :            :                                         return -EINVAL;
    1682                 :            :                                 }
    1683                 :            :                         }
    1684                 :            :                         break;
    1685                 :          0 :                 case 2:
    1686                 :          0 :                         mtr = nix_get_mtr(eth_dev, cur_mtr_id);
    1687         [ #  # ]:          0 :                         if (mtr == NULL)
    1688                 :            :                                 return -EINVAL;
    1689         [ #  # ]:          0 :                         if (mtr->level == ROC_NIX_BPF_LEVEL_IDX_INVALID) {
    1690                 :          0 :                                 nix_mtr_level_update(eth_dev, cur_mtr_id, 2);
    1691                 :          0 :                                 prev_mtr_id = *prev_id;
    1692                 :          0 :                                 nix_mtr_chain_update(eth_dev, cur_mtr_id,
    1693                 :            :                                                      prev_mtr_id, -1);
    1694                 :            :                         } else {
    1695         [ #  # ]:          0 :                                 if (mtr->level == 2) {
    1696                 :          0 :                                         mtr->prev_cnt++;
    1697                 :          0 :                                         prev_mtr_id = *prev_id;
    1698                 :          0 :                                         nix_mtr_chain_update(eth_dev,
    1699                 :            :                                                              cur_mtr_id,
    1700                 :            :                                                              prev_mtr_id, -1);
    1701                 :          0 :                                         mtr->is_used = true;
    1702                 :            :                                 } else {
    1703                 :            :                                         return -EINVAL;
    1704                 :            :                                 }
    1705                 :            :                         }
    1706                 :            :                         break;
    1707                 :            :                 }
    1708                 :          0 :                 *next_id = 0xffff;
    1709                 :            :         }
    1710                 :            : 
    1711                 :            :         return 0;
    1712                 :            : }
    1713                 :            : 
    1714                 :            : int
    1715                 :          0 : nix_mtr_capabilities_init(struct rte_eth_dev *eth_dev)
    1716                 :            : {
    1717                 :            :         struct rte_mtr_capabilities capa;
    1718                 :            :         struct rte_mtr_error error;
    1719                 :            : 
    1720                 :          0 :         return cnxk_nix_mtr_capabilities_get(eth_dev, &capa, &error);
    1721                 :            : }

Generated by: LCOV version 1.14