net/ipn3ke: remove commented out code
[dpdk.git] / drivers / net / ipn3ke / ipn3ke_tm.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4
5 #include <stdint.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include <rte_bus_pci.h>
10 #include <rte_ethdev.h>
11 #include <rte_pci.h>
12 #include <rte_malloc.h>
13 #include <rte_tm_driver.h>
14
15 #include <rte_mbuf.h>
16 #include <rte_sched.h>
17 #include <rte_ethdev_driver.h>
18
19 #include <rte_io.h>
20 #include <rte_rawdev.h>
21 #include <rte_rawdev_pmd.h>
22 #include <rte_bus_ifpga.h>
23 #include <ifpga_logs.h>
24
25 #include "ipn3ke_rawdev_api.h"
26 #include "ipn3ke_flow.h"
27 #include "ipn3ke_logs.h"
28 #include "ipn3ke_ethdev.h"
29
30 #define BYTES_IN_MBPS     (1000 * 1000 / 8)
31 #define SUBPORT_TC_PERIOD 10
32 #define PIPE_TC_PERIOD    40
33
34 struct ipn3ke_tm_shaper_params_range_type {
35         uint32_t m1;
36         uint32_t m2;
37         uint32_t exp;
38         uint32_t exp2;
39         uint32_t low;
40         uint32_t high;
41 };
42 struct ipn3ke_tm_shaper_params_range_type ipn3ke_tm_shaper_params_rang[] = {
43         {  0,       1,     0,        1,           0,            4},
44         {  2,       3,     0,        1,           8,           12},
45         {  4,       7,     0,        1,          16,           28},
46         {  8,      15,     0,        1,          32,           60},
47         { 16,      31,     0,        1,          64,          124},
48         { 32,      63,     0,        1,         128,          252},
49         { 64,     127,     0,        1,         256,          508},
50         {128,     255,     0,        1,         512,         1020},
51         {256,     511,     0,        1,        1024,         2044},
52         {512,    1023,     0,        1,        2048,         4092},
53         {512,    1023,     1,        2,        4096,         8184},
54         {512,    1023,     2,        4,        8192,        16368},
55         {512,    1023,     3,        8,       16384,        32736},
56         {512,    1023,     4,       16,       32768,        65472},
57         {512,    1023,     5,       32,       65536,       130944},
58         {512,    1023,     6,       64,      131072,       261888},
59         {512,    1023,     7,      128,      262144,       523776},
60         {512,    1023,     8,      256,      524288,      1047552},
61         {512,    1023,     9,      512,     1048576,      2095104},
62         {512,    1023,    10,     1024,     2097152,      4190208},
63         {512,    1023,    11,     2048,     4194304,      8380416},
64         {512,    1023,    12,     4096,     8388608,     16760832},
65         {512,    1023,    13,     8192,    16777216,     33521664},
66         {512,    1023,    14,    16384,    33554432,     67043328},
67         {512,    1023,    15,    32768,    67108864,    134086656},
68 };
69
70 #define IPN3KE_TM_SHAPER_RANGE_NUM (sizeof(ipn3ke_tm_shaper_params_rang) / \
71         sizeof(struct ipn3ke_tm_shaper_params_range_type))
72
73 #define IPN3KE_TM_SHAPER_COMMITTED_RATE_MAX \
74         (ipn3ke_tm_shaper_params_rang[IPN3KE_TM_SHAPER_RANGE_NUM - 1].high)
75
76 #define IPN3KE_TM_SHAPER_PEAK_RATE_MAX \
77         (ipn3ke_tm_shaper_params_rang[IPN3KE_TM_SHAPER_RANGE_NUM - 1].high)
78
79 int
80 ipn3ke_hw_tm_init(struct ipn3ke_hw *hw)
81 {
82 #define SCRATCH_DATA 0xABCDEF
83         struct ipn3ke_tm_node *nodes;
84         struct ipn3ke_tm_tdrop_profile *tdrop_profile;
85         int node_num;
86         int i;
87
88         if (hw == NULL)
89                 return -EINVAL;
90 #if IPN3KE_TM_SCRATCH_RW
91         uint32_t scratch_data;
92         IPN3KE_MASK_WRITE_REG(hw,
93                                         IPN3KE_TM_SCRATCH,
94                                         0,
95                                         SCRATCH_DATA,
96                                         0xFFFFFFFF);
97         scratch_data = IPN3KE_MASK_READ_REG(hw,
98                                         IPN3KE_TM_SCRATCH,
99                                         0,
100                                         0xFFFFFFFF);
101         if (scratch_data != SCRATCH_DATA)
102                 return -EINVAL;
103 #endif
104         /* alloc memory for all hierarchy nodes */
105         node_num = hw->port_num +
106                 IPN3KE_TM_VT_NODE_NUM +
107                 IPN3KE_TM_COS_NODE_NUM;
108
109         nodes = rte_zmalloc("ipn3ke_tm_nodes",
110                         sizeof(struct ipn3ke_tm_node) * node_num,
111                         0);
112         if (!nodes)
113                 return -ENOMEM;
114
115         /* alloc memory for Tail Drop Profile */
116         tdrop_profile = rte_zmalloc("ipn3ke_tm_tdrop_profile",
117                                 sizeof(struct ipn3ke_tm_tdrop_profile) *
118                                 IPN3KE_TM_TDROP_PROFILE_NUM,
119                                 0);
120         if (!tdrop_profile) {
121                 rte_free(nodes);
122                 return -ENOMEM;
123         }
124
125         hw->nodes = nodes;
126         hw->port_nodes = nodes;
127         hw->vt_nodes = hw->port_nodes + hw->port_num;
128         hw->cos_nodes = hw->vt_nodes + IPN3KE_TM_VT_NODE_NUM;
129         hw->tdrop_profile = tdrop_profile;
130         hw->tdrop_profile_num = IPN3KE_TM_TDROP_PROFILE_NUM;
131
132         for (i = 0, nodes = hw->port_nodes;
133                 i < hw->port_num;
134                 i++, nodes++) {
135                 nodes->node_index = i;
136                 nodes->level = IPN3KE_TM_NODE_LEVEL_PORT;
137                 nodes->tm_id = RTE_TM_NODE_ID_NULL;
138                 nodes->node_state = IPN3KE_TM_NODE_STATE_IDLE;
139                 nodes->parent_node_id = RTE_TM_NODE_ID_NULL;
140                 nodes->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
141                 nodes->weight = 0;
142                 nodes->parent_node = NULL;
143                 nodes->shaper_profile.valid = 0;
144                 nodes->tdrop_profile = NULL;
145                 nodes->n_children = 0;
146                 TAILQ_INIT(&nodes->children_node_list);
147         }
148
149         for (i = 0, nodes = hw->vt_nodes;
150                 i < IPN3KE_TM_VT_NODE_NUM;
151                 i++, nodes++) {
152                 nodes->node_index = i;
153                 nodes->level = IPN3KE_TM_NODE_LEVEL_VT;
154                 nodes->tm_id = RTE_TM_NODE_ID_NULL;
155                 nodes->node_state = IPN3KE_TM_NODE_STATE_IDLE;
156                 nodes->parent_node_id = RTE_TM_NODE_ID_NULL;
157                 nodes->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
158                 nodes->weight = 0;
159                 nodes->parent_node = NULL;
160                 nodes->shaper_profile.valid = 0;
161                 nodes->tdrop_profile = NULL;
162                 nodes->n_children = 0;
163                 TAILQ_INIT(&nodes->children_node_list);
164         }
165
166         for (i = 0, nodes = hw->cos_nodes;
167                 i < IPN3KE_TM_COS_NODE_NUM;
168                 i++, nodes++) {
169                 nodes->node_index = i;
170                 nodes->level = IPN3KE_TM_NODE_LEVEL_COS;
171                 nodes->tm_id = RTE_TM_NODE_ID_NULL;
172                 nodes->node_state = IPN3KE_TM_NODE_STATE_IDLE;
173                 nodes->parent_node_id = RTE_TM_NODE_ID_NULL;
174                 nodes->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
175                 nodes->weight = 0;
176                 nodes->parent_node = NULL;
177                 nodes->shaper_profile.valid = 0;
178                 nodes->tdrop_profile = NULL;
179                 nodes->n_children = 0;
180                 TAILQ_INIT(&nodes->children_node_list);
181         }
182
183         for (i = 0, tdrop_profile = hw->tdrop_profile;
184                 i < IPN3KE_TM_TDROP_PROFILE_NUM;
185                 i++, tdrop_profile++) {
186                 tdrop_profile->tdrop_profile_id = i;
187                 tdrop_profile->n_users = 0;
188                 tdrop_profile->valid = 0;
189         }
190
191         return 0;
192 }
193
194 void
195 ipn3ke_tm_init(struct ipn3ke_rpst *rpst)
196 {
197         struct ipn3ke_tm_internals *tm;
198         struct ipn3ke_tm_node *port_node;
199
200         tm = &rpst->tm;
201
202         port_node = &rpst->hw->port_nodes[rpst->port_id];
203         tm->h.port_node = port_node;
204
205         tm->h.n_shaper_profiles = 0;
206         tm->h.n_tdrop_profiles = 0;
207         tm->h.n_vt_nodes = 0;
208         tm->h.n_cos_nodes = 0;
209
210         tm->h.port_commit_node = NULL;
211         TAILQ_INIT(&tm->h.vt_commit_node_list);
212         TAILQ_INIT(&tm->h.cos_commit_node_list);
213
214         tm->hierarchy_frozen = 0;
215         tm->tm_started = 1;
216         tm->tm_id = rpst->port_id;
217 }
218
219 static struct ipn3ke_tm_shaper_profile *
220 ipn3ke_hw_tm_shaper_profile_search(struct ipn3ke_hw *hw,
221         uint32_t shaper_profile_id, struct rte_tm_error *error)
222 {
223         struct ipn3ke_tm_shaper_profile *sp = NULL;
224         uint32_t level_of_node_id;
225         uint32_t node_index;
226
227         /* Shaper profile ID must not be NONE. */
228         if (shaper_profile_id == RTE_TM_SHAPER_PROFILE_ID_NONE) {
229                 rte_tm_error_set(error,
230                                 EINVAL,
231                                 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
232                                 NULL,
233                                 rte_strerror(EINVAL));
234
235                 return NULL;
236         }
237
238         level_of_node_id = shaper_profile_id / IPN3KE_TM_NODE_LEVEL_MOD;
239         node_index = shaper_profile_id % IPN3KE_TM_NODE_LEVEL_MOD;
240
241         switch (level_of_node_id) {
242         case IPN3KE_TM_NODE_LEVEL_PORT:
243                 if (node_index >= hw->port_num)
244                         rte_tm_error_set(error,
245                                         EEXIST,
246                                         RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
247                                         NULL,
248                                         rte_strerror(EEXIST));
249                 else
250                         sp = &hw->port_nodes[node_index].shaper_profile;
251
252                 break;
253
254         case IPN3KE_TM_NODE_LEVEL_VT:
255                 if (node_index >= IPN3KE_TM_VT_NODE_NUM)
256                         rte_tm_error_set(error,
257                                         EEXIST,
258                                         RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
259                                         NULL,
260                                         rte_strerror(EEXIST));
261                 else
262                         sp = &hw->vt_nodes[node_index].shaper_profile;
263
264                 break;
265
266         case IPN3KE_TM_NODE_LEVEL_COS:
267                 if (node_index >= IPN3KE_TM_COS_NODE_NUM)
268                         rte_tm_error_set(error,
269                                         EEXIST,
270                                         RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
271                                         NULL,
272                                         rte_strerror(EEXIST));
273                 else
274                         sp = &hw->cos_nodes[node_index].shaper_profile;
275
276                 break;
277         default:
278                 rte_tm_error_set(error,
279                                 EEXIST,
280                                 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
281                                 NULL,
282                                 rte_strerror(EEXIST));
283         }
284
285         return sp;
286 }
287
288 static struct ipn3ke_tm_tdrop_profile *
289 ipn3ke_hw_tm_tdrop_profile_search(struct ipn3ke_hw *hw,
290         uint32_t tdrop_profile_id)
291 {
292         struct ipn3ke_tm_tdrop_profile *tdrop_profile;
293
294         if (tdrop_profile_id >= hw->tdrop_profile_num)
295                 return NULL;
296
297         tdrop_profile = &hw->tdrop_profile[tdrop_profile_id];
298         if (tdrop_profile->valid)
299                 return tdrop_profile;
300
301         return NULL;
302 }
303
304 static struct ipn3ke_tm_node *
305 ipn3ke_hw_tm_node_search(struct ipn3ke_hw *hw, uint32_t tm_id,
306         uint32_t node_id, uint32_t state_mask)
307 {
308         uint32_t level_of_node_id;
309         uint32_t node_index;
310         struct ipn3ke_tm_node *n;
311
312         level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD;
313         node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD;
314
315         switch (level_of_node_id) {
316         case IPN3KE_TM_NODE_LEVEL_PORT:
317                 if (node_index >= hw->port_num)
318                         return NULL;
319                 n = &hw->port_nodes[node_index];
320
321                 break;
322         case IPN3KE_TM_NODE_LEVEL_VT:
323                 if (node_index >= IPN3KE_TM_VT_NODE_NUM)
324                         return NULL;
325                 n = &hw->vt_nodes[node_index];
326
327                 break;
328         case IPN3KE_TM_NODE_LEVEL_COS:
329                 if (node_index >= IPN3KE_TM_COS_NODE_NUM)
330                         return NULL;
331                 n = &hw->cos_nodes[node_index];
332
333                 break;
334         default:
335                 return NULL;
336         }
337
338         /* Check tm node status */
339         if (n->node_state == IPN3KE_TM_NODE_STATE_IDLE) {
340                 if (n->tm_id != RTE_TM_NODE_ID_NULL ||
341                 n->parent_node_id != RTE_TM_NODE_ID_NULL ||
342                 n->parent_node != NULL ||
343                 n->n_children > 0) {
344                         IPN3KE_AFU_PMD_ERR("tm node check error %d", 1);
345                 }
346         } else if (n->node_state < IPN3KE_TM_NODE_STATE_MAX) {
347                 if (n->tm_id == RTE_TM_NODE_ID_NULL ||
348                 (level_of_node_id != IPN3KE_TM_NODE_LEVEL_PORT &&
349                         n->parent_node_id == RTE_TM_NODE_ID_NULL) ||
350                 (level_of_node_id != IPN3KE_TM_NODE_LEVEL_PORT &&
351                         n->parent_node == NULL)) {
352                         IPN3KE_AFU_PMD_ERR("tm node check error %d", 1);
353                 }
354         } else {
355                 IPN3KE_AFU_PMD_ERR("tm node check error %d", 1);
356         }
357
358         if (IPN3KE_BIT_ISSET(state_mask, n->node_state)) {
359                 if (n->node_state == IPN3KE_TM_NODE_STATE_IDLE)
360                         return n;
361                 else if (n->tm_id == tm_id)
362                         return n;
363                 else
364                         return NULL;
365         } else {
366                 return NULL;
367         }
368 }
369
370 /* Traffic manager node type get */
371 static int
372 ipn3ke_pmd_tm_node_type_get(struct rte_eth_dev *dev,
373         uint32_t node_id, int *is_leaf, struct rte_tm_error *error)
374 {
375         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
376         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
377         uint32_t tm_id;
378         struct ipn3ke_tm_node *node;
379         uint32_t state_mask;
380
381         if (is_leaf == NULL)
382                 return -rte_tm_error_set(error,
383                                         EINVAL,
384                                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
385                                         NULL,
386                                         rte_strerror(EINVAL));
387
388         tm_id = tm->tm_id;
389
390         state_mask = 0;
391         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED);
392         node = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask);
393         if (node_id == RTE_TM_NODE_ID_NULL ||
394                 node == NULL)
395                 return -rte_tm_error_set(error,
396                                         EINVAL,
397                                         RTE_TM_ERROR_TYPE_NODE_ID,
398                                         NULL,
399                                         rte_strerror(EINVAL));
400
401         *is_leaf = (node->level == IPN3KE_TM_NODE_LEVEL_COS) ? 1 : 0;
402
403         return 0;
404 }
405
406 #define WRED_SUPPORTED    0
407
408 #define STATS_MASK_DEFAULT \
409         (RTE_TM_STATS_N_PKTS | \
410         RTE_TM_STATS_N_BYTES | \
411         RTE_TM_STATS_N_PKTS_GREEN_DROPPED | \
412         RTE_TM_STATS_N_BYTES_GREEN_DROPPED)
413
414 #define STATS_MASK_QUEUE \
415         (STATS_MASK_DEFAULT | RTE_TM_STATS_N_PKTS_QUEUED)
416
417 /* Traffic manager capabilities get */
418 static int
419 ipn3ke_tm_capabilities_get(__rte_unused struct rte_eth_dev *dev,
420         struct rte_tm_capabilities *cap, struct rte_tm_error *error)
421 {
422         if (cap == NULL)
423                 return -rte_tm_error_set(error,
424                                         EINVAL,
425                                         RTE_TM_ERROR_TYPE_CAPABILITIES,
426                                         NULL,
427                                         rte_strerror(EINVAL));
428
429         /* set all the parameters to 0 first. */
430         memset(cap, 0, sizeof(*cap));
431
432         cap->n_nodes_max = 1 + IPN3KE_TM_COS_NODE_NUM + IPN3KE_TM_VT_NODE_NUM;
433         cap->n_levels_max = IPN3KE_TM_NODE_LEVEL_MAX;
434
435         cap->non_leaf_nodes_identical = 0;
436         cap->leaf_nodes_identical = 1;
437
438         cap->shaper_n_max = 1 + IPN3KE_TM_VT_NODE_NUM;
439         cap->shaper_private_n_max = 1 + IPN3KE_TM_VT_NODE_NUM;
440         cap->shaper_private_dual_rate_n_max = 0;
441         cap->shaper_private_rate_min = 1;
442         cap->shaper_private_rate_max = 1 + IPN3KE_TM_VT_NODE_NUM;
443
444         cap->shaper_shared_n_max = 0;
445         cap->shaper_shared_n_nodes_per_shaper_max = 0;
446         cap->shaper_shared_n_shapers_per_node_max = 0;
447         cap->shaper_shared_dual_rate_n_max = 0;
448         cap->shaper_shared_rate_min = 0;
449         cap->shaper_shared_rate_max = 0;
450
451         cap->shaper_pkt_length_adjust_min = RTE_TM_ETH_FRAMING_OVERHEAD_FCS;
452         cap->shaper_pkt_length_adjust_max = RTE_TM_ETH_FRAMING_OVERHEAD_FCS;
453
454         cap->sched_n_children_max = IPN3KE_TM_COS_NODE_NUM;
455         cap->sched_sp_n_priorities_max = 3;
456         cap->sched_wfq_n_children_per_group_max = UINT32_MAX;
457         cap->sched_wfq_n_groups_max = 1;
458         cap->sched_wfq_weight_max = UINT32_MAX;
459
460         cap->cman_wred_packet_mode_supported = 0;
461         cap->cman_wred_byte_mode_supported = 0;
462         cap->cman_head_drop_supported = 0;
463         cap->cman_wred_context_n_max = 0;
464         cap->cman_wred_context_private_n_max = 0;
465         cap->cman_wred_context_shared_n_max = 0;
466         cap->cman_wred_context_shared_n_nodes_per_context_max = 0;
467         cap->cman_wred_context_shared_n_contexts_per_node_max = 0;
468
469         /**
470          * cap->mark_vlan_dei_supported = {0, 0, 0};
471          * cap->mark_ip_ecn_tcp_supported = {0, 0, 0};
472          * cap->mark_ip_ecn_sctp_supported = {0, 0, 0};
473          * cap->mark_ip_dscp_supported = {0, 0, 0};
474          */
475
476         cap->dynamic_update_mask = 0;
477
478         cap->stats_mask = 0;
479
480         return 0;
481 }
482
483 /* Traffic manager level capabilities get */
484 static int
485 ipn3ke_tm_level_capabilities_get(struct rte_eth_dev *dev,
486         uint32_t level_id, struct rte_tm_level_capabilities *cap,
487         struct rte_tm_error *error)
488 {
489         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
490
491         if (cap == NULL)
492                 return -rte_tm_error_set(error,
493                                         EINVAL,
494                                         RTE_TM_ERROR_TYPE_CAPABILITIES,
495                                         NULL,
496                                         rte_strerror(EINVAL));
497
498         if (level_id >= IPN3KE_TM_NODE_LEVEL_MAX)
499                 return -rte_tm_error_set(error,
500                                         EINVAL,
501                                         RTE_TM_ERROR_TYPE_LEVEL_ID,
502                                         NULL,
503                                         rte_strerror(EINVAL));
504
505         /* set all the parameters to 0 first. */
506         memset(cap, 0, sizeof(*cap));
507
508         switch (level_id) {
509         case IPN3KE_TM_NODE_LEVEL_PORT:
510                 cap->n_nodes_max = hw->port_num;
511                 cap->n_nodes_nonleaf_max = IPN3KE_TM_VT_NODE_NUM;
512                 cap->n_nodes_leaf_max = 0;
513                 cap->non_leaf_nodes_identical = 0;
514                 cap->leaf_nodes_identical = 0;
515
516                 cap->nonleaf.shaper_private_supported = 0;
517                 cap->nonleaf.shaper_private_dual_rate_supported = 0;
518                 cap->nonleaf.shaper_private_rate_min = 1;
519                 cap->nonleaf.shaper_private_rate_max = UINT32_MAX;
520                 cap->nonleaf.shaper_shared_n_max = 0;
521
522                 cap->nonleaf.sched_n_children_max = IPN3KE_TM_VT_NODE_NUM;
523                 cap->nonleaf.sched_sp_n_priorities_max = 1;
524                 cap->nonleaf.sched_wfq_n_children_per_group_max = 0;
525                 cap->nonleaf.sched_wfq_n_groups_max = 0;
526                 cap->nonleaf.sched_wfq_weight_max = 0;
527
528                 cap->nonleaf.stats_mask = STATS_MASK_DEFAULT;
529                 break;
530
531         case IPN3KE_TM_NODE_LEVEL_VT:
532                 cap->n_nodes_max = IPN3KE_TM_VT_NODE_NUM;
533                 cap->n_nodes_nonleaf_max = IPN3KE_TM_COS_NODE_NUM;
534                 cap->n_nodes_leaf_max = 0;
535                 cap->non_leaf_nodes_identical = 0;
536                 cap->leaf_nodes_identical = 0;
537
538                 cap->nonleaf.shaper_private_supported = 0;
539                 cap->nonleaf.shaper_private_dual_rate_supported = 0;
540                 cap->nonleaf.shaper_private_rate_min = 1;
541                 cap->nonleaf.shaper_private_rate_max = UINT32_MAX;
542                 cap->nonleaf.shaper_shared_n_max = 0;
543
544                 cap->nonleaf.sched_n_children_max = IPN3KE_TM_COS_NODE_NUM;
545                 cap->nonleaf.sched_sp_n_priorities_max = 1;
546                 cap->nonleaf.sched_wfq_n_children_per_group_max = 0;
547                 cap->nonleaf.sched_wfq_n_groups_max = 0;
548                 cap->nonleaf.sched_wfq_weight_max = 0;
549
550                 cap->nonleaf.stats_mask = STATS_MASK_DEFAULT;
551                 break;
552
553         case IPN3KE_TM_NODE_LEVEL_COS:
554                 cap->n_nodes_max = IPN3KE_TM_COS_NODE_NUM;
555                 cap->n_nodes_nonleaf_max = 0;
556                 cap->n_nodes_leaf_max = IPN3KE_TM_COS_NODE_NUM;
557                 cap->non_leaf_nodes_identical = 0;
558                 cap->leaf_nodes_identical = 0;
559
560                 cap->leaf.shaper_private_supported = 0;
561                 cap->leaf.shaper_private_dual_rate_supported = 0;
562                 cap->leaf.shaper_private_rate_min = 0;
563                 cap->leaf.shaper_private_rate_max = 0;
564                 cap->leaf.shaper_shared_n_max = 0;
565
566                 cap->leaf.cman_head_drop_supported = 0;
567                 cap->leaf.cman_wred_packet_mode_supported = WRED_SUPPORTED;
568                 cap->leaf.cman_wred_byte_mode_supported = 0;
569                 cap->leaf.cman_wred_context_private_supported = WRED_SUPPORTED;
570                 cap->leaf.cman_wred_context_shared_n_max = 0;
571
572                 cap->leaf.stats_mask = STATS_MASK_QUEUE;
573                 break;
574
575         default:
576                 return -rte_tm_error_set(error,
577                                         EINVAL,
578                                         RTE_TM_ERROR_TYPE_LEVEL_ID,
579                                         NULL,
580                                         rte_strerror(EINVAL));
581                 break;
582         }
583
584         return 0;
585 }
586
587 /* Traffic manager node capabilities get */
588 static int
589 ipn3ke_tm_node_capabilities_get(struct rte_eth_dev *dev,
590         uint32_t node_id, struct rte_tm_node_capabilities *cap,
591         struct rte_tm_error *error)
592 {
593         struct ipn3ke_rpst *representor = IPN3KE_DEV_PRIVATE_TO_RPST(dev);
594         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
595         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
596         uint32_t tm_id;
597         struct ipn3ke_tm_node *tm_node;
598         uint32_t state_mask;
599
600         if (cap == NULL)
601                 return -rte_tm_error_set(error,
602                                         EINVAL,
603                                         RTE_TM_ERROR_TYPE_CAPABILITIES,
604                                         NULL,
605                                         rte_strerror(EINVAL));
606
607         tm_id = tm->tm_id;
608
609         state_mask = 0;
610         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED);
611         tm_node = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask);
612         if (tm_node == NULL)
613                 return -rte_tm_error_set(error,
614                                         EINVAL,
615                                         RTE_TM_ERROR_TYPE_NODE_ID,
616                                         NULL,
617                                         rte_strerror(EINVAL));
618
619         if (tm_node->tm_id != representor->port_id)
620                 return -rte_tm_error_set(error,
621                                         EINVAL,
622                                         RTE_TM_ERROR_TYPE_NODE_ID,
623                                         NULL,
624                                         rte_strerror(EINVAL));
625
626         /* set all the parameters to 0 first. */
627         memset(cap, 0, sizeof(*cap));
628
629         switch (tm_node->level) {
630         case IPN3KE_TM_NODE_LEVEL_PORT:
631                 cap->shaper_private_supported = 1;
632                 cap->shaper_private_dual_rate_supported = 0;
633                 cap->shaper_private_rate_min = 1;
634                 cap->shaper_private_rate_max = UINT32_MAX;
635                 cap->shaper_shared_n_max = 0;
636
637                 cap->nonleaf.sched_n_children_max = IPN3KE_TM_VT_NODE_NUM;
638                 cap->nonleaf.sched_sp_n_priorities_max = 1;
639                 cap->nonleaf.sched_wfq_n_children_per_group_max =
640                         IPN3KE_TM_VT_NODE_NUM;
641                 cap->nonleaf.sched_wfq_n_groups_max = 1;
642                 cap->nonleaf.sched_wfq_weight_max = 1;
643
644                 cap->stats_mask = STATS_MASK_DEFAULT;
645                 break;
646
647         case IPN3KE_TM_NODE_LEVEL_VT:
648                 cap->shaper_private_supported = 1;
649                 cap->shaper_private_dual_rate_supported = 0;
650                 cap->shaper_private_rate_min = 1;
651                 cap->shaper_private_rate_max = UINT32_MAX;
652                 cap->shaper_shared_n_max = 0;
653
654                 cap->nonleaf.sched_n_children_max = IPN3KE_TM_COS_NODE_NUM;
655                 cap->nonleaf.sched_sp_n_priorities_max = 1;
656                 cap->nonleaf.sched_wfq_n_children_per_group_max =
657                         IPN3KE_TM_COS_NODE_NUM;
658                 cap->nonleaf.sched_wfq_n_groups_max = 1;
659                 cap->nonleaf.sched_wfq_weight_max = 1;
660
661                 cap->stats_mask = STATS_MASK_DEFAULT;
662                 break;
663
664         case IPN3KE_TM_NODE_LEVEL_COS:
665                 cap->shaper_private_supported = 0;
666                 cap->shaper_private_dual_rate_supported = 0;
667                 cap->shaper_private_rate_min = 0;
668                 cap->shaper_private_rate_max = 0;
669                 cap->shaper_shared_n_max = 0;
670
671                 cap->leaf.cman_head_drop_supported = 0;
672                 cap->leaf.cman_wred_packet_mode_supported = WRED_SUPPORTED;
673                 cap->leaf.cman_wred_byte_mode_supported = 0;
674                 cap->leaf.cman_wred_context_private_supported = WRED_SUPPORTED;
675                 cap->leaf.cman_wred_context_shared_n_max = 0;
676
677                 cap->stats_mask = STATS_MASK_QUEUE;
678                 break;
679         default:
680                 break;
681         }
682
683         return 0;
684 }
685
686 static int
687 ipn3ke_tm_shaper_parame_trans(struct rte_tm_shaper_params *profile,
688         struct ipn3ke_tm_shaper_profile *local_profile,
689         const struct ipn3ke_tm_shaper_params_range_type *ref_data)
690 {
691         uint32_t i;
692         const struct ipn3ke_tm_shaper_params_range_type *r;
693         uint64_t rate;
694
695         rate = profile->peak.rate;
696         for (i = 0, r = ref_data; i < IPN3KE_TM_SHAPER_RANGE_NUM; i++, r++) {
697                 if (rate >= r->low &&
698                 rate <= r->high) {
699                         local_profile->m = (rate / 4) / r->exp2;
700                         local_profile->e = r->exp;
701                         local_profile->rate = rate;
702
703                         return 0;
704                 }
705         }
706
707         return -1;
708 }
709
710 static int
711 ipn3ke_tm_shaper_profile_add(struct rte_eth_dev *dev,
712         uint32_t shaper_profile_id, struct rte_tm_shaper_params *profile,
713         struct rte_tm_error *error)
714 {
715         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
716         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
717         struct ipn3ke_tm_shaper_profile *sp;
718
719         /* Shaper profile must not exist. */
720         sp = ipn3ke_hw_tm_shaper_profile_search(hw, shaper_profile_id, error);
721         if (!sp || (sp && sp->valid))
722                 return -rte_tm_error_set(error,
723                                         EEXIST,
724                                         RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
725                                         NULL,
726                                         rte_strerror(EEXIST));
727
728         /* Profile must not be NULL. */
729         if (profile == NULL)
730                 return -rte_tm_error_set(error,
731                                         EINVAL,
732                                         RTE_TM_ERROR_TYPE_SHAPER_PROFILE,
733                                         NULL,
734                                         rte_strerror(EINVAL));
735
736         /* Peak rate: non-zero, 32-bit */
737         if (profile->peak.rate == 0 ||
738                 profile->peak.rate > IPN3KE_TM_SHAPER_PEAK_RATE_MAX)
739                 return -rte_tm_error_set(error,
740                                 EINVAL,
741                                 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE,
742                                 NULL,
743                                 rte_strerror(EINVAL));
744
745         /* Peak size: non-zero, 32-bit */
746         if (profile->peak.size != 0)
747                 return -rte_tm_error_set(error,
748                                 EINVAL,
749                                 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE,
750                                 NULL,
751                                 rte_strerror(EINVAL));
752
753         /* Dual-rate profiles are not supported. */
754         if (profile->committed.rate > IPN3KE_TM_SHAPER_COMMITTED_RATE_MAX)
755                 return -rte_tm_error_set(error,
756                                 EINVAL,
757                                 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_RATE,
758                                 NULL,
759                                 rte_strerror(EINVAL));
760
761         /* Packet length adjust: 24 bytes */
762         if (profile->pkt_length_adjust != 0)
763                 return -rte_tm_error_set(error,
764                                 EINVAL,
765                                 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN,
766                                 NULL,
767                                 rte_strerror(EINVAL));
768
769         if (ipn3ke_tm_shaper_parame_trans(profile,
770                                         sp,
771                                         ipn3ke_tm_shaper_params_rang)) {
772                 return -rte_tm_error_set(error,
773                                 EINVAL,
774                                 RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE,
775                                 NULL,
776                                 rte_strerror(EINVAL));
777         } else {
778                 sp->valid = 1;
779                 rte_memcpy(&sp->params, profile, sizeof(sp->params));
780         }
781
782         tm->h.n_shaper_profiles++;
783
784         return 0;
785 }
786
787 /* Traffic manager shaper profile delete */
788 static int
789 ipn3ke_tm_shaper_profile_delete(struct rte_eth_dev *dev,
790         uint32_t shaper_profile_id, struct rte_tm_error *error)
791 {
792         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
793         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
794         struct ipn3ke_tm_shaper_profile *sp;
795
796         /* Check existing */
797         sp = ipn3ke_hw_tm_shaper_profile_search(hw, shaper_profile_id, error);
798         if (!sp || (sp && !sp->valid))
799                 return -rte_tm_error_set(error,
800                                         EINVAL,
801                                         RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
802                                         NULL,
803                                         rte_strerror(EINVAL));
804
805         sp->valid = 0;
806         tm->h.n_shaper_profiles--;
807
808         return 0;
809 }
810
811 static int
812 ipn3ke_tm_tdrop_profile_check(__rte_unused struct rte_eth_dev *dev,
813         uint32_t tdrop_profile_id, struct rte_tm_wred_params *profile,
814         struct rte_tm_error *error)
815 {
816         enum rte_color color;
817
818         /* TDROP profile ID must not be NONE. */
819         if (tdrop_profile_id == RTE_TM_WRED_PROFILE_ID_NONE)
820                 return -rte_tm_error_set(error,
821                                         EINVAL,
822                                         RTE_TM_ERROR_TYPE_WRED_PROFILE_ID,
823                                         NULL,
824                                         rte_strerror(EINVAL));
825
826         /* Profile must not be NULL. */
827         if (profile == NULL)
828                 return -rte_tm_error_set(error,
829                                         EINVAL,
830                                         RTE_TM_ERROR_TYPE_WRED_PROFILE,
831                                         NULL,
832                                         rte_strerror(EINVAL));
833
834         /* TDROP profile should be in packet mode */
835         if (profile->packet_mode != 0)
836                 return -rte_tm_error_set(error,
837                                         ENOTSUP,
838                                         RTE_TM_ERROR_TYPE_WRED_PROFILE,
839                                         NULL,
840                                         rte_strerror(ENOTSUP));
841
842         /* min_th <= max_th, max_th > 0  */
843         for (color = RTE_COLOR_GREEN; color <= RTE_COLOR_GREEN; color++) {
844                 uint64_t min_th = profile->red_params[color].min_th;
845                 uint64_t max_th = profile->red_params[color].max_th;
846
847                 if (((min_th >> IPN3KE_TDROP_TH1_SHIFT) >>
848                                 IPN3KE_TDROP_TH1_SHIFT) ||
849                         max_th != 0)
850                         return -rte_tm_error_set(error,
851                                                 EINVAL,
852                                                 RTE_TM_ERROR_TYPE_WRED_PROFILE,
853                                                 NULL,
854                                                 rte_strerror(EINVAL));
855         }
856
857         return 0;
858 }
859
860 static int
861 ipn3ke_hw_tm_tdrop_wr(struct ipn3ke_hw *hw,
862                                 struct ipn3ke_tm_tdrop_profile *tp)
863 {
864         if (tp->valid) {
865                 IPN3KE_MASK_WRITE_REG(hw,
866                                 IPN3KE_CCB_PROFILE_MS,
867                                 0,
868                                 tp->th2,
869                                 IPN3KE_CCB_PROFILE_MS_MASK);
870
871                 IPN3KE_MASK_WRITE_REG(hw,
872                                 IPN3KE_CCB_PROFILE_P,
873                                 tp->tdrop_profile_id,
874                                 tp->th1,
875                                 IPN3KE_CCB_PROFILE_MASK);
876         } else {
877                 IPN3KE_MASK_WRITE_REG(hw,
878                                 IPN3KE_CCB_PROFILE_MS,
879                                 0,
880                                 0,
881                                 IPN3KE_CCB_PROFILE_MS_MASK);
882
883                 IPN3KE_MASK_WRITE_REG(hw,
884                                 IPN3KE_CCB_PROFILE_P,
885                                 tp->tdrop_profile_id,
886                                 0,
887                                 IPN3KE_CCB_PROFILE_MASK);
888         }
889
890         return 0;
891 }
892
893 /* Traffic manager TDROP profile add */
894 static int
895 ipn3ke_tm_tdrop_profile_add(struct rte_eth_dev *dev,
896         uint32_t tdrop_profile_id, struct rte_tm_wred_params *profile,
897         struct rte_tm_error *error)
898 {
899         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
900         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
901         struct ipn3ke_tm_tdrop_profile *tp;
902         int status;
903         uint64_t min_th;
904         uint32_t th1, th2;
905
906         /* Check input params */
907         status = ipn3ke_tm_tdrop_profile_check(dev,
908                                         tdrop_profile_id,
909                                         profile,
910                                         error);
911         if (status)
912                 return status;
913
914         /* Memory allocation */
915         tp = &hw->tdrop_profile[tdrop_profile_id];
916
917         /* Fill in */
918         tp->valid = 1;
919         min_th = profile->red_params[RTE_COLOR_GREEN].min_th;
920         th1 = (uint32_t)(min_th & IPN3KE_TDROP_TH1_MASK);
921         th2 = (uint32_t)((min_th >> IPN3KE_TDROP_TH1_SHIFT) &
922                         IPN3KE_TDROP_TH2_MASK);
923         tp->th1 = th1;
924         tp->th2 = th2;
925         rte_memcpy(&tp->params, profile, sizeof(tp->params));
926
927         /* Add to list */
928         tm->h.n_tdrop_profiles++;
929
930         /* Write FPGA */
931         ipn3ke_hw_tm_tdrop_wr(hw, tp);
932
933         return 0;
934 }
935
936 /* Traffic manager TDROP profile delete */
937 static int
938 ipn3ke_tm_tdrop_profile_delete(struct rte_eth_dev *dev,
939         uint32_t tdrop_profile_id, struct rte_tm_error *error)
940 {
941         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
942         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
943         struct ipn3ke_tm_tdrop_profile *tp;
944
945         /* Check existing */
946         tp = ipn3ke_hw_tm_tdrop_profile_search(hw, tdrop_profile_id);
947         if (tp == NULL)
948                 return -rte_tm_error_set(error,
949                                         EINVAL,
950                                         RTE_TM_ERROR_TYPE_WRED_PROFILE_ID,
951                                         NULL,
952                                         rte_strerror(EINVAL));
953
954         /* Check unused */
955         if (tp->n_users)
956                 return -rte_tm_error_set(error,
957                                         EBUSY,
958                                         RTE_TM_ERROR_TYPE_WRED_PROFILE_ID,
959                                         NULL,
960                                         rte_strerror(EBUSY));
961
962         /* Set free */
963         tp->valid = 0;
964         tm->h.n_tdrop_profiles--;
965
966         /* Write FPGA */
967         ipn3ke_hw_tm_tdrop_wr(hw, tp);
968
969         return 0;
970 }
971
972 static int
973 ipn3ke_tm_node_add_check_parameter(uint32_t tm_id,
974         uint32_t node_id, uint32_t parent_node_id, uint32_t priority,
975         uint32_t weight, uint32_t level_id, struct rte_tm_node_params *params,
976         struct rte_tm_error *error)
977 {
978         uint32_t level_of_node_id;
979         uint32_t node_index;
980         uint32_t parent_level_id;
981
982         if (node_id == RTE_TM_NODE_ID_NULL)
983                 return -rte_tm_error_set(error,
984                                         EINVAL,
985                                         RTE_TM_ERROR_TYPE_NODE_ID,
986                                         NULL,
987                                         rte_strerror(EINVAL));
988
989         /* priority: must be 0, 1, 2, 3 */
990         if (priority > IPN3KE_TM_NODE_PRIORITY_HIGHEST)
991                 return -rte_tm_error_set(error,
992                                         EINVAL,
993                                         RTE_TM_ERROR_TYPE_NODE_PRIORITY,
994                                         NULL,
995                                         rte_strerror(EINVAL));
996
997         /* weight: must be 1 .. 255 */
998         if (weight > IPN3KE_TM_NODE_WEIGHT_MAX)
999                 return -rte_tm_error_set(error,
1000                                         EINVAL,
1001                                         RTE_TM_ERROR_TYPE_NODE_WEIGHT,
1002                                         NULL,
1003                                         rte_strerror(EINVAL));
1004
1005         /* check node id and parent id*/
1006         level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD;
1007         if (level_of_node_id != level_id)
1008                 return -rte_tm_error_set(error,
1009                                         EINVAL,
1010                                         RTE_TM_ERROR_TYPE_NODE_ID,
1011                                         NULL,
1012                                         rte_strerror(EINVAL));
1013         node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD;
1014         parent_level_id = parent_node_id / IPN3KE_TM_NODE_LEVEL_MOD;
1015         switch (level_id) {
1016         case IPN3KE_TM_NODE_LEVEL_PORT:
1017                 if (node_index != tm_id)
1018                         return -rte_tm_error_set(error,
1019                                                 EINVAL,
1020                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1021                                                 NULL,
1022                                                 rte_strerror(EINVAL));
1023                 if (parent_node_id != RTE_TM_NODE_ID_NULL)
1024                         return -rte_tm_error_set(error,
1025                                         EINVAL,
1026                                         RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
1027                                         NULL,
1028                                         rte_strerror(EINVAL));
1029                 break;
1030
1031         case IPN3KE_TM_NODE_LEVEL_VT:
1032                 if (node_index >= IPN3KE_TM_VT_NODE_NUM)
1033                         return -rte_tm_error_set(error,
1034                                                 EINVAL,
1035                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1036                                                 NULL,
1037                                                 rte_strerror(EINVAL));
1038                 if (parent_level_id != IPN3KE_TM_NODE_LEVEL_PORT)
1039                         return -rte_tm_error_set(error,
1040                                         EINVAL,
1041                                         RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
1042                                         NULL,
1043                                         rte_strerror(EINVAL));
1044                 break;
1045
1046         case IPN3KE_TM_NODE_LEVEL_COS:
1047                 if (node_index >= IPN3KE_TM_COS_NODE_NUM)
1048                         return -rte_tm_error_set(error,
1049                                                 EINVAL,
1050                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1051                                                 NULL,
1052                                                 rte_strerror(EINVAL));
1053                 if (parent_level_id != IPN3KE_TM_NODE_LEVEL_VT)
1054                         return -rte_tm_error_set(error,
1055                                         EINVAL,
1056                                         RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
1057                                         NULL,
1058                                         rte_strerror(EINVAL));
1059                 break;
1060         default:
1061                 return -rte_tm_error_set(error,
1062                                         EINVAL,
1063                                         RTE_TM_ERROR_TYPE_LEVEL_ID,
1064                                         NULL,
1065                                         rte_strerror(EINVAL));
1066         }
1067
1068         /* params: must not be NULL */
1069         if (params == NULL)
1070                 return -rte_tm_error_set(error,
1071                                         EINVAL,
1072                                         RTE_TM_ERROR_TYPE_NODE_PARAMS,
1073                                         NULL,
1074                                         rte_strerror(EINVAL));
1075         /* No shared shapers */
1076         if (params->n_shared_shapers != 0)
1077                 return -rte_tm_error_set(error,
1078                                 EINVAL,
1079                                 RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS,
1080                                 NULL,
1081                                 rte_strerror(EINVAL));
1082         return 0;
1083 }
1084
1085 static int
1086 ipn3ke_tm_node_add_check_mount(uint32_t tm_id,
1087         uint32_t node_id, uint32_t parent_node_id, uint32_t level_id,
1088         struct rte_tm_error *error)
1089 {
1090         uint32_t node_index;
1091         uint32_t parent_index;
1092         uint32_t parent_index1;
1093
1094         node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD;
1095         parent_index = parent_node_id % IPN3KE_TM_NODE_LEVEL_MOD;
1096         parent_index1 = node_index / IPN3KE_TM_NODE_MOUNT_MAX;
1097         switch (level_id) {
1098         case IPN3KE_TM_NODE_LEVEL_PORT:
1099                 break;
1100
1101         case IPN3KE_TM_NODE_LEVEL_VT:
1102                 if (parent_index != tm_id)
1103                         return -rte_tm_error_set(error,
1104                                         EINVAL,
1105                                         RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
1106                                         NULL,
1107                                         rte_strerror(EINVAL));
1108                 break;
1109
1110         case IPN3KE_TM_NODE_LEVEL_COS:
1111                 if (parent_index != parent_index1)
1112                         return -rte_tm_error_set(error,
1113                                         EINVAL,
1114                                         RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
1115                                         NULL,
1116                                         rte_strerror(EINVAL));
1117                 break;
1118         default:
1119                 return -rte_tm_error_set(error,
1120                                         EINVAL,
1121                                         RTE_TM_ERROR_TYPE_LEVEL_ID,
1122                                         NULL,
1123                                         rte_strerror(EINVAL));
1124         }
1125
1126         return 0;
1127 }
1128
1129 /* Traffic manager node add */
1130 static int
1131 ipn3ke_tm_node_add(struct rte_eth_dev *dev,
1132         uint32_t node_id, uint32_t parent_node_id, uint32_t priority,
1133         uint32_t weight, uint32_t level_id, struct rte_tm_node_params *params,
1134         struct rte_tm_error *error)
1135 {
1136         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
1137         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1138         uint32_t tm_id;
1139         struct ipn3ke_tm_node *n, *parent_node;
1140         uint32_t node_state, state_mask;
1141         int status;
1142
1143         /* Checks */
1144         if (tm->hierarchy_frozen)
1145                 return -rte_tm_error_set(error,
1146                                         EBUSY,
1147                                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
1148                                         NULL,
1149                                         rte_strerror(EBUSY));
1150
1151         tm_id = tm->tm_id;
1152
1153         status = ipn3ke_tm_node_add_check_parameter(tm_id,
1154                                                 node_id,
1155                                                 parent_node_id,
1156                                                 priority,
1157                                                 weight,
1158                                                 level_id,
1159                                                 params,
1160                                                 error);
1161         if (status)
1162                 return status;
1163
1164         status = ipn3ke_tm_node_add_check_mount(tm_id,
1165                                                 node_id,
1166                                                 parent_node_id,
1167                                                 level_id,
1168                                                 error);
1169         if (status)
1170                 return status;
1171
1172         /* Shaper profile ID must not be NONE. */
1173         if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE &&
1174                 params->shaper_profile_id != node_id)
1175                 return -rte_tm_error_set(error,
1176                                         EINVAL,
1177                                         RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID,
1178                                         NULL,
1179                                         rte_strerror(EINVAL));
1180
1181         /* Memory allocation */
1182         state_mask = 0;
1183         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_IDLE);
1184         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_DEL);
1185         n = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask);
1186         if (!n)
1187                 return -rte_tm_error_set(error,
1188                                         EINVAL,
1189                                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
1190                                         NULL,
1191                                         rte_strerror(EINVAL));
1192         node_state = n->node_state;
1193
1194         /* Check parent node */
1195         state_mask = 0;
1196         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_ADD);
1197         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED);
1198         if (parent_node_id != RTE_TM_NODE_ID_NULL) {
1199                 parent_node = ipn3ke_hw_tm_node_search(hw,
1200                                                         tm_id,
1201                                                         parent_node_id,
1202                                                         state_mask);
1203                 if (!parent_node)
1204                         return -rte_tm_error_set(error,
1205                                         EINVAL,
1206                                         RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
1207                                         NULL,
1208                                         rte_strerror(EINVAL));
1209         } else {
1210                 parent_node = NULL;
1211         }
1212
1213         switch (level_id) {
1214         case IPN3KE_TM_NODE_LEVEL_PORT:
1215                 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_ADD;
1216                 n->tm_id = tm_id;
1217                 tm->h.port_commit_node = n;
1218                 break;
1219
1220         case IPN3KE_TM_NODE_LEVEL_VT:
1221                 if (node_state == IPN3KE_TM_NODE_STATE_IDLE) {
1222                         TAILQ_INSERT_TAIL(&tm->h.vt_commit_node_list, n, node);
1223                         if (parent_node)
1224                                 parent_node->n_children++;
1225                         tm->h.n_vt_nodes++;
1226                 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) {
1227                         if (parent_node)
1228                                 parent_node->n_children++;
1229                         tm->h.n_vt_nodes++;
1230                 }
1231                 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_ADD;
1232                 n->parent_node_id = parent_node_id;
1233                 n->tm_id = tm_id;
1234                 n->parent_node = parent_node;
1235
1236                 break;
1237
1238         case IPN3KE_TM_NODE_LEVEL_COS:
1239                 if (node_state == IPN3KE_TM_NODE_STATE_IDLE) {
1240                         TAILQ_INSERT_TAIL(&tm->h.cos_commit_node_list,
1241                                 n, node);
1242                         if (parent_node)
1243                                 parent_node->n_children++;
1244                         tm->h.n_cos_nodes++;
1245                 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) {
1246                         if (parent_node)
1247                                 parent_node->n_children++;
1248                         tm->h.n_cos_nodes++;
1249                 }
1250                 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_ADD;
1251                 n->parent_node_id = parent_node_id;
1252                 n->tm_id = tm_id;
1253                 n->parent_node = parent_node;
1254
1255                 break;
1256         default:
1257                 return -rte_tm_error_set(error,
1258                                         EINVAL,
1259                                         RTE_TM_ERROR_TYPE_LEVEL_ID,
1260                                         NULL,
1261                                         rte_strerror(EINVAL));
1262         }
1263
1264         /* Fill in */
1265         n->priority = priority;
1266         n->weight = weight;
1267
1268         if (n->level == IPN3KE_TM_NODE_LEVEL_COS &&
1269                 params->leaf.cman == RTE_TM_CMAN_TAIL_DROP)
1270                 n->tdrop_profile = ipn3ke_hw_tm_tdrop_profile_search(hw,
1271                         params->leaf.wred.wred_profile_id);
1272
1273         rte_memcpy(&n->params, params, sizeof(n->params));
1274
1275         return 0;
1276 }
1277
1278 static int
1279 ipn3ke_tm_node_del_check_parameter(uint32_t tm_id,
1280         uint32_t node_id, struct rte_tm_error *error)
1281 {
1282         uint32_t level_of_node_id;
1283         uint32_t node_index;
1284
1285         if (node_id == RTE_TM_NODE_ID_NULL)
1286                 return -rte_tm_error_set(error,
1287                                         EINVAL,
1288                                         RTE_TM_ERROR_TYPE_NODE_ID,
1289                                         NULL,
1290                                         rte_strerror(EINVAL));
1291
1292         /* check node id and parent id*/
1293         level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD;
1294         node_index = node_id % IPN3KE_TM_NODE_LEVEL_MOD;
1295         switch (level_of_node_id) {
1296         case IPN3KE_TM_NODE_LEVEL_PORT:
1297                 if (node_index != tm_id)
1298                         return -rte_tm_error_set(error,
1299                                                 EINVAL,
1300                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1301                                                 NULL,
1302                                                 rte_strerror(EINVAL));
1303                 break;
1304
1305         case IPN3KE_TM_NODE_LEVEL_VT:
1306                 if (node_index >= IPN3KE_TM_VT_NODE_NUM)
1307                         return -rte_tm_error_set(error,
1308                                                 EINVAL,
1309                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1310                                                 NULL,
1311                                                 rte_strerror(EINVAL));
1312                 break;
1313
1314         case IPN3KE_TM_NODE_LEVEL_COS:
1315                 if (node_index >= IPN3KE_TM_COS_NODE_NUM)
1316                         return -rte_tm_error_set(error,
1317                                                 EINVAL,
1318                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1319                                                 NULL,
1320                                                 rte_strerror(EINVAL));
1321                 break;
1322         default:
1323                 return -rte_tm_error_set(error,
1324                                         EINVAL,
1325                                         RTE_TM_ERROR_TYPE_LEVEL_ID,
1326                                         NULL,
1327                                         rte_strerror(EINVAL));
1328         }
1329
1330         return 0;
1331 }
1332
1333 /* Traffic manager node delete */
1334 static int
1335 ipn3ke_pmd_tm_node_delete(struct rte_eth_dev *dev,
1336         uint32_t node_id, struct rte_tm_error *error)
1337 {
1338         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
1339         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1340         struct ipn3ke_tm_node *n, *parent_node;
1341         uint32_t tm_id;
1342         int status;
1343         uint32_t level_of_node_id;
1344         uint32_t node_state;
1345         uint32_t state_mask;
1346
1347         /* Check hierarchy changes are currently allowed */
1348         if (tm->hierarchy_frozen)
1349                 return -rte_tm_error_set(error,
1350                                         EBUSY,
1351                                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
1352                                         NULL,
1353                                         rte_strerror(EBUSY));
1354
1355         tm_id = tm->tm_id;
1356
1357         status = ipn3ke_tm_node_del_check_parameter(tm_id,
1358                                                 node_id,
1359                                                 error);
1360         if (status)
1361                 return status;
1362
1363         /* Check existing */
1364         state_mask = 0;
1365         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_ADD);
1366         IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED);
1367         n = ipn3ke_hw_tm_node_search(hw, tm_id, node_id, state_mask);
1368         if (n == NULL)
1369                 return -rte_tm_error_set(error,
1370                                         EINVAL,
1371                                         RTE_TM_ERROR_TYPE_NODE_ID,
1372                                         NULL,
1373                                         rte_strerror(EINVAL));
1374
1375         if (n->n_children > 0)
1376                 return -rte_tm_error_set(error,
1377                                         EINVAL,
1378                                         RTE_TM_ERROR_TYPE_NODE_ID,
1379                                         NULL,
1380                                         rte_strerror(EINVAL));
1381
1382         node_state = n->node_state;
1383
1384         level_of_node_id = node_id / IPN3KE_TM_NODE_LEVEL_MOD;
1385
1386         /* Check parent node */
1387         if (n->parent_node_id != RTE_TM_NODE_ID_NULL) {
1388                 state_mask = 0;
1389                 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_CONFIGURED_ADD);
1390                 IPN3KE_BIT_SET(state_mask, IPN3KE_TM_NODE_STATE_COMMITTED);
1391                 parent_node = ipn3ke_hw_tm_node_search(hw,
1392                                                 tm_id,
1393                                                 n->parent_node_id,
1394                                                 state_mask);
1395                 if (!parent_node)
1396                         return -rte_tm_error_set(error,
1397                                         EINVAL,
1398                                         RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID,
1399                                         NULL,
1400                                         rte_strerror(EINVAL));
1401                 if (n->parent_node != parent_node)
1402                         return -rte_tm_error_set(error,
1403                                                 EINVAL,
1404                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1405                                                 NULL,
1406                                                 rte_strerror(EINVAL));
1407         } else {
1408                 parent_node = NULL;
1409         }
1410
1411         switch (level_of_node_id) {
1412         case IPN3KE_TM_NODE_LEVEL_PORT:
1413                 if (tm->h.port_node != n)
1414                         return -rte_tm_error_set(error,
1415                                                 EINVAL,
1416                                                 RTE_TM_ERROR_TYPE_NODE_ID,
1417                                                 NULL,
1418                                                 rte_strerror(EINVAL));
1419                 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_DEL;
1420                 tm->h.port_commit_node = n;
1421
1422                 break;
1423
1424         case IPN3KE_TM_NODE_LEVEL_VT:
1425                 if (node_state == IPN3KE_TM_NODE_STATE_COMMITTED) {
1426                         if (parent_node)
1427                                 TAILQ_REMOVE(&parent_node->children_node_list,
1428                                         n, node);
1429                         TAILQ_INSERT_TAIL(&tm->h.vt_commit_node_list, n, node);
1430                         if (parent_node)
1431                                 parent_node->n_children--;
1432                         tm->h.n_vt_nodes--;
1433                 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) {
1434                         if (parent_node)
1435                                 parent_node->n_children--;
1436                         tm->h.n_vt_nodes--;
1437                 }
1438                 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_DEL;
1439
1440                 break;
1441
1442         case IPN3KE_TM_NODE_LEVEL_COS:
1443                 if (node_state == IPN3KE_TM_NODE_STATE_COMMITTED) {
1444                         if (parent_node)
1445                                 TAILQ_REMOVE(&parent_node->children_node_list,
1446                                         n, node);
1447                         TAILQ_INSERT_TAIL(&tm->h.cos_commit_node_list,
1448                                 n, node);
1449                         if (parent_node)
1450                                 parent_node->n_children--;
1451                         tm->h.n_cos_nodes--;
1452                 } else if (node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) {
1453                         if (parent_node)
1454                                 parent_node->n_children--;
1455                         tm->h.n_cos_nodes--;
1456                 }
1457                 n->node_state = IPN3KE_TM_NODE_STATE_CONFIGURED_DEL;
1458
1459                 break;
1460         default:
1461                 return -rte_tm_error_set(error,
1462                                         EINVAL,
1463                                         RTE_TM_ERROR_TYPE_LEVEL_ID,
1464                                         NULL,
1465                                         rte_strerror(EINVAL));
1466         }
1467
1468         return 0;
1469 }
1470
1471 static int
1472 ipn3ke_tm_hierarchy_commit_check(struct rte_eth_dev *dev,
1473                                                 struct rte_tm_error *error)
1474 {
1475         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1476         uint32_t tm_id;
1477         struct ipn3ke_tm_node_list *nl;
1478         struct ipn3ke_tm_node *n, *parent_node;
1479
1480         tm_id = tm->tm_id;
1481
1482         nl = &tm->h.cos_commit_node_list;
1483         TAILQ_FOREACH(n, nl, node) {
1484                 parent_node = n->parent_node;
1485                 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) {
1486                         if (n->parent_node_id == RTE_TM_NODE_ID_NULL ||
1487                                 n->level != IPN3KE_TM_NODE_LEVEL_COS ||
1488                                 n->tm_id != tm_id ||
1489                                 parent_node == NULL ||
1490                                 (parent_node &&
1491                                         parent_node->node_state ==
1492                                         IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) ||
1493                                 (parent_node &&
1494                                         parent_node->node_state ==
1495                                                 IPN3KE_TM_NODE_STATE_IDLE) ||
1496                                 n->shaper_profile.valid == 0) {
1497                                 return -rte_tm_error_set(error,
1498                                                 EINVAL,
1499                                                 RTE_TM_ERROR_TYPE_UNSPECIFIED,
1500                                                 NULL,
1501                                                 rte_strerror(EINVAL));
1502                         }
1503                 } else if (n->node_state ==
1504                                 IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) {
1505                         if (n->level != IPN3KE_TM_NODE_LEVEL_COS ||
1506                                 n->n_children != 0) {
1507                                 return -rte_tm_error_set(error,
1508                                                 EINVAL,
1509                                                 RTE_TM_ERROR_TYPE_UNSPECIFIED,
1510                                                 NULL,
1511                                                 rte_strerror(EINVAL));
1512                         }
1513                 }
1514         }
1515
1516         nl = &tm->h.vt_commit_node_list;
1517         TAILQ_FOREACH(n, nl, node) {
1518                 parent_node = n->parent_node;
1519                 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) {
1520                         if (n->parent_node_id == RTE_TM_NODE_ID_NULL ||
1521                                 n->level != IPN3KE_TM_NODE_LEVEL_VT ||
1522                                 n->tm_id != tm_id ||
1523                                 parent_node == NULL ||
1524                                 (parent_node &&
1525                                         parent_node->node_state ==
1526                                         IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) ||
1527                                 (parent_node &&
1528                                         parent_node->node_state ==
1529                                                 IPN3KE_TM_NODE_STATE_IDLE) ||
1530                                 n->shaper_profile.valid == 0) {
1531                                 return -rte_tm_error_set(error,
1532                                                 EINVAL,
1533                                                 RTE_TM_ERROR_TYPE_UNSPECIFIED,
1534                                                 NULL,
1535                                                 rte_strerror(EINVAL));
1536                         }
1537                 } else if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_DEL)
1538                         return -rte_tm_error_set(error,
1539                                                 EINVAL,
1540                                                 RTE_TM_ERROR_TYPE_UNSPECIFIED,
1541                                                 NULL,
1542                                                 rte_strerror(EINVAL));
1543         }
1544
1545         n = tm->h.port_commit_node;
1546         if (n &&
1547                 (n->parent_node_id != RTE_TM_NODE_ID_NULL ||
1548                 n->level != IPN3KE_TM_NODE_LEVEL_PORT ||
1549                 n->tm_id != tm_id ||
1550                 n->parent_node != NULL ||
1551                 n->shaper_profile.valid == 0)) {
1552                 return -rte_tm_error_set(error,
1553                                         EINVAL,
1554                                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
1555                                         NULL,
1556                                         rte_strerror(EINVAL));
1557         }
1558
1559         return 0;
1560 }
1561
1562 static int
1563 ipn3ke_hw_tm_node_wr(struct ipn3ke_hw *hw,
1564         struct ipn3ke_tm_node *n,
1565         struct ipn3ke_tm_node *parent_node)
1566 {
1567         uint32_t level;
1568
1569         level = n->level;
1570
1571         switch (level) {
1572         case IPN3KE_TM_NODE_LEVEL_PORT:
1573                 /**
1574                  * Configure Type
1575                  */
1576                 IPN3KE_MASK_WRITE_REG(hw,
1577                                 IPN3KE_QOS_TYPE_L3_X,
1578                                 n->node_index,
1579                                 n->priority,
1580                                 IPN3KE_QOS_TYPE_MASK);
1581
1582                 /**
1583                  * Configure Sch_wt
1584                  */
1585                 IPN3KE_MASK_WRITE_REG(hw,
1586                                 IPN3KE_QOS_SCH_WT_L3_X,
1587                                 n->node_index,
1588                                 n->weight,
1589                                 IPN3KE_QOS_SCH_WT_MASK);
1590
1591                 /**
1592                  * Configure Shap_wt
1593                  */
1594                 if (n->shaper_profile.valid)
1595                         IPN3KE_MASK_WRITE_REG(hw,
1596                                         IPN3KE_QOS_SHAP_WT_L3_X,
1597                                         n->node_index,
1598                                         ((n->shaper_profile.e << 10) |
1599                                                 n->shaper_profile.m),
1600                                         IPN3KE_QOS_SHAP_WT_MASK);
1601
1602                 break;
1603         case IPN3KE_TM_NODE_LEVEL_VT:
1604                 /**
1605                  * Configure Type
1606                  */
1607                 IPN3KE_MASK_WRITE_REG(hw,
1608                                 IPN3KE_QOS_TYPE_L2_X,
1609                                 n->node_index,
1610                                 n->priority,
1611                                 IPN3KE_QOS_TYPE_MASK);
1612
1613                 /**
1614                  * Configure Sch_wt
1615                  */
1616                 IPN3KE_MASK_WRITE_REG(hw,
1617                                 IPN3KE_QOS_SCH_WT_L2_X,
1618                                 n->node_index,
1619                                 n->weight,
1620                                 IPN3KE_QOS_SCH_WT_MASK);
1621
1622                 /**
1623                  * Configure Shap_wt
1624                  */
1625                 if (n->shaper_profile.valid)
1626                         IPN3KE_MASK_WRITE_REG(hw,
1627                                         IPN3KE_QOS_SHAP_WT_L2_X,
1628                                         n->node_index,
1629                                         ((n->shaper_profile.e << 10) |
1630                                                 n->shaper_profile.m),
1631                                         IPN3KE_QOS_SHAP_WT_MASK);
1632
1633                 /**
1634                  * Configure Map
1635                  */
1636                 if (parent_node)
1637                         IPN3KE_MASK_WRITE_REG(hw,
1638                                         IPN3KE_QOS_MAP_L2_X,
1639                                         n->node_index,
1640                                         parent_node->node_index,
1641                                         IPN3KE_QOS_MAP_L2_MASK);
1642
1643                 break;
1644         case IPN3KE_TM_NODE_LEVEL_COS:
1645                 /**
1646                  * Configure Tail Drop mapping
1647                  */
1648                 if (n->tdrop_profile && n->tdrop_profile->valid) {
1649                         IPN3KE_MASK_WRITE_REG(hw,
1650                                         IPN3KE_CCB_QPROFILE_Q,
1651                                         n->node_index,
1652                                         n->tdrop_profile->tdrop_profile_id,
1653                                         IPN3KE_CCB_QPROFILE_MASK);
1654                 }
1655
1656                 /**
1657                  * Configure Type
1658                  */
1659                 IPN3KE_MASK_WRITE_REG(hw,
1660                                 IPN3KE_QOS_TYPE_L1_X,
1661                                 n->node_index,
1662                                 n->priority,
1663                                 IPN3KE_QOS_TYPE_MASK);
1664
1665                 /**
1666                  * Configure Sch_wt
1667                  */
1668                 IPN3KE_MASK_WRITE_REG(hw,
1669                                 IPN3KE_QOS_SCH_WT_L1_X,
1670                                 n->node_index,
1671                                 n->weight,
1672                                 IPN3KE_QOS_SCH_WT_MASK);
1673
1674                 /**
1675                  * Configure Shap_wt
1676                  */
1677                 if (n->shaper_profile.valid)
1678                         IPN3KE_MASK_WRITE_REG(hw,
1679                                         IPN3KE_QOS_SHAP_WT_L1_X,
1680                                         n->node_index,
1681                                         ((n->shaper_profile.e << 10) |
1682                                                 n->shaper_profile.m),
1683                                         IPN3KE_QOS_SHAP_WT_MASK);
1684
1685                 /**
1686                  * Configure COS queue to port
1687                  */
1688                 while (IPN3KE_MASK_READ_REG(hw,
1689                                         IPN3KE_QM_UID_CONFIG_CTRL,
1690                                         0,
1691                                         0x80000000))
1692                         ;
1693
1694                 if (parent_node && parent_node->parent_node)
1695                         IPN3KE_MASK_WRITE_REG(hw,
1696                                 IPN3KE_QM_UID_CONFIG_DATA,
1697                                 0,
1698                                 (1 << 8 | parent_node->parent_node->node_index),
1699                                 0x1FF);
1700
1701                 IPN3KE_MASK_WRITE_REG(hw,
1702                                 IPN3KE_QM_UID_CONFIG_CTRL,
1703                                 0,
1704                                 n->node_index,
1705                                 0xFFFFF);
1706
1707                 while (IPN3KE_MASK_READ_REG(hw,
1708                                         IPN3KE_QM_UID_CONFIG_CTRL,
1709                                         0,
1710                                         0x80000000))
1711                         ;
1712
1713                 /**
1714                  * Configure Map
1715                  */
1716                 if (parent_node)
1717                         IPN3KE_MASK_WRITE_REG(hw,
1718                                         IPN3KE_QOS_MAP_L1_X,
1719                                         n->node_index,
1720                                         parent_node->node_index,
1721                                         IPN3KE_QOS_MAP_L1_MASK);
1722
1723                 break;
1724         default:
1725                 return -1;
1726         }
1727
1728         return 0;
1729 }
1730
1731 static int
1732 ipn3ke_tm_hierarchy_hw_commit(struct rte_eth_dev *dev,
1733                                         struct rte_tm_error *error)
1734 {
1735         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
1736         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1737         struct ipn3ke_tm_node_list *nl;
1738         struct ipn3ke_tm_node *n, *nn, *parent_node;
1739
1740         n = tm->h.port_commit_node;
1741         if (n) {
1742                 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) {
1743                         tm->h.port_commit_node = NULL;
1744
1745                         n->node_state = IPN3KE_TM_NODE_STATE_COMMITTED;
1746                 } else if (n->node_state ==
1747                                         IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) {
1748                         tm->h.port_commit_node = NULL;
1749
1750                         n->node_state = IPN3KE_TM_NODE_STATE_IDLE;
1751                         n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
1752                         n->weight = 0;
1753                         n->tm_id = RTE_TM_NODE_ID_NULL;
1754                 } else {
1755                         return -rte_tm_error_set(error,
1756                                                 EINVAL,
1757                                                 RTE_TM_ERROR_TYPE_UNSPECIFIED,
1758                                                 NULL,
1759                                                 rte_strerror(EINVAL));
1760                 }
1761                 parent_node = n->parent_node;
1762                 ipn3ke_hw_tm_node_wr(hw, n, parent_node);
1763         }
1764
1765         nl = &tm->h.vt_commit_node_list;
1766         for (n = TAILQ_FIRST(nl); n != NULL; n = nn) {
1767                 nn = TAILQ_NEXT(n, node);
1768                 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) {
1769                         n->node_state = IPN3KE_TM_NODE_STATE_COMMITTED;
1770                         parent_node = n->parent_node;
1771                         TAILQ_REMOVE(nl, n, node);
1772                         TAILQ_INSERT_TAIL(&parent_node->children_node_list,
1773                                                 n, node);
1774                 } else if (n->node_state ==
1775                                         IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) {
1776                         parent_node = n->parent_node;
1777                         TAILQ_REMOVE(nl, n, node);
1778
1779                         n->node_state = IPN3KE_TM_NODE_STATE_IDLE;
1780                         n->parent_node_id = RTE_TM_NODE_ID_NULL;
1781                         n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
1782                         n->weight = 0;
1783                         n->tm_id = RTE_TM_NODE_ID_NULL;
1784                         n->parent_node = NULL;
1785                 } else {
1786                         return -rte_tm_error_set(error,
1787                                                 EINVAL,
1788                                                 RTE_TM_ERROR_TYPE_UNSPECIFIED,
1789                                                 NULL,
1790                                                 rte_strerror(EINVAL));
1791                 }
1792                 ipn3ke_hw_tm_node_wr(hw, n, parent_node);
1793         }
1794
1795         nl = &tm->h.cos_commit_node_list;
1796         for (n = TAILQ_FIRST(nl); n != NULL; n = nn) {
1797                 nn = TAILQ_NEXT(n, node);
1798                 if (n->node_state == IPN3KE_TM_NODE_STATE_CONFIGURED_ADD) {
1799                         n->node_state = IPN3KE_TM_NODE_STATE_COMMITTED;
1800                         parent_node = n->parent_node;
1801                         TAILQ_REMOVE(nl, n, node);
1802                         TAILQ_INSERT_TAIL(&parent_node->children_node_list,
1803                                         n, node);
1804                 } else if (n->node_state ==
1805                                         IPN3KE_TM_NODE_STATE_CONFIGURED_DEL) {
1806                         n->node_state = IPN3KE_TM_NODE_STATE_IDLE;
1807                         parent_node = n->parent_node;
1808                         TAILQ_REMOVE(nl, n, node);
1809
1810                         n->node_state = IPN3KE_TM_NODE_STATE_IDLE;
1811                         n->parent_node_id = RTE_TM_NODE_ID_NULL;
1812                         n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
1813                         n->weight = 0;
1814                         n->tm_id = RTE_TM_NODE_ID_NULL;
1815                         n->parent_node = NULL;
1816
1817                         if (n->tdrop_profile)
1818                                 n->tdrop_profile->n_users--;
1819                 } else {
1820                         return -rte_tm_error_set(error,
1821                                                 EINVAL,
1822                                                 RTE_TM_ERROR_TYPE_UNSPECIFIED,
1823                                                 NULL,
1824                                                 rte_strerror(EINVAL));
1825                 }
1826                 ipn3ke_hw_tm_node_wr(hw, n, parent_node);
1827         }
1828
1829         return 0;
1830 }
1831
1832 static int
1833 ipn3ke_tm_hierarchy_commit_clear(struct rte_eth_dev *dev)
1834 {
1835         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1836         struct ipn3ke_tm_node_list *nl;
1837         struct ipn3ke_tm_node *n;
1838         struct ipn3ke_tm_node *nn;
1839
1840         n = tm->h.port_commit_node;
1841         if (n) {
1842                 n->node_state = IPN3KE_TM_NODE_STATE_IDLE;
1843                 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
1844                 n->weight = 0;
1845                 n->tm_id = RTE_TM_NODE_ID_NULL;
1846                 n->n_children = 0;
1847
1848                 tm->h.port_commit_node = NULL;
1849         }
1850
1851         nl = &tm->h.vt_commit_node_list;
1852         for (n = TAILQ_FIRST(nl); n != NULL; n = nn) {
1853                 nn = TAILQ_NEXT(n, node);
1854
1855                 n->node_state = IPN3KE_TM_NODE_STATE_IDLE;
1856                 n->parent_node_id = RTE_TM_NODE_ID_NULL;
1857                 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
1858                 n->weight = 0;
1859                 n->tm_id = RTE_TM_NODE_ID_NULL;
1860                 n->parent_node = NULL;
1861                 n->n_children = 0;
1862                 tm->h.n_vt_nodes--;
1863
1864                 TAILQ_REMOVE(nl, n, node);
1865         }
1866
1867         nl = &tm->h.cos_commit_node_list;
1868         for (n = TAILQ_FIRST(nl); n != NULL; n = nn) {
1869                 nn = TAILQ_NEXT(n, node);
1870
1871                 n->node_state = IPN3KE_TM_NODE_STATE_IDLE;
1872                 n->parent_node_id = RTE_TM_NODE_ID_NULL;
1873                 n->priority = IPN3KE_TM_NODE_PRIORITY_NORMAL0;
1874                 n->weight = 0;
1875                 n->tm_id = RTE_TM_NODE_ID_NULL;
1876                 n->parent_node = NULL;
1877                 tm->h.n_cos_nodes--;
1878
1879                 TAILQ_REMOVE(nl, n, node);
1880         }
1881
1882         return 0;
1883 }
1884
1885 static void
1886 ipn3ke_tm_show(struct rte_eth_dev *dev)
1887 {
1888         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1889         uint32_t tm_id;
1890         struct ipn3ke_tm_node_list *vt_nl, *cos_nl;
1891         struct ipn3ke_tm_node *port_n, *vt_n, *cos_n;
1892         const char *str_state[IPN3KE_TM_NODE_STATE_MAX] = {"Idle",
1893                                                 "CfgAdd",
1894                                                 "CfgDel",
1895                                                 "Committed"};
1896
1897         tm_id = tm->tm_id;
1898
1899         IPN3KE_AFU_PMD_DEBUG("***HQoS Tree(%d)***\n", tm_id);
1900
1901         port_n = tm->h.port_node;
1902         IPN3KE_AFU_PMD_DEBUG("Port: (%d|%s)\n", port_n->node_index,
1903                                 str_state[port_n->node_state]);
1904
1905         vt_nl = &tm->h.port_node->children_node_list;
1906         TAILQ_FOREACH(vt_n, vt_nl, node) {
1907                 cos_nl = &vt_n->children_node_list;
1908                 IPN3KE_AFU_PMD_DEBUG("    VT%d: ", vt_n->node_index);
1909                 TAILQ_FOREACH(cos_n, cos_nl, node) {
1910                         if (cos_n->parent_node_id !=
1911                                 (vt_n->node_index + IPN3KE_TM_NODE_LEVEL_MOD))
1912                                 IPN3KE_AFU_PMD_ERR("(%d|%s), ",
1913                                         cos_n->node_index,
1914                                         str_state[cos_n->node_state]);
1915                 }
1916                 IPN3KE_AFU_PMD_DEBUG("\n");
1917         }
1918 }
1919
1920 static void
1921 ipn3ke_tm_show_commmit(struct rte_eth_dev *dev)
1922 {
1923         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1924         uint32_t tm_id;
1925         struct ipn3ke_tm_node_list *nl;
1926         struct ipn3ke_tm_node *n;
1927         const char *str_state[IPN3KE_TM_NODE_STATE_MAX] = {"Idle",
1928                                                 "CfgAdd",
1929                                                 "CfgDel",
1930                                                 "Committed"};
1931
1932         tm_id = tm->tm_id;
1933
1934         IPN3KE_AFU_PMD_DEBUG("***Commit Tree(%d)***\n", tm_id);
1935         n = tm->h.port_commit_node;
1936         IPN3KE_AFU_PMD_DEBUG("Port: ");
1937         if (n)
1938                 IPN3KE_AFU_PMD_DEBUG("(%d|%s)",
1939                         n->node_index,
1940                         str_state[n->node_state]);
1941         IPN3KE_AFU_PMD_DEBUG("\n");
1942
1943         nl = &tm->h.vt_commit_node_list;
1944         IPN3KE_AFU_PMD_DEBUG("VT  : ");
1945         TAILQ_FOREACH(n, nl, node) {
1946                 IPN3KE_AFU_PMD_DEBUG("(%d|%s), ",
1947                                 n->node_index,
1948                                 str_state[n->node_state]);
1949         }
1950         IPN3KE_AFU_PMD_DEBUG("\n");
1951
1952         nl = &tm->h.cos_commit_node_list;
1953         IPN3KE_AFU_PMD_DEBUG("COS : ");
1954         TAILQ_FOREACH(n, nl, node) {
1955                 IPN3KE_AFU_PMD_DEBUG("(%d|%s), ",
1956                                 n->node_index,
1957                                 str_state[n->node_state]);
1958         }
1959         IPN3KE_AFU_PMD_DEBUG("\n");
1960 }
1961
1962 /* Traffic manager hierarchy commit */
1963 static int
1964 ipn3ke_tm_hierarchy_commit(struct rte_eth_dev *dev,
1965         int clear_on_fail, struct rte_tm_error *error)
1966 {
1967         struct ipn3ke_tm_internals *tm = IPN3KE_DEV_PRIVATE_TO_TM(dev);
1968         int status;
1969
1970         /* Checks */
1971         if (tm->hierarchy_frozen)
1972                 return -rte_tm_error_set(error,
1973                                         EBUSY,
1974                                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
1975                                         NULL,
1976                                         rte_strerror(EBUSY));
1977
1978         ipn3ke_tm_show_commmit(dev);
1979
1980         status = ipn3ke_tm_hierarchy_commit_check(dev, error);
1981         if (status) {
1982                 if (clear_on_fail)
1983                         ipn3ke_tm_hierarchy_commit_clear(dev);
1984                 return status;
1985         }
1986
1987         ipn3ke_tm_hierarchy_hw_commit(dev, error);
1988         ipn3ke_tm_show(dev);
1989
1990         return 0;
1991 }
1992
1993 const struct rte_tm_ops ipn3ke_tm_ops = {
1994         .node_type_get = ipn3ke_pmd_tm_node_type_get,
1995         .capabilities_get = ipn3ke_tm_capabilities_get,
1996         .level_capabilities_get = ipn3ke_tm_level_capabilities_get,
1997         .node_capabilities_get = ipn3ke_tm_node_capabilities_get,
1998
1999         .wred_profile_add = ipn3ke_tm_tdrop_profile_add,
2000         .wred_profile_delete = ipn3ke_tm_tdrop_profile_delete,
2001         .shared_wred_context_add_update = NULL,
2002         .shared_wred_context_delete = NULL,
2003
2004         .shaper_profile_add = ipn3ke_tm_shaper_profile_add,
2005         .shaper_profile_delete = ipn3ke_tm_shaper_profile_delete,
2006         .shared_shaper_add_update = NULL,
2007         .shared_shaper_delete = NULL,
2008
2009         .node_add = ipn3ke_tm_node_add,
2010         .node_delete = ipn3ke_pmd_tm_node_delete,
2011         .node_suspend = NULL,
2012         .node_resume = NULL,
2013         .hierarchy_commit = ipn3ke_tm_hierarchy_commit,
2014
2015         .node_parent_update = NULL,
2016         .node_shaper_update = NULL,
2017         .node_shared_shaper_update = NULL,
2018         .node_stats_update = NULL,
2019         .node_wfq_weight_mode_update = NULL,
2020         .node_cman_update = NULL,
2021         .node_wred_context_update = NULL,
2022         .node_shared_wred_context_update = NULL,
2023
2024         .node_stats_read = NULL,
2025 };
2026
2027 int
2028 ipn3ke_tm_ops_get(struct rte_eth_dev *ethdev,
2029                 void *arg)
2030 {
2031         struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(ethdev);
2032         struct ipn3ke_rpst *rpst = IPN3KE_DEV_PRIVATE_TO_RPST(ethdev);
2033         struct rte_eth_dev *i40e_pf_eth;
2034         const struct rte_tm_ops *ops;
2035
2036         if (!arg)
2037                 return -EINVAL;
2038
2039         if (hw->acc_tm) {
2040                 *(const void **)arg = &ipn3ke_tm_ops;
2041         } else if (rpst->i40e_pf_eth) {
2042                 i40e_pf_eth = rpst->i40e_pf_eth;
2043                 if (i40e_pf_eth->dev_ops->tm_ops_get == NULL ||
2044                         i40e_pf_eth->dev_ops->tm_ops_get(i40e_pf_eth,
2045                         &ops) != 0 ||
2046                         ops == NULL) {
2047                         return -EINVAL;
2048                 }
2049                 *(const void **)arg = ops;
2050         } else {
2051                 return -EINVAL;
2052         }
2053
2054         return 0;
2055 }