LCOV - code coverage report
Current view: top level - drivers/net/intel/i40e - i40e_tm.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 449 0.0 %
Date: 2025-02-01 18:54:23 Functions: 0 14 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 240 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2017 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_malloc.h>
       6                 :            : 
       7                 :            : #include "base/i40e_prototype.h"
       8                 :            : #include "i40e_ethdev.h"
       9                 :            : 
      10                 :            : static int i40e_tm_capabilities_get(struct rte_eth_dev *dev,
      11                 :            :                                     struct rte_tm_capabilities *cap,
      12                 :            :                                     struct rte_tm_error *error);
      13                 :            : static int i40e_shaper_profile_add(struct rte_eth_dev *dev,
      14                 :            :                                    uint32_t shaper_profile_id,
      15                 :            :                                    const struct rte_tm_shaper_params *profile,
      16                 :            :                                    struct rte_tm_error *error);
      17                 :            : static int i40e_shaper_profile_del(struct rte_eth_dev *dev,
      18                 :            :                                    uint32_t shaper_profile_id,
      19                 :            :                                    struct rte_tm_error *error);
      20                 :            : static int i40e_node_add(struct rte_eth_dev *dev, uint32_t node_id,
      21                 :            :                          uint32_t parent_node_id, uint32_t priority,
      22                 :            :                          uint32_t weight, uint32_t level_id,
      23                 :            :                          const struct rte_tm_node_params *params,
      24                 :            :                          struct rte_tm_error *error);
      25                 :            : static int i40e_node_delete(struct rte_eth_dev *dev, uint32_t node_id,
      26                 :            :                             struct rte_tm_error *error);
      27                 :            : static int i40e_node_type_get(struct rte_eth_dev *dev, uint32_t node_id,
      28                 :            :                               int *is_leaf, struct rte_tm_error *error);
      29                 :            : static int i40e_level_capabilities_get(struct rte_eth_dev *dev,
      30                 :            :                                        uint32_t level_id,
      31                 :            :                                        struct rte_tm_level_capabilities *cap,
      32                 :            :                                        struct rte_tm_error *error);
      33                 :            : static int i40e_node_capabilities_get(struct rte_eth_dev *dev,
      34                 :            :                                       uint32_t node_id,
      35                 :            :                                       struct rte_tm_node_capabilities *cap,
      36                 :            :                                       struct rte_tm_error *error);
      37                 :            : static int i40e_hierarchy_commit(struct rte_eth_dev *dev,
      38                 :            :                                  int clear_on_fail,
      39                 :            :                                  struct rte_tm_error *error);
      40                 :            : 
      41                 :            : const struct rte_tm_ops i40e_tm_ops = {
      42                 :            :         .capabilities_get = i40e_tm_capabilities_get,
      43                 :            :         .shaper_profile_add = i40e_shaper_profile_add,
      44                 :            :         .shaper_profile_delete = i40e_shaper_profile_del,
      45                 :            :         .node_add = i40e_node_add,
      46                 :            :         .node_delete = i40e_node_delete,
      47                 :            :         .node_type_get = i40e_node_type_get,
      48                 :            :         .level_capabilities_get = i40e_level_capabilities_get,
      49                 :            :         .node_capabilities_get = i40e_node_capabilities_get,
      50                 :            :         .hierarchy_commit = i40e_hierarchy_commit,
      51                 :            : };
      52                 :            : 
      53                 :            : int
      54                 :          0 : i40e_tm_ops_get(struct rte_eth_dev *dev __rte_unused,
      55                 :            :                 void *arg)
      56                 :            : {
      57         [ #  # ]:          0 :         if (!arg)
      58                 :            :                 return -EINVAL;
      59                 :            : 
      60                 :          0 :         *(const void **)arg = &i40e_tm_ops;
      61                 :            : 
      62                 :          0 :         return 0;
      63                 :            : }
      64                 :            : 
      65                 :            : void
      66                 :          0 : i40e_tm_conf_init(struct rte_eth_dev *dev)
      67                 :            : {
      68                 :          0 :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
      69                 :            : 
      70                 :            :         /* initialize shaper profile list */
      71                 :          0 :         TAILQ_INIT(&pf->tm_conf.shaper_profile_list);
      72                 :            : 
      73                 :            :         /* initialize node configuration */
      74                 :          0 :         pf->tm_conf.root = NULL;
      75                 :          0 :         TAILQ_INIT(&pf->tm_conf.tc_list);
      76                 :          0 :         TAILQ_INIT(&pf->tm_conf.queue_list);
      77                 :          0 :         pf->tm_conf.nb_tc_node = 0;
      78                 :          0 :         pf->tm_conf.nb_queue_node = 0;
      79                 :          0 :         pf->tm_conf.committed = false;
      80                 :          0 : }
      81                 :            : 
      82                 :            : void
      83                 :          0 : i40e_tm_conf_uninit(struct rte_eth_dev *dev)
      84                 :            : {
      85                 :          0 :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
      86                 :            :         struct i40e_tm_shaper_profile *shaper_profile;
      87                 :            :         struct i40e_tm_node *tm_node;
      88                 :            : 
      89                 :            :         /* clear node configuration */
      90         [ #  # ]:          0 :         while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) {
      91         [ #  # ]:          0 :                 TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
      92                 :          0 :                 rte_free(tm_node);
      93                 :            :         }
      94                 :          0 :         pf->tm_conf.nb_queue_node = 0;
      95         [ #  # ]:          0 :         while ((tm_node = TAILQ_FIRST(&pf->tm_conf.tc_list))) {
      96         [ #  # ]:          0 :                 TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node);
      97                 :          0 :                 rte_free(tm_node);
      98                 :            :         }
      99                 :          0 :         pf->tm_conf.nb_tc_node = 0;
     100         [ #  # ]:          0 :         if (pf->tm_conf.root) {
     101                 :          0 :                 rte_free(pf->tm_conf.root);
     102                 :          0 :                 pf->tm_conf.root = NULL;
     103                 :            :         }
     104                 :            : 
     105                 :            :         /* Remove all shaper profiles */
     106         [ #  # ]:          0 :         while ((shaper_profile =
     107                 :            :                TAILQ_FIRST(&pf->tm_conf.shaper_profile_list))) {
     108         [ #  # ]:          0 :                 TAILQ_REMOVE(&pf->tm_conf.shaper_profile_list,
     109                 :            :                              shaper_profile, node);
     110                 :          0 :                 rte_free(shaper_profile);
     111                 :            :         }
     112                 :          0 : }
     113                 :            : 
     114                 :            : static inline uint16_t
     115                 :            : i40e_tc_nb_get(struct rte_eth_dev *dev)
     116                 :            : {
     117                 :            :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     118                 :          0 :         struct i40e_vsi *main_vsi = pf->main_vsi;
     119                 :            :         uint16_t sum = 0;
     120                 :            :         int i;
     121                 :            : 
     122   [ #  #  #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
     123   [ #  #  #  # ]:          0 :                 if (main_vsi->enabled_tc & BIT_ULL(i))
     124                 :          0 :                         sum++;
     125                 :            :         }
     126                 :            : 
     127                 :            :         return sum;
     128                 :            : }
     129                 :            : 
     130                 :            : static int
     131                 :          0 : i40e_tm_capabilities_get(struct rte_eth_dev *dev,
     132                 :            :                          struct rte_tm_capabilities *cap,
     133                 :            :                          struct rte_tm_error *error)
     134                 :            : {
     135                 :          0 :         struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     136                 :            :         uint16_t tc_nb = i40e_tc_nb_get(dev);
     137                 :            : 
     138         [ #  # ]:          0 :         if (!cap || !error)
     139                 :            :                 return -EINVAL;
     140                 :            : 
     141         [ #  # ]:          0 :         if (tc_nb > hw->func_caps.num_tx_qp)
     142                 :            :                 return -EINVAL;
     143                 :            : 
     144                 :          0 :         error->type = RTE_TM_ERROR_TYPE_NONE;
     145                 :            : 
     146                 :            :         /* set all the parameters to 0 first. */
     147                 :            :         memset(cap, 0, sizeof(struct rte_tm_capabilities));
     148                 :            : 
     149                 :            :         /**
     150                 :            :          * support port + TCs + queues
     151                 :            :          * here shows the max capability not the current configuration.
     152                 :            :          */
     153                 :          0 :         cap->n_nodes_max = 1 + I40E_MAX_TRAFFIC_CLASS + hw->func_caps.num_tx_qp;
     154                 :          0 :         cap->n_levels_max = 3; /* port, TC, queue */
     155                 :          0 :         cap->non_leaf_nodes_identical = 1;
     156                 :          0 :         cap->leaf_nodes_identical = 1;
     157                 :          0 :         cap->shaper_n_max = cap->n_nodes_max;
     158                 :          0 :         cap->shaper_private_n_max = cap->n_nodes_max;
     159                 :            :         cap->shaper_private_dual_rate_n_max = 0;
     160                 :            :         cap->shaper_private_rate_min = 0;
     161                 :            :         /* 40Gbps -> 5GBps */
     162                 :          0 :         cap->shaper_private_rate_max = 5000000000ull;
     163                 :            :         cap->shaper_private_packet_mode_supported = 0;
     164                 :          0 :         cap->shaper_private_byte_mode_supported = 1;
     165                 :            :         cap->shaper_shared_n_max = 0;
     166                 :            :         cap->shaper_shared_n_nodes_per_shaper_max = 0;
     167                 :            :         cap->shaper_shared_n_shapers_per_node_max = 0;
     168                 :            :         cap->shaper_shared_dual_rate_n_max = 0;
     169                 :            :         cap->shaper_shared_rate_min = 0;
     170                 :            :         cap->shaper_shared_rate_max = 0;
     171                 :            :         cap->shaper_shared_packet_mode_supported = 0;
     172                 :            :         cap->shaper_shared_byte_mode_supported = 0;
     173                 :          0 :         cap->sched_n_children_max = hw->func_caps.num_tx_qp;
     174                 :            :         /**
     175                 :            :          * HW supports SP. But no plan to support it now.
     176                 :            :          * So, all the nodes should have the same priority.
     177                 :            :          */
     178                 :          0 :         cap->sched_sp_n_priorities_max = 1;
     179                 :            :         cap->sched_wfq_n_children_per_group_max = 0;
     180                 :            :         cap->sched_wfq_n_groups_max = 0;
     181                 :            :         /**
     182                 :            :          * SW only supports fair round robin now.
     183                 :            :          * So, all the nodes should have the same weight.
     184                 :            :          */
     185                 :          0 :         cap->sched_wfq_weight_max = 1;
     186                 :            :         cap->sched_wfq_packet_mode_supported = 0;
     187                 :            :         cap->sched_wfq_byte_mode_supported = 0;
     188                 :            :         cap->cman_head_drop_supported = 0;
     189                 :            :         cap->dynamic_update_mask = 0;
     190                 :          0 :         cap->shaper_pkt_length_adjust_min = RTE_TM_ETH_FRAMING_OVERHEAD;
     191                 :          0 :         cap->shaper_pkt_length_adjust_max = RTE_TM_ETH_FRAMING_OVERHEAD_FCS;
     192                 :            :         cap->cman_wred_context_n_max = 0;
     193                 :            :         cap->cman_wred_context_private_n_max = 0;
     194                 :            :         cap->cman_wred_context_shared_n_max = 0;
     195                 :            :         cap->cman_wred_context_shared_n_nodes_per_context_max = 0;
     196                 :            :         cap->cman_wred_context_shared_n_contexts_per_node_max = 0;
     197                 :            :         cap->stats_mask = 0;
     198                 :            : 
     199                 :          0 :         return 0;
     200                 :            : }
     201                 :            : 
     202                 :            : static inline struct i40e_tm_shaper_profile *
     203                 :            : i40e_shaper_profile_search(struct rte_eth_dev *dev,
     204                 :            :                            uint32_t shaper_profile_id)
     205                 :            : {
     206                 :            :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     207                 :            :         struct i40e_shaper_profile_list *shaper_profile_list =
     208                 :            :                 &pf->tm_conf.shaper_profile_list;
     209                 :            :         struct i40e_tm_shaper_profile *shaper_profile;
     210                 :            : 
     211   [ #  #  #  #  :          0 :         TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {
                   #  # ]
     212   [ #  #  #  #  :          0 :                 if (shaper_profile_id == shaper_profile->shaper_profile_id)
                   #  # ]
     213                 :            :                         return shaper_profile;
     214                 :            :         }
     215                 :            : 
     216                 :            :         return NULL;
     217                 :            : }
     218                 :            : 
     219                 :            : static int
     220                 :            : i40e_shaper_profile_param_check(const struct rte_tm_shaper_params *profile,
     221                 :            :                                 struct rte_tm_error *error)
     222                 :            : {
     223                 :            :         /* min rate not supported */
     224         [ #  # ]:          0 :         if (profile->committed.rate) {
     225                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_RATE;
     226                 :          0 :                 error->message = "committed rate not supported";
     227                 :            :                 return -EINVAL;
     228                 :            :         }
     229                 :            :         /* min bucket size not supported */
     230         [ #  # ]:          0 :         if (profile->committed.size) {
     231                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_SIZE;
     232                 :          0 :                 error->message = "committed bucket size not supported";
     233                 :            :                 return -EINVAL;
     234                 :            :         }
     235                 :            :         /* max bucket size not supported */
     236         [ #  # ]:          0 :         if (profile->peak.size) {
     237                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE;
     238                 :          0 :                 error->message = "peak bucket size not supported";
     239                 :            :                 return -EINVAL;
     240                 :            :         }
     241                 :            :         /* length adjustment not supported */
     242         [ #  # ]:          0 :         if (profile->pkt_length_adjust) {
     243                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN;
     244                 :          0 :                 error->message = "packet length adjustment not supported";
     245                 :            :                 return -EINVAL;
     246                 :            :         }
     247                 :            : 
     248                 :            :         return 0;
     249                 :            : }
     250                 :            : 
     251                 :            : static int
     252                 :          0 : i40e_shaper_profile_add(struct rte_eth_dev *dev,
     253                 :            :                         uint32_t shaper_profile_id,
     254                 :            :                         const struct rte_tm_shaper_params *profile,
     255                 :            :                         struct rte_tm_error *error)
     256                 :            : {
     257                 :          0 :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     258                 :            :         struct i40e_tm_shaper_profile *shaper_profile;
     259                 :            :         int ret;
     260                 :            : 
     261         [ #  # ]:          0 :         if (!profile || !error)
     262                 :            :                 return -EINVAL;
     263                 :            : 
     264                 :            :         ret = i40e_shaper_profile_param_check(profile, error);
     265                 :            :         if (ret)
     266                 :          0 :                 return ret;
     267                 :            : 
     268                 :            :         shaper_profile = i40e_shaper_profile_search(dev, shaper_profile_id);
     269                 :            : 
     270         [ #  # ]:          0 :         if (shaper_profile) {
     271                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID;
     272                 :          0 :                 error->message = "profile ID exist";
     273                 :          0 :                 return -EINVAL;
     274                 :            :         }
     275                 :            : 
     276                 :          0 :         shaper_profile = rte_zmalloc("i40e_tm_shaper_profile",
     277                 :            :                                      sizeof(struct i40e_tm_shaper_profile),
     278                 :            :                                      0);
     279         [ #  # ]:          0 :         if (!shaper_profile)
     280                 :            :                 return -ENOMEM;
     281                 :          0 :         shaper_profile->shaper_profile_id = shaper_profile_id;
     282         [ #  # ]:          0 :         rte_memcpy(&shaper_profile->profile, profile,
     283                 :            :                          sizeof(struct rte_tm_shaper_params));
     284                 :          0 :         TAILQ_INSERT_TAIL(&pf->tm_conf.shaper_profile_list,
     285                 :            :                           shaper_profile, node);
     286                 :            : 
     287                 :          0 :         return 0;
     288                 :            : }
     289                 :            : 
     290                 :            : static int
     291                 :          0 : i40e_shaper_profile_del(struct rte_eth_dev *dev,
     292                 :            :                         uint32_t shaper_profile_id,
     293                 :            :                         struct rte_tm_error *error)
     294                 :            : {
     295                 :          0 :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     296                 :            :         struct i40e_tm_shaper_profile *shaper_profile;
     297                 :            : 
     298         [ #  # ]:          0 :         if (!error)
     299                 :            :                 return -EINVAL;
     300                 :            : 
     301                 :            :         shaper_profile = i40e_shaper_profile_search(dev, shaper_profile_id);
     302                 :            : 
     303         [ #  # ]:          0 :         if (!shaper_profile) {
     304                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID;
     305                 :          0 :                 error->message = "profile ID not exist";
     306                 :          0 :                 return -EINVAL;
     307                 :            :         }
     308                 :            : 
     309                 :            :         /* don't delete a profile if it's used by one or several nodes */
     310         [ #  # ]:          0 :         if (shaper_profile->reference_count) {
     311                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE;
     312                 :          0 :                 error->message = "profile in use";
     313                 :          0 :                 return -EINVAL;
     314                 :            :         }
     315                 :            : 
     316         [ #  # ]:          0 :         TAILQ_REMOVE(&pf->tm_conf.shaper_profile_list, shaper_profile, node);
     317                 :          0 :         rte_free(shaper_profile);
     318                 :            : 
     319                 :          0 :         return 0;
     320                 :            : }
     321                 :            : 
     322                 :            : static inline struct i40e_tm_node *
     323                 :          0 : i40e_tm_node_search(struct rte_eth_dev *dev,
     324                 :            :                     uint32_t node_id, enum i40e_tm_node_type *node_type)
     325                 :            : {
     326                 :          0 :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     327                 :            :         struct i40e_tm_node_list *queue_list = &pf->tm_conf.queue_list;
     328                 :            :         struct i40e_tm_node_list *tc_list = &pf->tm_conf.tc_list;
     329                 :            :         struct i40e_tm_node *tm_node;
     330                 :            : 
     331   [ #  #  #  # ]:          0 :         if (pf->tm_conf.root && pf->tm_conf.root->id == node_id) {
     332                 :          0 :                 *node_type = I40E_TM_NODE_TYPE_PORT;
     333                 :          0 :                 return pf->tm_conf.root;
     334                 :            :         }
     335                 :            : 
     336         [ #  # ]:          0 :         TAILQ_FOREACH(tm_node, tc_list, node) {
     337         [ #  # ]:          0 :                 if (tm_node->id == node_id) {
     338                 :          0 :                         *node_type = I40E_TM_NODE_TYPE_TC;
     339                 :          0 :                         return tm_node;
     340                 :            :                 }
     341                 :            :         }
     342                 :            : 
     343         [ #  # ]:          0 :         TAILQ_FOREACH(tm_node, queue_list, node) {
     344         [ #  # ]:          0 :                 if (tm_node->id == node_id) {
     345                 :          0 :                         *node_type = I40E_TM_NODE_TYPE_QUEUE;
     346                 :          0 :                         return tm_node;
     347                 :            :                 }
     348                 :            :         }
     349                 :            : 
     350                 :            :         return NULL;
     351                 :            : }
     352                 :            : 
     353                 :            : static int
     354                 :          0 : i40e_node_param_check(struct rte_eth_dev *dev, uint32_t node_id,
     355                 :            :                       uint32_t priority, uint32_t weight,
     356                 :            :                       const struct rte_tm_node_params *params,
     357                 :            :                       struct rte_tm_error *error)
     358                 :            : {
     359                 :          0 :         struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     360                 :            : 
     361         [ #  # ]:          0 :         if (node_id == RTE_TM_NODE_ID_NULL) {
     362                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     363                 :          0 :                 error->message = "invalid node id";
     364                 :          0 :                 return -EINVAL;
     365                 :            :         }
     366                 :            : 
     367         [ #  # ]:          0 :         if (priority) {
     368                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_PRIORITY;
     369                 :          0 :                 error->message = "priority should be 0";
     370                 :          0 :                 return -EINVAL;
     371                 :            :         }
     372                 :            : 
     373         [ #  # ]:          0 :         if (weight != 1) {
     374                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT;
     375                 :          0 :                 error->message = "weight must be 1";
     376                 :          0 :                 return -EINVAL;
     377                 :            :         }
     378                 :            : 
     379                 :            :         /* not support shared shaper */
     380         [ #  # ]:          0 :         if (params->shared_shaper_id) {
     381                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID;
     382                 :          0 :                 error->message = "shared shaper not supported";
     383                 :          0 :                 return -EINVAL;
     384                 :            :         }
     385         [ #  # ]:          0 :         if (params->n_shared_shapers) {
     386                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS;
     387                 :          0 :                 error->message = "shared shaper not supported";
     388                 :          0 :                 return -EINVAL;
     389                 :            :         }
     390                 :            : 
     391                 :            :         /* for non-leaf node */
     392         [ #  # ]:          0 :         if (node_id >= hw->func_caps.num_tx_qp) {
     393         [ #  # ]:          0 :                 if (params->nonleaf.wfq_weight_mode) {
     394                 :          0 :                         error->type =
     395                 :            :                                 RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE;
     396                 :          0 :                         error->message = "WFQ not supported";
     397                 :          0 :                         return -EINVAL;
     398                 :            :                 }
     399         [ #  # ]:          0 :                 if (params->nonleaf.n_sp_priorities != 1) {
     400                 :          0 :                         error->type =
     401                 :            :                                 RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SP_PRIORITIES;
     402                 :          0 :                         error->message = "SP priority not supported";
     403                 :          0 :                         return -EINVAL;
     404                 :            :                 } else if (params->nonleaf.wfq_weight_mode &&
     405                 :            :                            !(*params->nonleaf.wfq_weight_mode)) {
     406                 :            :                         error->type =
     407                 :            :                                 RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE;
     408                 :            :                         error->message = "WFP should be byte mode";
     409                 :            :                         return -EINVAL;
     410                 :            :                 }
     411                 :            : 
     412                 :            :                 return 0;
     413                 :            :         }
     414                 :            : 
     415                 :            :         /* for leaf node */
     416         [ #  # ]:          0 :         if (params->leaf.cman) {
     417                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN;
     418                 :          0 :                 error->message = "Congestion management not supported";
     419                 :          0 :                 return -EINVAL;
     420                 :            :         }
     421         [ #  # ]:          0 :         if (params->leaf.wred.wred_profile_id !=
     422                 :            :             RTE_TM_WRED_PROFILE_ID_NONE) {
     423                 :          0 :                 error->type =
     424                 :            :                         RTE_TM_ERROR_TYPE_NODE_PARAMS_WRED_PROFILE_ID;
     425                 :          0 :                 error->message = "WRED not supported";
     426                 :          0 :                 return -EINVAL;
     427                 :            :         }
     428         [ #  # ]:          0 :         if (params->leaf.wred.shared_wred_context_id) {
     429                 :          0 :                 error->type =
     430                 :            :                         RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_WRED_CONTEXT_ID;
     431                 :          0 :                 error->message = "WRED not supported";
     432                 :          0 :                 return -EINVAL;
     433                 :            :         }
     434         [ #  # ]:          0 :         if (params->leaf.wred.n_shared_wred_contexts) {
     435                 :          0 :                 error->type =
     436                 :            :                         RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_WRED_CONTEXTS;
     437                 :          0 :                 error->message = "WRED not supported";
     438                 :          0 :                 return -EINVAL;
     439                 :            :         }
     440                 :            : 
     441                 :            :         return 0;
     442                 :            : }
     443                 :            : 
     444                 :            : /**
     445                 :            :  * Now the TC and queue configuration is controlled by DCB.
     446                 :            :  * We need check if the node configuration follows the DCB configuration.
     447                 :            :  * In the future, we may use TM to cover DCB.
     448                 :            :  */
     449                 :            : static int
     450                 :          0 : i40e_node_add(struct rte_eth_dev *dev, uint32_t node_id,
     451                 :            :               uint32_t parent_node_id, uint32_t priority,
     452                 :            :               uint32_t weight, uint32_t level_id,
     453                 :            :               const struct rte_tm_node_params *params,
     454                 :            :               struct rte_tm_error *error)
     455                 :            : {
     456                 :          0 :         struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     457                 :            :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     458                 :          0 :         enum i40e_tm_node_type node_type = I40E_TM_NODE_TYPE_MAX;
     459                 :          0 :         enum i40e_tm_node_type parent_node_type = I40E_TM_NODE_TYPE_MAX;
     460                 :            :         struct i40e_tm_shaper_profile *shaper_profile = NULL;
     461                 :            :         struct i40e_tm_node *tm_node;
     462                 :            :         struct i40e_tm_node *parent_node;
     463                 :            :         uint16_t tc_nb = 0;
     464                 :            :         int ret;
     465                 :            : 
     466         [ #  # ]:          0 :         if (!params || !error)
     467                 :            :                 return -EINVAL;
     468                 :            : 
     469                 :            :         /* if already committed */
     470         [ #  # ]:          0 :         if (pf->tm_conf.committed) {
     471                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
     472                 :          0 :                 error->message = "already committed";
     473                 :          0 :                 return -EINVAL;
     474                 :            :         }
     475                 :            : 
     476                 :          0 :         ret = i40e_node_param_check(dev, node_id, priority, weight,
     477                 :            :                                     params, error);
     478         [ #  # ]:          0 :         if (ret)
     479                 :            :                 return ret;
     480                 :            : 
     481                 :            :         /* check if the node ID is already used */
     482         [ #  # ]:          0 :         if (i40e_tm_node_search(dev, node_id, &node_type)) {
     483                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     484                 :          0 :                 error->message = "node id already used";
     485                 :          0 :                 return -EINVAL;
     486                 :            :         }
     487                 :            : 
     488                 :            :         /* check the shaper profile id */
     489         [ #  # ]:          0 :         if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) {
     490                 :            :                 shaper_profile = i40e_shaper_profile_search(
     491                 :            :                                         dev, params->shaper_profile_id);
     492         [ #  # ]:          0 :                 if (!shaper_profile) {
     493                 :          0 :                         error->type =
     494                 :            :                                 RTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID;
     495                 :          0 :                         error->message = "shaper profile not exist";
     496                 :          0 :                         return -EINVAL;
     497                 :            :                 }
     498                 :            :         }
     499                 :            : 
     500                 :            :         /* root node if not have a parent */
     501         [ #  # ]:          0 :         if (parent_node_id == RTE_TM_NODE_ID_NULL) {
     502                 :            :                 /* check level */
     503         [ #  # ]:          0 :                 if (level_id != RTE_TM_NODE_LEVEL_ID_ANY &&
     504                 :            :                     level_id > I40E_TM_NODE_TYPE_PORT) {
     505                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS;
     506                 :          0 :                         error->message = "Wrong level";
     507                 :          0 :                         return -EINVAL;
     508                 :            :                 }
     509                 :            : 
     510                 :            :                 /* obviously no more than one root */
     511         [ #  # ]:          0 :                 if (pf->tm_conf.root) {
     512                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID;
     513                 :          0 :                         error->message = "already have a root";
     514                 :          0 :                         return -EINVAL;
     515                 :            :                 }
     516                 :            : 
     517                 :            :                 /* add the root node */
     518                 :          0 :                 tm_node = rte_zmalloc("i40e_tm_node",
     519                 :            :                                       sizeof(struct i40e_tm_node),
     520                 :            :                                       0);
     521         [ #  # ]:          0 :                 if (!tm_node)
     522                 :            :                         return -ENOMEM;
     523                 :          0 :                 tm_node->id = node_id;
     524                 :          0 :                 tm_node->priority = priority;
     525                 :          0 :                 tm_node->weight = weight;
     526                 :          0 :                 tm_node->reference_count = 0;
     527                 :          0 :                 tm_node->parent = NULL;
     528                 :          0 :                 tm_node->shaper_profile = shaper_profile;
     529         [ #  # ]:          0 :                 rte_memcpy(&tm_node->params, params,
     530                 :            :                                  sizeof(struct rte_tm_node_params));
     531                 :          0 :                 pf->tm_conf.root = tm_node;
     532                 :            : 
     533                 :            :                 /* increase the reference counter of the shaper profile */
     534         [ #  # ]:          0 :                 if (shaper_profile)
     535                 :          0 :                         shaper_profile->reference_count++;
     536                 :            : 
     537                 :          0 :                 return 0;
     538                 :            :         }
     539                 :            : 
     540                 :            :         /* TC or queue node */
     541                 :            :         /* check the parent node */
     542                 :          0 :         parent_node = i40e_tm_node_search(dev, parent_node_id,
     543                 :            :                                           &parent_node_type);
     544         [ #  # ]:          0 :         if (!parent_node) {
     545                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID;
     546                 :          0 :                 error->message = "parent not exist";
     547                 :          0 :                 return -EINVAL;
     548                 :            :         }
     549         [ #  # ]:          0 :         if (parent_node_type != I40E_TM_NODE_TYPE_PORT &&
     550                 :            :             parent_node_type != I40E_TM_NODE_TYPE_TC) {
     551                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID;
     552                 :          0 :                 error->message = "parent is not port or TC";
     553                 :          0 :                 return -EINVAL;
     554                 :            :         }
     555                 :            :         /* check level */
     556         [ #  # ]:          0 :         if (level_id != RTE_TM_NODE_LEVEL_ID_ANY &&
     557         [ #  # ]:          0 :             level_id != (uint32_t)parent_node_type + 1) {
     558                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS;
     559                 :          0 :                 error->message = "Wrong level";
     560                 :          0 :                 return -EINVAL;
     561                 :            :         }
     562                 :            : 
     563                 :            :         /* check the node number */
     564         [ #  # ]:          0 :         if (parent_node_type == I40E_TM_NODE_TYPE_PORT) {
     565                 :            :                 /* check the TC number */
     566                 :            :                 tc_nb = i40e_tc_nb_get(dev);
     567         [ #  # ]:          0 :                 if (pf->tm_conf.nb_tc_node >= tc_nb) {
     568                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     569                 :          0 :                         error->message = "too many TCs";
     570                 :          0 :                         return -EINVAL;
     571                 :            :                 }
     572                 :            :         } else {
     573                 :            :                 /* check the queue number */
     574         [ #  # ]:          0 :                 if (pf->tm_conf.nb_queue_node >= hw->func_caps.num_tx_qp) {
     575                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     576                 :          0 :                         error->message = "too many queues";
     577                 :          0 :                         return -EINVAL;
     578                 :            :                 }
     579                 :            : 
     580                 :            :                 /**
     581                 :            :                  * check the node id.
     582                 :            :                  * For queue, the node id means queue id.
     583                 :            :                  */
     584         [ #  # ]:          0 :                 if (node_id >= hw->func_caps.num_tx_qp) {
     585                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     586                 :          0 :                         error->message = "too large queue id";
     587                 :          0 :                         return -EINVAL;
     588                 :            :                 }
     589                 :            :         }
     590                 :            : 
     591                 :            :         /* add the TC or queue node */
     592                 :          0 :         tm_node = rte_zmalloc("i40e_tm_node",
     593                 :            :                               sizeof(struct i40e_tm_node),
     594                 :            :                               0);
     595         [ #  # ]:          0 :         if (!tm_node)
     596                 :            :                 return -ENOMEM;
     597                 :          0 :         tm_node->id = node_id;
     598                 :          0 :         tm_node->priority = priority;
     599                 :          0 :         tm_node->weight = weight;
     600                 :          0 :         tm_node->reference_count = 0;
     601                 :          0 :         tm_node->parent = parent_node;
     602                 :          0 :         tm_node->shaper_profile = shaper_profile;
     603         [ #  # ]:          0 :         rte_memcpy(&tm_node->params, params,
     604                 :            :                          sizeof(struct rte_tm_node_params));
     605         [ #  # ]:          0 :         if (parent_node_type == I40E_TM_NODE_TYPE_PORT) {
     606                 :          0 :                 TAILQ_INSERT_TAIL(&pf->tm_conf.tc_list,
     607                 :            :                                   tm_node, node);
     608                 :          0 :                 pf->tm_conf.nb_tc_node++;
     609                 :            :         } else {
     610                 :          0 :                 TAILQ_INSERT_TAIL(&pf->tm_conf.queue_list,
     611                 :            :                                   tm_node, node);
     612                 :          0 :                 pf->tm_conf.nb_queue_node++;
     613                 :            :         }
     614                 :          0 :         tm_node->parent->reference_count++;
     615                 :            : 
     616                 :            :         /* increase the reference counter of the shaper profile */
     617         [ #  # ]:          0 :         if (shaper_profile)
     618                 :          0 :                 shaper_profile->reference_count++;
     619                 :            : 
     620                 :            :         return 0;
     621                 :            : }
     622                 :            : 
     623                 :            : static int
     624                 :          0 : i40e_node_delete(struct rte_eth_dev *dev, uint32_t node_id,
     625                 :            :                  struct rte_tm_error *error)
     626                 :            : {
     627                 :          0 :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     628                 :          0 :         enum i40e_tm_node_type node_type = I40E_TM_NODE_TYPE_MAX;
     629                 :            :         struct i40e_tm_node *tm_node;
     630                 :            : 
     631         [ #  # ]:          0 :         if (!error)
     632                 :            :                 return -EINVAL;
     633                 :            : 
     634                 :            :         /* if already committed */
     635         [ #  # ]:          0 :         if (pf->tm_conf.committed) {
     636                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED;
     637                 :          0 :                 error->message = "already committed";
     638                 :          0 :                 return -EINVAL;
     639                 :            :         }
     640                 :            : 
     641         [ #  # ]:          0 :         if (node_id == RTE_TM_NODE_ID_NULL) {
     642                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     643                 :          0 :                 error->message = "invalid node id";
     644                 :          0 :                 return -EINVAL;
     645                 :            :         }
     646                 :            : 
     647                 :            :         /* check if the node id exists */
     648                 :          0 :         tm_node = i40e_tm_node_search(dev, node_id, &node_type);
     649         [ #  # ]:          0 :         if (!tm_node) {
     650                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     651                 :          0 :                 error->message = "no such node";
     652                 :          0 :                 return -EINVAL;
     653                 :            :         }
     654                 :            : 
     655                 :            :         /* the node should have no child */
     656         [ #  # ]:          0 :         if (tm_node->reference_count) {
     657                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     658                 :          0 :                 error->message =
     659                 :            :                         "cannot delete a node which has children";
     660                 :          0 :                 return -EINVAL;
     661                 :            :         }
     662                 :            : 
     663                 :            :         /* root node */
     664         [ #  # ]:          0 :         if (node_type == I40E_TM_NODE_TYPE_PORT) {
     665         [ #  # ]:          0 :                 if (tm_node->shaper_profile)
     666                 :          0 :                         tm_node->shaper_profile->reference_count--;
     667                 :          0 :                 rte_free(tm_node);
     668                 :          0 :                 pf->tm_conf.root = NULL;
     669                 :          0 :                 return 0;
     670                 :            :         }
     671                 :            : 
     672                 :            :         /* TC or queue node */
     673         [ #  # ]:          0 :         if (tm_node->shaper_profile)
     674                 :          0 :                 tm_node->shaper_profile->reference_count--;
     675                 :          0 :         tm_node->parent->reference_count--;
     676         [ #  # ]:          0 :         if (node_type == I40E_TM_NODE_TYPE_TC) {
     677         [ #  # ]:          0 :                 TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node);
     678                 :          0 :                 pf->tm_conf.nb_tc_node--;
     679                 :            :         } else {
     680         [ #  # ]:          0 :                 TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
     681                 :          0 :                 pf->tm_conf.nb_queue_node--;
     682                 :            :         }
     683                 :          0 :         rte_free(tm_node);
     684                 :            : 
     685                 :          0 :         return 0;
     686                 :            : }
     687                 :            : 
     688                 :            : static int
     689                 :          0 : i40e_node_type_get(struct rte_eth_dev *dev, uint32_t node_id,
     690                 :            :                    int *is_leaf, struct rte_tm_error *error)
     691                 :            : {
     692                 :          0 :         enum i40e_tm_node_type node_type = I40E_TM_NODE_TYPE_MAX;
     693                 :            :         struct i40e_tm_node *tm_node;
     694                 :            : 
     695         [ #  # ]:          0 :         if (!is_leaf || !error)
     696                 :            :                 return -EINVAL;
     697                 :            : 
     698         [ #  # ]:          0 :         if (node_id == RTE_TM_NODE_ID_NULL) {
     699                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     700                 :          0 :                 error->message = "invalid node id";
     701                 :          0 :                 return -EINVAL;
     702                 :            :         }
     703                 :            : 
     704                 :            :         /* check if the node id exists */
     705                 :          0 :         tm_node = i40e_tm_node_search(dev, node_id, &node_type);
     706         [ #  # ]:          0 :         if (!tm_node) {
     707                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     708                 :          0 :                 error->message = "no such node";
     709                 :          0 :                 return -EINVAL;
     710                 :            :         }
     711                 :            : 
     712         [ #  # ]:          0 :         if (node_type == I40E_TM_NODE_TYPE_QUEUE)
     713                 :          0 :                 *is_leaf = true;
     714                 :            :         else
     715                 :          0 :                 *is_leaf = false;
     716                 :            : 
     717                 :            :         return 0;
     718                 :            : }
     719                 :            : 
     720                 :            : static int
     721                 :          0 : i40e_level_capabilities_get(struct rte_eth_dev *dev,
     722                 :            :                             uint32_t level_id,
     723                 :            :                             struct rte_tm_level_capabilities *cap,
     724                 :            :                             struct rte_tm_error *error)
     725                 :            : {
     726                 :          0 :         struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     727                 :            : 
     728         [ #  # ]:          0 :         if (!cap || !error)
     729                 :            :                 return -EINVAL;
     730                 :            : 
     731         [ #  # ]:          0 :         if (level_id >= I40E_TM_NODE_TYPE_MAX) {
     732                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_LEVEL_ID;
     733                 :          0 :                 error->message = "too deep level";
     734                 :          0 :                 return -EINVAL;
     735                 :            :         }
     736                 :            : 
     737                 :            :         /* root node */
     738         [ #  # ]:          0 :         if (level_id == I40E_TM_NODE_TYPE_PORT) {
     739                 :          0 :                 cap->n_nodes_max = 1;
     740                 :          0 :                 cap->n_nodes_nonleaf_max = 1;
     741                 :          0 :                 cap->n_nodes_leaf_max = 0;
     742         [ #  # ]:          0 :         } else if (level_id == I40E_TM_NODE_TYPE_TC) {
     743                 :            :                 /* TC */
     744                 :          0 :                 cap->n_nodes_max = I40E_MAX_TRAFFIC_CLASS;
     745                 :          0 :                 cap->n_nodes_nonleaf_max = I40E_MAX_TRAFFIC_CLASS;
     746                 :          0 :                 cap->n_nodes_leaf_max = 0;
     747                 :            :         } else {
     748                 :            :                 /* queue */
     749                 :          0 :                 cap->n_nodes_max = hw->func_caps.num_tx_qp;
     750                 :          0 :                 cap->n_nodes_nonleaf_max = 0;
     751                 :          0 :                 cap->n_nodes_leaf_max = hw->func_caps.num_tx_qp;
     752                 :            :         }
     753                 :            : 
     754                 :          0 :         cap->non_leaf_nodes_identical = true;
     755                 :          0 :         cap->leaf_nodes_identical = true;
     756                 :            : 
     757         [ #  # ]:          0 :         if (level_id != I40E_TM_NODE_TYPE_QUEUE) {
     758                 :          0 :                 cap->nonleaf.shaper_private_supported = true;
     759                 :          0 :                 cap->nonleaf.shaper_private_dual_rate_supported = false;
     760                 :          0 :                 cap->nonleaf.shaper_private_rate_min = 0;
     761                 :            :                 /* 40Gbps -> 5GBps */
     762                 :          0 :                 cap->nonleaf.shaper_private_rate_max = 5000000000ull;
     763                 :          0 :                 cap->nonleaf.shaper_private_packet_mode_supported = 0;
     764                 :          0 :                 cap->nonleaf.shaper_private_byte_mode_supported = 1;
     765                 :          0 :                 cap->nonleaf.shaper_shared_n_max = 0;
     766                 :          0 :                 cap->nonleaf.shaper_shared_packet_mode_supported = 0;
     767                 :          0 :                 cap->nonleaf.shaper_shared_byte_mode_supported = 0;
     768         [ #  # ]:          0 :                 if (level_id == I40E_TM_NODE_TYPE_PORT)
     769                 :          0 :                         cap->nonleaf.sched_n_children_max =
     770                 :            :                                 I40E_MAX_TRAFFIC_CLASS;
     771                 :            :                 else
     772                 :          0 :                         cap->nonleaf.sched_n_children_max =
     773                 :          0 :                                 hw->func_caps.num_tx_qp;
     774                 :          0 :                 cap->nonleaf.sched_sp_n_priorities_max = 1;
     775                 :          0 :                 cap->nonleaf.sched_wfq_n_children_per_group_max = 0;
     776                 :          0 :                 cap->nonleaf.sched_wfq_n_groups_max = 0;
     777                 :          0 :                 cap->nonleaf.sched_wfq_weight_max = 1;
     778                 :          0 :                 cap->nonleaf.sched_wfq_packet_mode_supported = 0;
     779                 :          0 :                 cap->nonleaf.sched_wfq_byte_mode_supported = 0;
     780                 :          0 :                 cap->nonleaf.stats_mask = 0;
     781                 :            : 
     782                 :          0 :                 return 0;
     783                 :            :         }
     784                 :            : 
     785                 :            :         /* queue node */
     786                 :          0 :         cap->leaf.shaper_private_supported = true;
     787                 :          0 :         cap->leaf.shaper_private_dual_rate_supported = false;
     788                 :          0 :         cap->leaf.shaper_private_rate_min = 0;
     789                 :            :         /* 40Gbps -> 5GBps */
     790                 :          0 :         cap->leaf.shaper_private_rate_max = 5000000000ull;
     791                 :          0 :         cap->leaf.shaper_private_packet_mode_supported = 0;
     792                 :          0 :         cap->leaf.shaper_private_byte_mode_supported = 1;
     793                 :          0 :         cap->leaf.shaper_shared_n_max = 0;
     794                 :          0 :         cap->leaf.shaper_shared_packet_mode_supported = 0;
     795                 :          0 :         cap->leaf.shaper_shared_byte_mode_supported = 0;
     796                 :          0 :         cap->leaf.cman_head_drop_supported = false;
     797                 :          0 :         cap->leaf.cman_wred_context_private_supported = true;
     798                 :          0 :         cap->leaf.cman_wred_context_shared_n_max = 0;
     799                 :          0 :         cap->leaf.stats_mask = 0;
     800                 :            : 
     801                 :          0 :         return 0;
     802                 :            : }
     803                 :            : 
     804                 :            : static int
     805                 :          0 : i40e_node_capabilities_get(struct rte_eth_dev *dev,
     806                 :            :                            uint32_t node_id,
     807                 :            :                            struct rte_tm_node_capabilities *cap,
     808                 :            :                            struct rte_tm_error *error)
     809                 :            : {
     810                 :          0 :         struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     811                 :            :         enum i40e_tm_node_type node_type;
     812                 :            :         struct i40e_tm_node *tm_node;
     813                 :            : 
     814         [ #  # ]:          0 :         if (!cap || !error)
     815                 :            :                 return -EINVAL;
     816                 :            : 
     817         [ #  # ]:          0 :         if (node_id == RTE_TM_NODE_ID_NULL) {
     818                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     819                 :          0 :                 error->message = "invalid node id";
     820                 :          0 :                 return -EINVAL;
     821                 :            :         }
     822                 :            : 
     823                 :            :         /* check if the node id exists */
     824                 :          0 :         tm_node = i40e_tm_node_search(dev, node_id, &node_type);
     825         [ #  # ]:          0 :         if (!tm_node) {
     826                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_NODE_ID;
     827                 :          0 :                 error->message = "no such node";
     828                 :          0 :                 return -EINVAL;
     829                 :            :         }
     830                 :            : 
     831                 :          0 :         cap->shaper_private_supported = true;
     832                 :          0 :         cap->shaper_private_dual_rate_supported = false;
     833                 :          0 :         cap->shaper_private_rate_min = 0;
     834                 :            :         /* 40Gbps -> 5GBps */
     835                 :          0 :         cap->shaper_private_rate_max = 5000000000ull;
     836                 :          0 :         cap->shaper_private_packet_mode_supported = 0;
     837                 :          0 :         cap->shaper_private_byte_mode_supported = 1;
     838                 :          0 :         cap->shaper_shared_n_max = 0;
     839                 :          0 :         cap->shaper_shared_packet_mode_supported = 0;
     840                 :          0 :         cap->shaper_shared_byte_mode_supported = 0;
     841                 :            : 
     842         [ #  # ]:          0 :         if (node_type == I40E_TM_NODE_TYPE_QUEUE) {
     843                 :          0 :                 cap->leaf.cman_head_drop_supported = false;
     844                 :          0 :                 cap->leaf.cman_wred_context_private_supported = true;
     845                 :          0 :                 cap->leaf.cman_wred_context_shared_n_max = 0;
     846                 :            :         } else {
     847         [ #  # ]:          0 :                 if (node_type == I40E_TM_NODE_TYPE_PORT)
     848                 :          0 :                         cap->nonleaf.sched_n_children_max =
     849                 :            :                                 I40E_MAX_TRAFFIC_CLASS;
     850                 :            :                 else
     851                 :          0 :                         cap->nonleaf.sched_n_children_max =
     852                 :          0 :                                 hw->func_caps.num_tx_qp;
     853                 :          0 :                 cap->nonleaf.sched_sp_n_priorities_max = 1;
     854                 :          0 :                 cap->nonleaf.sched_wfq_n_children_per_group_max = 0;
     855                 :          0 :                 cap->nonleaf.sched_wfq_n_groups_max = 0;
     856                 :          0 :                 cap->nonleaf.sched_wfq_weight_max = 1;
     857                 :          0 :                 cap->nonleaf.sched_wfq_packet_mode_supported = 0;
     858                 :          0 :                 cap->nonleaf.sched_wfq_byte_mode_supported = 0;
     859                 :            :         }
     860                 :            : 
     861                 :          0 :         cap->stats_mask = 0;
     862                 :            : 
     863                 :          0 :         return 0;
     864                 :            : }
     865                 :            : 
     866                 :            : static int
     867                 :          0 : i40e_hierarchy_commit(struct rte_eth_dev *dev,
     868                 :            :                       int clear_on_fail,
     869                 :            :                       struct rte_tm_error *error)
     870                 :            : {
     871                 :          0 :         struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
     872                 :            :         struct i40e_tm_node_list *tc_list = &pf->tm_conf.tc_list;
     873                 :            :         struct i40e_tm_node_list *queue_list = &pf->tm_conf.queue_list;
     874                 :            :         struct i40e_tm_node *tm_node;
     875                 :            :         struct i40e_vsi *vsi;
     876                 :            :         struct i40e_hw *hw;
     877                 :            :         struct i40e_aqc_configure_vsi_ets_sla_bw_data tc_bw;
     878                 :            :         uint64_t bw;
     879                 :            :         uint8_t tc_map;
     880                 :            :         int ret;
     881                 :            :         int i;
     882                 :            : 
     883         [ #  # ]:          0 :         if (!error)
     884                 :            :                 return -EINVAL;
     885                 :            : 
     886                 :            :         /* check the setting */
     887         [ #  # ]:          0 :         if (!pf->tm_conf.root)
     888                 :          0 :                 goto done;
     889                 :            : 
     890                 :          0 :         vsi = pf->main_vsi;
     891                 :          0 :         hw = I40E_VSI_TO_HW(vsi);
     892                 :            : 
     893                 :            :         /**
     894                 :            :          * Don't support bandwidth control for port and TCs in parallel.
     895                 :            :          * If the port has a max bandwidth, the TCs should have none.
     896                 :            :          */
     897                 :            :         /* port */
     898         [ #  # ]:          0 :         if (pf->tm_conf.root->shaper_profile)
     899                 :          0 :                 bw = pf->tm_conf.root->shaper_profile->profile.peak.rate;
     900                 :            :         else
     901                 :            :                 bw = 0;
     902         [ #  # ]:          0 :         if (bw) {
     903                 :            :                 /* check if any TC has a max bandwidth */
     904         [ #  # ]:          0 :                 TAILQ_FOREACH(tm_node, tc_list, node) {
     905         [ #  # ]:          0 :                         if (tm_node->shaper_profile &&
     906         [ #  # ]:          0 :                             tm_node->shaper_profile->profile.peak.rate) {
     907                 :          0 :                                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE;
     908                 :          0 :                                 error->message = "no port and TC max bandwidth"
     909                 :            :                                                  " in parallel";
     910                 :          0 :                                 goto fail_clear;
     911                 :            :                         }
     912                 :            :                 }
     913                 :            : 
     914                 :            :                 /* interpret Bps to 50Mbps */
     915                 :          0 :                 bw = bw * 8 / 1000 / 1000 / I40E_QOS_BW_GRANULARITY;
     916                 :            : 
     917                 :            :                 /* set the max bandwidth */
     918                 :          0 :                 ret = i40e_aq_config_vsi_bw_limit(hw, vsi->seid,
     919                 :          0 :                                                   (uint16_t)bw, 0, NULL);
     920         [ #  # ]:          0 :                 if (ret) {
     921                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE;
     922                 :          0 :                         error->message = "fail to set port max bandwidth";
     923                 :          0 :                         goto fail_clear;
     924                 :            :                 }
     925                 :            : 
     926                 :          0 :                 goto done;
     927                 :            :         }
     928                 :            : 
     929                 :            :         /* TC */
     930                 :            :         memset(&tc_bw, 0, sizeof(tc_bw));
     931                 :          0 :         tc_bw.tc_valid_bits = vsi->enabled_tc;
     932                 :            :         tc_map = vsi->enabled_tc;
     933         [ #  # ]:          0 :         TAILQ_FOREACH(tm_node, tc_list, node) {
     934         [ #  # ]:          0 :                 if (!tm_node->reference_count) {
     935                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS;
     936                 :          0 :                         error->message = "TC without queue assigned";
     937                 :          0 :                         goto fail_clear;
     938                 :            :                 }
     939                 :            : 
     940                 :            :                 i = 0;
     941   [ #  #  #  # ]:          0 :                 while (i < I40E_MAX_TRAFFIC_CLASS && !(tc_map & BIT_ULL(i)))
     942                 :          0 :                         i++;
     943         [ #  # ]:          0 :                 if (i >= I40E_MAX_TRAFFIC_CLASS) {
     944                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS;
     945                 :          0 :                         error->message = "cannot find the TC";
     946                 :          0 :                         goto fail_clear;
     947                 :            :                 }
     948                 :          0 :                 tc_map &= ~BIT_ULL(i);
     949                 :            : 
     950         [ #  # ]:          0 :                 if (tm_node->shaper_profile)
     951                 :          0 :                         bw = tm_node->shaper_profile->profile.peak.rate;
     952                 :            :                 else
     953                 :            :                         bw = 0;
     954         [ #  # ]:          0 :                 if (!bw)
     955                 :          0 :                         continue;
     956                 :            : 
     957                 :            :                 /* interpret Bps to 50Mbps */
     958                 :          0 :                 bw = bw * 8 / 1000 / 1000 / I40E_QOS_BW_GRANULARITY;
     959                 :            : 
     960                 :          0 :                 tc_bw.tc_bw_credits[i] = rte_cpu_to_le_16((uint16_t)bw);
     961                 :            :         }
     962                 :            : 
     963         [ #  # ]:          0 :         TAILQ_FOREACH(tm_node, queue_list, node) {
     964         [ #  # ]:          0 :                 if (tm_node->shaper_profile)
     965                 :          0 :                         bw = tm_node->shaper_profile->profile.peak.rate;
     966                 :            :                 else
     967                 :            :                         bw = 0;
     968         [ #  # ]:          0 :                 if (bw) {
     969                 :          0 :                         error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS;
     970                 :          0 :                         error->message = "not support queue QoS";
     971                 :          0 :                         goto fail_clear;
     972                 :            :                 }
     973                 :            :         }
     974                 :            : 
     975                 :          0 :         ret = i40e_aq_config_vsi_ets_sla_bw_limit(hw, vsi->seid, &tc_bw, NULL);
     976         [ #  # ]:          0 :         if (ret) {
     977                 :          0 :                 error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE;
     978                 :          0 :                 error->message = "fail to set TC max bandwidth";
     979                 :          0 :                 goto fail_clear;
     980                 :            :         }
     981                 :            : 
     982                 :          0 : done:
     983                 :          0 :         pf->tm_conf.committed = true;
     984                 :          0 :         return 0;
     985                 :            : 
     986                 :          0 : fail_clear:
     987                 :            :         /* clear all the traffic manager configuration */
     988         [ #  # ]:          0 :         if (clear_on_fail) {
     989                 :          0 :                 i40e_tm_conf_uninit(dev);
     990                 :          0 :                 i40e_tm_conf_init(dev);
     991                 :            :         }
     992                 :            :         return -EINVAL;
     993                 :            : }

Generated by: LCOV version 1.14