LCOV - code coverage report
Current view: top level - drivers/net/zxdh - zxdh_mtr.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 462 0.0 %
Date: 2025-04-03 19:37:06 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(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(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 :                 struct zxdh_msg_reply_info 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                 :            :                         &reply_info, sizeof(struct zxdh_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 :                 struct zxdh_msg_reply_info reply_info = {0};
     361                 :            :                 struct zxdh_plcr_profile_add  *zxdh_plcr_profile_add =
     362                 :            :                         &msg_info.data.zxdh_plcr_profile_add;
     363                 :            : 
     364                 :            :                 zxdh_plcr_profile_add->car_type = CAR_A;
     365                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PLCR_CAR_PROFILE_ID_ADD, &msg_info);
     366                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
     367                 :            :                         ZXDH_MSG_HEAD_LEN + sizeof(struct zxdh_plcr_profile_add),
     368                 :            :                         &reply_info, sizeof(struct zxdh_msg_reply_info));
     369                 :            : 
     370         [ #  # ]:          0 :                 if (ret) {
     371                 :          0 :                         PMD_DRV_LOG(ERR,
     372                 :            :                                 "Failed to send msg: port 0x%x msg type ZXDH_PLCR_CAR_PROFILE_ID_ADD ",
     373                 :            :                                 hw->vport.vport);
     374                 :            : 
     375                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     376                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     377                 :            :                                         "Meter offload alloc profile  id msg failed ");
     378                 :            :                 }
     379                 :          0 :                 *hw_profile_id = reply_info.reply_body.mtr_profile_info.profile_id;
     380         [ #  # ]:          0 :                 if (*hw_profile_id == ZXDH_HW_PROFILE_MAX) {
     381                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     382                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL,
     383                 :            :                                         "Meter offload alloc profile  id invalid  ");
     384                 :            :                 }
     385                 :            :         }
     386                 :            : 
     387                 :            :         return ret;
     388                 :            : }
     389                 :            : 
     390                 :            : int
     391                 :          0 : zxdh_hw_profile_unref(struct rte_eth_dev *dev,
     392                 :            :         uint8_t car_type,
     393                 :            :         uint16_t hw_profile_id,
     394                 :            :         struct rte_mtr_error *error)
     395                 :            : {
     396         [ #  # ]:          0 :         if (hw_profile_id >= ZXDH_HW_PROFILE_MAX)
     397                 :            :                 return -1;
     398                 :            : 
     399                 :            :         rte_spinlock_lock(&g_mtr_res.hw_plcr_res_lock);
     400         [ #  # ]:          0 :         if (g_mtr_res.hw_profile_refcnt[hw_profile_id] == 0) {
     401                 :          0 :                 PMD_DRV_LOG(ERR, "del hw profile id %d  but ref 0", hw_profile_id);
     402                 :            :                 rte_spinlock_unlock(&g_mtr_res.hw_plcr_res_lock);
     403                 :          0 :                 return -1;
     404                 :            :         }
     405         [ #  # ]:          0 :         if (--g_mtr_res.hw_profile_refcnt[hw_profile_id] == 0) {
     406                 :          0 :                 PMD_DRV_LOG(INFO, "del hw profile id %d ", hw_profile_id);
     407                 :          0 :                 zxdh_hw_profile_free(dev, car_type, hw_profile_id, error);
     408                 :            :         }
     409                 :            :         rte_spinlock_unlock(&g_mtr_res.hw_plcr_res_lock);
     410                 :          0 :         return 0;
     411                 :            : }
     412                 :            : 
     413                 :            : static int
     414                 :          0 : zxdh_mtr_hw_counter_query(struct rte_eth_dev *dev,
     415                 :            :         bool clear,
     416                 :            :         bool dir,
     417                 :            :         struct zxdh_mtr_stats *mtr_stats,
     418                 :            :         struct rte_mtr_error *error)
     419                 :            : {
     420                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     421                 :            :         int ret = 0;
     422                 :            : 
     423         [ #  # ]:          0 :         if (hw->is_pf) {
     424                 :          0 :                 ret = zxdh_mtr_stats_get(dev, dir, mtr_stats);
     425         [ #  # ]:          0 :                 if (ret) {
     426                 :          0 :                         PMD_DRV_LOG(ERR,
     427                 :            :                                 "ZXDH_PORT_METER_STAT_GET port %u dir %d failed",
     428                 :            :                                 hw->vport.vport,
     429                 :            :                                 dir);
     430                 :            : 
     431                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_STATS, NULL, "Failed to bind plcr flow.");
     432                 :            :                 }
     433                 :            :         } else { /* send msg to pf */
     434                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     435                 :          0 :                 struct zxdh_msg_reply_info reply_info = {0};
     436                 :            :                 struct zxdh_mtr_stats_query *zxdh_mtr_stats_query =
     437                 :            :                                 &msg_info.data.zxdh_mtr_stats_query;
     438                 :            : 
     439                 :          0 :                 zxdh_mtr_stats_query->direction = dir;
     440                 :          0 :                 zxdh_mtr_stats_query->is_clr = !!clear;
     441                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PORT_METER_STAT_GET, &msg_info);
     442                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev,
     443                 :            :                         &msg_info,
     444                 :            :                         sizeof(msg_info),
     445                 :            :                         &reply_info,
     446                 :            :                         sizeof(struct zxdh_msg_reply_info));
     447                 :            : 
     448         [ #  # ]:          0 :                 if (ret) {
     449                 :          0 :                         PMD_DRV_LOG(ERR,
     450                 :            :                                 "Failed to send msg: port 0x%x msg type ZXDH_PORT_METER_STAT_GET",
     451                 :            :                                 hw->vport.vport);
     452                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_STATS, NULL, "Meter offload alloc profile failed");
     453                 :            :                 }
     454                 :            :                 struct zxdh_mtr_stats *hw_mtr_stats = &reply_info.reply_body.hw_mtr_stats;
     455                 :            : 
     456                 :          0 :                 mtr_stats->n_bytes_dropped = hw_mtr_stats->n_bytes_dropped;
     457                 :          0 :                 mtr_stats->n_pkts_dropped = hw_mtr_stats->n_pkts_dropped;
     458                 :            :         }
     459                 :            : 
     460                 :            :         return ret;
     461                 :            : }
     462                 :            : 
     463                 :            : 
     464                 :            : static void
     465                 :          0 : zxdh_mtr_profile_res_free(struct rte_eth_dev *dev,
     466                 :            :                 struct rte_mempool *mtr_profile_mp,
     467                 :            :                 struct zxdh_meter_profile *meter_profile,
     468                 :            :                 struct rte_mtr_error *error)
     469                 :            : {
     470         [ #  # ]:          0 :         if (meter_profile->ref_cnt == 0) {
     471                 :          0 :                 ZXDH_MP_FREE_OBJ_FUNC(mtr_profile_mp, meter_profile);
     472                 :          0 :                 return;
     473                 :            :         }
     474         [ #  # ]:          0 :         if (meter_profile->ref_cnt == 1) {
     475                 :          0 :                 meter_profile->ref_cnt--;
     476                 :          0 :                 zxdh_hw_profile_unref(dev, CAR_A, meter_profile->hw_profile_id, error);
     477                 :            : 
     478   [ #  #  #  # ]:          0 :                 TAILQ_REMOVE(&zxdh_shared_data->meter_profile_list, meter_profile, next);
     479                 :          0 :                 ZXDH_MP_FREE_OBJ_FUNC(mtr_profile_mp, meter_profile);
     480                 :            :         } else {
     481                 :          0 :                 PMD_DRV_LOG(INFO,
     482                 :            :                         "profile %d ref %d is busy",
     483                 :            :                         meter_profile->meter_profile_id,
     484                 :            :                         meter_profile->ref_cnt);
     485                 :            :         }
     486                 :            : }
     487                 :            : 
     488                 :            : static uint16_t
     489                 :          0 : zxdh_check_hw_profile_exist(struct zxdh_mtr_profile_list *mpl,
     490                 :            :         struct rte_mtr_meter_profile *profile,
     491                 :            :         uint16_t hw_profile_owner_vport)
     492                 :            : {
     493                 :            :         struct zxdh_meter_profile *mp;
     494                 :            : 
     495         [ #  # ]:          0 :         TAILQ_FOREACH(mp, mpl, next) {
     496         [ #  # ]:          0 :                 if ((memcmp(profile, &mp->profile, sizeof(struct rte_mtr_meter_profile)) == 0) &&
     497         [ #  # ]:          0 :                         hw_profile_owner_vport == mp->hw_profile_owner_vport) {
     498                 :          0 :                         return mp->hw_profile_id;
     499                 :            :                 }
     500                 :            :         }
     501                 :            :         return ZXDH_HW_PROFILE_MAX;
     502                 :            : }
     503                 :            : 
     504                 :            : static void
     505                 :          0 : zxdh_plcr_param_build(struct rte_mtr_meter_profile *profile,
     506                 :            :                 void *plcr_param, uint16_t profile_id)
     507                 :            : {
     508         [ #  # ]:          0 :         if (profile->packet_mode == 0) {
     509                 :            :                 ZXDH_STAT_CAR_PROFILE_CFG_T *p_car_byte_profile_cfg =
     510                 :            :                         (ZXDH_STAT_CAR_PROFILE_CFG_T *)plcr_param;
     511                 :            : 
     512                 :          0 :                 p_car_byte_profile_cfg->profile_id = profile_id;
     513                 :          0 :                 p_car_byte_profile_cfg->pkt_sign = profile->packet_mode;
     514                 :          0 :                 p_car_byte_profile_cfg->cf = ZXDH_PLCR_CF_UNOVERFLOW;
     515                 :          0 :                 p_car_byte_profile_cfg->cm = ZXDH_PLCR_CM_BLIND;
     516         [ #  # ]:          0 :                 if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
     517                 :          0 :                         p_car_byte_profile_cfg->cd  = ZXDH_PLCR_CD_SRTCM;
     518                 :          0 :                         p_car_byte_profile_cfg->cir = profile->srtcm_rfc2697.cir * 8 / 1000;
     519                 :          0 :                         p_car_byte_profile_cfg->cbs = profile->srtcm_rfc2697.cbs;
     520                 :          0 :                         p_car_byte_profile_cfg->ebs = profile->srtcm_rfc2697.ebs;
     521                 :            :                 } else {
     522                 :          0 :                         p_car_byte_profile_cfg->cd  = ZXDH_PLCR_CD_TRTCM;
     523                 :          0 :                         p_car_byte_profile_cfg->cir = profile->trtcm_rfc2698.cir * 8 / 1000;
     524                 :          0 :                         p_car_byte_profile_cfg->cbs = profile->trtcm_rfc2698.cbs;
     525                 :          0 :                         p_car_byte_profile_cfg->eir = (profile->trtcm_rfc2698.pir -
     526                 :          0 :                                 profile->trtcm_rfc2698.cir) * 8 / 1000;
     527                 :          0 :                         p_car_byte_profile_cfg->ebs =
     528                 :          0 :                                 profile->trtcm_rfc2698.pbs - profile->trtcm_rfc2698.cbs;
     529                 :            :                 }
     530                 :            :         } else {
     531                 :            :                 ZXDH_STAT_CAR_PKT_PROFILE_CFG_T *p_car_pkt_profile_cfg =
     532                 :            :                         (ZXDH_STAT_CAR_PKT_PROFILE_CFG_T *)plcr_param;
     533                 :            : 
     534                 :          0 :                 p_car_pkt_profile_cfg->profile_id = profile_id;
     535                 :          0 :                 p_car_pkt_profile_cfg->pkt_sign = profile->packet_mode;
     536                 :            : 
     537         [ #  # ]:          0 :                 if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
     538                 :          0 :                         p_car_pkt_profile_cfg->cir = profile->srtcm_rfc2697.cir;
     539                 :          0 :                         p_car_pkt_profile_cfg->cbs = profile->srtcm_rfc2697.cbs;
     540                 :            :                 } else {
     541                 :          0 :                         p_car_pkt_profile_cfg->cir = profile->trtcm_rfc2698.cir;
     542                 :          0 :                         p_car_pkt_profile_cfg->cbs = profile->trtcm_rfc2698.cbs;
     543                 :            :                 }
     544                 :            :         }
     545                 :          0 : }
     546                 :            : 
     547                 :            : static int
     548                 :          0 : zxdh_hw_profile_config_direct(struct rte_eth_dev *dev __rte_unused,
     549                 :            :         ZXDH_PROFILE_TYPE car_type,
     550                 :            :         uint16_t hw_profile_id,
     551                 :            :         struct zxdh_meter_profile *mp,
     552                 :            :         struct rte_mtr_error *error)
     553                 :            : {
     554                 :          0 :         int ret = zxdh_np_car_profile_cfg_set(mp->hw_profile_owner_vport,
     555                 :          0 :                 car_type, mp->profile.packet_mode,
     556                 :          0 :                 (uint32_t)hw_profile_id, &mp->plcr_param);
     557         [ #  # ]:          0 :         if (ret) {
     558                 :          0 :                 PMD_DRV_LOG(ERR, " config hw profile %u failed", hw_profile_id);
     559                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     560                 :            :                         "Meter offload cfg profile failed");
     561                 :            :         }
     562                 :            : 
     563                 :            :         return 0;
     564                 :            : }
     565                 :            : 
     566                 :          0 : static int zxdh_hw_profile_config(struct rte_eth_dev *dev, uint16_t hw_profile_id,
     567                 :            :         struct zxdh_meter_profile *mp, struct rte_mtr_error *error)
     568                 :            : {
     569                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     570                 :            :         int ret = 0;
     571                 :            : 
     572         [ #  # ]:          0 :         if (hw->is_pf) {
     573                 :          0 :                 ret = zxdh_hw_profile_config_direct(dev, CAR_A, hw_profile_id, mp, error);
     574                 :            :         } else {
     575                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     576                 :          0 :                 struct zxdh_msg_reply_info reply_info = {0};
     577                 :            :                 struct zxdh_plcr_profile_cfg *zxdh_plcr_profile_cfg =
     578                 :            :                         &msg_info.data.zxdh_plcr_profile_cfg;
     579                 :            : 
     580                 :            :                 zxdh_plcr_profile_cfg->car_type = CAR_A;
     581                 :          0 :                 zxdh_plcr_profile_cfg->packet_mode = mp->profile.packet_mode;
     582                 :          0 :                 zxdh_plcr_profile_cfg->hw_profile_id = hw_profile_id;
     583                 :            :                 rte_memcpy(&zxdh_plcr_profile_cfg->plcr_param,
     584         [ #  # ]:          0 :                         &mp->plcr_param,
     585                 :            :                         sizeof(zxdh_plcr_profile_cfg->plcr_param));
     586                 :            : 
     587                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PLCR_CAR_PROFILE_CFG_SET, &msg_info);
     588                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev,
     589                 :            :                         &msg_info,
     590                 :            :                         ZXDH_MSG_HEAD_LEN + sizeof(struct zxdh_plcr_profile_cfg),
     591                 :            :                         &reply_info,
     592                 :            :                         sizeof(struct zxdh_msg_reply_info));
     593                 :            : 
     594         [ #  # ]:          0 :                 if (ret) {
     595                 :          0 :                         PMD_DRV_LOG(ERR,
     596                 :            :                                 "Failed msg: port 0x%x msg type ZXDH_PLCR_CAR_PROFILE_CFG_SET ",
     597                 :            :                                 hw->vport.vport);
     598                 :            : 
     599                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     600                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
     601                 :            :                                         "Meter offload cfg profile failed ");
     602                 :            :                 }
     603                 :            :         }
     604                 :            : 
     605                 :            :         return ret;
     606                 :            : }
     607                 :            : 
     608                 :            : static int
     609                 :          0 : zxdh_mtr_profile_offload(struct rte_eth_dev *dev, struct zxdh_meter_profile *mp,
     610                 :            :                 struct rte_mtr_meter_profile *profile, struct rte_mtr_error *error)
     611                 :            : {
     612                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     613                 :          0 :         uint16_t hw_profile_owner_vport = ZXDH_GET_OWNER_PF_VPORT(hw->vport.vport);
     614                 :            : 
     615                 :          0 :         mp->hw_profile_owner_vport = hw_profile_owner_vport;
     616                 :          0 :         uint64_t hw_profile_id =
     617                 :          0 :                 zxdh_check_hw_profile_exist(&zxdh_shared_data->meter_profile_list,
     618                 :            :                         profile,
     619                 :            :                         hw_profile_owner_vport);
     620                 :            : 
     621         [ #  # ]:          0 :         if (hw_profile_id == ZXDH_HW_PROFILE_MAX) {
     622                 :          0 :                 uint32_t ret = zxdh_hw_profile_alloc(dev, &hw_profile_id, error);
     623                 :            : 
     624         [ #  # ]:          0 :                 if (ret) {
     625                 :          0 :                         PMD_DRV_LOG(ERR, "hw_profile alloc fail");
     626                 :          0 :                         return ret;
     627                 :            :                 }
     628                 :            : 
     629                 :          0 :                 zxdh_plcr_param_build(profile, &mp->plcr_param, hw_profile_id);
     630                 :          0 :                 ret = zxdh_hw_profile_config(dev, hw_profile_id, mp, error);
     631         [ #  # ]:          0 :                 if (ret) {
     632                 :          0 :                         PMD_DRV_LOG(ERR, "zxdh_hw_profile_config fail");
     633                 :            :                         hw_profile_id = ZXDH_HW_PROFILE_MAX;
     634                 :          0 :                         return ret;
     635                 :            :                 }
     636                 :            :         }
     637                 :          0 :         zxdh_hw_profile_ref(hw_profile_id);
     638                 :          0 :         mp->hw_profile_id = hw_profile_id;
     639                 :            : 
     640                 :          0 :         return 0;
     641                 :            : }
     642                 :            : 
     643                 :            : static int
     644                 :          0 : zxdh_meter_profile_add(struct rte_eth_dev *dev,
     645                 :            :                                 uint32_t meter_profile_id,
     646                 :            :                                 struct rte_mtr_meter_profile *profile,
     647                 :            :                                 struct rte_mtr_error *error)
     648                 :            : {
     649                 :            :         struct zxdh_meter_profile *mp;
     650                 :            :         int ret;
     651                 :            : 
     652                 :          0 :         ret = zxdh_mtr_profile_validate(meter_profile_id, profile, error);
     653         [ #  # ]:          0 :         if (ret)
     654                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     655                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
     656                 :            :                                         NULL, "meter profile validate failed");
     657                 :          0 :         mp = zxdh_mtr_profile_find_by_id(&zxdh_shared_data->meter_profile_list,
     658                 :            :                 meter_profile_id,
     659                 :          0 :                 dev->data->port_id);
     660                 :            : 
     661         [ #  # ]:          0 :         if (mp)
     662                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     663                 :            :                                           RTE_MTR_ERROR_TYPE_METER_PROFILE,
     664                 :            :                                           NULL,
     665                 :            :                                           "meter profile is exists");
     666                 :            : 
     667                 :          0 :         mp = zxdh_mtr_profile_res_alloc(zxdh_shared_data->mtr_profile_mp);
     668         [ #  # ]:          0 :         if (mp == NULL)
     669                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     670                 :            :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
     671                 :            :                                         NULL, "Meter profile res memory alloc failed.");
     672                 :            : 
     673                 :            :         memset(mp, 0, sizeof(struct zxdh_meter_profile));
     674                 :            : 
     675                 :          0 :         mp->meter_profile_id = meter_profile_id;
     676                 :          0 :         mp->dpdk_port_id = dev->data->port_id;
     677                 :          0 :         mp->hw_profile_id = UINT16_MAX;
     678         [ #  # ]:          0 :         rte_memcpy(&mp->profile, profile, sizeof(struct rte_mtr_meter_profile));
     679                 :            : 
     680                 :          0 :         ret = zxdh_mtr_profile_offload(dev, mp, profile, error);
     681         [ #  # ]:          0 :         if (ret) {
     682                 :          0 :                 PMD_DRV_LOG(ERR,
     683                 :            :                         " port %d profile id  %d offload failed  ",
     684                 :            :                         dev->data->port_id,
     685                 :            :                         meter_profile_id);
     686                 :          0 :                 goto error;
     687                 :            :         }
     688                 :            : 
     689                 :          0 :         TAILQ_INSERT_TAIL(&zxdh_shared_data->meter_profile_list, mp, next);
     690                 :          0 :         PMD_DRV_LOG(DEBUG,
     691                 :            :                 "add profile id %d mp %p  mp->ref_cnt %d",
     692                 :            :                 meter_profile_id,
     693                 :            :                 mp,
     694                 :            :                 mp->ref_cnt);
     695                 :            : 
     696                 :          0 :         mp->ref_cnt++;
     697                 :            : 
     698                 :          0 :         return 0;
     699                 :            : error:
     700                 :          0 :         zxdh_mtr_profile_res_free(dev, zxdh_shared_data->mtr_profile_mp, mp, error);
     701                 :          0 :         return ret;
     702                 :            : }
     703                 :            : 
     704                 :            : static int
     705                 :          0 : zxdh_meter_profile_delete(struct rte_eth_dev *dev,
     706                 :            :                                 uint32_t meter_profile_id,
     707                 :            :                                 struct rte_mtr_error *error)
     708                 :            : {
     709                 :            :         struct zxdh_meter_profile *mp;
     710                 :            : 
     711                 :          0 :         mp = zxdh_mtr_profile_find_by_id(&zxdh_shared_data->meter_profile_list,
     712                 :            :                 meter_profile_id,
     713                 :          0 :                 dev->data->port_id);
     714                 :            : 
     715         [ #  # ]:          0 :         if (mp == NULL) {
     716                 :          0 :                 PMD_DRV_LOG(ERR, "del profile id %d  unfind ", meter_profile_id);
     717                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
     718                 :            :                                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
     719                 :            :                                                 &meter_profile_id,
     720                 :            :                                                  "Meter profile id is not exists.");
     721                 :            :         }
     722                 :          0 :         zxdh_mtr_profile_res_free(dev, zxdh_shared_data->mtr_profile_mp, mp, error);
     723                 :            : 
     724                 :          0 :         return 0;
     725                 :            : }
     726                 :            : 
     727                 :            : static int
     728                 :          0 : zxdh_meter_policy_add(struct rte_eth_dev *dev,
     729                 :            :                 uint32_t policy_id,
     730                 :            :                 struct rte_mtr_meter_policy_params *policy,
     731                 :            :                 struct rte_mtr_error *error)
     732                 :            : {
     733                 :            :         int ret = 0;
     734                 :            :         struct zxdh_meter_policy *mtr_policy = NULL;
     735                 :            : 
     736         [ #  # ]:          0 :         if (policy_id >= ZXDH_MAX_POLICY_NUM)
     737                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     738                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     739                 :            :                                         NULL, "policy ID is invalid. ");
     740                 :          0 :         mtr_policy = zxdh_mtr_policy_find_by_id(&zxdh_shared_data->mtr_policy_list,
     741                 :            :                                 policy_id,
     742                 :          0 :                                 dev->data->port_id);
     743                 :            : 
     744         [ #  # ]:          0 :         if (mtr_policy)
     745                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     746                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     747                 :            :                                         NULL, "policy ID  exists. ");
     748                 :            :         ret = zxdh_policy_validate_actions(policy->actions, error);
     749                 :            :         if (ret) {
     750                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     751                 :            :                                 RTE_MTR_ERROR_TYPE_METER_POLICY,
     752                 :            :                                 NULL, "  only supports def action.");
     753                 :            :         }
     754                 :            : 
     755                 :          0 :         mtr_policy = zxdh_mtr_policy_res_alloc(zxdh_shared_data->mtr_policy_mp);
     756         [ #  # ]:          0 :         if (mtr_policy == NULL) {
     757                 :          0 :                 return -rte_mtr_error_set(error, ENOMEM,
     758                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     759                 :            :                                         NULL, "Meter policy res memory alloc  failed.");
     760                 :            :         }
     761                 :            :         /* Fill profile info. */
     762                 :            :         memset(mtr_policy, 0, sizeof(struct zxdh_meter_policy));
     763                 :          0 :         mtr_policy->policy_id = policy_id;
     764                 :          0 :         mtr_policy->dpdk_port_id = dev->data->port_id;
     765         [ #  # ]:          0 :         rte_memcpy(&mtr_policy->policy, policy, sizeof(struct rte_mtr_meter_policy_params));
     766                 :            :         /* Add to list. */
     767                 :          0 :         TAILQ_INSERT_TAIL(&zxdh_shared_data->mtr_policy_list, mtr_policy, next);
     768                 :          0 :         mtr_policy->ref_cnt++;
     769                 :          0 :         PMD_DRV_LOG(INFO, "allic policy id %d ok %p ", mtr_policy->policy_id, mtr_policy);
     770                 :          0 :         return 0;
     771                 :            : }
     772                 :            : 
     773                 :            : static int
     774                 :          0 : zxdh_meter_policy_delete(struct rte_eth_dev *dev,
     775                 :            :         uint32_t policy_id,
     776                 :            :         struct rte_mtr_error *error)
     777                 :            : {
     778                 :            :         struct zxdh_meter_policy *mtr_policy = NULL;
     779                 :            : 
     780         [ #  # ]:          0 :         if (policy_id >= ZXDH_MAX_POLICY_NUM)
     781                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
     782                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     783                 :            :                                         NULL, "policy ID is invalid. ");
     784                 :          0 :         mtr_policy = zxdh_mtr_policy_find_by_id(&zxdh_shared_data->mtr_policy_list,
     785                 :          0 :                 policy_id, dev->data->port_id);
     786                 :            : 
     787   [ #  #  #  # ]:          0 :         if (mtr_policy && mtr_policy->ref_cnt == 1) {
     788         [ #  # ]:          0 :                 TAILQ_REMOVE(&zxdh_shared_data->mtr_policy_list, mtr_policy, next);
     789         [ #  # ]:          0 :                 MP_FREE_OBJ_FUNC(zxdh_shared_data->mtr_policy_mp, mtr_policy);
     790                 :            :         } else {
     791         [ #  # ]:          0 :                 if (mtr_policy) {
     792                 :          0 :                         PMD_DRV_LOG(INFO,
     793                 :            :                                 " policy id %d ref %d is busy ",
     794                 :            :                                 mtr_policy->policy_id,
     795                 :            :                                 mtr_policy->ref_cnt);
     796                 :            :                 } else {
     797                 :          0 :                         PMD_DRV_LOG(ERR, " policy id %d  is not exist ", policy_id);
     798                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     799                 :            :                                         RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
     800                 :            :                                         NULL, "policy ID is  not exist. ");
     801                 :            :                 }
     802                 :            :         }
     803                 :            :         return 0;
     804                 :            : }
     805                 :            : 
     806                 :            : static int
     807                 :          0 : zxdh_meter_validate(uint32_t meter_id,
     808                 :            :                         struct rte_mtr_params *params,
     809                 :            :                         struct rte_mtr_error *error)
     810                 :            : {
     811                 :            :         /* Meter params must not be NULL. */
     812         [ #  # ]:          0 :         if (params == NULL)
     813                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     814                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     815                 :            :                                         NULL, "Meter object params null.");
     816                 :            :         /* Previous meter color is not supported. */
     817         [ #  # ]:          0 :         if (params->use_prev_mtr_color)
     818                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     819                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     820                 :            :                                         NULL,
     821                 :            :                                         "Previous meter color not supported");
     822         [ #  # ]:          0 :         if (meter_id > ZXDH_MAX_MTR_NUM / 2) {
     823                 :          0 :                 return -rte_mtr_error_set(error, EINVAL,
     824                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     825                 :            :                                 NULL,
     826                 :            :                                 " meter id exceed 1024 unsupported");
     827                 :            :         }
     828                 :            :         return 0;
     829                 :            : }
     830                 :            : 
     831                 :            : static int
     832                 :          0 : zxdh_check_port_mtr_bind(struct rte_eth_dev *dev, uint32_t dir)
     833                 :            : {
     834                 :            :         struct zxdh_mtr_object *mtr_obj = NULL;
     835                 :            : 
     836         [ #  # ]:          0 :         TAILQ_FOREACH(mtr_obj, &zxdh_shared_data->mtr_list, next) {
     837         [ #  # ]:          0 :                 if (mtr_obj->direction != dir)
     838                 :          0 :                         continue;
     839         [ #  # ]:          0 :                 if (mtr_obj->port_id == dev->data->port_id) {
     840                 :          0 :                         PMD_DRV_LOG(INFO,
     841                 :            :                                 "port %d dir %d already bind meter %d",
     842                 :            :                                 dev->data->port_id,
     843                 :            :                                 dir,
     844                 :            :                                 mtr_obj->meter_id);
     845                 :          0 :                         return -1;
     846                 :            :                 }
     847                 :            :         }
     848                 :            : 
     849                 :            :         return 0;
     850                 :            : }
     851                 :            : 
     852                 :            : static struct zxdh_mtr_object
     853                 :          0 : *zxdh_mtr_obj_alloc(struct rte_mempool *mtr_mp)
     854                 :            : {
     855         [ #  # ]:          0 :         struct zxdh_mtr_object *mtr_obj = NULL;
     856                 :            : 
     857         [ #  # ]:          0 :         if (ZXDH_MP_ALLOC_OBJ_FUNC(mtr_mp, mtr_obj) != 0)
     858                 :            :                 return NULL;
     859                 :            : 
     860                 :          0 :         return mtr_obj;
     861                 :            : }
     862                 :            : 
     863                 :            : static uint32_t dir_to_mtr_mode[] = {
     864                 :            :         ZXDH_PORT_EGRESS_METER_EN_OFF_FLAG,
     865                 :            :         ZXDH_PORT_INGRESS_METER_EN_OFF_FLAG
     866                 :            : };
     867                 :            : 
     868                 :            : static int
     869                 :          0 : zxdh_set_mtr_enable(struct rte_eth_dev *dev, uint8_t dir, bool enable, struct rte_mtr_error *error)
     870                 :            : {
     871                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
     872                 :          0 :         struct zxdh_port_attr_table port_attr = {0};
     873                 :            :         int ret = 0;
     874                 :            : 
     875         [ #  # ]:          0 :         if (priv->is_pf) {
     876                 :          0 :                 ret = zxdh_get_port_attr(priv, priv->vport.vport, &port_attr);
     877                 :          0 :                 port_attr.ingress_meter_enable = enable;
     878                 :          0 :                 ret = zxdh_set_port_attr(priv, priv->vport.vport, &port_attr);
     879         [ #  # ]:          0 :                 if (ret) {
     880                 :          0 :                         PMD_DRV_LOG(ERR, "%s set port attr failed", __func__);
     881                 :          0 :                         return -ret;
     882                 :            :                 }
     883                 :            :         } else {
     884                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     885                 :            :                 struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
     886                 :            : 
     887                 :          0 :                 attr_msg->mode  = dir_to_mtr_mode[dir];
     888                 :          0 :                 attr_msg->value = enable;
     889                 :          0 :                 zxdh_msg_head_build(priv, ZXDH_PORT_ATTRS_SET, &msg_info);
     890                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
     891                 :            :                         sizeof(struct zxdh_msg_head) + sizeof(struct zxdh_port_attr_set_msg),
     892                 :            :                         NULL, 0);
     893                 :            :         }
     894         [ #  # ]:          0 :         if (ret) {
     895                 :          0 :                 PMD_DRV_LOG(ERR, " port %d  mtr enable failed", priv->port_id);
     896                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
     897                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
     898                 :            :                                         "Meter  enable failed.");
     899                 :            :         }
     900         [ #  # ]:          0 :         if (dir == ZXDH_INGRESS)
     901                 :          0 :                 priv->i_mtr_en = !!enable;
     902                 :            :         else
     903                 :          0 :                 priv->e_mtr_en = !!enable;
     904                 :            : 
     905                 :            :         return ret;
     906                 :            : }
     907                 :            : 
     908                 :            : static void
     909                 :            : zxdh_meter_build_actions(struct zxdh_meter_action *mtr_action,
     910                 :            :                 struct rte_mtr_params *params)
     911                 :            : {
     912                 :          0 :         mtr_action->stats_mask = params->stats_mask;
     913                 :          0 :         mtr_action->action[RTE_COLOR_RED] = ZXDH_MTR_POLICER_ACTION_DROP;
     914                 :            : }
     915                 :            : 
     916                 :            : static int
     917                 :          0 : zxdh_hw_plcrflow_config(struct rte_eth_dev *dev, uint16_t hw_flow_id,
     918                 :            :                 struct zxdh_mtr_object *mtr, struct rte_mtr_error *error)
     919                 :            : {
     920                 :          0 :         struct zxdh_hw *hw = dev->data->dev_private;
     921                 :            :         int ret = 0;
     922                 :            : 
     923         [ #  # ]:          0 :         if (hw->is_pf) {
     924                 :          0 :                 uint64_t hw_profile_id = (uint64_t)mtr->profile->hw_profile_id;
     925                 :            : 
     926                 :          0 :                 ret = zxdh_np_stat_car_queue_cfg_set(hw->dev_id, CAR_A,
     927                 :          0 :                         hw_flow_id, 1, mtr->enable, hw_profile_id);
     928                 :            : 
     929         [ #  # ]:          0 :                 if (ret) {
     930                 :          0 :                         PMD_DRV_LOG(ERR, "dpp_stat_car_queue_cfg_set failed flowid %d  profile id %d",
     931                 :            :                                                         hw_flow_id, mtr->profile->hw_profile_id);
     932                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     933                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     934                 :            :                                         NULL, "Failed to  bind  plcr flow.");
     935                 :            :                         ;
     936                 :            :                 }
     937                 :            :         } else {
     938                 :          0 :                 struct zxdh_msg_info msg_info = {0};
     939                 :          0 :                 struct zxdh_msg_reply_info reply_info = {0};
     940                 :            :                 struct zxdh_plcr_flow_cfg *zxdh_plcr_flow_cfg = &msg_info.data.zxdh_plcr_flow_cfg;
     941                 :            : 
     942                 :            :                 zxdh_plcr_flow_cfg->car_type = CAR_A;
     943                 :          0 :                 zxdh_plcr_flow_cfg->flow_id = hw_flow_id;
     944                 :          0 :                 zxdh_plcr_flow_cfg->drop_flag = 1;
     945                 :          0 :                 zxdh_plcr_flow_cfg->plcr_en = mtr->enable;
     946                 :          0 :                 zxdh_plcr_flow_cfg->profile_id = mtr->profile->hw_profile_id;
     947                 :          0 :                 zxdh_msg_head_build(hw, ZXDH_PLCR_CAR_QUEUE_CFG_SET, &msg_info);
     948                 :          0 :                 ret = zxdh_vf_send_msg_to_pf(dev, &msg_info,
     949                 :            :                         ZXDH_MSG_HEAD_LEN + sizeof(struct zxdh_plcr_flow_cfg),
     950                 :            :                         &reply_info,
     951                 :            :                         sizeof(struct zxdh_msg_reply_info));
     952         [ #  # ]:          0 :                 if (ret) {
     953                 :          0 :                         PMD_DRV_LOG(ERR,
     954                 :            :                                 "Failed msg: port 0x%x msg type ZXDH_PLCR_CAR_QUEUE_CFG_SET ",
     955                 :            :                                 hw->vport.vport);
     956                 :          0 :                         return -rte_mtr_error_set(error, ENOTSUP,
     957                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
     958                 :            :                                         NULL, "Failed to  bind  plcr flow.");
     959                 :            :                 }
     960                 :            :         }
     961                 :            : 
     962                 :            :         return ret;
     963                 :            : }
     964                 :            : 
     965                 :            : static void
     966                 :          0 : zxdh_mtr_obj_free(struct rte_eth_dev *dev, struct zxdh_mtr_object *mtr_obj)
     967                 :            : {
     968                 :          0 :         struct zxdh_mtr_list *mtr_list = &zxdh_shared_data->mtr_list;
     969                 :          0 :         struct rte_mempool *mtr_mp = zxdh_shared_data->mtr_mp;
     970                 :            : 
     971                 :          0 :         PMD_DRV_LOG(INFO, "free port %d dir %d meter %d  mtr refcnt:%d ....",
     972                 :            :                 dev->data->port_id, mtr_obj->direction, mtr_obj->meter_id, mtr_obj->mtr_ref_cnt);
     973                 :            : 
     974         [ #  # ]:          0 :         if (mtr_obj->policy)
     975                 :          0 :                 mtr_obj->policy->ref_cnt--;
     976                 :            : 
     977         [ #  # ]:          0 :         if (mtr_obj->profile)
     978                 :          0 :                 mtr_obj->profile->ref_cnt--;
     979                 :            : 
     980         [ #  # ]:          0 :         PMD_DRV_LOG(INFO,
     981                 :            :                 "free port %d dir %d meter %d  profile refcnt:%d ",
     982                 :            :                 dev->data->port_id,
     983                 :            :                 mtr_obj->direction,
     984                 :            :                 mtr_obj->meter_id,
     985                 :            :                 mtr_obj->profile ? mtr_obj->profile->ref_cnt : 0);
     986                 :            : 
     987         [ #  # ]:          0 :         if (--mtr_obj->mtr_ref_cnt == 0) {
     988                 :          0 :                 PMD_DRV_LOG(INFO, "rm  mtr %p refcnt:%d ....", mtr_obj, mtr_obj->mtr_ref_cnt);
     989   [ #  #  #  # ]:          0 :                 TAILQ_REMOVE(mtr_list, mtr_obj, next);
     990                 :          0 :                 MP_FREE_OBJ_FUNC(mtr_mp, mtr_obj);
     991                 :            :         }
     992                 :          0 : }
     993                 :            : 
     994                 :            : static int
     995                 :            : zxdh_mtr_flow_offlad(struct rte_eth_dev *dev,
     996                 :            :         struct zxdh_mtr_object *mtr,
     997                 :            :         struct rte_mtr_error *error)
     998                 :            : {
     999                 :            :         uint16_t hw_flow_id;
    1000                 :            : 
    1001                 :          0 :         hw_flow_id = mtr->vfid * 2 + ZXDH_PORT_MTR_FID_BASE + mtr->direction;
    1002                 :          0 :         return zxdh_hw_plcrflow_config(dev, hw_flow_id, mtr, error);
    1003                 :            : }
    1004                 :            : 
    1005                 :            : static struct zxdh_mtr_object *
    1006                 :          0 : zxdh_mtr_find(uint32_t meter_id, uint16_t dpdk_portid)
    1007                 :            : {
    1008                 :          0 :         struct zxdh_mtr_list *mtr_list = &zxdh_shared_data->mtr_list;
    1009                 :            :         struct zxdh_mtr_object *mtr = NULL;
    1010                 :            : 
    1011         [ #  # ]:          0 :         TAILQ_FOREACH(mtr, mtr_list, next) {
    1012                 :          0 :                 PMD_DRV_LOG(INFO,
    1013                 :            :                         "mtrlist head %p  mtr %p mtr->meterid %d to find mtrid %d",
    1014                 :            :                         TAILQ_FIRST(mtr_list),
    1015                 :            :                         mtr,
    1016                 :            :                         mtr->meter_id,
    1017                 :            :                         meter_id
    1018                 :            :                 );
    1019                 :            : 
    1020   [ #  #  #  # ]:          0 :                 if (meter_id == mtr->meter_id && dpdk_portid == mtr->port_id)
    1021                 :          0 :                         return mtr;
    1022                 :            :         }
    1023                 :            :         return NULL;
    1024                 :            : }
    1025                 :            : 
    1026                 :            : static int
    1027                 :          0 : zxdh_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
    1028                 :            :                                 struct rte_mtr_params *params, int shared,
    1029                 :            :                                 struct rte_mtr_error *error)
    1030                 :            : {
    1031                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
    1032                 :          0 :         struct zxdh_mtr_list *mtr_list = &zxdh_shared_data->mtr_list;
    1033                 :            :         struct zxdh_mtr_object *mtr;
    1034                 :            :         struct zxdh_meter_profile *mtr_profile;
    1035                 :            :         struct zxdh_meter_policy *mtr_policy;
    1036                 :            :         uint8_t dir = 0;
    1037                 :            :         int ret;
    1038                 :            : 
    1039         [ #  # ]:          0 :         if (shared)
    1040                 :          0 :                 return -rte_mtr_error_set(error, ENOTSUP,
    1041                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
    1042                 :            :                                         "Meter share is not supported");
    1043                 :            : 
    1044                 :          0 :         ret = zxdh_meter_validate(meter_id, params, error);
    1045         [ #  # ]:          0 :         if (ret)
    1046                 :            :                 return ret;
    1047                 :            : 
    1048         [ #  # ]:          0 :         if (zxdh_check_port_mtr_bind(dev, dir))
    1049                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
    1050                 :            :                                 RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
    1051                 :            :                                 "Meter object already bind to dev.");
    1052                 :            : 
    1053                 :          0 :         mtr_profile = zxdh_mtr_profile_find_by_id(&zxdh_shared_data->meter_profile_list,
    1054                 :            :                         params->meter_profile_id,
    1055                 :          0 :                         dev->data->port_id
    1056                 :            :         );
    1057                 :            : 
    1058         [ #  # ]:          0 :         if (mtr_profile == NULL)
    1059                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
    1060         [ #  # ]:          0 :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE, &params->meter_profile_id,
    1061                 :            :                                         "Meter profile object is not exists.");
    1062                 :          0 :         mtr_profile->ref_cnt++;
    1063                 :          0 :         mtr_policy = zxdh_mtr_policy_find_by_id(&zxdh_shared_data->mtr_policy_list,
    1064                 :          0 :                         params->meter_policy_id,
    1065                 :            :                         dev->data->port_id);
    1066                 :            : 
    1067         [ #  # ]:          0 :         if (mtr_policy == NULL) {
    1068                 :            :                 ret = -rte_mtr_error_set(error, EEXIST,
    1069         [ #  # ]:          0 :                                         RTE_MTR_ERROR_TYPE_METER_PROFILE, &params->meter_policy_id,
    1070                 :            :                                         "Meter policy object is not exists.");
    1071                 :          0 :                 mtr_profile->ref_cnt--;
    1072                 :          0 :                 return ret;
    1073                 :            :         }
    1074                 :          0 :         mtr_policy->ref_cnt++;
    1075                 :            : 
    1076                 :          0 :         mtr = zxdh_mtr_obj_alloc(zxdh_shared_data->mtr_mp);
    1077         [ #  # ]:          0 :         if (mtr == NULL) {
    1078                 :            :                 ret = -rte_mtr_error_set(error, ENOMEM,
    1079                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
    1080                 :            :                                         "Memory alloc failed for meter.");
    1081                 :          0 :                 mtr_policy->ref_cnt--;
    1082                 :          0 :                 mtr_profile->ref_cnt--;
    1083                 :          0 :                 return ret;
    1084                 :            :         }
    1085                 :            :         memset(mtr, 0, sizeof(struct zxdh_mtr_object));
    1086                 :            : 
    1087                 :          0 :         mtr->meter_id = meter_id;
    1088                 :          0 :         mtr->profile = mtr_profile;
    1089                 :            : 
    1090                 :            :         zxdh_meter_build_actions(&mtr->mtr_action, params);
    1091                 :          0 :         TAILQ_INSERT_TAIL(mtr_list, mtr, next);
    1092                 :          0 :         mtr->enable = !!params->meter_enable;
    1093                 :          0 :         mtr->shared = !!shared;
    1094                 :          0 :         mtr->mtr_ref_cnt++;
    1095                 :          0 :         mtr->vfid = priv->vfid;
    1096                 :          0 :         mtr->port_id = dev->data->port_id;
    1097                 :          0 :         mtr->policy = mtr_policy;
    1098                 :          0 :         mtr->direction = !!dir;
    1099         [ #  # ]:          0 :         if (params->meter_enable) {
    1100                 :            :                 ret = zxdh_mtr_flow_offlad(dev, mtr, error);
    1101         [ #  # ]:          0 :                 if (ret)
    1102                 :          0 :                         goto error;
    1103                 :            :         }
    1104                 :          0 :         ret = zxdh_set_mtr_enable(dev, mtr->direction, 1, error);
    1105         [ #  # ]:          0 :         if (ret)
    1106                 :          0 :                 goto error;
    1107                 :            :         return ret;
    1108                 :          0 : error:
    1109                 :          0 :         zxdh_mtr_obj_free(dev, mtr);
    1110                 :          0 :         return ret;
    1111                 :            : }
    1112                 :            : 
    1113                 :            : static int
    1114                 :          0 : zxdh_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,
    1115                 :            :                         struct rte_mtr_error *error)
    1116                 :            : {
    1117                 :            :         struct zxdh_mtr_object *mtr;
    1118                 :            : 
    1119                 :          0 :         mtr = zxdh_mtr_find(meter_id, dev->data->port_id);
    1120         [ #  # ]:          0 :         if (mtr == NULL)
    1121                 :          0 :                 return -rte_mtr_error_set(error, EEXIST,
    1122                 :            :                                           RTE_MTR_ERROR_TYPE_MTR_ID,
    1123                 :            :                                           NULL, "Meter object id not valid.");
    1124                 :          0 :         mtr->enable = 0;
    1125                 :          0 :         zxdh_set_mtr_enable(dev, mtr->direction, 0, error);
    1126                 :            : 
    1127         [ #  # ]:          0 :         if (zxdh_mtr_flow_offlad(dev, mtr, error))
    1128                 :            :                 return -1;
    1129                 :            : 
    1130                 :          0 :         zxdh_mtr_obj_free(dev, mtr);
    1131                 :          0 :         return 0;
    1132                 :            : }
    1133                 :            : 
    1134                 :            : void
    1135                 :          0 : zxdh_mtr_policy_res_free(struct rte_mempool *mtr_policy_mp, struct zxdh_meter_policy *policy)
    1136                 :            : {
    1137                 :          0 :         PMD_DRV_LOG(INFO, "to free policy %d  ref  %d  ", policy->policy_id,  policy->ref_cnt);
    1138                 :            : 
    1139         [ #  # ]:          0 :         if (--policy->ref_cnt == 0) {
    1140   [ #  #  #  # ]:          0 :                 TAILQ_REMOVE(&zxdh_shared_data->mtr_policy_list, policy, next);
    1141                 :          0 :                 MP_FREE_OBJ_FUNC(mtr_policy_mp, policy);
    1142                 :            :         }
    1143                 :          0 : }
    1144                 :            : 
    1145                 :            : static int
    1146                 :          0 : zxdh_mtr_stats_read(struct rte_eth_dev *dev,
    1147                 :            :                                                                 uint32_t mtr_id,
    1148                 :            :                                                                 struct rte_mtr_stats *stats,
    1149                 :            :                                                                 uint64_t *stats_mask,
    1150                 :            :                                                                 int clear,
    1151                 :            :                                                                 struct rte_mtr_error *error)
    1152                 :            : {
    1153                 :          0 :         struct zxdh_mtr_stats mtr_stat = {0};
    1154                 :            :         struct zxdh_mtr_object *mtr = NULL;
    1155                 :            :         int ret = 0;
    1156                 :            :         /* Meter object must exist. */
    1157                 :          0 :         mtr = zxdh_mtr_find(mtr_id, dev->data->port_id);
    1158         [ #  # ]:          0 :         if (mtr == NULL)
    1159                 :          0 :                 return -rte_mtr_error_set(error, ENOENT,
    1160                 :            :                                         RTE_MTR_ERROR_TYPE_MTR_ID,
    1161                 :            :                                         NULL, "Meter object id not valid.");
    1162                 :          0 :         *stats_mask = RTE_MTR_STATS_N_BYTES_DROPPED | RTE_MTR_STATS_N_PKTS_DROPPED;
    1163                 :            :         memset(&mtr_stat, 0, sizeof(mtr_stat));
    1164                 :          0 :         ret = zxdh_mtr_hw_counter_query(dev, clear, mtr->direction, &mtr_stat, error);
    1165         [ #  # ]:          0 :         if (ret)
    1166         [ #  # ]:          0 :                 goto error;
    1167                 :          0 :         stats->n_bytes_dropped = mtr_stat.n_bytes_dropped;
    1168                 :          0 :         stats->n_pkts_dropped = mtr_stat.n_pkts_dropped;
    1169                 :            : 
    1170                 :          0 :         return 0;
    1171                 :            : error:
    1172                 :          0 :         return -rte_mtr_error_set(error, ret, RTE_MTR_ERROR_TYPE_STATS, NULL,
    1173                 :            :                                 "Failed to read meter drop counters.");
    1174                 :            : }
    1175                 :            : 
    1176                 :            : static const struct rte_mtr_ops zxdh_mtr_ops = {
    1177                 :            :         .capabilities_get = zxdh_meter_cap_get,
    1178                 :            :         .meter_profile_add = zxdh_meter_profile_add,
    1179                 :            :         .meter_profile_delete = zxdh_meter_profile_delete,
    1180                 :            :         .create = zxdh_meter_create,
    1181                 :            :         .destroy = zxdh_meter_destroy,
    1182                 :            :         .stats_read = zxdh_mtr_stats_read,
    1183                 :            :         .meter_policy_add = zxdh_meter_policy_add,
    1184                 :            :         .meter_policy_delete = zxdh_meter_policy_delete,
    1185                 :            : };
    1186                 :            : 
    1187                 :            : int
    1188                 :          0 : zxdh_meter_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
    1189                 :            : {
    1190                 :          0 :         *(const struct rte_mtr_ops **)arg = &zxdh_mtr_ops;
    1191                 :          0 :         return 0;
    1192                 :            : }
    1193                 :            : 
    1194                 :            : void
    1195                 :          0 : zxdh_mtr_release(struct rte_eth_dev *dev)
    1196                 :            : {
    1197                 :          0 :         struct zxdh_hw *priv = dev->data->dev_private;
    1198                 :            :         struct zxdh_meter_profile *profile;
    1199                 :          0 :         struct rte_mtr_error error = {0};
    1200                 :            :         struct zxdh_mtr_object *mtr_obj;
    1201                 :            : 
    1202         [ #  # ]:          0 :         RTE_TAILQ_FOREACH(mtr_obj, &zxdh_shared_data->mtr_list, next) {
    1203         [ #  # ]:          0 :                 if (mtr_obj->port_id == priv->port_id)
    1204                 :          0 :                         zxdh_mtr_obj_free(dev, mtr_obj);
    1205                 :            :         }
    1206                 :            : 
    1207                 :            : 
    1208         [ #  # ]:          0 :         RTE_TAILQ_FOREACH(profile, &zxdh_shared_data->meter_profile_list, next) {
    1209         [ #  # ]:          0 :                 if (profile->dpdk_port_id == priv->port_id)
    1210                 :          0 :                         zxdh_mtr_profile_res_free(dev,
    1211                 :          0 :                                 zxdh_shared_data->mtr_profile_mp,
    1212                 :            :                                 profile,
    1213                 :            :                                 &error
    1214                 :            :                         );
    1215                 :            :         }
    1216                 :            : 
    1217                 :            :         struct zxdh_meter_policy *policy;
    1218                 :            : 
    1219         [ #  # ]:          0 :         RTE_TAILQ_FOREACH(policy, &zxdh_shared_data->mtr_policy_list, next) {
    1220         [ #  # ]:          0 :                 if (policy->dpdk_port_id == priv->port_id)
    1221                 :          0 :                         zxdh_mtr_policy_res_free(zxdh_shared_data->mtr_policy_mp, policy);
    1222                 :            :         }
    1223                 :          0 : }

Generated by: LCOV version 1.14