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