LCOV - code coverage report
Current view: top level - drivers/net/zxdh - zxdh_mtr.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 464 0.0 %
Date: 2025-07-01 21:32:37 Functions: 0 36 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 284 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2024 ZTE Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <bus_pci_driver.h>
       6                 :            : #include <rte_ethdev.h>
       7                 :            : #include <rte_mtr_driver.h>
       8                 :            : #include <rte_mempool.h>
       9                 :            : 
      10                 :            : #include "zxdh_logs.h"
      11                 :            : #include "zxdh_mtr.h"
      12                 :            : #include "zxdh_msg.h"
      13                 :            : #include "zxdh_ethdev.h"
      14                 :            : #include "zxdh_tables.h"
      15                 :            : 
      16                 :            : #define ZXDH_SHARE_FLOW_MAX       2048
      17                 :            : #define ZXDH_HW_PROFILE_MAX       512
      18                 :            : #define ZXDH_MAX_MTR_PROFILE_NUM  ZXDH_HW_PROFILE_MAX
      19                 :            : #define ZXDH_PORT_MTR_FID_BASE    8192
      20                 :            : 
      21                 :            : /*  Maximum value of srTCM metering parameters, unit_step: 64kb
      22                 :            :  *  61K~400000000(400G) bps, uint 64Kbps CBS/EBS/PBS max bucket depth 128MB
      23                 :            :  *  PPS: 1pps~600Mpps
      24                 :            :  */
      25                 :            : #define ZXDH_SRTCM_CIR_MIN_BPS  (61 * (1ULL << 10))
      26                 :            : #define ZXDH_SRTCM_CIR_MAX_BPS  (400 * (1ULL << 30))
      27                 :            : #define ZXDH_SRTCM_EBS_MAX_B    (128 * (1ULL << 20))
      28                 :            : #define ZXDH_SRTCM_CBS_MAX_B    (128 * (1ULL << 20))
      29                 :            : #define ZXDH_TRTCM_PBS_MAX_B    (128 * (1ULL << 20))
      30                 :            : #define ZXDH_TRTCM_PIR_MAX_BPS  (400 * (1ULL << 30))
      31                 :            : #define ZXDH_TRTCM_PIR_MIN_BPS  (61 * (1ULL << 10))
      32                 :            : 
      33                 :            : #define ZXDH_SRTCM_CIR_MIN_PPS  (1)
      34                 :            : #define ZXDH_SRTCM_CIR_MAX_PPS  (200 * (1ULL << 20))
      35                 :            : #define ZXDH_SRTCM_CBS_MAX_P    (8192)
      36                 :            : #define ZXDH_SRTCM_EBS_MAX_P    (8192)
      37                 :            : #define ZXDH_TRTCM_PBS_MAX_P    (8192)
      38                 :            : #define ZXDH_TRTCM_PIR_MIN_PPS  (1)
      39                 :            : #define ZXDH_TRTCM_PIR_MAX_PPS  (200 * (1ULL << 20))
      40                 :            : 
      41                 :            : #define ZXDH_MP_ALLOC_OBJ_FUNC(mp, obj) rte_mempool_get(mp, (void **)&(obj))
      42                 :            : #define ZXDH_MP_FREE_OBJ_FUNC(mp, obj) rte_mempool_put(mp, obj)
      43                 :            : 
      44                 :            : #define ZXDH_VFUNC_ACTIVE_BIT  11
      45                 :            : #define ZXDH_VFUNC_NUM_MASK    0xff
      46                 :            : #define ZXDH_GET_OWNER_PF_VPORT(vport) \
      47                 :            :         (((vport) & ~(ZXDH_VFUNC_NUM_MASK)) & (~(1 << ZXDH_VFUNC_ACTIVE_BIT)))
      48                 :            : 
      49                 :            : enum ZXDH_PLCR_CD {
      50                 :            :         ZXDH_PLCR_CD_SRTCM = 0,
      51                 :            :         ZXDH_PLCR_CD_TRTCM,
      52                 :            :         ZXDH_PLCR_CD_MEF101,
      53                 :            : };
      54                 :            : enum ZXDH_PLCR_CM {
      55                 :            :         ZXDH_PLCR_CM_BLIND = 0,
      56                 :            :         ZXDH_PLCR_CM_AWARE,
      57                 :            : };
      58                 :            : enum ZXDH_PLCR_CF {
      59                 :            :         ZXDH_PLCR_CF_UNOVERFLOW = 0,
      60                 :            :         ZXDH_PLCR_CF_OVERFLOW,
      61                 :            : };
      62                 :            : 
      63                 :            : int
      64                 :          0 : zxdh_hw_profile_ref(uint16_t hw_profile_id)
      65                 :            : {
      66         [ #  # ]:          0 :         if (hw_profile_id >= HW_PROFILE_MAX)
      67                 :            :                 return  -1;
      68                 :            : 
      69                 :            :         rte_spinlock_lock(&g_mtr_res.hw_plcr_res_lock);
      70                 :          0 :         g_mtr_res.hw_profile_refcnt[hw_profile_id]++;
      71                 :            :         rte_spinlock_unlock(&g_mtr_res.hw_plcr_res_lock);
      72                 :          0 :         return 0;
      73                 :            : }
      74                 :            : 
      75                 :            : static struct zxdh_meter_policy
      76                 :            : *zxdh_mtr_policy_find_by_id(struct zxdh_mtr_policy_list *mtr_policy_list,
      77                 :            :         uint16_t policy_id, uint16_t dpdk_portid)
      78                 :            : {
      79                 :            :         struct zxdh_meter_policy *mtr_policy = NULL;
      80                 :            : 
      81   [ #  #  #  #  :          0 :         TAILQ_FOREACH(mtr_policy, mtr_policy_list, next) {
                   #  # ]
      82   [ #  #  #  #  :          0 :                 if (policy_id == mtr_policy->policy_id &&
                   #  # ]
      83   [ #  #  #  #  :          0 :                         dpdk_portid == mtr_policy->dpdk_port_id)
                   #  # ]
      84                 :            :                         return mtr_policy;
      85                 :            :         }
      86                 :            :         return NULL;
      87                 :            : }
      88                 :            : 
      89                 :            : static int
      90                 :            : zxdh_policy_validate_actions(const struct rte_flow_action *actions[RTE_COLORS],
      91                 :            :         struct rte_mtr_error *error)
      92                 :            : {
      93   [ #  #  #  # ]:          0 :         if (!actions[RTE_COLOR_RED] || actions[RTE_COLOR_RED]->type != RTE_FLOW_ACTION_TYPE_DROP)
      94                 :            :                 return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_POLICY, NULL,
      95                 :            :                         "Red color only supports drop action.");
      96                 :            :         return 0;
      97                 :            : }
      98                 :            : 
      99                 :            : static int
     100                 :          0 : mtr_hw_stats_get(struct zxdh_hw *hw, uint8_t direction, struct zxdh_hw_mtr_stats *hw_mtr_stats)
     101                 :            : {
     102                 :          0 :         union zxdh_virport_num v_port = hw->vport;
     103                 :            :         uint32_t stat_baseaddr = (direction == ZXDH_EGRESS)
     104                 :            :                 ? ZXDH_MTR_STATS_EGRESS_BASE
     105         [ #  # ]:          0 :                 : ZXDH_MTR_STATS_INGRESS_BASE;
     106                 :          0 :         uint32_t idx = zxdh_vport_to_vfid(v_port) + stat_baseaddr;
     107                 :          0 :         struct zxdh_dtb_shared_data *dtb_sd = &hw->dev_sd->dtb_sd;
     108                 :            : 
     109                 :          0 :         int ret = zxdh_np_dtb_stats_get(hw->dev_id,
     110                 :          0 :                 dtb_sd->queueid, ZXDH_STAT_128_MODE,
     111                 :            :                 idx, (uint32_t *)hw_mtr_stats);
     112                 :            : 
     113         [ #  # ]:          0 :         if (ret) {
     114                 :          0 :                 PMD_DRV_LOG(ERR, "get vport 0x%x (vfid 0x%x) dir %u stats failed",
     115                 :            :                                 v_port.vport,
     116                 :            :                                 hw->vfid,
     117                 :            :                                 direction);
     118                 :          0 :                 return ret;
     119                 :            :         }
     120                 :          0 :         PMD_DRV_LOG(INFO, "get vport 0x%x (vfid 0x%x) dir %u stats",
     121                 :            :                         v_port.vport,
     122                 :            :                         hw->vfid,
     123                 :            :                         direction);
     124                 :          0 :         return 0;
     125                 :            : }
     126                 :            : 
     127                 :            : static int
     128                 :          0 : zxdh_mtr_stats_get(struct rte_eth_dev *dev, int dir, struct zxdh_mtr_stats *mtr_stats)
     129                 :            : {
     130                 :          0 :         struct zxdh_hw_mtr_stats hw_mtr_stat = {0};
     131                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     132                 :          0 :         int ret = mtr_hw_stats_get(hw, dir, &hw_mtr_stat);
     133                 :            : 
     134         [ #  # ]:          0 :         if (ret) {
     135                 :          0 :                 PMD_DRV_LOG(ERR, "port %u dir %u get mtr stats failed", hw->vport.vport, dir);
     136                 :          0 :                 return ret;
     137                 :            :         }
     138                 :          0 :         mtr_stats->n_bytes_dropped =
     139                 :          0 :                 (uint64_t)(rte_le_to_cpu_32(hw_mtr_stat.n_bytes_dropped_hi)) << 32 |
     140                 :          0 :                 rte_le_to_cpu_32(hw_mtr_stat.n_bytes_dropped_lo);
     141                 :          0 :         mtr_stats->n_pkts_dropped =
     142                 :          0 :                 (uint64_t)(rte_le_to_cpu_32(hw_mtr_stat.n_pkts_dropped_hi)) << 32 |
     143                 :          0 :                 rte_le_to_cpu_32(hw_mtr_stat.n_pkts_dropped_lo);
     144                 :            : 
     145                 :          0 :         return 0;
     146                 :            : }
     147                 :            : 
     148                 :            : static int
     149                 :          0 : zxdh_meter_cap_get(struct rte_eth_dev *dev __rte_unused,
     150                 :            :         struct rte_mtr_capabilities *cap,
     151                 :            :         struct rte_mtr_error *error __rte_unused)
     152                 :            : {
     153                 :            :         struct rte_mtr_capabilities capa = {
     154                 :            :                 .n_max = ZXDH_MAX_MTR_NUM,
     155                 :            :                 .n_shared_max = ZXDH_SHARE_FLOW_MAX,
     156                 :            :                 .meter_srtcm_rfc2697_n_max = ZXDH_MAX_MTR_PROFILE_NUM,
     157                 :            :                 .meter_trtcm_rfc2698_n_max = ZXDH_MAX_MTR_PROFILE_NUM,
     158                 :            :                 .color_aware_srtcm_rfc2697_supported = 1,
     159                 :            :                 .color_aware_trtcm_rfc2698_supported = 1,
     160                 :            :                 .meter_rate_max = ZXDH_SRTCM_CIR_MAX_BPS,
     161                 :            :                 .meter_policy_n_max = ZXDH_MAX_POLICY_NUM,
     162                 :            :                 .srtcm_rfc2697_byte_mode_supported   = 1,
     163                 :            :                 .srtcm_rfc2697_packet_mode_supported = 1,
     164                 :            :                 .trtcm_rfc2698_byte_mode_supported   = 1,
     165                 :            :                 .trtcm_rfc2698_packet_mode_supported = 1,
     166                 :            :                 .stats_mask = RTE_MTR_STATS_N_PKTS_DROPPED | RTE_MTR_STATS_N_BYTES_DROPPED,
     167                 :            :         };
     168                 :            : 
     169                 :          0 :         *cap = capa;
     170                 :          0 :         return 0;
     171                 :            : }
     172                 :            : 
     173                 :            : static int
     174                 :          0 : zxdh_mtr_profile_validate(uint32_t meter_profile_id,
     175                 :            :                 struct rte_mtr_meter_profile *profile,
     176                 :            :                 struct rte_mtr_error *error)
     177                 :            : {
     178                 :            :         uint64_t cir_min, cir_max, cbs_max, ebs_max, pir_min, pir_max, pbs_max;
     179                 :            : 
     180         [ #  # ]:          0 :         if (profile == NULL || meter_profile_id >= ZXDH_MAX_MTR_PROFILE_NUM) {
     181                 :          0 :                 return -rte_mtr_error_set(error, EINVAL, RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     182                 :            :                         "Meter profile param id invalid or null");
     183                 :            :         }
     184                 :            : 
     185         [ #  # ]:          0 :         if (profile->packet_mode == 0) {
     186                 :            :                 cir_min = ZXDH_SRTCM_CIR_MIN_BPS / 8;
     187                 :            :                 cir_max = ZXDH_SRTCM_CIR_MAX_BPS / 8;
     188                 :            :                 cbs_max = ZXDH_SRTCM_CBS_MAX_B;
     189                 :            :                 ebs_max = ZXDH_SRTCM_EBS_MAX_B;
     190                 :            :                 pir_min = ZXDH_TRTCM_PIR_MIN_BPS / 8;
     191                 :            :                 pir_max = ZXDH_TRTCM_PIR_MAX_BPS / 8;
     192                 :            :                 pbs_max = ZXDH_TRTCM_PBS_MAX_B;
     193                 :            :         } else {
     194                 :            :                 cir_min = ZXDH_SRTCM_CIR_MIN_PPS;
     195                 :            :                 cir_max = ZXDH_SRTCM_CIR_MAX_PPS;
     196                 :            :                 cbs_max = ZXDH_SRTCM_CBS_MAX_P;
     197                 :            :                 ebs_max = ZXDH_SRTCM_EBS_MAX_P;
     198                 :            :                 pir_min = ZXDH_TRTCM_PIR_MIN_PPS;
     199                 :            :                 pir_max = ZXDH_TRTCM_PIR_MAX_PPS;
     200                 :            :                 pbs_max = ZXDH_TRTCM_PBS_MAX_P;
     201                 :            :         }
     202         [ #  # ]:          0 :         if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
     203   [ #  #  #  # ]:          0 :                 if (profile->srtcm_rfc2697.cir >= cir_min &&
     204                 :          0 :                         profile->srtcm_rfc2697.cir < cir_max &&
     205   [ #  #  #  # ]:          0 :                         profile->srtcm_rfc2697.cbs < cbs_max &&
     206                 :          0 :                         profile->srtcm_rfc2697.cbs > 0 &&
     207   [ #  #  #  # ]:          0 :                         profile->srtcm_rfc2697.ebs > 0 &&
     208                 :            :                         profile->srtcm_rfc2697.ebs < ebs_max) {
     209                 :          0 :                         goto check_exist;
     210                 :            :                 } else {
     211                 :          0 :                         return -rte_mtr_error_set
     212                 :            :                                         (error, ENOTSUP,
     213                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
     214                 :            :                                         NULL,
     215                 :            :                                         "Invalid metering parameters");
     216                 :            :                 }
     217         [ #  # ]:          0 :         } else if (profile->alg == RTE_MTR_TRTCM_RFC2698) {
     218   [ #  #  #  # ]:          0 :                 if (profile->trtcm_rfc2698.cir >= cir_min &&
     219                 :          0 :                         profile->trtcm_rfc2698.cir < cir_max &&
     220   [ #  #  #  # ]:          0 :                         profile->trtcm_rfc2698.cbs < cbs_max &&
     221                 :          0 :                         profile->trtcm_rfc2698.cbs > 0 &&
     222   [ #  #  #  # ]:          0 :                         profile->trtcm_rfc2698.pir >= pir_min &&
     223         [ #  # ]:          0 :                         profile->trtcm_rfc2698.pir < pir_max &&
     224                 :          0 :                         profile->trtcm_rfc2698.cir < profile->trtcm_rfc2698.pir &&
     225   [ #  #  #  # ]:          0 :                         profile->trtcm_rfc2698.pbs > 0 &&
     226                 :            :                         profile->trtcm_rfc2698.pbs < pbs_max)
     227                 :          0 :                         goto check_exist;
     228                 :            :                 else
     229                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     230                 :            :                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
     231                 :            :                                 NULL,
     232                 :            :                                 "Invalid metering parameters");
     233                 :            :         } else {
     234                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     235                 :            :                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
     236                 :            :                         NULL,
     237                 :            :                         "algorithm not supported");
     238                 :            :         }
     239                 :            : 
     240                 :          0 : check_exist:
     241                 :            :         return 0;
     242                 :            : }
     243                 :            : 
     244                 :            : static struct zxdh_meter_profile
     245                 :            : *zxdh_mtr_profile_find_by_id(struct zxdh_mtr_profile_list *mpl,
     246                 :            :                 uint32_t meter_profile_id, uint16_t dpdk_portid)
     247                 :            : {
     248                 :            :         struct zxdh_meter_profile *mp = NULL;
     249                 :            : 
     250   [ #  #  #  #  :          0 :         TAILQ_FOREACH(mp, mpl, next) {
                   #  # ]
     251   [ #  #  #  #  :          0 :                 if (meter_profile_id == mp->meter_profile_id && mp->dpdk_port_id == dpdk_portid)
          #  #  #  #  #  
                #  #  # ]
     252                 :            :                         return mp;
     253                 :            :         }
     254                 :            :         return NULL;
     255                 :            : }
     256                 :            : 
     257                 :            : static struct zxdh_meter_profile
     258                 :          0 : *zxdh_mtr_profile_res_alloc(struct rte_mempool *mtr_profile_mp)
     259                 :            : {
     260         [ #  # ]:          0 :         struct zxdh_meter_profile *meter_profile = NULL;
     261                 :            : 
     262         [ #  # ]:          0 :         if (ZXDH_MP_ALLOC_OBJ_FUNC(mtr_profile_mp, meter_profile) != 0)
     263                 :            :                 return NULL;
     264                 :            : 
     265                 :          0 :         return meter_profile;
     266                 :            : }
     267                 :            : 
     268                 :            : static struct zxdh_meter_policy
     269                 :          0 : *zxdh_mtr_policy_res_alloc(struct rte_mempool *mtr_policy_mp)
     270                 :            : {
     271         [ #  # ]:          0 :         struct zxdh_meter_policy *policy = NULL;
     272                 :            : 
     273                 :            :         rte_mempool_get(mtr_policy_mp, (void **)&policy);
     274                 :          0 :         PMD_DRV_LOG(INFO, "policy %p", policy);
     275                 :          0 :         return policy;
     276                 :            : }
     277                 :            : 
     278                 :            : static int
     279                 :          0 : zxdh_hw_profile_free_direct(struct rte_eth_dev *dev, ZXDH_PROFILE_TYPE car_type,
     280                 :            :                 uint16_t hw_profile_id, struct rte_mtr_error *error)
     281                 :            : {
     282                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     283                 :          0 :         uint16_t vport = hw->vport.vport;
     284                 :          0 :         int ret = zxdh_np_car_profile_id_delete(hw->dev_id, vport, car_type,
     285                 :            :                         (uint64_t)hw_profile_id);
     286         [ #  # ]:          0 :         if (ret) {
     287                 :          0 :                 PMD_DRV_LOG(ERR, "port %u free hw profile %u failed", vport, hw_profile_id);
     288                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     289                 :            :                         "Meter free profile failed");
     290                 :            :         }
     291                 :            : 
     292                 :            :         return 0;
     293                 :            : }
     294                 :            : 
     295                 :            : int
     296                 :          0 : zxdh_hw_profile_alloc_direct(struct rte_eth_dev *dev, ZXDH_PROFILE_TYPE car_type,
     297                 :            :                 uint64_t *hw_profile_id, struct rte_mtr_error *error)
     298                 :            : {
     299                 :          0 :         uint64_t profile_id = HW_PROFILE_MAX;
     300                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     301                 :          0 :         uint16_t vport = hw->vport.vport;
     302                 :          0 :         int ret = zxdh_np_car_profile_id_add(hw->dev_id, vport, car_type, &profile_id);
     303                 :            : 
     304         [ #  # ]:          0 :         if (ret) {
     305                 :          0 :                 PMD_DRV_LOG(ERR, "port %u alloc hw profile failed", vport);
     306                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     307                 :            :                         "Meter offload alloc profile failed");
     308                 :            :         }
     309                 :          0 :         *hw_profile_id = profile_id;
     310         [ #  # ]:          0 :         if (*hw_profile_id == ZXDH_HW_PROFILE_MAX) {
     311                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     312                 :            :                         "Meter offload alloc profile id invalid");
     313                 :            :         }
     314                 :            : 
     315                 :            :         return 0;
     316                 :            : }
     317                 :            : 
     318                 :            : static uint16_t
     319                 :          0 : zxdh_hw_profile_free(struct rte_eth_dev *dev, uint8_t car_type,
     320                 :            :                 uint16_t hw_profile_id, struct rte_mtr_error *error)
     321                 :            : {
     322                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     323                 :            :         int ret = 0;
     324                 :            : 
     325         [ #  # ]:          0 :         if (hw->is_pf) {
     326                 :          0 :                 ret = zxdh_hw_profile_free_direct(dev, car_type, (uint64_t)hw_profile_id, error);
     327                 :            :         } else {
     328                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     329                 :          0 :                 uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
     330                 :            :                 struct zxdh_plcr_profile_free *zxdh_plcr_profile_free =
     331                 :            :                         &msg_info.data.zxdh_plcr_profile_free;
     332                 :            : 
     333                 :          0 :                 zxdh_plcr_profile_free->profile_id = hw_profile_id;
     334                 :          0 :                 zxdh_plcr_profile_free->car_type = car_type;
     335                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PLCR_CAR_PROFILE_ID_DELETE, &msg_info);
     336                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
     337                 :            :                         ZXDH_MSG_HEAD_LEN + sizeof(struct zxdh_plcr_profile_free),
     338                 :            :                         zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
     339                 :            : 
     340         [ #  # ]:          0 :                 if (ret)
     341                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     342                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     343                 :            :                                         "Meter free  profile failed ");
     344                 :            :         }
     345                 :            : 
     346                 :          0 :         return ret;
     347                 :            : }
     348                 :            : 
     349                 :            : static int
     350                 :          0 : zxdh_hw_profile_alloc(struct rte_eth_dev *dev, uint64_t *hw_profile_id,
     351                 :            :                 struct rte_mtr_error *error)
     352                 :            : {
     353                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     354                 :            :         int ret = 0;
     355                 :            : 
     356         [ #  # ]:          0 :         if (hw->is_pf) {
     357                 :          0 :                 ret = zxdh_hw_profile_alloc_direct(dev, CAR_A, hw_profile_id, error);
     358                 :            :         } else {
     359                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     360                 :          0 :                 uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
     361                 :            :                 struct zxdh_plcr_profile_add  *zxdh_plcr_profile_add =
     362                 :            :                         &msg_info.data.zxdh_plcr_profile_add;
     363                 :            :                 void *reply_body_addr =
     364                 :            :                         ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
     365                 :            :                 void *mtr_profile_info_addr =
     366                 :            :                         ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, mtr_profile_info);
     367                 :            : 
     368                 :            :                 zxdh_plcr_profile_add->car_type = CAR_A;
     369                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PLCR_CAR_PROFILE_ID_ADD, &msg_info);
     370                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
     371                 :            :                         ZXDH_MSG_HEAD_LEN + sizeof(struct zxdh_plcr_profile_add),
     372                 :            :                         zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info));
     373                 :            : 
     374         [ #  # ]:          0 :                 if (ret) {
     375                 :          0 :                         PMD_DRV_LOG(ERR,
     376                 :            :                                 "Failed to send msg: port 0x%x msg type ZXDH_PLCR_CAR_PROFILE_ID_ADD ",
     377                 :            :                                 hw->vport.vport);
     378                 :            : 
     379                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     380                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     381                 :            :                                         "Meter offload alloc profile  id msg failed ");
     382                 :            :                 }
     383                 :          0 :                 *hw_profile_id = ZXDH_GET(mtr_profile_info, mtr_profile_info_addr, profile_id);
     384         [ #  # ]:          0 :                 if (*hw_profile_id == ZXDH_HW_PROFILE_MAX) {
     385                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     386                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     387                 :            :                                         "Meter offload alloc profile  id invalid  ");
     388                 :            :                 }
     389                 :            :         }
     390                 :            : 
     391                 :            :         return ret;
     392                 :            : }
     393                 :            : 
     394                 :            : int
     395                 :          0 : zxdh_hw_profile_unref(struct rte_eth_dev *dev,
     396                 :            :         uint8_t car_type,
     397                 :            :         uint16_t hw_profile_id,
     398                 :            :         struct rte_mtr_error *error)
     399                 :            : {
     400         [ #  # ]:          0 :         if (hw_profile_id >= ZXDH_HW_PROFILE_MAX)
     401                 :            :                 return -1;
     402                 :            : 
     403                 :            :         rte_spinlock_lock(&g_mtr_res.hw_plcr_res_lock);
     404         [ #  # ]:          0 :         if (g_mtr_res.hw_profile_refcnt[hw_profile_id] == 0) {
     405                 :          0 :                 PMD_DRV_LOG(ERR, "del hw profile id %d  but ref 0", hw_profile_id);
     406                 :            :                 rte_spinlock_unlock(&g_mtr_res.hw_plcr_res_lock);
     407                 :          0 :                 return -1;
     408                 :            :         }
     409         [ #  # ]:          0 :         if (--g_mtr_res.hw_profile_refcnt[hw_profile_id] == 0) {
     410                 :          0 :                 PMD_DRV_LOG(INFO, "del hw profile id %d ", hw_profile_id);
     411                 :          0 :                 zxdh_hw_profile_free(dev, car_type, hw_profile_id, error);
     412                 :            :         }
     413                 :            :         rte_spinlock_unlock(&g_mtr_res.hw_plcr_res_lock);
     414                 :          0 :         return 0;
     415                 :            : }
     416                 :            : 
     417                 :            : static int
     418                 :          0 : zxdh_mtr_hw_counter_query(struct rte_eth_dev *dev,
     419                 :            :         bool clear,
     420                 :            :         bool dir,
     421                 :            :         struct zxdh_mtr_stats *mtr_stats,
     422                 :            :         struct rte_mtr_error *error)
     423                 :            : {
     424                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     425                 :            :         int ret = 0;
     426                 :            : 
     427         [ #  # ]:          0 :         if (hw->is_pf) {
     428                 :          0 :                 ret = zxdh_mtr_stats_get(dev, dir, mtr_stats);
     429         [ #  # ]:          0 :                 if (ret) {
     430                 :          0 :                         PMD_DRV_LOG(ERR,
     431                 :            :                                 "ZXDH_PORT_METER_STAT_GET port %u dir %d failed",
     432                 :            :                                 hw->vport.vport,
     433                 :            :                                 dir);
     434                 :            : 
     435                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_STATS, NULL, "Failed to bind plcr flow.");
     436                 :            :                 }
     437                 :            :         } else { /* send msg to pf */
     438                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     439                 :          0 :                 uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
     440                 :            :                 struct zxdh_mtr_stats_query *zxdh_mtr_stats_query =
     441                 :            :                                 &msg_info.data.zxdh_mtr_stats_query;
     442                 :            : 
     443                 :          0 :                 zxdh_mtr_stats_query->direction = dir;
     444                 :          0 :                 zxdh_mtr_stats_query->is_clr = !!clear;
     445                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PORT_METER_STAT_GET, &msg_info);
     446                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev,
     447                 :            :                         &msg_info,
     448                 :            :                         sizeof(msg_info),
     449                 :            :                         zxdh_msg_reply_info,
     450                 :            :                         ZXDH_ST_SZ_BYTES(msg_reply_info));
     451                 :            : 
     452         [ #  # ]:          0 :                 if (ret) {
     453                 :          0 :                         PMD_DRV_LOG(ERR,
     454                 :            :                                 "Failed to send msg: port 0x%x msg type ZXDH_PORT_METER_STAT_GET",
     455                 :            :                                 hw->vport.vport);
     456                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_STATS, NULL, "Meter offload alloc profile failed");
     457                 :            :                 }
     458                 :            :                 void *reply_body_addr =
     459                 :            :                         ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
     460                 :            :                 void *hw_mtr_stats_addr =
     461                 :            :                         ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, hw_mtr_stats);
     462                 :            :                 struct zxdh_mtr_stats *hw_mtr_stats = (struct zxdh_mtr_stats *)hw_mtr_stats_addr;
     463                 :            : 
     464                 :          0 :                 mtr_stats->n_bytes_dropped = hw_mtr_stats->n_bytes_dropped;
     465                 :          0 :                 mtr_stats->n_pkts_dropped = hw_mtr_stats->n_pkts_dropped;
     466                 :            :         }
     467                 :            : 
     468                 :            :         return ret;
     469                 :            : }
     470                 :            : 
     471                 :            : 
     472                 :            : static void
     473                 :          0 : zxdh_mtr_profile_res_free(struct rte_eth_dev *dev,
     474                 :            :                 struct rte_mempool *mtr_profile_mp,
     475                 :            :                 struct zxdh_meter_profile *meter_profile,
     476                 :            :                 struct rte_mtr_error *error)
     477                 :            : {
     478         [ #  # ]:          0 :         if (meter_profile->ref_cnt == 0) {
     479                 :          0 :                 ZXDH_MP_FREE_OBJ_FUNC(mtr_profile_mp, meter_profile);
     480                 :          0 :                 return;
     481                 :            :         }
     482         [ #  # ]:          0 :         if (meter_profile->ref_cnt == 1) {
     483                 :          0 :                 meter_profile->ref_cnt--;
     484                 :          0 :                 zxdh_hw_profile_unref(dev, CAR_A, meter_profile->hw_profile_id, error);
     485                 :            : 
     486   [ #  #  #  # ]:          0 :                 TAILQ_REMOVE(&zxdh_shared_data->meter_profile_list, meter_profile, next);
     487                 :          0 :                 ZXDH_MP_FREE_OBJ_FUNC(mtr_profile_mp, meter_profile);
     488                 :            :         } else {
     489                 :          0 :                 PMD_DRV_LOG(INFO,
     490                 :            :                         "profile %d ref %d is busy",
     491                 :            :                         meter_profile->meter_profile_id,
     492                 :            :                         meter_profile->ref_cnt);
     493                 :            :         }
     494                 :            : }
     495                 :            : 
     496                 :            : static uint16_t
     497                 :          0 : zxdh_check_hw_profile_exist(struct zxdh_mtr_profile_list *mpl,
     498                 :            :         struct rte_mtr_meter_profile *profile,
     499                 :            :         uint16_t hw_profile_owner_vport)
     500                 :            : {
     501                 :            :         struct zxdh_meter_profile *mp;
     502                 :            : 
     503         [ #  # ]:          0 :         TAILQ_FOREACH(mp, mpl, next) {
     504         [ #  # ]:          0 :                 if ((memcmp(profile, &mp->profile, sizeof(struct rte_mtr_meter_profile)) == 0) &&
     505         [ #  # ]:          0 :                         hw_profile_owner_vport == mp->hw_profile_owner_vport) {
     506                 :          0 :                         return mp->hw_profile_id;
     507                 :            :                 }
     508                 :            :         }
     509                 :            :         return ZXDH_HW_PROFILE_MAX;
     510                 :            : }
     511                 :            : 
     512                 :            : static void
     513                 :          0 : zxdh_plcr_param_build(struct rte_mtr_meter_profile *profile,
     514                 :            :                 void *plcr_param, uint16_t profile_id)
     515                 :            : {
     516         [ #  # ]:          0 :         if (profile->packet_mode == 0) {
     517                 :            :                 ZXDH_STAT_CAR_PROFILE_CFG_T *p_car_byte_profile_cfg =
     518                 :            :                         (ZXDH_STAT_CAR_PROFILE_CFG_T *)plcr_param;
     519                 :            : 
     520                 :          0 :                 p_car_byte_profile_cfg->profile_id = profile_id;
     521                 :          0 :                 p_car_byte_profile_cfg->pkt_sign = profile->packet_mode;
     522                 :          0 :                 p_car_byte_profile_cfg->cf = ZXDH_PLCR_CF_UNOVERFLOW;
     523                 :          0 :                 p_car_byte_profile_cfg->cm = ZXDH_PLCR_CM_BLIND;
     524         [ #  # ]:          0 :                 if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
     525                 :          0 :                         p_car_byte_profile_cfg->cd  = ZXDH_PLCR_CD_SRTCM;
     526                 :          0 :                         p_car_byte_profile_cfg->cir = profile->srtcm_rfc2697.cir * 8 / 1000;
     527                 :          0 :                         p_car_byte_profile_cfg->cbs = profile->srtcm_rfc2697.cbs;
     528                 :          0 :                         p_car_byte_profile_cfg->ebs = profile->srtcm_rfc2697.ebs;
     529                 :            :                 } else {
     530                 :          0 :                         p_car_byte_profile_cfg->cd  = ZXDH_PLCR_CD_TRTCM;
     531                 :          0 :                         p_car_byte_profile_cfg->cir = profile->trtcm_rfc2698.cir * 8 / 1000;
     532                 :          0 :                         p_car_byte_profile_cfg->cbs = profile->trtcm_rfc2698.cbs;
     533                 :          0 :                         p_car_byte_profile_cfg->eir = (profile->trtcm_rfc2698.pir -
     534                 :          0 :                                 profile->trtcm_rfc2698.cir) * 8 / 1000;
     535                 :          0 :                         p_car_byte_profile_cfg->ebs =
     536                 :          0 :                                 profile->trtcm_rfc2698.pbs - profile->trtcm_rfc2698.cbs;
     537                 :            :                 }
     538                 :            :         } else {
     539                 :            :                 ZXDH_STAT_CAR_PKT_PROFILE_CFG_T *p_car_pkt_profile_cfg =
     540                 :            :                         (ZXDH_STAT_CAR_PKT_PROFILE_CFG_T *)plcr_param;
     541                 :            : 
     542                 :          0 :                 p_car_pkt_profile_cfg->profile_id = profile_id;
     543                 :          0 :                 p_car_pkt_profile_cfg->pkt_sign = profile->packet_mode;
     544                 :            : 
     545         [ #  # ]:          0 :                 if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
     546                 :          0 :                         p_car_pkt_profile_cfg->cir = profile->srtcm_rfc2697.cir;
     547                 :          0 :                         p_car_pkt_profile_cfg->cbs = profile->srtcm_rfc2697.cbs;
     548                 :            :                 } else {
     549                 :          0 :                         p_car_pkt_profile_cfg->cir = profile->trtcm_rfc2698.cir;
     550                 :          0 :                         p_car_pkt_profile_cfg->cbs = profile->trtcm_rfc2698.cbs;
     551                 :            :                 }
     552                 :            :         }
     553                 :          0 : }
     554                 :            : 
     555                 :            : static int
     556                 :          0 : zxdh_hw_profile_config_direct(struct rte_eth_dev *dev __rte_unused,
     557                 :            :         ZXDH_PROFILE_TYPE car_type,
     558                 :            :         uint16_t hw_profile_id,
     559                 :            :         struct zxdh_meter_profile *mp,
     560                 :            :         struct rte_mtr_error *error)
     561                 :            : {
     562                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     563                 :          0 :         int ret = zxdh_np_car_profile_cfg_set(hw->dev_id,
     564                 :          0 :                 mp->hw_profile_owner_vport,
     565                 :          0 :                 car_type, mp->profile.packet_mode,
     566                 :          0 :                 (uint32_t)hw_profile_id, &mp->plcr_param);
     567         [ #  # ]:          0 :         if (ret) {
     568                 :          0 :                 PMD_DRV_LOG(ERR, " config hw profile %u failed", hw_profile_id);
     569                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     570                 :            :                         "Meter offload cfg profile failed");
     571                 :            :         }
     572                 :            : 
     573                 :            :         return 0;
     574                 :            : }
     575                 :            : 
     576                 :          0 : static int zxdh_hw_profile_config(struct rte_eth_dev *dev, uint16_t hw_profile_id,
     577                 :            :         struct zxdh_meter_profile *mp, struct rte_mtr_error *error)
     578                 :            : {
     579                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     580                 :            :         int ret = 0;
     581                 :            : 
     582         [ #  # ]:          0 :         if (hw->is_pf) {
     583                 :          0 :                 ret = zxdh_hw_profile_config_direct(dev, CAR_A, hw_profile_id, mp, error);
     584                 :            :         } else {
     585                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     586                 :          0 :                 uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
     587                 :            :                 struct zxdh_plcr_profile_cfg *zxdh_plcr_profile_cfg =
     588                 :            :                         &msg_info.data.zxdh_plcr_profile_cfg;
     589                 :            : 
     590                 :            :                 zxdh_plcr_profile_cfg->car_type = CAR_A;
     591                 :          0 :                 zxdh_plcr_profile_cfg->packet_mode = mp->profile.packet_mode;
     592                 :          0 :                 zxdh_plcr_profile_cfg->hw_profile_id = hw_profile_id;
     593                 :            :                 rte_memcpy(&zxdh_plcr_profile_cfg->plcr_param,
     594         [ #  # ]:          0 :                         &mp->plcr_param,
     595                 :            :                         sizeof(zxdh_plcr_profile_cfg->plcr_param));
     596                 :            : 
     597                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PLCR_CAR_PROFILE_CFG_SET, &msg_info);
     598                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev,
     599                 :            :                         &msg_info,
     600                 :            :                         ZXDH_MSG_HEAD_LEN + sizeof(struct zxdh_plcr_profile_cfg),
     601                 :            :                         zxdh_msg_reply_info,
     602                 :            :                         ZXDH_ST_SZ_BYTES(msg_reply_info)
     603                 :            :                 );
     604         [ #  # ]:          0 :                 if (ret) {
     605                 :          0 :                         PMD_DRV_LOG(ERR,
     606                 :            :                                 "Failed msg: port 0x%x msg type ZXDH_PLCR_CAR_PROFILE_CFG_SET ",
     607                 :            :                                 hw->vport.vport);
     608                 :            : 
     609                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     610                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     611                 :            :                                         "Meter offload cfg profile failed ");
     612                 :            :                 }
     613                 :            :         }
     614                 :            : 
     615                 :            :         return ret;
     616                 :            : }
     617                 :            : 
     618                 :            : static int
     619                 :          0 : zxdh_mtr_profile_offload(struct rte_eth_dev *dev, struct zxdh_meter_profile *mp,
     620                 :            :                 struct rte_mtr_meter_profile *profile, struct rte_mtr_error *error)
     621                 :            : {
     622                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     623                 :          0 :         uint16_t hw_profile_owner_vport = ZXDH_GET_OWNER_PF_VPORT(hw->vport.vport);
     624                 :            : 
     625                 :          0 :         mp->hw_profile_owner_vport = hw_profile_owner_vport;
     626                 :          0 :         uint64_t hw_profile_id =
     627                 :          0 :                 zxdh_check_hw_profile_exist(&zxdh_shared_data->meter_profile_list,
     628                 :            :                         profile,
     629                 :            :                         hw_profile_owner_vport);
     630                 :            : 
     631         [ #  # ]:          0 :         if (hw_profile_id == ZXDH_HW_PROFILE_MAX) {
     632                 :          0 :                 uint32_t ret = zxdh_hw_profile_alloc(dev, &hw_profile_id, error);
     633                 :            : 
     634         [ #  # ]:          0 :                 if (ret) {
     635                 :          0 :                         PMD_DRV_LOG(ERR, "hw_profile alloc fail");
     636                 :          0 :                         return ret;
     637                 :            :                 }
     638                 :            : 
     639                 :          0 :                 zxdh_plcr_param_build(profile, &mp->plcr_param, hw_profile_id);
     640                 :          0 :                 ret = zxdh_hw_profile_config(dev, hw_profile_id, mp, error);
     641         [ #  # ]:          0 :                 if (ret) {
     642                 :          0 :                         PMD_DRV_LOG(ERR, "zxdh_hw_profile_config fail");
     643                 :            :                         hw_profile_id = ZXDH_HW_PROFILE_MAX;
     644                 :          0 :                         return ret;
     645                 :            :                 }
     646                 :            :         }
     647                 :          0 :         zxdh_hw_profile_ref(hw_profile_id);
     648                 :          0 :         mp->hw_profile_id = hw_profile_id;
     649                 :            : 
     650                 :          0 :         return 0;
     651                 :            : }
     652                 :            : 
     653                 :            : static int
     654                 :          0 : zxdh_meter_profile_add(struct rte_eth_dev *dev,
     655                 :            :                                 uint32_t meter_profile_id,
     656                 :            :                                 struct rte_mtr_meter_profile *profile,
     657                 :            :                                 struct rte_mtr_error *error)
     658                 :            : {
     659                 :            :         struct zxdh_meter_profile *mp;
     660                 :            :         int ret;
     661                 :            : 
     662                 :          0 :         ret = zxdh_mtr_profile_validate(meter_profile_id, profile, error);
     663         [ #  # ]:          0 :         if (ret)
     664                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     665                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
     666                 :            :                                         NULL, "meter profile validate failed");
     667                 :          0 :         mp = zxdh_mtr_profile_find_by_id(&zxdh_shared_data->meter_profile_list,
     668                 :            :                 meter_profile_id,
     669                 :          0 :                 dev->data->port_id);
     670                 :            : 
     671         [ #  # ]:          0 :         if (mp)
     672                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     673                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE,
     674                 :            :                                           NULL,
     675                 :            :                                           "meter profile is exists");
     676                 :            : 
     677                 :          0 :         mp = zxdh_mtr_profile_res_alloc(zxdh_shared_data->mtr_profile_mp);
     678         [ #  # ]:          0 :         if (mp == NULL)
     679                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     680                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
     681                 :            :                                         NULL, "Meter profile res memory alloc failed.");
     682                 :            : 
     683                 :            :         memset(mp, 0, sizeof(struct zxdh_meter_profile));
     684                 :            : 
     685                 :          0 :         mp->meter_profile_id = meter_profile_id;
     686                 :          0 :         mp->dpdk_port_id = dev->data->port_id;
     687                 :          0 :         mp->hw_profile_id = UINT16_MAX;
     688         [ #  # ]:          0 :         rte_memcpy(&mp->profile, profile, sizeof(struct rte_mtr_meter_profile));
     689                 :            : 
     690                 :          0 :         ret = zxdh_mtr_profile_offload(dev, mp, profile, error);
     691         [ #  # ]:          0 :         if (ret) {
     692                 :          0 :                 PMD_DRV_LOG(ERR,
     693                 :            :                         " port %d profile id  %d offload failed  ",
     694                 :            :                         dev->data->port_id,
     695                 :            :                         meter_profile_id);
     696                 :          0 :                 goto error;
     697                 :            :         }
     698                 :            : 
     699                 :          0 :         TAILQ_INSERT_TAIL(&zxdh_shared_data->meter_profile_list, mp, next);
     700                 :          0 :         PMD_DRV_LOG(DEBUG,
     701                 :            :                 "add profile id %d mp %p  mp->ref_cnt %d",
     702                 :            :                 meter_profile_id,
     703                 :            :                 mp,
     704                 :            :                 mp->ref_cnt);
     705                 :            : 
     706                 :          0 :         mp->ref_cnt++;
     707                 :            : 
     708                 :          0 :         return 0;
     709                 :            : error:
     710                 :          0 :         zxdh_mtr_profile_res_free(dev, zxdh_shared_data->mtr_profile_mp, mp, error);
     711                 :          0 :         return ret;
     712                 :            : }
     713                 :            : 
     714                 :            : static int
     715                 :          0 : zxdh_meter_profile_delete(struct rte_eth_dev *dev,
     716                 :            :                                 uint32_t meter_profile_id,
     717                 :            :                                 struct rte_mtr_error *error)
     718                 :            : {
     719                 :            :         struct zxdh_meter_profile *mp;
     720                 :            : 
     721                 :          0 :         mp = zxdh_mtr_profile_find_by_id(&zxdh_shared_data->meter_profile_list,
     722                 :            :                 meter_profile_id,
     723                 :          0 :                 dev->data->port_id);
     724                 :            : 
     725         [ #  # ]:          0 :         if (mp == NULL) {
     726                 :          0 :                 PMD_DRV_LOG(ERR, "del profile id %d  unfind ", meter_profile_id);
     727                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     728                 :            :                                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
     729                 :            :                                                 &meter_profile_id,
     730                 :            :                                                  "Meter profile id is not exists.");
     731                 :            :         }
     732                 :          0 :         zxdh_mtr_profile_res_free(dev, zxdh_shared_data->mtr_profile_mp, mp, error);
     733                 :            : 
     734                 :          0 :         return 0;
     735                 :            : }
     736                 :            : 
     737                 :            : static int
     738                 :          0 : zxdh_meter_policy_add(struct rte_eth_dev *dev,
     739                 :            :                 uint32_t policy_id,
     740                 :            :                 struct rte_mtr_meter_policy_params *policy,
     741                 :            :                 struct rte_mtr_error *error)
     742                 :            : {
     743                 :            :         int ret = 0;
     744                 :            :         struct zxdh_meter_policy *mtr_policy = NULL;
     745                 :            : 
     746         [ #  # ]:          0 :         if (policy_id >= ZXDH_MAX_POLICY_NUM)
     747                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     748                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     749                 :            :                                         NULL, "policy ID is invalid. ");
     750                 :          0 :         mtr_policy = zxdh_mtr_policy_find_by_id(&zxdh_shared_data->mtr_policy_list,
     751                 :            :                                 policy_id,
     752                 :          0 :                                 dev->data->port_id);
     753                 :            : 
     754         [ #  # ]:          0 :         if (mtr_policy)
     755                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     756                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     757                 :            :                                         NULL, "policy ID  exists. ");
     758                 :            :         ret = zxdh_policy_validate_actions(policy->actions, error);
     759                 :            :         if (ret) {
     760                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     761                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY,
     762                 :            :                                 NULL, "  only supports def action.");
     763                 :            :         }
     764                 :            : 
     765                 :          0 :         mtr_policy = zxdh_mtr_policy_res_alloc(zxdh_shared_data->mtr_policy_mp);
     766         [ #  # ]:          0 :         if (mtr_policy == NULL) {
     767                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     768                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     769                 :            :                                         NULL, "Meter policy res memory alloc  failed.");
     770                 :            :         }
     771                 :            :         /* Fill profile info. */
     772                 :            :         memset(mtr_policy, 0, sizeof(struct zxdh_meter_policy));
     773                 :          0 :         mtr_policy->policy_id = policy_id;
     774                 :          0 :         mtr_policy->dpdk_port_id = dev->data->port_id;
     775         [ #  # ]:          0 :         rte_memcpy(&mtr_policy->policy, policy, sizeof(struct rte_mtr_meter_policy_params));
     776                 :            :         /* Add to list. */
     777                 :          0 :         TAILQ_INSERT_TAIL(&zxdh_shared_data->mtr_policy_list, mtr_policy, next);
     778                 :          0 :         mtr_policy->ref_cnt++;
     779                 :          0 :         PMD_DRV_LOG(INFO, "allic policy id %d ok %p ", mtr_policy->policy_id, mtr_policy);
     780                 :          0 :         return 0;
     781                 :            : }
     782                 :            : 
     783                 :            : static int
     784                 :          0 : zxdh_meter_policy_delete(struct rte_eth_dev *dev,
     785                 :            :         uint32_t policy_id,
     786                 :            :         struct rte_mtr_error *error)
     787                 :            : {
     788                 :            :         struct zxdh_meter_policy *mtr_policy = NULL;
     789                 :            : 
     790         [ #  # ]:          0 :         if (policy_id >= ZXDH_MAX_POLICY_NUM)
     791                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     792                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     793                 :            :                                         NULL, "policy ID is invalid. ");
     794                 :          0 :         mtr_policy = zxdh_mtr_policy_find_by_id(&zxdh_shared_data->mtr_policy_list,
     795                 :          0 :                 policy_id, dev->data->port_id);
     796                 :            : 
     797   [ #  #  #  # ]:          0 :         if (mtr_policy && mtr_policy->ref_cnt == 1) {
     798         [ #  # ]:          0 :                 TAILQ_REMOVE(&zxdh_shared_data->mtr_policy_list, mtr_policy, next);
     799         [ #  # ]:          0 :                 MP_FREE_OBJ_FUNC(zxdh_shared_data->mtr_policy_mp, mtr_policy);
     800                 :            :         } else {
     801         [ #  # ]:          0 :                 if (mtr_policy) {
     802                 :          0 :                         PMD_DRV_LOG(INFO,
     803                 :            :                                 " policy id %d ref %d is busy ",
     804                 :            :                                 mtr_policy->policy_id,
     805                 :            :                                 mtr_policy->ref_cnt);
     806                 :            :                 } else {
     807                 :          0 :                         PMD_DRV_LOG(ERR, " policy id %d  is not exist ", policy_id);
     808                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     809                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     810                 :            :                                         NULL, "policy ID is  not exist. ");
     811                 :            :                 }
     812                 :            :         }
     813                 :            :         return 0;
     814                 :            : }
     815                 :            : 
     816                 :            : static int
     817                 :          0 : zxdh_meter_validate(uint32_t meter_id,
     818                 :            :                         struct rte_mtr_params *params,
     819                 :            :                         struct rte_mtr_error *error)
     820                 :            : {
     821                 :            :         /* Meter params must not be NULL. */
     822         [ #  # ]:          0 :         if (params == NULL)
     823                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     824                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     825                 :            :                                         NULL, "Meter object params null.");
     826                 :            :         /* Previous meter color is not supported. */
     827         [ #  # ]:          0 :         if (params->use_prev_mtr_color)
     828                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     829                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     830                 :            :                                         NULL,
     831                 :            :                                         "Previous meter color not supported");
     832         [ #  # ]:          0 :         if (meter_id > ZXDH_MAX_MTR_NUM / 2) {
     833                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     834                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     835                 :            :                                 NULL,
     836                 :            :                                 " meter id exceed 1024 unsupported");
     837                 :            :         }
     838                 :            :         return 0;
     839                 :            : }
     840                 :            : 
     841                 :            : static int
     842                 :          0 : zxdh_check_port_mtr_bind(struct rte_eth_dev *dev, uint32_t dir)
     843                 :            : {
     844                 :            :         struct zxdh_mtr_object *mtr_obj = NULL;
     845                 :            : 
     846         [ #  # ]:          0 :         TAILQ_FOREACH(mtr_obj, &zxdh_shared_data->mtr_list, next) {
     847         [ #  # ]:          0 :                 if (mtr_obj->direction != dir)
     848                 :          0 :                         continue;
     849         [ #  # ]:          0 :                 if (mtr_obj->port_id == dev->data->port_id) {
     850                 :          0 :                         PMD_DRV_LOG(INFO,
     851                 :            :                                 "port %d dir %d already bind meter %d",
     852                 :            :                                 dev->data->port_id,
     853                 :            :                                 dir,
     854                 :            :                                 mtr_obj->meter_id);
     855                 :          0 :                         return -1;
     856                 :            :                 }
     857                 :            :         }
     858                 :            : 
     859                 :            :         return 0;
     860                 :            : }
     861                 :            : 
     862                 :            : static struct zxdh_mtr_object
     863                 :          0 : *zxdh_mtr_obj_alloc(struct rte_mempool *mtr_mp)
     864                 :            : {
     865         [ #  # ]:          0 :         struct zxdh_mtr_object *mtr_obj = NULL;
     866                 :            : 
     867         [ #  # ]:          0 :         if (ZXDH_MP_ALLOC_OBJ_FUNC(mtr_mp, mtr_obj) != 0)
     868                 :            :                 return NULL;
     869                 :            : 
     870                 :          0 :         return mtr_obj;
     871                 :            : }
     872                 :            : 
     873                 :            : static uint32_t dir_to_mtr_mode[] = {
     874                 :            :         ZXDH_PORT_EGRESS_METER_EN_OFF_FLAG,
     875                 :            :         ZXDH_PORT_INGRESS_METER_EN_OFF_FLAG
     876                 :            : };
     877                 :            : 
     878                 :            : static int
     879                 :          0 : zxdh_set_mtr_enable(struct rte_eth_dev *dev, uint8_t dir, bool enable, struct rte_mtr_error *error)
     880                 :            : {
     881                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
     882                 :          0 :         struct zxdh_port_attr_table port_attr = {0};
     883                 :            :         int ret = 0;
     884                 :            : 
     885         [ #  # ]:          0 :         if (priv->is_pf) {
     886                 :          0 :                 ret = zxdh_get_port_attr(priv, priv->vport.vport, &port_attr);
     887                 :          0 :                 port_attr.egress_meter_enable = enable;
     888                 :          0 :                 ret = zxdh_set_port_attr(priv, priv->vport.vport, &port_attr);
     889         [ #  # ]:          0 :                 if (ret) {
     890                 :          0 :                         PMD_DRV_LOG(ERR, "%s set port attr failed", __func__);
     891                 :          0 :                         return -ret;
     892                 :            :                 }
     893                 :            :         } else {
     894                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     895                 :            :                 struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
     896                 :            : 
     897                 :          0 :                 attr_msg->mode  = dir_to_mtr_mode[dir];
     898                 :          0 :                 attr_msg->value = enable;
     899                 :          0 :                 zxdh_msg_head_build(priv, ZXDH_PORT_ATTRS_SET, &msg_info);
     900                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
     901                 :            :                         sizeof(struct zxdh_msg_head) + sizeof(struct zxdh_port_attr_set_msg),
     902                 :            :                         NULL, 0);
     903                 :            :         }
     904         [ #  # ]:          0 :         if (ret) {
     905                 :          0 :                 PMD_DRV_LOG(ERR, " port %d  mtr enable failed", priv->port_id);
     906                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     907                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
     908                 :            :                                         "Meter  enable failed.");
     909                 :            :         }
     910         [ #  # ]:          0 :         if (dir == ZXDH_INGRESS)
     911                 :          0 :                 priv->i_mtr_en = !!enable;
     912                 :            :         else
     913                 :          0 :                 priv->e_mtr_en = !!enable;
     914                 :            : 
     915                 :            :         return ret;
     916                 :            : }
     917                 :            : 
     918                 :            : static void
     919                 :            : zxdh_meter_build_actions(struct zxdh_meter_action *mtr_action,
     920                 :            :                 struct rte_mtr_params *params)
     921                 :            : {
     922                 :          0 :         mtr_action->stats_mask = params->stats_mask;
     923                 :          0 :         mtr_action->action[RTE_COLOR_RED] = ZXDH_MTR_POLICER_ACTION_DROP;
     924                 :            : }
     925                 :            : 
     926                 :            : static int
     927                 :          0 : zxdh_hw_plcrflow_config(struct rte_eth_dev *dev, uint16_t hw_flow_id,
     928                 :            :                 struct zxdh_mtr_object *mtr, struct rte_mtr_error *error)
     929                 :            : {
     930                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     931                 :            :         int ret = 0;
     932                 :            : 
     933         [ #  # ]:          0 :         if (hw->is_pf) {
     934                 :          0 :                 uint64_t hw_profile_id = (uint64_t)mtr->profile->hw_profile_id;
     935                 :            : 
     936                 :          0 :                 ret = zxdh_np_stat_car_queue_cfg_set(hw->dev_id, CAR_A,
     937                 :          0 :                         hw_flow_id, 1, mtr->enable, hw_profile_id);
     938                 :            : 
     939         [ #  # ]:          0 :                 if (ret) {
     940                 :          0 :                         PMD_DRV_LOG(ERR, "dpp_stat_car_queue_cfg_set failed flowid %d  profile id %d",
     941                 :            :                                                         hw_flow_id, mtr->profile->hw_profile_id);
     942                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     943                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     944                 :            :                                         NULL, "Failed to  bind  plcr flow.");
     945                 :            :                         ;
     946                 :            :                 }
     947                 :            :         } else {
     948                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     949                 :          0 :                 uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)] = {0};
     950                 :            :                 struct zxdh_plcr_flow_cfg *zxdh_plcr_flow_cfg = &msg_info.data.zxdh_plcr_flow_cfg;
     951                 :            : 
     952                 :            :                 zxdh_plcr_flow_cfg->car_type = CAR_A;
     953                 :          0 :                 zxdh_plcr_flow_cfg->flow_id = hw_flow_id;
     954                 :          0 :                 zxdh_plcr_flow_cfg->drop_flag = 1;
     955                 :          0 :                 zxdh_plcr_flow_cfg->plcr_en = mtr->enable;
     956                 :          0 :                 zxdh_plcr_flow_cfg->profile_id = mtr->profile->hw_profile_id;
     957                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PLCR_CAR_QUEUE_CFG_SET, &msg_info);
     958                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
     959                 :            :                         ZXDH_MSG_HEAD_LEN + sizeof(struct zxdh_plcr_flow_cfg),
     960                 :            :                         zxdh_msg_reply_info,
     961                 :            :                         ZXDH_ST_SZ_BYTES(msg_reply_info));
     962         [ #  # ]:          0 :                 if (ret) {
     963                 :          0 :                         PMD_DRV_LOG(ERR,
     964                 :            :                                 "Failed msg: port 0x%x msg type ZXDH_PLCR_CAR_QUEUE_CFG_SET ",
     965                 :            :                                 hw->vport.vport);
     966                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     967                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     968                 :            :                                         NULL, "Failed to  bind  plcr flow.");
     969                 :            :                 }
     970                 :            :         }
     971                 :            : 
     972                 :            :         return ret;
     973                 :            : }
     974                 :            : 
     975                 :            : static void
     976                 :          0 : zxdh_mtr_obj_free(struct rte_eth_dev *dev, struct zxdh_mtr_object *mtr_obj)
     977                 :            : {
     978                 :          0 :         struct zxdh_mtr_list *mtr_list = &zxdh_shared_data->mtr_list;
     979                 :          0 :         struct rte_mempool *mtr_mp = zxdh_shared_data->mtr_mp;
     980                 :            : 
     981                 :          0 :         PMD_DRV_LOG(INFO, "free port %d dir %d meter %d  mtr refcnt:%d ....",
     982                 :            :                 dev->data->port_id, mtr_obj->direction, mtr_obj->meter_id, mtr_obj->mtr_ref_cnt);
     983                 :            : 
     984         [ #  # ]:          0 :         if (mtr_obj->policy)
     985                 :          0 :                 mtr_obj->policy->ref_cnt--;
     986                 :            : 
     987         [ #  # ]:          0 :         if (mtr_obj->profile)
     988                 :          0 :                 mtr_obj->profile->ref_cnt--;
     989                 :            : 
     990         [ #  # ]:          0 :         PMD_DRV_LOG(INFO,
     991                 :            :                 "free port %d dir %d meter %d  profile refcnt:%d ",
     992                 :            :                 dev->data->port_id,
     993                 :            :                 mtr_obj->direction,
     994                 :            :                 mtr_obj->meter_id,
     995                 :            :                 mtr_obj->profile ? mtr_obj->profile->ref_cnt : 0);
     996                 :            : 
     997         [ #  # ]:          0 :         if (--mtr_obj->mtr_ref_cnt == 0) {
     998                 :          0 :                 PMD_DRV_LOG(INFO, "rm  mtr %p refcnt:%d ....", mtr_obj, mtr_obj->mtr_ref_cnt);
     999   [ #  #  #  # ]:          0 :                 TAILQ_REMOVE(mtr_list, mtr_obj, next);
    1000                 :          0 :                 MP_FREE_OBJ_FUNC(mtr_mp, mtr_obj);
    1001                 :            :         }
    1002                 :          0 : }
    1003                 :            : 
    1004                 :            : static int
    1005                 :            : zxdh_mtr_flow_offlad(struct rte_eth_dev *dev,
    1006                 :            :         struct zxdh_mtr_object *mtr,
    1007                 :            :         struct rte_mtr_error *error)
    1008                 :            : {
    1009                 :            :         uint16_t hw_flow_id;
    1010                 :            : 
    1011                 :          0 :         hw_flow_id = mtr->vfid * 2 + ZXDH_PORT_MTR_FID_BASE + mtr->direction;
    1012                 :          0 :         return zxdh_hw_plcrflow_config(dev, hw_flow_id, mtr, error);
    1013                 :            : }
    1014                 :            : 
    1015                 :            : static struct zxdh_mtr_object *
    1016                 :          0 : zxdh_mtr_find(uint32_t meter_id, uint16_t dpdk_portid)
    1017                 :            : {
    1018                 :          0 :         struct zxdh_mtr_list *mtr_list = &zxdh_shared_data->mtr_list;
    1019                 :            :         struct zxdh_mtr_object *mtr = NULL;
    1020                 :            : 
    1021         [ #  # ]:          0 :         TAILQ_FOREACH(mtr, mtr_list, next) {
    1022                 :          0 :                 PMD_DRV_LOG(INFO,
    1023                 :            :                         "mtrlist head %p  mtr %p mtr->meterid %d to find mtrid %d",
    1024                 :            :                         TAILQ_FIRST(mtr_list),
    1025                 :            :                         mtr,
    1026                 :            :                         mtr->meter_id,
    1027                 :            :                         meter_id
    1028                 :            :                 );
    1029                 :            : 
    1030   [ #  #  #  # ]:          0 :                 if (meter_id == mtr->meter_id && dpdk_portid == mtr->port_id)
    1031                 :          0 :                         return mtr;
    1032                 :            :         }
    1033                 :            :         return NULL;
    1034                 :            : }
    1035                 :            : 
    1036                 :            : static int
    1037                 :          0 : zxdh_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
    1038                 :            :                                 struct rte_mtr_params *params, int shared,
    1039                 :            :                                 struct rte_mtr_error *error)
    1040                 :            : {
    1041                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
    1042                 :          0 :         struct zxdh_mtr_list *mtr_list = &zxdh_shared_data->mtr_list;
    1043                 :            :         struct zxdh_mtr_object *mtr;
    1044                 :            :         struct zxdh_meter_profile *mtr_profile;
    1045                 :            :         struct zxdh_meter_policy *mtr_policy;
    1046                 :            :         uint8_t dir = 0;
    1047                 :            :         int ret;
    1048                 :            : 
    1049         [ #  # ]:          0 :         if (shared)
    1050                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
    1051                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
    1052                 :            :                                         "Meter share is not supported");
    1053                 :            : 
    1054                 :          0 :         ret = zxdh_meter_validate(meter_id, params, error);
    1055         [ #  # ]:          0 :         if (ret)
    1056                 :            :                 return ret;
    1057                 :            : 
    1058         [ #  # ]:          0 :         if (zxdh_check_port_mtr_bind(dev, dir))
    1059                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
    1060                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
    1061                 :            :                                 "Meter object already bind to dev.");
    1062                 :            : 
    1063                 :          0 :         mtr_profile = zxdh_mtr_profile_find_by_id(&zxdh_shared_data->meter_profile_list,
    1064                 :            :                         params->meter_profile_id,
    1065                 :          0 :                         dev->data->port_id
    1066                 :            :         );
    1067                 :            : 
    1068         [ #  # ]:          0 :         if (mtr_profile == NULL)
    1069                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
    1070         [ #  # ]:          0 :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE, &params->meter_profile_id,
    1071                 :            :                                         "Meter profile object is not exists.");
    1072                 :          0 :         mtr_profile->ref_cnt++;
    1073                 :          0 :         mtr_policy = zxdh_mtr_policy_find_by_id(&zxdh_shared_data->mtr_policy_list,
    1074                 :          0 :                         params->meter_policy_id,
    1075                 :            :                         dev->data->port_id);
    1076                 :            : 
    1077         [ #  # ]:          0 :         if (mtr_policy == NULL) {
    1078                 :            :                 ret = -rte_mtr_error_set(error, EEXIST,
    1079         [ #  # ]:          0 :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE, &params->meter_policy_id,
    1080                 :            :                                         "Meter policy object is not exists.");
    1081                 :          0 :                 mtr_profile->ref_cnt--;
    1082                 :          0 :                 return ret;
    1083                 :            :         }
    1084                 :          0 :         mtr_policy->ref_cnt++;
    1085                 :            : 
    1086                 :          0 :         mtr = zxdh_mtr_obj_alloc(zxdh_shared_data->mtr_mp);
    1087         [ #  # ]:          0 :         if (mtr == NULL) {
    1088                 :            :                 ret = -rte_mtr_error_set(error, ENOMEM,
    1089                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
    1090                 :            :                                         "Memory alloc failed for meter.");
    1091                 :          0 :                 mtr_policy->ref_cnt--;
    1092                 :          0 :                 mtr_profile->ref_cnt--;
    1093                 :          0 :                 return ret;
    1094                 :            :         }
    1095                 :            :         memset(mtr, 0, sizeof(struct zxdh_mtr_object));
    1096                 :            : 
    1097                 :          0 :         mtr->meter_id = meter_id;
    1098                 :          0 :         mtr->profile = mtr_profile;
    1099                 :            : 
    1100                 :            :         zxdh_meter_build_actions(&mtr->mtr_action, params);
    1101                 :          0 :         TAILQ_INSERT_TAIL(mtr_list, mtr, next);
    1102                 :          0 :         mtr->enable = !!params->meter_enable;
    1103                 :          0 :         mtr->shared = !!shared;
    1104                 :          0 :         mtr->mtr_ref_cnt++;
    1105                 :          0 :         mtr->vfid = priv->vfid;
    1106                 :          0 :         mtr->port_id = dev->data->port_id;
    1107                 :          0 :         mtr->policy = mtr_policy;
    1108                 :          0 :         mtr->direction = !!dir;
    1109         [ #  # ]:          0 :         if (params->meter_enable) {
    1110                 :            :                 ret = zxdh_mtr_flow_offlad(dev, mtr, error);
    1111         [ #  # ]:          0 :                 if (ret)
    1112                 :          0 :                         goto error;
    1113                 :            :         }
    1114                 :          0 :         ret = zxdh_set_mtr_enable(dev, mtr->direction, 1, error);
    1115         [ #  # ]:          0 :         if (ret)
    1116                 :          0 :                 goto error;
    1117                 :            :         return ret;
    1118                 :          0 : error:
    1119                 :          0 :         zxdh_mtr_obj_free(dev, mtr);
    1120                 :          0 :         return ret;
    1121                 :            : }
    1122                 :            : 
    1123                 :            : static int
    1124                 :          0 : zxdh_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,
    1125                 :            :                         struct rte_mtr_error *error)
    1126                 :            : {
    1127                 :            :         struct zxdh_mtr_object *mtr;
    1128                 :            : 
    1129                 :          0 :         mtr = zxdh_mtr_find(meter_id, dev->data->port_id);
    1130         [ #  # ]:          0 :         if (mtr == NULL)
    1131                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
    1132                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID,
    1133                 :            :                                           NULL, "Meter object id not valid.");
    1134                 :          0 :         mtr->enable = 0;
    1135                 :          0 :         zxdh_set_mtr_enable(dev, mtr->direction, 0, error);
    1136                 :            : 
    1137         [ #  # ]:          0 :         if (zxdh_mtr_flow_offlad(dev, mtr, error))
    1138                 :            :                 return -1;
    1139                 :            : 
    1140                 :          0 :         zxdh_mtr_obj_free(dev, mtr);
    1141                 :          0 :         return 0;
    1142                 :            : }
    1143                 :            : 
    1144                 :            : void
    1145                 :          0 : zxdh_mtr_policy_res_free(struct rte_mempool *mtr_policy_mp, struct zxdh_meter_policy *policy)
    1146                 :            : {
    1147                 :          0 :         PMD_DRV_LOG(INFO, "to free policy %d  ref  %d  ", policy->policy_id,  policy->ref_cnt);
    1148                 :            : 
    1149         [ #  # ]:          0 :         if (--policy->ref_cnt == 0) {
    1150   [ #  #  #  # ]:          0 :                 TAILQ_REMOVE(&zxdh_shared_data->mtr_policy_list, policy, next);
    1151                 :          0 :                 MP_FREE_OBJ_FUNC(mtr_policy_mp, policy);
    1152                 :            :         }
    1153                 :          0 : }
    1154                 :            : 
    1155                 :            : static int
    1156                 :          0 : zxdh_mtr_stats_read(struct rte_eth_dev *dev,
    1157                 :            :                                                                 uint32_t mtr_id,
    1158                 :            :                                                                 struct rte_mtr_stats *stats,
    1159                 :            :                                                                 uint64_t *stats_mask,
    1160                 :            :                                                                 int clear,
    1161                 :            :                                                                 struct rte_mtr_error *error)
    1162                 :            : {
    1163                 :          0 :         struct zxdh_mtr_stats mtr_stat = {0};
    1164                 :            :         struct zxdh_mtr_object *mtr = NULL;
    1165                 :            :         int ret = 0;
    1166                 :            :         /* Meter object must exist. */
    1167                 :          0 :         mtr = zxdh_mtr_find(mtr_id, dev->data->port_id);
    1168         [ #  # ]:          0 :         if (mtr == NULL)
    1169                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
    1170                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_ID,
    1171                 :            :                                         NULL, "Meter object id not valid.");
    1172                 :          0 :         *stats_mask = RTE_MTR_STATS_N_BYTES_DROPPED | RTE_MTR_STATS_N_PKTS_DROPPED;
    1173                 :            :         memset(&mtr_stat, 0, sizeof(mtr_stat));
    1174                 :          0 :         ret = zxdh_mtr_hw_counter_query(dev, clear, mtr->direction, &mtr_stat, error);
    1175         [ #  # ]:          0 :         if (ret)
    1176         [ #  # ]:          0 :                 goto error;
    1177                 :          0 :         stats->n_bytes_dropped = mtr_stat.n_bytes_dropped;
    1178                 :          0 :         stats->n_pkts_dropped = mtr_stat.n_pkts_dropped;
    1179                 :            : 
    1180                 :          0 :         return 0;
    1181                 :            : error:
    1182                 :          0 :         return -rte_mtr_error_set(error, ret, RTE_MTR_ERROR_TYPE_STATS, NULL,
    1183                 :            :                                 "Failed to read meter drop counters.");
    1184                 :            : }
    1185                 :            : 
    1186                 :            : static const struct rte_mtr_ops zxdh_mtr_ops = {
    1187                 :            :         .capabilities_get = zxdh_meter_cap_get,
    1188                 :            :         .meter_profile_add = zxdh_meter_profile_add,
    1189                 :            :         .meter_profile_delete = zxdh_meter_profile_delete,
    1190                 :            :         .create = zxdh_meter_create,
    1191                 :            :         .destroy = zxdh_meter_destroy,
    1192                 :            :         .stats_read = zxdh_mtr_stats_read,
    1193                 :            :         .meter_policy_add = zxdh_meter_policy_add,
    1194                 :            :         .meter_policy_delete = zxdh_meter_policy_delete,
    1195                 :            : };
    1196                 :            : 
    1197                 :            : int
    1198                 :          0 : zxdh_meter_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
    1199                 :            : {
    1200                 :          0 :         *(const struct rte_mtr_ops **)arg = &zxdh_mtr_ops;
    1201                 :          0 :         return 0;
    1202                 :            : }
    1203                 :            : 
    1204                 :            : void
    1205                 :          0 : zxdh_mtr_release(struct rte_eth_dev *dev)
    1206                 :            : {
    1207                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
    1208                 :            :         struct zxdh_meter_profile *profile;
    1209                 :          0 :         struct rte_mtr_error error = {0};
    1210                 :            :         struct zxdh_mtr_object *mtr_obj;
    1211                 :            : 
    1212         [ #  # ]:          0 :         RTE_TAILQ_FOREACH(mtr_obj, &zxdh_shared_data->mtr_list, next) {
    1213         [ #  # ]:          0 :                 if (mtr_obj->port_id == priv->port_id)
    1214                 :          0 :                         zxdh_mtr_obj_free(dev, mtr_obj);
    1215                 :            :         }
    1216                 :            : 
    1217                 :            : 
    1218         [ #  # ]:          0 :         RTE_TAILQ_FOREACH(profile, &zxdh_shared_data->meter_profile_list, next) {
    1219         [ #  # ]:          0 :                 if (profile->dpdk_port_id == priv->port_id)
    1220                 :          0 :                         zxdh_mtr_profile_res_free(dev,
    1221                 :          0 :                                 zxdh_shared_data->mtr_profile_mp,
    1222                 :            :                                 profile,
    1223                 :            :                                 &error
    1224                 :            :                         );
    1225                 :            :         }
    1226                 :            : 
    1227                 :            :         struct zxdh_meter_policy *policy;
    1228                 :            : 
    1229         [ #  # ]:          0 :         RTE_TAILQ_FOREACH(policy, &zxdh_shared_data->mtr_policy_list, next) {
    1230         [ #  # ]:          0 :                 if (policy->dpdk_port_id == priv->port_id)
    1231                 :          0 :                         zxdh_mtr_policy_res_free(zxdh_shared_data->mtr_policy_mp, policy);
    1232                 :            :         }
    1233                 :          0 : }

Generated by: LCOV version 1.14