app/testpmd: add commands for TM capability and stats
[dpdk.git] / app / test-pmd / cmdline_tm.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <cmdline_parse.h>
35 #include <cmdline_parse_num.h>
36 #include <cmdline_parse_string.h>
37
38 #include <rte_ethdev.h>
39 #include <rte_flow.h>
40 #include <rte_tm.h>
41
42 #include "testpmd.h"
43 #include "cmdline_tm.h"
44
45 /** Display TM Error Message */
46 static void
47 print_err_msg(struct rte_tm_error *error)
48 {
49         static const char *const errstrlist[] = {
50                 [RTE_TM_ERROR_TYPE_NONE] = "no error",
51                 [RTE_TM_ERROR_TYPE_UNSPECIFIED] = "cause unspecified",
52                 [RTE_TM_ERROR_TYPE_CAPABILITIES]
53                         = "capability parameter null",
54                 [RTE_TM_ERROR_TYPE_LEVEL_ID] = "level id",
55                 [RTE_TM_ERROR_TYPE_WRED_PROFILE]
56                         = "wred profile null",
57                 [RTE_TM_ERROR_TYPE_WRED_PROFILE_GREEN] = "wred profile(green)",
58                 [RTE_TM_ERROR_TYPE_WRED_PROFILE_YELLOW]
59                         = "wred profile(yellow)",
60                 [RTE_TM_ERROR_TYPE_WRED_PROFILE_RED] = "wred profile(red)",
61                 [RTE_TM_ERROR_TYPE_WRED_PROFILE_ID] = "wred profile id",
62                 [RTE_TM_ERROR_TYPE_SHARED_WRED_CONTEXT_ID]
63                         = "shared wred context id",
64                 [RTE_TM_ERROR_TYPE_SHAPER_PROFILE] = "shaper profile null",
65                 [RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_RATE]
66                         = "committed rate field (shaper profile)",
67                 [RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_SIZE]
68                         = "committed size field (shaper profile)",
69                 [RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE]
70                         = "peak rate field (shaper profile)",
71                 [RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE]
72                         = "peak size field (shaper profile)",
73                 [RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN]
74                         = "packet adjust length field (shaper profile)",
75                 [RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID] = "shaper profile id",
76                 [RTE_TM_ERROR_TYPE_SHARED_SHAPER_ID] = "shared shaper id",
77                 [RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID] = "parent node id",
78                 [RTE_TM_ERROR_TYPE_NODE_PRIORITY] = "node priority",
79                 [RTE_TM_ERROR_TYPE_NODE_WEIGHT] = "node weight",
80                 [RTE_TM_ERROR_TYPE_NODE_PARAMS] = "node parameter null",
81                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID]
82                         = "shaper profile id field (node params)",
83                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID]
84                         = "shared shaper id field (node params)",
85                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS]
86                         = "num shared shapers field (node params)",
87                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE]
88                         = "wfq weght mode field (node params)",
89                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SP_PRIORITIES]
90                         = "num strict priorities field (node params)",
91                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN]
92                         = "congestion management mode field (node params)",
93                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_WRED_PROFILE_ID] =
94                         "wred profile id field (node params)",
95                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_WRED_CONTEXT_ID]
96                         = "shared wred context id field (node params)",
97                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_WRED_CONTEXTS]
98                         = "num shared wred contexts field (node params)",
99                 [RTE_TM_ERROR_TYPE_NODE_PARAMS_STATS]
100                         = "stats field (node params)",
101                 [RTE_TM_ERROR_TYPE_NODE_ID] = "node id",
102         };
103
104         const char *errstr;
105         char buf[64];
106
107         if ((unsigned int)error->type >= RTE_DIM(errstrlist) ||
108                 !errstrlist[error->type])
109                 errstr = "unknown type";
110         else
111                 errstr = errstrlist[error->type];
112
113         if (error->cause)
114                 snprintf(buf, sizeof(buf), "cause: %p, ", error->cause);
115
116         printf("%s: %s%s (error %d)\n", errstr, error->cause ? buf : "",
117                 error->message ? error->message : "(no stated reason)",
118                 error->type);
119 }
120
121 /* *** Port TM Capability *** */
122 struct cmd_show_port_tm_cap_result {
123         cmdline_fixed_string_t show;
124         cmdline_fixed_string_t port;
125         cmdline_fixed_string_t tm;
126         cmdline_fixed_string_t cap;
127         uint16_t port_id;
128 };
129
130 cmdline_parse_token_string_t cmd_show_port_tm_cap_show =
131         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_cap_result,
132                 show, "show");
133 cmdline_parse_token_string_t cmd_show_port_tm_cap_port =
134         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_cap_result,
135                 port, "port");
136 cmdline_parse_token_string_t cmd_show_port_tm_cap_tm =
137         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_cap_result,
138                 tm, "tm");
139 cmdline_parse_token_string_t cmd_show_port_tm_cap_cap =
140         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_cap_result,
141                 cap, "cap");
142 cmdline_parse_token_num_t cmd_show_port_tm_cap_port_id =
143         TOKEN_NUM_INITIALIZER(struct cmd_show_port_tm_cap_result,
144                  port_id, UINT16);
145
146 static void cmd_show_port_tm_cap_parsed(void *parsed_result,
147         __attribute__((unused)) struct cmdline *cl,
148         __attribute__((unused)) void *data)
149 {
150         struct cmd_show_port_tm_cap_result *res = parsed_result;
151         struct rte_tm_capabilities cap;
152         struct rte_tm_error error;
153         portid_t port_id = res->port_id;
154         uint32_t i;
155         int ret;
156
157         if (port_id_is_invalid(port_id, ENABLED_WARN))
158                 return;
159
160         memset(&cap, 0, sizeof(struct rte_tm_capabilities));
161         ret = rte_tm_capabilities_get(port_id, &cap, &error);
162         if (ret) {
163                 print_err_msg(&error);
164                 return;
165         }
166
167         printf("\n****   Port TM Capabilities ****\n\n");
168         printf("cap.n_nodes_max %" PRIu32 "\n", cap.n_nodes_max);
169         printf("cap.n_levels_max %" PRIu32 "\n", cap.n_levels_max);
170         printf("cap.non_leaf_nodes_identical %" PRId32 "\n",
171                 cap.non_leaf_nodes_identical);
172         printf("cap.leaf_nodes_identical %" PRId32 "\n",
173                 cap.leaf_nodes_identical);
174         printf("cap.shaper_n_max %u\n", cap.shaper_n_max);
175         printf("cap.shaper_private_n_max %" PRIu32 "\n",
176                 cap.shaper_private_n_max);
177         printf("cap.shaper_private_dual_rate_n_max %" PRId32 "\n",
178                 cap.shaper_private_dual_rate_n_max);
179         printf("cap.shaper_private_rate_min %" PRIu64 "\n",
180                 cap.shaper_private_rate_min);
181         printf("cap.shaper_private_rate_max %" PRIu64 "\n",
182                 cap.shaper_private_rate_max);
183         printf("cap.shaper_shared_n_max %" PRIu32 "\n",
184                 cap.shaper_shared_n_max);
185         printf("cap.shaper_shared_n_nodes_per_shaper_max %" PRIu32 "\n",
186                 cap.shaper_shared_n_nodes_per_shaper_max);
187         printf("cap.shaper_shared_n_shapers_per_node_max %" PRIu32 "\n",
188                 cap.shaper_shared_n_shapers_per_node_max);
189         printf("cap.shaper_shared_dual_rate_n_max %" PRIu32 "\n",
190                 cap.shaper_shared_dual_rate_n_max);
191         printf("cap.shaper_shared_rate_min %" PRIu64 "\n",
192                 cap.shaper_shared_rate_min);
193         printf("cap.shaper_shared_rate_max %" PRIu64 "\n",
194                 cap.shaper_shared_rate_max);
195         printf("cap.shaper_pkt_length_adjust_min %" PRId32 "\n",
196                 cap.shaper_pkt_length_adjust_min);
197         printf("cap.shaper_pkt_length_adjust_max %" PRId32 "\n",
198                 cap.shaper_pkt_length_adjust_max);
199         printf("cap.sched_n_children_max %" PRIu32 "\n",
200                 cap.sched_n_children_max);
201         printf("cap.sched_sp_n_priorities_max %" PRIu32 "\n",
202                 cap.sched_sp_n_priorities_max);
203         printf("cap.sched_wfq_n_children_per_group_max %" PRIu32 "\n",
204                 cap.sched_wfq_n_children_per_group_max);
205         printf("cap.sched_wfq_n_groups_max %" PRIu32 "\n",
206                 cap.sched_wfq_n_groups_max);
207         printf("cap.sched_wfq_weight_max %" PRIu32 "\n",
208                 cap.sched_wfq_weight_max);
209         printf("cap.cman_head_drop_supported %" PRId32 "\n",
210                 cap.cman_head_drop_supported);
211         printf("cap.cman_wred_context_n_max %" PRIu32 "\n",
212                 cap.cman_wred_context_n_max);
213         printf("cap.cman_wred_context_private_n_max %" PRIu32 "\n",
214                 cap.cman_wred_context_private_n_max);
215         printf("cap.cman_wred_context_shared_n_max %" PRIu32 "\n",
216                 cap.cman_wred_context_shared_n_max);
217         printf("cap.cman_wred_context_shared_n_nodes_per_context_max %" PRIu32
218                 "\n", cap.cman_wred_context_shared_n_nodes_per_context_max);
219         printf("cap.cman_wred_context_shared_n_contexts_per_node_max %" PRIu32
220                 "\n", cap.cman_wred_context_shared_n_contexts_per_node_max);
221
222         for (i = 0; i < RTE_TM_COLORS; i++) {
223                 printf("cap.mark_vlan_dei_supported %" PRId32 "\n",
224                         cap.mark_vlan_dei_supported[i]);
225                 printf("cap.mark_ip_ecn_tcp_supported %" PRId32 "\n",
226                         cap.mark_ip_ecn_tcp_supported[i]);
227                 printf("cap.mark_ip_ecn_sctp_supported %" PRId32 "\n",
228                         cap.mark_ip_ecn_sctp_supported[i]);
229                 printf("cap.mark_ip_dscp_supported %" PRId32 "\n",
230                         cap.mark_ip_dscp_supported[i]);
231         }
232
233         printf("cap.dynamic_update_mask %" PRIx64 "\n",
234                 cap.dynamic_update_mask);
235         printf("cap.stats_mask %" PRIx64 "\n", cap.stats_mask);
236 }
237
238 cmdline_parse_inst_t cmd_show_port_tm_cap = {
239         .f = cmd_show_port_tm_cap_parsed,
240         .data = NULL,
241         .help_str = "Show Port TM Capabilities",
242         .tokens = {
243                 (void *)&cmd_show_port_tm_cap_show,
244                 (void *)&cmd_show_port_tm_cap_port,
245                 (void *)&cmd_show_port_tm_cap_tm,
246                 (void *)&cmd_show_port_tm_cap_cap,
247                 (void *)&cmd_show_port_tm_cap_port_id,
248                 NULL,
249         },
250 };
251
252 /* *** Port TM Hierarchical Level Capability *** */
253 struct cmd_show_port_tm_level_cap_result {
254         cmdline_fixed_string_t show;
255         cmdline_fixed_string_t port;
256         cmdline_fixed_string_t tm;
257         cmdline_fixed_string_t level;
258         cmdline_fixed_string_t cap;
259         uint16_t port_id;
260         uint32_t level_id;
261 };
262
263 cmdline_parse_token_string_t cmd_show_port_tm_level_cap_show =
264         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_level_cap_result,
265                 show, "show");
266 cmdline_parse_token_string_t cmd_show_port_tm_level_cap_port =
267         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_level_cap_result,
268                 port, "port");
269 cmdline_parse_token_string_t cmd_show_port_tm_level_cap_tm =
270         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_level_cap_result,
271                 tm, "tm");
272 cmdline_parse_token_string_t cmd_show_port_tm_level_cap_level =
273         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_level_cap_result,
274                 level, "level");
275 cmdline_parse_token_string_t cmd_show_port_tm_level_cap_cap =
276         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_level_cap_result,
277                 cap, "cap");
278 cmdline_parse_token_num_t cmd_show_port_tm_level_cap_port_id =
279         TOKEN_NUM_INITIALIZER(struct cmd_show_port_tm_level_cap_result,
280                  port_id, UINT16);
281 cmdline_parse_token_num_t cmd_show_port_tm_level_cap_level_id =
282         TOKEN_NUM_INITIALIZER(struct cmd_show_port_tm_level_cap_result,
283                  level_id, UINT32);
284
285
286 static void cmd_show_port_tm_level_cap_parsed(void *parsed_result,
287         __attribute__((unused)) struct cmdline *cl,
288         __attribute__((unused)) void *data)
289 {
290         struct cmd_show_port_tm_level_cap_result *res = parsed_result;
291         struct rte_tm_level_capabilities lcap;
292         struct rte_tm_error error;
293         portid_t port_id = res->port_id;
294         uint32_t level_id = res->level_id;
295         int ret;
296
297         if (port_id_is_invalid(port_id, ENABLED_WARN))
298                 return;
299
300         memset(&lcap, 0, sizeof(struct rte_tm_level_capabilities));
301         ret = rte_tm_level_capabilities_get(port_id, level_id, &lcap, &error);
302         if (ret) {
303                 print_err_msg(&error);
304                 return;
305         }
306         printf("\n**   Port TM Hierarchy level %" PRIu32 " Capability **\n\n",
307                 level_id);
308
309         printf("cap.n_nodes_max %" PRIu32 "\n", lcap.n_nodes_max);
310         printf("cap.n_nodes_nonleaf_max %" PRIu32 "\n",
311                 lcap.n_nodes_nonleaf_max);
312         printf("cap.n_nodes_leaf_max %" PRIu32 "\n", lcap.n_nodes_leaf_max);
313         printf("cap.non_leaf_nodes_identical %" PRId32 "\n",
314                 lcap.non_leaf_nodes_identical);
315         printf("cap.leaf_nodes_identical %" PRId32 "\n",
316                 lcap.leaf_nodes_identical);
317         if (level_id <= 3) {
318                 printf("cap.nonleaf.shaper_private_supported %" PRId32 "\n",
319                         lcap.nonleaf.shaper_private_supported);
320                 printf("cap.nonleaf.shaper_private_dual_rate_supported %" PRId32
321                         "\n", lcap.nonleaf.shaper_private_dual_rate_supported);
322                 printf("cap.nonleaf.shaper_private_rate_min %" PRIu64 "\n",
323                         lcap.nonleaf.shaper_private_rate_min);
324                 printf("cap.nonleaf.shaper_private_rate_max %" PRIu64 "\n",
325                         lcap.nonleaf.shaper_private_rate_max);
326                 printf("cap.nonleaf.shaper_shared_n_max %" PRIu32 "\n",
327                         lcap.nonleaf.shaper_shared_n_max);
328                 printf("cap.nonleaf.sched_n_children_max %" PRIu32 "\n",
329                         lcap.nonleaf.sched_n_children_max);
330                 printf("cap.nonleaf.sched_sp_n_priorities_max %" PRIu32 "\n",
331                         lcap.nonleaf.sched_sp_n_priorities_max);
332                 printf("cap.nonleaf.sched_wfq_n_children_per_group_max %" PRIu32
333                         "\n", lcap.nonleaf.sched_wfq_n_children_per_group_max);
334                 printf("cap.nonleaf.sched_wfq_n_groups_max %" PRIu32 "\n",
335                         lcap.nonleaf.sched_wfq_n_groups_max);
336                 printf("cap.nonleaf.sched_wfq_weight_max %" PRIu32 "\n",
337                         lcap.nonleaf.sched_wfq_weight_max);
338                 printf("cap.nonleaf.stats_mask %" PRIx64 "\n",
339                         lcap.nonleaf.stats_mask);
340         } else {
341                 printf("cap.leaf.shaper_private_supported %" PRId32 "\n",
342                         lcap.leaf.shaper_private_supported);
343                 printf("cap.leaf.shaper_private_dual_rate_supported %" PRId32
344                         "\n", lcap.leaf.shaper_private_dual_rate_supported);
345                 printf("cap.leaf.shaper_private_rate_min %" PRIu64 "\n",
346                         lcap.leaf.shaper_private_rate_min);
347                 printf("cap.leaf.shaper_private_rate_max %" PRIu64 "\n",
348                         lcap.leaf.shaper_private_rate_max);
349                 printf("cap.leaf.shaper_shared_n_max %" PRIu32 "\n",
350                         lcap.leaf.shaper_shared_n_max);
351                 printf("cap.leaf.cman_head_drop_supported %" PRId32 "\n",
352                         lcap.leaf.cman_head_drop_supported);
353                 printf("cap.leaf.cman_wred_context_private_supported %" PRId32
354                         "\n", lcap.leaf.cman_wred_context_private_supported);
355                 printf("cap.leaf.cman_wred_context_shared_n_max %" PRIu32 "\n",
356                         lcap.leaf.cman_wred_context_shared_n_max);
357                 printf("cap.leaf.stats_mask %" PRIx64 "\n",
358                         lcap.leaf.stats_mask);
359         }
360 }
361
362 cmdline_parse_inst_t cmd_show_port_tm_level_cap = {
363         .f = cmd_show_port_tm_level_cap_parsed,
364         .data = NULL,
365         .help_str = "Show Port TM Hierarhical level Capabilities",
366         .tokens = {
367                 (void *)&cmd_show_port_tm_level_cap_show,
368                 (void *)&cmd_show_port_tm_level_cap_port,
369                 (void *)&cmd_show_port_tm_level_cap_tm,
370                 (void *)&cmd_show_port_tm_level_cap_level,
371                 (void *)&cmd_show_port_tm_level_cap_cap,
372                 (void *)&cmd_show_port_tm_level_cap_port_id,
373                 (void *)&cmd_show_port_tm_level_cap_level_id,
374                 NULL,
375         },
376 };
377
378 /* *** Port TM Hierarchy Node Capability *** */
379 struct cmd_show_port_tm_node_cap_result {
380         cmdline_fixed_string_t show;
381         cmdline_fixed_string_t port;
382         cmdline_fixed_string_t tm;
383         cmdline_fixed_string_t node;
384         cmdline_fixed_string_t cap;
385         uint16_t port_id;
386         uint32_t node_id;
387 };
388
389 cmdline_parse_token_string_t cmd_show_port_tm_node_cap_show =
390         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_node_cap_result,
391                 show, "show");
392 cmdline_parse_token_string_t cmd_show_port_tm_node_cap_port =
393         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_node_cap_result,
394                 port, "port");
395 cmdline_parse_token_string_t cmd_show_port_tm_node_cap_tm =
396         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_node_cap_result,
397                 tm, "tm");
398 cmdline_parse_token_string_t cmd_show_port_tm_node_cap_node =
399         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_node_cap_result,
400                 node, "node");
401 cmdline_parse_token_string_t cmd_show_port_tm_node_cap_cap =
402         TOKEN_STRING_INITIALIZER(struct cmd_show_port_tm_node_cap_result,
403                 cap, "cap");
404 cmdline_parse_token_num_t cmd_show_port_tm_node_cap_port_id =
405         TOKEN_NUM_INITIALIZER(struct cmd_show_port_tm_node_cap_result,
406                  port_id, UINT16);
407 cmdline_parse_token_num_t cmd_show_port_tm_node_cap_node_id =
408         TOKEN_NUM_INITIALIZER(struct cmd_show_port_tm_node_cap_result,
409                  node_id, UINT32);
410
411 static void cmd_show_port_tm_node_cap_parsed(void *parsed_result,
412         __attribute__((unused)) struct cmdline *cl,
413         __attribute__((unused)) void *data)
414 {
415         struct cmd_show_port_tm_node_cap_result *res = parsed_result;
416         struct rte_tm_node_capabilities ncap;
417         struct rte_tm_error error;
418         uint32_t node_id = res->node_id;
419         portid_t port_id = res->port_id;
420         int ret, is_leaf = 0;
421
422         if (port_id_is_invalid(port_id, ENABLED_WARN))
423                 return;
424
425         /* Node id must be valid */
426         ret = rte_tm_node_type_get(port_id, node_id, &is_leaf, &error);
427         if (ret != 0) {
428                 print_err_msg(&error);
429                 return;
430         }
431
432         memset(&ncap, 0, sizeof(struct rte_tm_node_capabilities));
433         ret = rte_tm_node_capabilities_get(port_id, node_id, &ncap, &error);
434         if (ret != 0) {
435                 print_err_msg(&error);
436                 return;
437         }
438         printf("\n**   Port TM Hierarchy node %" PRIu32 " Capability **\n\n",
439                 node_id);
440         printf("cap.shaper_private_supported %" PRId32 "\n",
441                 ncap.shaper_private_supported);
442         printf("cap.shaper_private_dual_rate_supported %" PRId32 "\n",
443                 ncap.shaper_private_dual_rate_supported);
444         printf("cap.shaper_private_rate_min %" PRIu64 "\n",
445                 ncap.shaper_private_rate_min);
446         printf("cap.shaper_private_rate_max %" PRIu64 "\n",
447                 ncap.shaper_private_rate_max);
448         printf("cap.shaper_shared_n_max %" PRIu32 "\n",
449                 ncap.shaper_shared_n_max);
450         if (!is_leaf) {
451                 printf("cap.nonleaf.sched_n_children_max %" PRIu32 "\n",
452                         ncap.nonleaf.sched_n_children_max);
453                 printf("cap.nonleaf.sched_sp_n_priorities_max %" PRIu32 "\n",
454                         ncap.nonleaf.sched_sp_n_priorities_max);
455                 printf("cap.nonleaf.sched_wfq_n_children_per_group_max %" PRIu32
456                         "\n", ncap.nonleaf.sched_wfq_n_children_per_group_max);
457                 printf("cap.nonleaf.sched_wfq_n_groups_max %" PRIu32 "\n",
458                         ncap.nonleaf.sched_wfq_n_groups_max);
459                 printf("cap.nonleaf.sched_wfq_weight_max %" PRIu32 "\n",
460                         ncap.nonleaf.sched_wfq_weight_max);
461         } else {
462                 printf("cap.leaf.cman_head_drop_supported %" PRId32 "\n",
463                         ncap.leaf.cman_head_drop_supported);
464                 printf("cap.leaf.cman_wred_context_private_supported %" PRId32
465                         "\n", ncap.leaf.cman_wred_context_private_supported);
466                 printf("cap.leaf.cman_wred_context_shared_n_max %" PRIu32 "\n",
467                         ncap.leaf.cman_wred_context_shared_n_max);
468         }
469         printf("cap.stats_mask %" PRIx64 "\n", ncap.stats_mask);
470 }
471
472 cmdline_parse_inst_t cmd_show_port_tm_node_cap = {
473         .f = cmd_show_port_tm_node_cap_parsed,
474         .data = NULL,
475         .help_str = "Show Port TM Hierarchy node capabilities",
476         .tokens = {
477                 (void *)&cmd_show_port_tm_node_cap_show,
478                 (void *)&cmd_show_port_tm_node_cap_port,
479                 (void *)&cmd_show_port_tm_node_cap_tm,
480                 (void *)&cmd_show_port_tm_node_cap_node,
481                 (void *)&cmd_show_port_tm_node_cap_cap,
482                 (void *)&cmd_show_port_tm_node_cap_port_id,
483                 (void *)&cmd_show_port_tm_node_cap_node_id,
484                 NULL,
485         },
486 };
487
488 /* *** Show Port TM Node Statistics *** */
489 struct cmd_show_port_tm_node_stats_result {
490         cmdline_fixed_string_t show;
491         cmdline_fixed_string_t port;
492         cmdline_fixed_string_t tm;
493         cmdline_fixed_string_t node;
494         cmdline_fixed_string_t stats;
495         uint16_t port_id;
496         uint32_t node_id;
497         uint32_t clear;
498 };
499
500 cmdline_parse_token_string_t cmd_show_port_tm_node_stats_show =
501         TOKEN_STRING_INITIALIZER(
502                 struct cmd_show_port_tm_node_stats_result, show, "show");
503 cmdline_parse_token_string_t cmd_show_port_tm_node_stats_port =
504         TOKEN_STRING_INITIALIZER(
505                 struct cmd_show_port_tm_node_stats_result, port, "port");
506 cmdline_parse_token_string_t cmd_show_port_tm_node_stats_tm =
507         TOKEN_STRING_INITIALIZER(
508                 struct cmd_show_port_tm_node_stats_result, tm, "tm");
509 cmdline_parse_token_string_t cmd_show_port_tm_node_stats_node =
510         TOKEN_STRING_INITIALIZER(
511                 struct cmd_show_port_tm_node_stats_result, node, "node");
512 cmdline_parse_token_string_t cmd_show_port_tm_node_stats_stats =
513         TOKEN_STRING_INITIALIZER(
514                 struct cmd_show_port_tm_node_stats_result, stats, "stats");
515 cmdline_parse_token_num_t cmd_show_port_tm_node_stats_port_id =
516         TOKEN_NUM_INITIALIZER(struct cmd_show_port_tm_node_stats_result,
517                         port_id, UINT16);
518 cmdline_parse_token_num_t cmd_show_port_tm_node_stats_node_id =
519         TOKEN_NUM_INITIALIZER(
520                 struct cmd_show_port_tm_node_stats_result,
521                         node_id, UINT32);
522 cmdline_parse_token_num_t cmd_show_port_tm_node_stats_clear =
523         TOKEN_NUM_INITIALIZER(
524                 struct cmd_show_port_tm_node_stats_result, clear, UINT32);
525
526 static void cmd_show_port_tm_node_stats_parsed(void *parsed_result,
527         __attribute__((unused)) struct cmdline *cl,
528         __attribute__((unused)) void *data)
529 {
530         struct cmd_show_port_tm_node_stats_result *res = parsed_result;
531         struct rte_tm_node_stats stats;
532         struct rte_tm_error error;
533         uint64_t stats_mask = 0;
534         uint32_t node_id = res->node_id;
535         uint32_t clear = res->clear;
536         portid_t port_id = res->port_id;
537         int ret;
538
539         if (port_id_is_invalid(port_id, ENABLED_WARN))
540                 return;
541
542         /* Port status */
543         if (!port_is_started(port_id)) {
544                 printf(" Port %u not started (error)\n", port_id);
545                 return;
546         }
547
548         memset(&stats, 0, sizeof(struct rte_tm_node_stats));
549         ret = rte_tm_node_stats_read(port_id, node_id, &stats,
550                         &stats_mask, clear, &error);
551         if (ret != 0) {
552                 print_err_msg(&error);
553                 return;
554         }
555
556         /* Display stats */
557         if (stats_mask & RTE_TM_STATS_N_PKTS)
558                 printf("\tPkts scheduled from node: %" PRIu64 "\n",
559                         stats.n_pkts);
560         if (stats_mask & RTE_TM_STATS_N_BYTES)
561                 printf("\tBytes scheduled from node: %" PRIu64 "\n",
562                         stats.n_bytes);
563         if (stats_mask & RTE_TM_STATS_N_PKTS_GREEN_DROPPED)
564                 printf("\tPkts dropped (green): %" PRIu64 "\n",
565                         stats.leaf.n_pkts_dropped[RTE_TM_GREEN]);
566         if (stats_mask & RTE_TM_STATS_N_PKTS_YELLOW_DROPPED)
567                 printf("\tPkts dropped (yellow): %" PRIu64 "\n",
568                         stats.leaf.n_pkts_dropped[RTE_TM_YELLOW]);
569         if (stats_mask & RTE_TM_STATS_N_PKTS_RED_DROPPED)
570                 printf("\tPkts dropped (red): %" PRIu64 "\n",
571                         stats.leaf.n_pkts_dropped[RTE_TM_RED]);
572         if (stats_mask & RTE_TM_STATS_N_BYTES_GREEN_DROPPED)
573                 printf("\tBytes dropped (green): %" PRIu64 "\n",
574                         stats.leaf.n_bytes_dropped[RTE_TM_GREEN]);
575         if (stats_mask & RTE_TM_STATS_N_BYTES_YELLOW_DROPPED)
576                 printf("\tBytes dropped (yellow): %" PRIu64 "\n",
577                         stats.leaf.n_bytes_dropped[RTE_TM_YELLOW]);
578         if (stats_mask & RTE_TM_STATS_N_BYTES_RED_DROPPED)
579                 printf("\tBytes dropped (red): %" PRIu64 "\n",
580                         stats.leaf.n_bytes_dropped[RTE_TM_RED]);
581         if (stats_mask & RTE_TM_STATS_N_PKTS_QUEUED)
582                 printf("\tPkts queued: %" PRIu64 "\n",
583                         stats.leaf.n_pkts_queued);
584         if (stats_mask & RTE_TM_STATS_N_BYTES_QUEUED)
585                 printf("\tBytes queued: %" PRIu64 "\n",
586                         stats.leaf.n_bytes_queued);
587 }
588
589 cmdline_parse_inst_t cmd_show_port_tm_node_stats = {
590         .f = cmd_show_port_tm_node_stats_parsed,
591         .data = NULL,
592         .help_str = "Show port tm node stats",
593         .tokens = {
594                 (void *)&cmd_show_port_tm_node_stats_show,
595                 (void *)&cmd_show_port_tm_node_stats_port,
596                 (void *)&cmd_show_port_tm_node_stats_tm,
597                 (void *)&cmd_show_port_tm_node_stats_node,
598                 (void *)&cmd_show_port_tm_node_stats_stats,
599                 (void *)&cmd_show_port_tm_node_stats_port_id,
600                 (void *)&cmd_show_port_tm_node_stats_node_id,
601                 (void *)&cmd_show_port_tm_node_stats_clear,
602                 NULL,
603         },
604 };
605
606 /* *** Show Port TM Node Type *** */
607 struct cmd_show_port_tm_node_type_result {
608         cmdline_fixed_string_t show;
609         cmdline_fixed_string_t port;
610         cmdline_fixed_string_t tm;
611         cmdline_fixed_string_t node;
612         cmdline_fixed_string_t type;
613         uint16_t port_id;
614         uint32_t node_id;
615 };
616
617 cmdline_parse_token_string_t cmd_show_port_tm_node_type_show =
618         TOKEN_STRING_INITIALIZER(
619                 struct cmd_show_port_tm_node_type_result, show, "show");
620 cmdline_parse_token_string_t cmd_show_port_tm_node_type_port =
621         TOKEN_STRING_INITIALIZER(
622                 struct cmd_show_port_tm_node_type_result, port, "port");
623 cmdline_parse_token_string_t cmd_show_port_tm_node_type_tm =
624         TOKEN_STRING_INITIALIZER(
625                 struct cmd_show_port_tm_node_type_result, tm, "tm");
626 cmdline_parse_token_string_t cmd_show_port_tm_node_type_node =
627         TOKEN_STRING_INITIALIZER(
628                 struct cmd_show_port_tm_node_type_result, node, "node");
629 cmdline_parse_token_string_t cmd_show_port_tm_node_type_type =
630         TOKEN_STRING_INITIALIZER(
631                 struct cmd_show_port_tm_node_type_result, type, "type");
632 cmdline_parse_token_num_t cmd_show_port_tm_node_type_port_id =
633         TOKEN_NUM_INITIALIZER(
634                 struct cmd_show_port_tm_node_type_result,
635                         port_id, UINT16);
636 cmdline_parse_token_num_t cmd_show_port_tm_node_type_node_id =
637         TOKEN_NUM_INITIALIZER(
638                 struct cmd_show_port_tm_node_type_result,
639                         node_id, UINT32);
640
641 static void cmd_show_port_tm_node_type_parsed(void *parsed_result,
642         __attribute__((unused)) struct cmdline *cl,
643         __attribute__((unused)) void *data)
644 {
645         struct cmd_show_port_tm_node_type_result *res = parsed_result;
646         struct rte_tm_error error;
647         uint32_t node_id = res->node_id;
648         portid_t port_id = res->port_id;
649         int ret, is_leaf = 0;
650
651         if (port_id_is_invalid(port_id, ENABLED_WARN))
652                 return;
653
654         ret = rte_tm_node_type_get(port_id, node_id, &is_leaf, &error);
655         if (ret != 0) {
656                 print_err_msg(&error);
657                 return;
658         }
659
660         if (is_leaf == 1)
661                 printf("leaf node\n");
662         else
663                 printf("nonleaf node\n");
664
665 }
666
667 cmdline_parse_inst_t cmd_show_port_tm_node_type = {
668         .f = cmd_show_port_tm_node_type_parsed,
669         .data = NULL,
670         .help_str = "Show port tm node type",
671         .tokens = {
672                 (void *)&cmd_show_port_tm_node_type_show,
673                 (void *)&cmd_show_port_tm_node_type_port,
674                 (void *)&cmd_show_port_tm_node_type_tm,
675                 (void *)&cmd_show_port_tm_node_type_node,
676                 (void *)&cmd_show_port_tm_node_type_type,
677                 (void *)&cmd_show_port_tm_node_type_port_id,
678                 (void *)&cmd_show_port_tm_node_type_node_id,
679                 NULL,
680         },
681 };