xref: /dpdk/app/proc-info/main.c (revision 8a171e52ed8b26f768ced79a22286914ebd30180)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2017 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdint.h>
8 #include <stdbool.h>
9 #include <errno.h>
10 #include <stdarg.h>
11 #include <inttypes.h>
12 #include <sys/queue.h>
13 #include <stdlib.h>
14 #include <getopt.h>
15 #include <unistd.h>
16 #include <strings.h>
17 
18 #include <rte_eal.h>
19 #include <rte_common.h>
20 #include <rte_debug.h>
21 #include <rte_ethdev.h>
22 #include <rte_malloc.h>
23 #include <rte_memory.h>
24 #include <rte_memzone.h>
25 #include <rte_launch.h>
26 #include <rte_tailq.h>
27 #include <rte_per_lcore.h>
28 #include <rte_lcore.h>
29 #include <rte_log.h>
30 #include <rte_branch_prediction.h>
31 #include <rte_string_fns.h>
32 #ifdef RTE_LIB_METRICS
33 #include <rte_metrics.h>
34 #endif
35 #include <rte_cycles.h>
36 #ifdef RTE_LIB_SECURITY
37 #include <rte_security.h>
38 #endif
39 #include <rte_cryptodev.h>
40 #include <rte_tm.h>
41 #include <rte_hexdump.h>
42 #include <rte_version.h>
43 #include <rte_eventdev.h>
44 
45 /* Maximum long option length for option parsing. */
46 #define MAX_LONG_OPT_SZ 64
47 #define MAX_STRING_LEN 256
48 
49 #define ETHDEV_FWVERS_LEN 32
50 #define RTE_RETA_CONF_GROUP_NUM 32
51 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
52 #define EEPROM_DUMP_CHUNKSIZE 1024
53 
54 #define STATS_BDR_FMT "========================================"
55 #define STATS_BDR_STR(w, s) printf("%.*s%s%.*s\n", w, \
56 	STATS_BDR_FMT, s, w, STATS_BDR_FMT)
57 
58 /* mask of enabled ports */
59 static unsigned long enabled_port_mask;
60 /* Enable stats. */
61 static uint32_t enable_stats;
62 /* Enable xstats. */
63 static uint32_t enable_xstats;
64 /* Enable collectd format */
65 static uint32_t enable_collectd_format;
66 /* FD to send collectd format messages to STDOUT */
67 static int stdout_fd;
68 /* Host id process is running on */
69 static char host_id[MAX_LONG_OPT_SZ];
70 #ifdef RTE_LIB_METRICS
71 /* Enable metrics. */
72 static uint32_t enable_metrics;
73 #endif
74 /* Enable stats reset. */
75 static uint32_t reset_stats;
76 /* Enable xstats reset. */
77 static uint32_t reset_xstats;
78 /* Enable memory info. */
79 static uint32_t mem_info;
80 /* Enable displaying xstat name. */
81 static uint32_t enable_xstats_name;
82 static char *xstats_name;
83 
84 /* Enable xstats by ids. */
85 #define MAX_NB_XSTATS_IDS 1024
86 static uint32_t nb_xstats_ids;
87 static uint64_t xstats_ids[MAX_NB_XSTATS_IDS];
88 
89 /* show border */
90 static char bdr_str[MAX_STRING_LEN];
91 
92 /* Enable show port. */
93 static uint32_t enable_shw_port;
94 /* Enable show port private info. */
95 static uint32_t enable_shw_port_priv;
96 /* Enable show tm. */
97 static uint32_t enable_shw_tm;
98 /* Enable show crypto. */
99 static uint32_t enable_shw_crypto;
100 /* Enable show ring. */
101 static uint32_t enable_shw_ring;
102 static char *ring_name;
103 /* Enable show mempool. */
104 static uint32_t enable_shw_mempool;
105 static char *mempool_name;
106 /* Enable iter mempool. */
107 static uint32_t enable_iter_mempool;
108 static char *mempool_iter_name;
109 /* Enable dump regs. */
110 static uint32_t enable_dump_regs;
111 static char *dump_regs_file_prefix;
112 /* Enable show DPDK version. */
113 static uint32_t enable_shw_version;
114 /* Enable show ethdev firmware version. */
115 static uint32_t enable_shw_fw_version;
116 /* Enable show RSS reta. */
117 static uint32_t enable_shw_rss_reta;
118 /* Enable show module eeprom information. */
119 static uint32_t enable_shw_module_eeprom;
120 
121 /* Enable dump Rx/Tx descriptor. */
122 static uint32_t enable_shw_rx_desc_dump;
123 static uint32_t enable_shw_tx_desc_dump;
124 
125 /* Note: Port_queue_id in xstats APIs is 8 bits, so we have a maximum of
126  * 256 ports and queues for event_Dev
127  */
128 #define MAX_PORTS_QUEUES 256
129 
130 struct eventdev_params {
131 	uint16_t ports[MAX_PORTS_QUEUES];
132 	uint16_t queues[MAX_PORTS_QUEUES];
133 	uint16_t num_queues;
134 	uint16_t num_ports;
135 	uint8_t shw_all_queues:1,
136 		shw_all_ports:1,
137 		dump_xstats:1,
138 		reset_xstats:1,
139 		shw_device_xstats:1;
140 };
141 
142 static struct eventdev_params eventdev_var[RTE_EVENT_MAX_DEVS];
143 
144 #define DESC_PARAM_NUM 3
145 
146 struct desc_param {
147 	uint16_t queue_id; /* A queue identifier on this port. */
148 	uint16_t offset;   /* The offset of the descriptor starting from tail. */
149 	uint16_t num;      /* The number of the descriptors to dump. */
150 };
151 
152 static struct desc_param rx_desc_param;
153 static struct desc_param tx_desc_param;
154 
155 #define RSS_HASH_KEY_SIZE 64
156 
157 /* display usage */
158 static void
159 proc_info_usage(const char *prgname)
160 {
161 	printf("%s [EAL options] -- -p PORTMASK\n"
162 		"  -m to display DPDK memory zones, segments and TAILQ information\n"
163 		"  -p PORTMASK: hexadecimal bitmask of ports to retrieve stats for\n"
164 		"  --stats: to display port statistics, enabled by default\n"
165 		"  --xstats: to display extended port statistics, disabled by "
166 			"default\n"
167 #ifdef RTE_LIB_METRICS
168 		"  --metrics: to display derived metrics of the ports, disabled by "
169 			"default\n"
170 #endif
171 		"  --xstats-name NAME: to display single xstat id by NAME\n"
172 		"  --xstats-ids IDLIST: to display xstat values by id. "
173 			"The argument is comma-separated list of xstat ids to print out.\n"
174 		"  --stats-reset: to reset port statistics\n"
175 		"  --xstats-reset: to reset port extended statistics\n"
176 		"  --collectd-format: to print statistics to STDOUT in expected by collectd format\n"
177 		"  --host-id STRING: host id used to identify the system process is running on\n"
178 		"  --show-port: to display ports information\n"
179 		"  --show-port-private: to display ports private information\n"
180 		"  --show-tm: to display traffic manager information for ports\n"
181 		"  --show-crypto: to display crypto information\n"
182 		"  --show-ring[=name]: to display ring information\n"
183 		"  --show-mempool[=name]: to display mempool information\n"
184 		"  --version: to display DPDK version\n"
185 		"  --firmware-version: to display ethdev firmware version\n"
186 		"  --show-rss-reta: to display ports redirection table\n"
187 		"  --show-module-eeprom: to display ports module eeprom information\n"
188 		"  --show-rx-descriptor queue_id:offset:num to display ports Rx descriptor information. "
189 			"queue_id: A Rx queue identifier on this port. "
190 			"offset: The offset of the descriptor starting from tail. "
191 			"num: The number of the descriptors to dump.\n"
192 		"  --show-tx-descriptor queue_id:offset:num to display ports Tx descriptor information. "
193 			"queue_id: A Tx queue identifier on this port. "
194 			"offset: The offset of the descriptor starting from tail. "
195 			"num: The number of the descriptors to dump.\n"
196 		"  --iter-mempool=name: iterate mempool elements to display content\n"
197 		"  --dump-regs=file-prefix: dump registers to file with the file-prefix\n"
198 		"  --show-edev-queue-xstats=queue_num:evdev_id or *:evdev_id to get queue xstats for specified queue or all queues;\n"
199 		"  --show-edev-port-xstats=port_num:evdev_id or *:evdev_id to get queue xstats for specified port or all ports;\n"
200 		"  --edev-dump-xstats=evdev_id to dump all event_dev xstats for specified eventdev device;\n"
201 		"  --edev-reset-xstats=evdev_id to reset event_dev xstats after reading;\n"
202 		"  --show-edev-device-xstats=evdev_id to get event_dev device xstats for specified eventdev device;\n",
203 		prgname);
204 }
205 
206 /*
207  * Parse the portmask provided at run time.
208  */
209 static int
210 parse_portmask(const char *portmask)
211 {
212 	char *end = NULL;
213 
214 	errno = 0;
215 
216 	/* parse hexadecimal string */
217 	enabled_port_mask = strtoul(portmask, &end, 16);
218 	if (portmask[0] == '\0' || end == NULL || *end != '\0' || errno != 0) {
219 		fprintf(stderr, "Invalid portmask '%s'\n", portmask);
220 		return -1;
221 	}
222 
223 	return 0;
224 }
225 
226 /*
227  * Parse ids value list into array
228  */
229 static int
230 parse_xstats_ids(char *list, uint64_t *ids, int limit) {
231 	int length;
232 	char *token;
233 	char *ctx = NULL;
234 	char *endptr;
235 
236 	length = 0;
237 	token = strtok_r(list, ",", &ctx);
238 	while (token != NULL) {
239 		ids[length] = strtoull(token, &endptr, 10);
240 		if (*endptr != '\0')
241 			return -EINVAL;
242 
243 		length++;
244 		if (length >= limit)
245 			return -E2BIG;
246 
247 		token = strtok_r(NULL, ",", &ctx);
248 	}
249 
250 	return length;
251 }
252 
253 static int
254 parse_descriptor_param(char *list, struct desc_param *desc)
255 {
256 	int ret;
257 
258 	ret = sscanf(list, "%hu:%hu:%hu", &desc->queue_id, &desc->offset,
259 		     &desc->num);
260 	if (ret != DESC_PARAM_NUM)
261 		return -EINVAL;
262 
263 	return 0;
264 }
265 
266 static int
267 parse_eventdev_id(const char *str)
268 {
269 	unsigned long evdev_id;
270 	char *endp;
271 
272 	evdev_id = strtoul(str, &endp, 0);
273 
274 	if (*str == '\0' || *endp != '\0' || evdev_id >= rte_event_dev_count()) {
275 		fprintf(stderr, "Invalid eventdev id: %s\n", str);
276 		return -1;
277 	}
278 
279 	return evdev_id;
280 }
281 
282 static int
283 parse_eventdev_dump_xstats_params(const char *list)
284 {
285 	int evdev_id = parse_eventdev_id(list);
286 
287 	if (evdev_id < 0)
288 		return -EINVAL;
289 
290 	eventdev_var[evdev_id].dump_xstats = 1;
291 
292 	return 0;
293 }
294 
295 static int
296 parse_eventdev_reset_xstats_params(const char *list)
297 {
298 	int evdev_id = parse_eventdev_id(list);
299 
300 	if (evdev_id < 0)
301 		return -EINVAL;
302 
303 	eventdev_var[evdev_id].reset_xstats = 1;
304 
305 	return 0;
306 }
307 
308 static int
309 parse_eventdev_device_xstats_params(const char *list)
310 {
311 	int evdev_id = parse_eventdev_id(list);
312 
313 	if (evdev_id < 0)
314 		return -EINVAL;
315 
316 	eventdev_var[evdev_id].shw_device_xstats = 1;
317 
318 	return 0;
319 }
320 
321 static int
322 parse_eventdev_queue_xstats_params(const char *list)
323 {
324 	uint16_t queue_id;
325 	uint16_t evdev_id;
326 
327 	if (sscanf(list, "*:%hu", &evdev_id) == 1) {
328 		if (evdev_id >= rte_event_dev_count()) {
329 			printf("Invalid eventdev id: %hu\n", evdev_id);
330 			return -EINVAL;
331 		}
332 		eventdev_var[evdev_id].shw_all_queues = 1;
333 	} else if (sscanf(list, "%hu:%hu", &queue_id, &evdev_id) == 2) {
334 		if (evdev_id >= rte_event_dev_count()) {
335 			printf("Invalid eventdev id: %hu\n", evdev_id);
336 			return -EINVAL;
337 		}
338 
339 		if (queue_id >= MAX_PORTS_QUEUES) {
340 			printf("Invalid queue_id: %hu\n", queue_id);
341 			return -EINVAL;
342 		}
343 
344 		eventdev_var[evdev_id].queues[eventdev_var[evdev_id].num_queues] = queue_id;
345 		eventdev_var[evdev_id].num_queues++;
346 	} else {
347 		return -EINVAL;
348 	}
349 
350 	return 0;
351 }
352 
353 static int
354 parse_eventdev_port_xstats_params(const char *list)
355 {
356 	uint16_t port_id;
357 	uint16_t evdev_id;
358 
359 	if (sscanf(list, "*:%hu", &evdev_id) == 1) {
360 		if (evdev_id >= rte_event_dev_count()) {
361 			printf("Invalid eventdev id: %hu\n", evdev_id);
362 			return -EINVAL;
363 		}
364 		eventdev_var[evdev_id].shw_all_ports = 1;
365 	} else if (sscanf(list, "%hu:%hu", &port_id, &evdev_id) == 2) {
366 		if (evdev_id >= rte_event_dev_count()) {
367 			printf("Invalid eventdev id: %hu\n", evdev_id);
368 			return -EINVAL;
369 		}
370 
371 		if (port_id >= MAX_PORTS_QUEUES) {
372 			printf("Invalid port_id: %hu\n", port_id);
373 			return -EINVAL;
374 		}
375 
376 		eventdev_var[evdev_id].ports[eventdev_var[evdev_id].num_ports] = port_id;
377 		eventdev_var[evdev_id].num_ports++;
378 	} else {
379 		return -EINVAL;
380 	}
381 
382 	return 0;
383 }
384 
385 static int
386 proc_info_preparse_args(int argc, char **argv)
387 {
388 	char *prgname = argv[0];
389 	int i;
390 
391 	for (i = 0; i < argc; i++) {
392 		/* Print stats or xstats to STDOUT in collectd format */
393 		if (!strncmp(argv[i], "--collectd-format", MAX_LONG_OPT_SZ)) {
394 			enable_collectd_format = 1;
395 			stdout_fd = dup(STDOUT_FILENO);
396 			close(STDOUT_FILENO);
397 		}
398 		if (!strncmp(argv[i], "--host-id", MAX_LONG_OPT_SZ)) {
399 			if ((i + 1) == argc) {
400 				printf("Invalid host id or not specified\n");
401 				proc_info_usage(prgname);
402 				return -1;
403 			}
404 			strlcpy(host_id, argv[i + 1], sizeof(host_id));
405 		}
406 	}
407 
408 	if (!strlen(host_id)) {
409 		int err = gethostname(host_id, MAX_LONG_OPT_SZ-1);
410 
411 		if (err)
412 			strlcpy(host_id, "unknown", sizeof(host_id));
413 	}
414 
415 	return 0;
416 }
417 
418 /* Parse the argument given in the command line of the application */
419 static int
420 proc_info_parse_args(int argc, char **argv)
421 {
422 	int opt;
423 	int option_index;
424 	char *prgname = argv[0];
425 	static struct option long_option[] = {
426 		{"stats", 0, NULL, 0},
427 		{"stats-reset", 0, NULL, 0},
428 		{"xstats", 0, NULL, 0},
429 #ifdef RTE_LIB_METRICS
430 		{"metrics", 0, NULL, 0},
431 #endif
432 		{"xstats-reset", 0, NULL, 0},
433 		{"xstats-name", required_argument, NULL, 1},
434 		{"collectd-format", 0, NULL, 0},
435 		{"xstats-ids", 1, NULL, 1},
436 		{"host-id", 0, NULL, 0},
437 		{"show-port", 0, NULL, 0},
438 		{"show-port-private", 0, NULL, 0},
439 		{"show-tm", 0, NULL, 0},
440 		{"show-crypto", 0, NULL, 0},
441 		{"show-ring", optional_argument, NULL, 0},
442 		{"show-mempool", optional_argument, NULL, 0},
443 		{"iter-mempool", required_argument, NULL, 0},
444 		{"dump-regs", required_argument, NULL, 0},
445 		{"version", 0, NULL, 0},
446 		{"firmware-version", 0, NULL, 0},
447 		{"show-rss-reta", 0, NULL, 0},
448 		{"show-module-eeprom", 0, NULL, 0},
449 		{"show-rx-descriptor", required_argument, NULL, 1},
450 		{"show-tx-descriptor", required_argument, NULL, 1},
451 		{"show-edev-queue-xstats", required_argument, NULL, 0},
452 		{"show-edev-port-xstats", required_argument, NULL, 0},
453 		{"edev-dump-xstats", required_argument, NULL, 0},
454 		{"edev-reset-xstats", required_argument, NULL, 0},
455 		{"show-edev-device-xstats", required_argument, NULL, 0},
456 		{NULL, 0, 0, 0}
457 	};
458 
459 	if (argc == 1)
460 		proc_info_usage(prgname);
461 
462 	/* Parse command line */
463 	while ((opt = getopt_long(argc, argv, "p:m",
464 			long_option, &option_index)) != EOF) {
465 		switch (opt) {
466 		/* portmask */
467 		case 'p':
468 			if (parse_portmask(optarg) < 0) {
469 				proc_info_usage(prgname);
470 				return -1;
471 			}
472 			break;
473 		case 'm':
474 			mem_info = 1;
475 			break;
476 		case 0:
477 			/* Print stats */
478 			if (!strncmp(long_option[option_index].name, "stats",
479 					MAX_LONG_OPT_SZ))
480 				enable_stats = 1;
481 			/* Print xstats */
482 			else if (!strncmp(long_option[option_index].name, "xstats",
483 					MAX_LONG_OPT_SZ))
484 				enable_xstats = 1;
485 #ifdef RTE_LIB_METRICS
486 			else if (!strncmp(long_option[option_index].name,
487 					"metrics",
488 					MAX_LONG_OPT_SZ))
489 				enable_metrics = 1;
490 #endif
491 			/* Reset stats */
492 			if (!strncmp(long_option[option_index].name, "stats-reset",
493 					MAX_LONG_OPT_SZ))
494 				reset_stats = 1;
495 			/* Reset xstats */
496 			else if (!strncmp(long_option[option_index].name, "xstats-reset",
497 					MAX_LONG_OPT_SZ))
498 				reset_xstats = 1;
499 			else if (!strncmp(long_option[option_index].name,
500 					"show-port", MAX_LONG_OPT_SZ))
501 				enable_shw_port = 1;
502 			else if (!strncmp(long_option[option_index].name,
503 					"show-port-private", MAX_LONG_OPT_SZ))
504 				enable_shw_port_priv = 1;
505 			else if (!strncmp(long_option[option_index].name,
506 					"show-tm", MAX_LONG_OPT_SZ))
507 				enable_shw_tm = 1;
508 			else if (!strncmp(long_option[option_index].name,
509 					"show-crypto", MAX_LONG_OPT_SZ))
510 				enable_shw_crypto = 1;
511 			else if (!strncmp(long_option[option_index].name,
512 					"show-ring", MAX_LONG_OPT_SZ)) {
513 				enable_shw_ring = 1;
514 				ring_name = optarg;
515 			} else if (!strncmp(long_option[option_index].name,
516 					"show-mempool", MAX_LONG_OPT_SZ)) {
517 				enable_shw_mempool = 1;
518 				mempool_name = optarg;
519 			} else if (!strncmp(long_option[option_index].name,
520 					"iter-mempool", MAX_LONG_OPT_SZ)) {
521 				enable_iter_mempool = 1;
522 				mempool_iter_name = optarg;
523 			} else if (!strncmp(long_option[option_index].name,
524 					"dump-regs", MAX_LONG_OPT_SZ)) {
525 				enable_dump_regs = 1;
526 				dump_regs_file_prefix = optarg;
527 			} else if (!strncmp(long_option[option_index].name,
528 					"version", MAX_LONG_OPT_SZ))
529 				enable_shw_version = 1;
530 			else if (!strncmp(long_option[option_index].name,
531 					"firmware-version", MAX_LONG_OPT_SZ))
532 				enable_shw_fw_version = 1;
533 			else if (!strncmp(long_option[option_index].name,
534 					"show-rss-reta", MAX_LONG_OPT_SZ))
535 				enable_shw_rss_reta = 1;
536 			else if (!strncmp(long_option[option_index].name,
537 					"show-module-eeprom", MAX_LONG_OPT_SZ))
538 				enable_shw_module_eeprom = 1;
539 			else if (!strncmp(long_option[option_index].name,
540 					"edev-dump-xstats", MAX_LONG_OPT_SZ)) {
541 				int ret = parse_eventdev_dump_xstats_params(optarg);
542 				if (ret < 0) {
543 					fprintf(stderr, "Error parsing eventdev dump xstats params: %s\n",
544 						strerror(-ret));
545 					return -1;
546 				}
547 			} else if (!strncmp(long_option[option_index].name,
548 					"edev-reset-xstats", MAX_LONG_OPT_SZ)) {
549 				int ret = parse_eventdev_reset_xstats_params(optarg);
550 				if (ret < 0) {
551 					fprintf(stderr, "Error parsing eventdev reset xstats params: %s\n",
552 						strerror(-ret));
553 					return -1;
554 				}
555 			} else if (!strncmp(long_option[option_index].name,
556 					"show-edev-device-xstats", MAX_LONG_OPT_SZ)) {
557 				int ret = parse_eventdev_device_xstats_params(optarg);
558 				if (ret < 0) {
559 					fprintf(stderr, "Error parsing eventdev reset xstats params: %s\n",
560 						strerror(-ret));
561 					return -1;
562 				}
563 			} else if (!strncmp(long_option[option_index].name,
564 					"show-edev-queue-xstats", MAX_LONG_OPT_SZ)) {
565 				int ret = parse_eventdev_queue_xstats_params(optarg);
566 				if (ret < 0) {
567 					fprintf(stderr, "Error parsing eventdev queue xstats params: %s\n",
568 						strerror(-ret));
569 					return -1;
570 				}
571 			} else if (!strncmp(long_option[option_index].name,
572 					"show-edev-port-xstats", MAX_LONG_OPT_SZ)) {
573 				int ret = parse_eventdev_port_xstats_params(optarg);
574 				if (ret < 0) {
575 					fprintf(stderr, "Error parsing eventdev port xstats params: %s\n",
576 						strerror(-ret));
577 					return -1;
578 				}
579 			}
580 			break;
581 		case 1:
582 			/* Print xstat single value given by name*/
583 			if (!strncmp(long_option[option_index].name,
584 					"xstats-name", MAX_LONG_OPT_SZ)) {
585 				enable_xstats_name = 1;
586 				xstats_name = optarg;
587 				printf("name:%s:%s\n",
588 						long_option[option_index].name,
589 						optarg);
590 			} else if (!strncmp(long_option[option_index].name,
591 					"xstats-ids",
592 					MAX_LONG_OPT_SZ))	{
593 				int ret = parse_xstats_ids(optarg,
594 						xstats_ids, MAX_NB_XSTATS_IDS);
595 				if (ret <= 0) {
596 					printf("xstats-id list parse error.\n");
597 					return -1;
598 				}
599 				nb_xstats_ids = ret;
600 			} else if (!strncmp(long_option[option_index].name,
601 				"show-rx-descriptor", MAX_LONG_OPT_SZ)) {
602 				int ret = parse_descriptor_param(optarg,
603 							&rx_desc_param);
604 				if (ret < 0) {
605 					fprintf(stderr, "Error parsing Rx descriptor param: %s\n",
606 						strerror(-ret));
607 					return -1;
608 				}
609 				enable_shw_rx_desc_dump = 1;
610 			} else if (!strncmp(long_option[option_index].name,
611 				"show-tx-descriptor", MAX_LONG_OPT_SZ)) {
612 				int ret = parse_descriptor_param(optarg,
613 							&tx_desc_param);
614 				if (ret < 0) {
615 					fprintf(stderr, "Error parsing Tx descriptor param: %s\n",
616 						strerror(-ret));
617 					return -1;
618 				}
619 				enable_shw_tx_desc_dump = 1;
620 			}
621 			break;
622 		default:
623 			proc_info_usage(prgname);
624 			return -1;
625 		}
626 	}
627 	return 0;
628 }
629 
630 static void
631 meminfo_display(void)
632 {
633 	printf("----------- MEMORY_SEGMENTS -----------\n");
634 	rte_dump_physmem_layout(stdout);
635 	printf("--------- END_MEMORY_SEGMENTS ---------\n");
636 
637 	printf("------------ MEMORY_ZONES -------------\n");
638 	rte_memzone_dump(stdout);
639 	printf("---------- END_MEMORY_ZONES -----------\n");
640 
641 	printf("---------- MALLOC_HEAP_DUMP -----------\n");
642 	rte_malloc_dump_heaps(stdout);
643 	printf("-------- END_MALLOC_HEAP_DUMP ---------\n");
644 
645 	printf("------------- TAIL_QUEUES -------------\n");
646 	rte_dump_tailq(stdout);
647 	printf("---------- END_TAIL_QUEUES ------------\n");
648 }
649 
650 static void
651 nic_stats_display(uint16_t port_id)
652 {
653 	struct rte_eth_stats stats;
654 	uint8_t i;
655 
656 	static const char *nic_stats_border = "########################";
657 
658 	rte_eth_stats_get(port_id, &stats);
659 	printf("\n  %s NIC statistics for port %-2d %s\n",
660 		   nic_stats_border, port_id, nic_stats_border);
661 
662 	printf("  RX-packets: %-10"PRIu64"  RX-errors:  %-10"PRIu64
663 	       "  RX-bytes:  %-10"PRIu64"\n", stats.ipackets, stats.ierrors,
664 	       stats.ibytes);
665 	printf("  RX-nombuf:  %-10"PRIu64"\n", stats.rx_nombuf);
666 	printf("  TX-packets: %-10"PRIu64"  TX-errors:  %-10"PRIu64
667 	       "  TX-bytes:  %-10"PRIu64"\n", stats.opackets, stats.oerrors,
668 	       stats.obytes);
669 
670 	printf("\n");
671 	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
672 		printf("  Stats reg %2d RX-packets: %-10"PRIu64
673 		       "  RX-errors: %-10"PRIu64
674 		       "  RX-bytes: %-10"PRIu64"\n",
675 		       i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]);
676 	}
677 
678 	printf("\n");
679 	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
680 		printf("  Stats reg %2d TX-packets: %-10"PRIu64
681 		       "  TX-bytes: %-10"PRIu64"\n",
682 		       i, stats.q_opackets[i], stats.q_obytes[i]);
683 	}
684 
685 	printf("  %s############################%s\n",
686 		   nic_stats_border, nic_stats_border);
687 }
688 
689 static void
690 nic_stats_clear(uint16_t port_id)
691 {
692 	printf("\n Clearing NIC stats for port %d\n", port_id);
693 	rte_eth_stats_reset(port_id);
694 	printf("\n  NIC statistics for port %d cleared\n", port_id);
695 }
696 
697 static void collectd_resolve_cnt_type(char *cnt_type, size_t cnt_type_len,
698 				      const char *cnt_name) {
699 	char *type_end = strrchr(cnt_name, '_');
700 
701 	if ((type_end != NULL) &&
702 	    (strncmp(cnt_name, "rx_", strlen("rx_")) == 0)) {
703 		if (strncmp(type_end, "_errors", strlen("_errors")) == 0)
704 			strlcpy(cnt_type, "if_rx_errors", cnt_type_len);
705 		else if (strncmp(type_end, "_dropped", strlen("_dropped")) == 0)
706 			strlcpy(cnt_type, "if_rx_dropped", cnt_type_len);
707 		else if (strncmp(type_end, "_bytes", strlen("_bytes")) == 0)
708 			strlcpy(cnt_type, "if_rx_octets", cnt_type_len);
709 		else if (strncmp(type_end, "_packets", strlen("_packets")) == 0)
710 			strlcpy(cnt_type, "if_rx_packets", cnt_type_len);
711 		else if (strncmp(type_end, "_placement",
712 				 strlen("_placement")) == 0)
713 			strlcpy(cnt_type, "if_rx_errors", cnt_type_len);
714 		else if (strncmp(type_end, "_buff", strlen("_buff")) == 0)
715 			strlcpy(cnt_type, "if_rx_errors", cnt_type_len);
716 		else
717 			/* Does not fit obvious type: use a more generic one */
718 			strlcpy(cnt_type, "derive", cnt_type_len);
719 	} else if ((type_end != NULL) &&
720 		(strncmp(cnt_name, "tx_", strlen("tx_"))) == 0) {
721 		if (strncmp(type_end, "_errors", strlen("_errors")) == 0)
722 			strlcpy(cnt_type, "if_tx_errors", cnt_type_len);
723 		else if (strncmp(type_end, "_dropped", strlen("_dropped")) == 0)
724 			strlcpy(cnt_type, "if_tx_dropped", cnt_type_len);
725 		else if (strncmp(type_end, "_bytes", strlen("_bytes")) == 0)
726 			strlcpy(cnt_type, "if_tx_octets", cnt_type_len);
727 		else if (strncmp(type_end, "_packets", strlen("_packets")) == 0)
728 			strlcpy(cnt_type, "if_tx_packets", cnt_type_len);
729 		else
730 			/* Does not fit obvious type: use a more generic one */
731 			strlcpy(cnt_type, "derive", cnt_type_len);
732 	} else if ((type_end != NULL) &&
733 		   (strncmp(cnt_name, "flow_", strlen("flow_"))) == 0) {
734 		if (strncmp(type_end, "_filters", strlen("_filters")) == 0)
735 			strlcpy(cnt_type, "filter_result", cnt_type_len);
736 		else if (strncmp(type_end, "_errors", strlen("_errors")) == 0)
737 			strlcpy(cnt_type, "errors", cnt_type_len);
738 	} else if ((type_end != NULL) &&
739 		   (strncmp(cnt_name, "mac_", strlen("mac_"))) == 0) {
740 		if (strncmp(type_end, "_errors", strlen("_errors")) == 0)
741 			strlcpy(cnt_type, "errors", cnt_type_len);
742 	} else {
743 		/* Does not fit obvious type, or strrchr error: */
744 		/* use a more generic type */
745 		strlcpy(cnt_type, "derive", cnt_type_len);
746 	}
747 }
748 
749 static void
750 nic_xstats_by_name_display(uint16_t port_id, char *name)
751 {
752 	uint64_t id;
753 
754 	printf("###### NIC statistics for port %-2d, statistic name '%s':\n",
755 			   port_id, name);
756 
757 	if (rte_eth_xstats_get_id_by_name(port_id, name, &id) == 0)
758 		printf("%s: %"PRIu64"\n", name, id);
759 	else
760 		printf("Statistic not found...\n");
761 
762 }
763 
764 static void
765 nic_xstats_by_ids_display(uint16_t port_id, uint64_t *ids, int len)
766 {
767 	struct rte_eth_xstat_name *xstats_names;
768 	uint64_t *values;
769 	int ret, i;
770 	static const char *nic_stats_border = "########################";
771 
772 	values = malloc(sizeof(*values) * len);
773 	if (values == NULL) {
774 		printf("Cannot allocate memory for xstats\n");
775 		return;
776 	}
777 
778 	xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len);
779 	if (xstats_names == NULL) {
780 		printf("Cannot allocate memory for xstat names\n");
781 		free(values);
782 		return;
783 	}
784 
785 	if (len != rte_eth_xstats_get_names_by_id(
786 			port_id, xstats_names, len, ids)) {
787 		printf("Cannot get xstat names\n");
788 		goto err;
789 	}
790 
791 	printf("###### NIC extended statistics for port %-2d #########\n",
792 			   port_id);
793 	printf("%s############################\n", nic_stats_border);
794 	ret = rte_eth_xstats_get_by_id(port_id, ids, values, len);
795 	if (ret < 0 || ret > len) {
796 		printf("Cannot get xstats\n");
797 		goto err;
798 	}
799 
800 	for (i = 0; i < len; i++)
801 		printf("%s: %"PRIu64"\n",
802 			xstats_names[i].name,
803 			values[i]);
804 
805 	printf("%s############################\n", nic_stats_border);
806 err:
807 	free(values);
808 	free(xstats_names);
809 }
810 
811 static void
812 nic_xstats_display(uint16_t port_id)
813 {
814 	struct rte_eth_xstat_name *xstats_names;
815 	uint64_t *values;
816 	int len, ret, i;
817 	static const char *nic_stats_border = "########################";
818 
819 	len = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
820 	if (len < 0) {
821 		printf("Cannot get xstats count\n");
822 		return;
823 	}
824 	values = malloc(sizeof(*values) * len);
825 	if (values == NULL) {
826 		printf("Cannot allocate memory for xstats\n");
827 		return;
828 	}
829 
830 	xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len);
831 	if (xstats_names == NULL) {
832 		printf("Cannot allocate memory for xstat names\n");
833 		free(values);
834 		return;
835 	}
836 	if (len != rte_eth_xstats_get_names_by_id(
837 			port_id, xstats_names, len, NULL)) {
838 		printf("Cannot get xstat names\n");
839 		goto err;
840 	}
841 
842 	printf("###### NIC extended statistics for port %-2d #########\n",
843 			   port_id);
844 	printf("%s############################\n",
845 			   nic_stats_border);
846 	ret = rte_eth_xstats_get_by_id(port_id, NULL, values, len);
847 	if (ret < 0 || ret > len) {
848 		printf("Cannot get xstats\n");
849 		goto err;
850 	}
851 
852 	for (i = 0; i < len; i++) {
853 		if (enable_collectd_format) {
854 			char counter_type[MAX_STRING_LEN];
855 			char buf[MAX_STRING_LEN];
856 			size_t n;
857 
858 			collectd_resolve_cnt_type(counter_type,
859 						  sizeof(counter_type),
860 						  xstats_names[i].name);
861 			n = snprintf(buf, MAX_STRING_LEN,
862 				"PUTVAL %s/dpdkstat-port.%u/%s-%s N:%"
863 				PRIu64"\n", host_id, port_id, counter_type,
864 				xstats_names[i].name, values[i]);
865 			if (n > sizeof(buf) - 1)
866 				n = sizeof(buf) - 1;
867 			ret = write(stdout_fd, buf, n);
868 			if (ret < 0)
869 				goto err;
870 		} else {
871 			printf("%s: %"PRIu64"\n", xstats_names[i].name,
872 					values[i]);
873 		}
874 	}
875 
876 	printf("%s############################\n",
877 			   nic_stats_border);
878 err:
879 	free(values);
880 	free(xstats_names);
881 }
882 
883 static void
884 nic_xstats_clear(uint16_t port_id)
885 {
886 	int ret;
887 
888 	printf("\n Clearing NIC xstats for port %d\n", port_id);
889 	ret = rte_eth_xstats_reset(port_id);
890 	if (ret != 0) {
891 		printf("\n Error clearing xstats for port %d: %s\n", port_id,
892 		       strerror(-ret));
893 		return;
894 	}
895 
896 	printf("\n  NIC extended statistics for port %d cleared\n", port_id);
897 }
898 
899 #ifdef RTE_LIB_METRICS
900 static void
901 metrics_display(int port_id)
902 {
903 	struct rte_metric_value *metrics;
904 	struct rte_metric_name *names;
905 	int len, ret;
906 	static const char *nic_stats_border = "########################";
907 
908 	len = rte_metrics_get_names(NULL, 0);
909 	if (len < 0) {
910 		printf("Cannot get metrics count\n");
911 		return;
912 	}
913 	if (len == 0) {
914 		printf("No metrics to display (none have been registered)\n");
915 		return;
916 	}
917 
918 	metrics = malloc(sizeof(struct rte_metric_value) * len);
919 	if (metrics == NULL) {
920 		printf("Cannot allocate memory for metrics\n");
921 		return;
922 	}
923 
924 	names = malloc(sizeof(struct rte_metric_name) * len);
925 	if (names == NULL) {
926 		printf("Cannot allocate memory for metrics names\n");
927 		free(metrics);
928 		return;
929 	}
930 
931 	if (len != rte_metrics_get_names(names, len)) {
932 		printf("Cannot get metrics names\n");
933 		free(metrics);
934 		free(names);
935 		return;
936 	}
937 
938 	if (port_id == RTE_METRICS_GLOBAL)
939 		printf("###### Non port specific metrics  #########\n");
940 	else
941 		printf("###### metrics for port %-2d #########\n", port_id);
942 	printf("%s############################\n", nic_stats_border);
943 	ret = rte_metrics_get_values(port_id, metrics, len);
944 	if (ret < 0 || ret > len) {
945 		printf("Cannot get metrics values\n");
946 		free(metrics);
947 		free(names);
948 		return;
949 	}
950 
951 	int i;
952 	for (i = 0; i < len; i++)
953 		printf("%s: %"PRIu64"\n", names[i].name, metrics[i].value);
954 
955 	printf("%s############################\n", nic_stats_border);
956 	free(metrics);
957 	free(names);
958 }
959 #endif
960 
961 static void
962 show_security_context(uint16_t portid, bool inline_offload)
963 {
964 	void *p_ctx;
965 	const struct rte_security_capability *s_cap;
966 
967 	if (inline_offload)
968 		p_ctx = rte_eth_dev_get_sec_ctx(portid);
969 	else
970 		p_ctx = rte_cryptodev_get_sec_ctx(portid);
971 
972 	if (p_ctx == NULL)
973 		return;
974 
975 	printf("  - crypto context\n");
976 	printf("\t  -- security context - %p\n", p_ctx);
977 	printf("\t  -- size %u\n",
978 	       rte_security_session_get_size(p_ctx));
979 
980 	s_cap = rte_security_capabilities_get(p_ctx);
981 	if (s_cap) {
982 		printf("\t  -- action (0x%x), protocol (0x%x),"
983 		       " offload flags (0x%x)\n",
984 		       s_cap->action,
985 		       s_cap->protocol,
986 		       s_cap->ol_flags);
987 		printf("\t  -- capabilities - oper type %x\n",
988 		       s_cap->crypto_capabilities->op);
989 	}
990 }
991 
992 static void
993 show_offloads(uint64_t offloads,
994 	      const char *(show_offload)(uint64_t))
995 {
996 	printf(" offloads :");
997 	while (offloads != 0) {
998 		uint64_t offload_flag = 1ULL << rte_ctz64(offloads);
999 		printf(" %s", show_offload(offload_flag));
1000 		offloads &= ~offload_flag;
1001 	}
1002 }
1003 
1004 static void
1005 show_port(void)
1006 {
1007 	int i, ret, j, k;
1008 
1009 	snprintf(bdr_str, MAX_STRING_LEN, " show - Port PMD ");
1010 	STATS_BDR_STR(10, bdr_str);
1011 
1012 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
1013 		uint16_t mtu = 0;
1014 		struct rte_eth_link link;
1015 		struct rte_eth_dev_info dev_info;
1016 		struct rte_eth_rss_conf rss_conf;
1017 		char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
1018 		struct rte_eth_fc_conf fc_conf;
1019 		struct rte_ether_addr mac;
1020 		struct rte_eth_dev_owner owner;
1021 		uint8_t rss_key[RSS_HASH_KEY_SIZE];
1022 
1023 		/* Skip if port is not in mask */
1024 		if ((enabled_port_mask & (1ul << i)) == 0)
1025 			continue;
1026 
1027 		/* Skip if port is unused */
1028 		if (!rte_eth_dev_is_valid_port(i))
1029 			continue;
1030 
1031 		memset(&rss_conf, 0, sizeof(rss_conf));
1032 
1033 		snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i);
1034 		STATS_BDR_STR(5, bdr_str);
1035 		printf("  - generic config\n");
1036 
1037 		ret = rte_eth_dev_info_get(i, &dev_info);
1038 		if (ret != 0) {
1039 			printf("Error during getting device info: %s\n",
1040 				strerror(-ret));
1041 			return;
1042 		}
1043 
1044 		printf("\t  -- driver %s device %s socket %d\n",
1045 		       dev_info.driver_name, rte_dev_name(dev_info.device),
1046 		       rte_eth_dev_socket_id(i));
1047 
1048 		ret = rte_eth_dev_owner_get(i, &owner);
1049 		if (ret == 0 && owner.id != RTE_ETH_DEV_NO_OWNER)
1050 			printf("\t --  owner %#"PRIx64":%s\n",
1051 			       owner.id, owner.name);
1052 
1053 		ret = rte_eth_link_get(i, &link);
1054 		if (ret < 0) {
1055 			printf("Link get failed (port %u): %s\n",
1056 			       i, rte_strerror(-ret));
1057 		} else {
1058 			rte_eth_link_to_str(link_status_text,
1059 					sizeof(link_status_text),
1060 					&link);
1061 			printf("\t%s\n", link_status_text);
1062 		}
1063 
1064 		ret = rte_eth_dev_flow_ctrl_get(i, &fc_conf);
1065 		if (ret == 0 && fc_conf.mode != RTE_ETH_FC_NONE)  {
1066 			printf("\t  -- flow control mode %s%s high %u low %u pause %u%s%s\n",
1067 			       fc_conf.mode == RTE_ETH_FC_RX_PAUSE ? "rx " :
1068 			       fc_conf.mode == RTE_ETH_FC_TX_PAUSE ? "tx " :
1069 			       fc_conf.mode == RTE_ETH_FC_FULL ? "full" : "???",
1070 			       fc_conf.autoneg ? " auto" : "",
1071 			       fc_conf.high_water,
1072 			       fc_conf.low_water,
1073 			       fc_conf.pause_time,
1074 			       fc_conf.send_xon ? " xon" : "",
1075 			       fc_conf.mac_ctrl_frame_fwd ? " mac_ctrl" : "");
1076 		}
1077 
1078 		ret = rte_eth_macaddr_get(i, &mac);
1079 		if (ret == 0) {
1080 			char ebuf[RTE_ETHER_ADDR_FMT_SIZE];
1081 
1082 			rte_ether_format_addr(ebuf, sizeof(ebuf), &mac);
1083 			printf("\t  -- mac %s\n", ebuf);
1084 		}
1085 
1086 		ret = rte_eth_promiscuous_get(i);
1087 		if (ret >= 0)
1088 			printf("\t  -- promiscuous mode %s\n",
1089 			       ret > 0 ? "enabled" : "disabled");
1090 
1091 		ret = rte_eth_allmulticast_get(i);
1092 		if (ret >= 0)
1093 			printf("\t  -- all multicast mode %s\n",
1094 			       ret > 0 ? "enabled" : "disabled");
1095 
1096 		ret = rte_eth_dev_get_mtu(i, &mtu);
1097 		if (ret == 0)
1098 			printf("\t  -- mtu (%d)\n", mtu);
1099 
1100 		for (j = 0; j < dev_info.nb_rx_queues; j++) {
1101 			struct rte_eth_rxq_info queue_info;
1102 			struct rte_eth_burst_mode mode;
1103 			int count;
1104 
1105 			ret = rte_eth_rx_queue_info_get(i, j, &queue_info);
1106 			if (ret != 0)
1107 				break;
1108 
1109 			if (j == 0)
1110 				printf("  - rx queue\n");
1111 
1112 			printf("\t  -- %d descriptors ", j);
1113 			count = rte_eth_rx_queue_count(i, j);
1114 			if (count >= 0)
1115 				printf("%d/", count);
1116 			printf("%u", queue_info.nb_desc);
1117 
1118 			if (queue_info.scattered_rx)
1119 				printf(" scattered");
1120 
1121 			if (queue_info.conf.rx_drop_en)
1122 				printf(" drop_en");
1123 
1124 			if (queue_info.conf.rx_deferred_start)
1125 				printf(" deferred_start");
1126 
1127 			if (queue_info.rx_buf_size != 0)
1128 				printf(" rx buffer size %u",
1129 				       queue_info.rx_buf_size);
1130 
1131 			printf(" mempool %s socket %d",
1132 			       queue_info.mp->name,
1133 			       queue_info.mp->socket_id);
1134 
1135 			if (queue_info.conf.offloads != 0)
1136 				show_offloads(queue_info.conf.offloads, rte_eth_dev_rx_offload_name);
1137 
1138 			if (rte_eth_rx_burst_mode_get(i, j, &mode) == 0)
1139 				printf(" burst mode : %s%s",
1140 				       mode.info,
1141 				       mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
1142 						" (per queue)" : "");
1143 
1144 			printf("\n");
1145 		}
1146 
1147 		for (j = 0; j < dev_info.nb_tx_queues; j++) {
1148 			struct rte_eth_txq_info queue_info;
1149 			struct rte_eth_burst_mode mode;
1150 
1151 			ret = rte_eth_tx_queue_info_get(i, j, &queue_info);
1152 			if (ret != 0)
1153 				break;
1154 
1155 			if (j == 0)
1156 				printf("  - tx queue\n");
1157 
1158 			printf("\t  -- %d descriptors %d",
1159 			       j, queue_info.nb_desc);
1160 
1161 			printf(" thresh %u/%u",
1162 			       queue_info.conf.tx_rs_thresh,
1163 			       queue_info.conf.tx_free_thresh);
1164 
1165 			if (queue_info.conf.tx_deferred_start)
1166 				printf(" deferred_start");
1167 
1168 			if (queue_info.conf.offloads != 0)
1169 				show_offloads(queue_info.conf.offloads, rte_eth_dev_tx_offload_name);
1170 
1171 			if (rte_eth_tx_burst_mode_get(i, j, &mode) == 0)
1172 				printf(" burst mode : %s%s",
1173 				       mode.info,
1174 				       mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ?
1175 						" (per queue)" : "");
1176 
1177 			printf("\n");
1178 		}
1179 
1180 		rss_conf.rss_key = rss_key;
1181 		rss_conf.rss_key_len = dev_info.hash_key_size;
1182 		ret = rte_eth_dev_rss_hash_conf_get(i, &rss_conf);
1183 		if (ret == 0) {
1184 			printf("  - RSS info\n");
1185 			printf("\t  -- key len : %u\n",
1186 					rss_conf.rss_key_len);
1187 			printf("\t  -- key (hex) : ");
1188 			for (k = 0; k < rss_conf.rss_key_len; k++)
1189 				printf("%02x", rss_conf.rss_key[k]);
1190 			printf("\n\t  -- hash function : 0x%"PRIx64"\n",
1191 					rss_conf.rss_hf);
1192 			printf("\t  -- hash algorithm : %s\n",
1193 				rte_eth_dev_rss_algo_name(rss_conf.algorithm));
1194 		}
1195 
1196 #ifdef RTE_LIB_SECURITY
1197 		show_security_context(i, true);
1198 #endif
1199 	}
1200 }
1201 
1202 static void
1203 show_port_private_info(void)
1204 {
1205 	int i;
1206 
1207 	snprintf(bdr_str, MAX_STRING_LEN, " Dump - Ports private information");
1208 	STATS_BDR_STR(10, bdr_str);
1209 
1210 	RTE_ETH_FOREACH_DEV(i) {
1211 		/* Skip if port is not in mask */
1212 		if ((enabled_port_mask & (1ul << i)) == 0)
1213 			continue;
1214 
1215 		snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i);
1216 		STATS_BDR_STR(5, bdr_str);
1217 		rte_eth_dev_priv_dump(i, stdout);
1218 	}
1219 }
1220 
1221 static void
1222 display_nodecap_info(int is_leaf, struct rte_tm_node_capabilities *cap)
1223 {
1224 	if (cap == NULL)
1225 		return;
1226 
1227 	if (!is_leaf) {
1228 		printf("\t  -- nonleaf sched max:\n"
1229 			"\t\t  + children (%u)\n"
1230 			"\t\t  + sp priorities (%u)\n"
1231 			"\t\t  + wfq children per group (%u)\n"
1232 			"\t\t  + wfq groups (%u)\n"
1233 			"\t\t  + wfq weight (%u)\n",
1234 			cap->nonleaf.sched_n_children_max,
1235 			cap->nonleaf.sched_sp_n_priorities_max,
1236 			cap->nonleaf.sched_wfq_n_children_per_group_max,
1237 			cap->nonleaf.sched_wfq_n_groups_max,
1238 			cap->nonleaf.sched_wfq_weight_max);
1239 	} else {
1240 		printf("\t  -- leaf cman support:\n"
1241 			"\t\t  + wred pkt mode (%d)\n"
1242 			"\t\t  + wred byte mode (%d)\n"
1243 			"\t\t  + head drop (%d)\n"
1244 			"\t\t  + wred context private (%d)\n"
1245 			"\t\t  + wred context shared (%u)\n",
1246 			cap->leaf.cman_wred_packet_mode_supported,
1247 			cap->leaf.cman_wred_byte_mode_supported,
1248 			cap->leaf.cman_head_drop_supported,
1249 			cap->leaf.cman_wred_context_private_supported,
1250 			cap->leaf.cman_wred_context_shared_n_max);
1251 	}
1252 }
1253 
1254 static void
1255 display_levelcap_info(int is_leaf, struct rte_tm_level_capabilities *cap)
1256 {
1257 	if (cap == NULL)
1258 		return;
1259 
1260 	if (!is_leaf) {
1261 		printf("\t  -- shaper private: (%d) dual rate (%d)\n",
1262 			cap->nonleaf.shaper_private_supported,
1263 			cap->nonleaf.shaper_private_dual_rate_supported);
1264 		printf("\t  -- shaper share: (%u)\n",
1265 			cap->nonleaf.shaper_shared_n_max);
1266 		printf("\t  -- non leaf sched MAX:\n"
1267 			"\t\t  + children (%u)\n"
1268 			"\t\t  + sp (%u)\n"
1269 			"\t\t  + wfq children per group (%u)\n"
1270 			"\t\t  + wfq groups (%u)\n"
1271 			"\t\t  + wfq weight (%u)\n",
1272 			cap->nonleaf.sched_n_children_max,
1273 			cap->nonleaf.sched_sp_n_priorities_max,
1274 			cap->nonleaf.sched_wfq_n_children_per_group_max,
1275 			cap->nonleaf.sched_wfq_n_groups_max,
1276 			cap->nonleaf.sched_wfq_weight_max);
1277 	} else {
1278 		printf("\t  -- shaper private: (%d) dual rate (%d)\n",
1279 			cap->leaf.shaper_private_supported,
1280 			cap->leaf.shaper_private_dual_rate_supported);
1281 		printf("\t  -- shaper share: (%u)\n",
1282 			cap->leaf.shaper_shared_n_max);
1283 		printf("  -- leaf cman support:\n"
1284 			"\t\t  + wred pkt mode (%d)\n"
1285 			"\t\t  + wred byte mode (%d)\n"
1286 			"\t\t  + head drop (%d)\n"
1287 			"\t\t  + wred context private (%d)\n"
1288 			"\t\t  + wred context shared (%u)\n",
1289 			cap->leaf.cman_wred_packet_mode_supported,
1290 			cap->leaf.cman_wred_byte_mode_supported,
1291 			cap->leaf.cman_head_drop_supported,
1292 			cap->leaf.cman_wred_context_private_supported,
1293 			cap->leaf.cman_wred_context_shared_n_max);
1294 	}
1295 }
1296 
1297 static void
1298 show_tm(void)
1299 {
1300 	int ret = 0, check_for_leaf = 0, is_leaf = 0;
1301 	unsigned int j, k;
1302 	uint16_t i = 0;
1303 
1304 	snprintf(bdr_str, MAX_STRING_LEN, " show - TM PMD ");
1305 	STATS_BDR_STR(10, bdr_str);
1306 
1307 	RTE_ETH_FOREACH_DEV(i) {
1308 		struct rte_eth_dev_info dev_info;
1309 		struct rte_tm_capabilities cap;
1310 		struct rte_tm_error error;
1311 		struct rte_tm_node_capabilities capnode;
1312 		struct rte_tm_level_capabilities caplevel;
1313 		uint32_t n_leaf_nodes = 0;
1314 
1315 		memset(&cap, 0, sizeof(cap));
1316 		memset(&error, 0, sizeof(error));
1317 
1318 		ret = rte_eth_dev_info_get(i, &dev_info);
1319 		if (ret != 0) {
1320 			printf("Error during getting device (port %u) info: %s\n",
1321 				i, strerror(-ret));
1322 			return;
1323 		}
1324 
1325 		printf("  - Generic for port (%u)\n"
1326 			"\t  -- driver name %s\n"
1327 			"\t  -- max vf (%u)\n"
1328 			"\t  -- max tx queues (%u)\n"
1329 			"\t  -- number of tx queues (%u)\n",
1330 			i,
1331 			dev_info.driver_name,
1332 			dev_info.max_vfs,
1333 			dev_info.max_tx_queues,
1334 			dev_info.nb_tx_queues);
1335 
1336 		ret = rte_tm_capabilities_get(i, &cap, &error);
1337 		if (ret)
1338 			continue;
1339 
1340 		printf("  - MAX: nodes (%u) levels (%u) children (%u)\n",
1341 			cap.n_nodes_max,
1342 			cap.n_levels_max,
1343 			cap.sched_n_children_max);
1344 
1345 		printf("  - identical nodes: non leaf (%d) leaf (%d)\n",
1346 			cap.non_leaf_nodes_identical,
1347 			cap.leaf_nodes_identical);
1348 
1349 		printf("  - Shaper MAX:\n"
1350 			"\t  -- total (%u)\n"
1351 			"\t  -- private (%u) private dual (%d)\n"
1352 			"\t  -- shared (%u) shared dual (%u)\n",
1353 			cap.shaper_n_max,
1354 			cap.shaper_private_n_max,
1355 			cap.shaper_private_dual_rate_n_max,
1356 			cap.shaper_shared_n_max,
1357 			cap.shaper_shared_dual_rate_n_max);
1358 
1359 		printf("  - mark support:\n");
1360 		printf("\t  -- vlan dei: GREEN (%d) YELLOW (%d) RED (%d)\n",
1361 			cap.mark_vlan_dei_supported[RTE_COLOR_GREEN],
1362 			cap.mark_vlan_dei_supported[RTE_COLOR_YELLOW],
1363 			cap.mark_vlan_dei_supported[RTE_COLOR_RED]);
1364 		printf("\t  -- ip ecn tcp: GREEN (%d) YELLOW (%d) RED (%d)\n",
1365 			cap.mark_ip_ecn_tcp_supported[RTE_COLOR_GREEN],
1366 			cap.mark_ip_ecn_tcp_supported[RTE_COLOR_YELLOW],
1367 			cap.mark_ip_ecn_tcp_supported[RTE_COLOR_RED]);
1368 		printf("\t  -- ip ecn sctp: GREEN (%d) YELLOW (%d) RED (%d)\n",
1369 			cap.mark_ip_ecn_sctp_supported[RTE_COLOR_GREEN],
1370 			cap.mark_ip_ecn_sctp_supported[RTE_COLOR_YELLOW],
1371 			cap.mark_ip_ecn_sctp_supported[RTE_COLOR_RED]);
1372 		printf("\t  -- ip dscp: GREEN (%d) YELLOW (%d) RED (%d)\n",
1373 			cap.mark_ip_dscp_supported[RTE_COLOR_GREEN],
1374 			cap.mark_ip_dscp_supported[RTE_COLOR_YELLOW],
1375 			cap.mark_ip_dscp_supported[RTE_COLOR_RED]);
1376 
1377 		printf("  - mask stats (0x%"PRIx64")"
1378 			" dynamic update (0x%"PRIx64")\n",
1379 			cap.stats_mask,
1380 			cap.dynamic_update_mask);
1381 
1382 		printf("  - sched MAX:\n"
1383 			"\t  -- total (%u)\n"
1384 			"\t  -- sp levels (%u)\n"
1385 			"\t  -- wfq children per group (%u)\n"
1386 			"\t  -- wfq groups (%u)\n"
1387 			"\t  -- wfq weight (%u)\n",
1388 			cap.sched_sp_n_priorities_max,
1389 			cap.sched_sp_n_priorities_max,
1390 			cap.sched_wfq_n_children_per_group_max,
1391 			cap.sched_wfq_n_groups_max,
1392 			cap.sched_wfq_weight_max);
1393 
1394 		printf("  - CMAN support:\n"
1395 			"\t  -- WRED mode: pkt (%d) byte (%d)\n"
1396 			"\t  -- head drop (%d)\n",
1397 			cap.cman_wred_packet_mode_supported,
1398 			cap.cman_wred_byte_mode_supported,
1399 			cap.cman_head_drop_supported);
1400 		printf("\t  -- MAX WRED CONTEXT:"
1401 			" total (%u) private (%u) shared (%u)\n",
1402 			cap.cman_wred_context_n_max,
1403 			cap.cman_wred_context_private_n_max,
1404 			cap.cman_wred_context_shared_n_max);
1405 
1406 		for (j = 0; j < cap.n_nodes_max; j++) {
1407 			memset(&capnode, 0, sizeof(capnode));
1408 			ret = rte_tm_node_capabilities_get(i, j,
1409 					&capnode, &error);
1410 			if (ret)
1411 				continue;
1412 
1413 			check_for_leaf = 1;
1414 
1415 			printf("  NODE %u\n", j);
1416 			printf("\t  - shaper private: (%d) dual rate (%d)\n",
1417 				capnode.shaper_private_supported,
1418 				capnode.shaper_private_dual_rate_supported);
1419 			printf("\t  - shaper shared max: (%u)\n",
1420 				capnode.shaper_shared_n_max);
1421 			printf("\t  - stats mask %"PRIx64"\n",
1422 				capnode.stats_mask);
1423 
1424 			ret = rte_tm_node_type_get(i, j, &is_leaf, &error);
1425 			if (ret)
1426 				continue;
1427 
1428 			display_nodecap_info(is_leaf, &capnode);
1429 		}
1430 
1431 		for (j = 0; j < cap.n_levels_max; j++) {
1432 			memset(&caplevel, 0, sizeof(caplevel));
1433 			ret = rte_tm_level_capabilities_get(i, j,
1434 					&caplevel, &error);
1435 			if (ret)
1436 				continue;
1437 
1438 			printf("  - Level %u\n", j);
1439 			printf("\t  -- node MAX: %u non leaf %u leaf %u\n",
1440 				caplevel.n_nodes_max,
1441 				caplevel.n_nodes_nonleaf_max,
1442 				caplevel.n_nodes_leaf_max);
1443 			printf("\t  -- identical: non leaf %u leaf %u\n",
1444 				caplevel.non_leaf_nodes_identical,
1445 				caplevel.leaf_nodes_identical);
1446 
1447 			for (k = 0; k < caplevel.n_nodes_max; k++) {
1448 				ret = rte_tm_node_type_get(i, k,
1449 					&is_leaf, &error);
1450 				if (ret)
1451 					continue;
1452 
1453 				display_levelcap_info(is_leaf, &caplevel);
1454 			}
1455 		}
1456 
1457 		if (check_for_leaf) {
1458 			ret = rte_tm_get_number_of_leaf_nodes(i,
1459 					&n_leaf_nodes, &error);
1460 			if (ret == 0)
1461 				printf("  - leaf nodes (%u)\n", n_leaf_nodes);
1462 		}
1463 
1464 		for (j = 0; j < n_leaf_nodes; j++) {
1465 			struct rte_tm_node_stats stats;
1466 			memset(&stats, 0, sizeof(stats));
1467 
1468 			ret = rte_tm_node_stats_read(i, j,
1469 					&stats, &cap.stats_mask, 0, &error);
1470 			if (ret)
1471 				continue;
1472 
1473 			printf("  - STATS for node (%u)\n", j);
1474 			printf("  -- pkts (%"PRIu64") bytes (%"PRIu64")\n",
1475 				stats.n_pkts, stats.n_bytes);
1476 
1477 			ret = rte_tm_node_type_get(i, j, &is_leaf, &error);
1478 			if (ret || (!is_leaf))
1479 				continue;
1480 
1481 			printf("  -- leaf queued:"
1482 				" pkts (%"PRIu64") bytes (%"PRIu64")\n",
1483 				stats.leaf.n_pkts_queued,
1484 				stats.leaf.n_bytes_queued);
1485 			printf("  - dropped:\n"
1486 				"\t  -- GREEN:"
1487 				" pkts (%"PRIu64") bytes (%"PRIu64")\n"
1488 				"\t  -- YELLOW:"
1489 				" pkts (%"PRIu64") bytes (%"PRIu64")\n"
1490 				"\t  -- RED:"
1491 				" pkts (%"PRIu64") bytes (%"PRIu64")\n",
1492 				stats.leaf.n_pkts_dropped[RTE_COLOR_GREEN],
1493 				stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN],
1494 				stats.leaf.n_pkts_dropped[RTE_COLOR_YELLOW],
1495 				stats.leaf.n_bytes_dropped[RTE_COLOR_YELLOW],
1496 				stats.leaf.n_pkts_dropped[RTE_COLOR_RED],
1497 				stats.leaf.n_bytes_dropped[RTE_COLOR_RED]);
1498 		}
1499 	}
1500 }
1501 
1502 static void
1503 display_crypto_feature_info(uint64_t x)
1504 {
1505 	if (x == 0)
1506 		return;
1507 
1508 	printf("\t  -- feature flags\n");
1509 	printf("\t\t  + symmetric (%c), asymmetric (%c)\n"
1510 		"\t\t  + symmetric operation chaining (%c)\n",
1511 		(x & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ? 'y' : 'n',
1512 		(x & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) ? 'y' : 'n',
1513 		(x & RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING) ? 'y' : 'n');
1514 	printf("\t\t  + CPU: SSE (%c), AVX (%c), AVX2 (%c), AVX512 (%c)\n",
1515 		(x & RTE_CRYPTODEV_FF_CPU_SSE) ? 'y' : 'n',
1516 		(x & RTE_CRYPTODEV_FF_CPU_AVX) ? 'y' : 'n',
1517 		(x & RTE_CRYPTODEV_FF_CPU_AVX2) ? 'y' : 'n',
1518 		(x & RTE_CRYPTODEV_FF_CPU_AVX512) ? 'y' : 'n');
1519 	printf("\t\t  + AESNI: CPU (%c), HW (%c)\n",
1520 		(x & RTE_CRYPTODEV_FF_CPU_AESNI) ? 'y' : 'n',
1521 		(x & RTE_CRYPTODEV_FF_HW_ACCELERATED) ? 'y' : 'n');
1522 	printf("\t\t  + SECURITY OFFLOAD (%c)\n",
1523 		(x & RTE_CRYPTODEV_FF_SECURITY) ? 'y' : 'n');
1524 	printf("\t\t  + ARM: NEON (%c), CE (%c)\n",
1525 		(x & RTE_CRYPTODEV_FF_CPU_NEON) ? 'y' : 'n',
1526 		(x & RTE_CRYPTODEV_FF_CPU_ARM_CE) ? 'y' : 'n');
1527 	printf("\t  -- buffer offload\n");
1528 	printf("\t\t  + IN_PLACE_SGL (%c)\n",
1529 		(x & RTE_CRYPTODEV_FF_IN_PLACE_SGL) ? 'y' : 'n');
1530 	printf("\t\t  + OOP_SGL_IN_SGL_OUT (%c)\n",
1531 		(x & RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT) ? 'y' : 'n');
1532 	printf("\t\t  + OOP_SGL_IN_LB_OUT (%c)\n",
1533 		(x & RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT) ? 'y' : 'n');
1534 	printf("\t\t  + OOP_LB_IN_SGL_OUT (%c)\n",
1535 		(x & RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT) ? 'y' : 'n');
1536 	printf("\t\t  + OOP_LB_IN_LB_OUT (%c)\n",
1537 		(x & RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT) ? 'y' : 'n');
1538 }
1539 
1540 static void
1541 show_crypto(void)
1542 {
1543 	uint8_t crypto_dev_count = rte_cryptodev_count(), i;
1544 
1545 	snprintf(bdr_str, MAX_STRING_LEN, " show - CRYPTO PMD ");
1546 	STATS_BDR_STR(10, bdr_str);
1547 
1548 	for (i = 0; i < crypto_dev_count; i++) {
1549 		struct rte_cryptodev_info dev_info;
1550 		struct rte_cryptodev_stats stats;
1551 
1552 		rte_cryptodev_info_get(i, &dev_info);
1553 
1554 		printf("  - device (%u)\n", i);
1555 		printf("\t  -- name (%s)\n"
1556 		       "\t  -- driver (%s)\n"
1557 		       "\t  -- id (%u) on socket (%d)\n"
1558 		       "\t  -- queue pairs (%d)\n",
1559 		       rte_cryptodev_name_get(i),
1560 		       dev_info.driver_name,
1561 		       dev_info.driver_id,
1562 		       rte_dev_numa_node(dev_info.device),
1563 		       rte_cryptodev_queue_pair_count(i));
1564 
1565 		display_crypto_feature_info(dev_info.feature_flags);
1566 
1567 		if (rte_cryptodev_stats_get(i, &stats) == 0) {
1568 			printf("\t  -- stats\n");
1569 			printf("\t\t  + enqueue count (%"PRIu64")"
1570 			       " error (%"PRIu64")\n",
1571 			       stats.enqueued_count,
1572 			       stats.enqueue_err_count);
1573 			printf("\t\t  + dequeue count (%"PRIu64")"
1574 			       " error (%"PRIu64")\n",
1575 			       stats.dequeued_count,
1576 			       stats.dequeue_err_count);
1577 		}
1578 
1579 #ifdef RTE_LIB_SECURITY
1580 		show_security_context(i, false);
1581 #endif
1582 	}
1583 }
1584 
1585 static void
1586 show_ring(char *name)
1587 {
1588 	snprintf(bdr_str, MAX_STRING_LEN, " show - RING ");
1589 	STATS_BDR_STR(10, bdr_str);
1590 
1591 	if (name != NULL) {
1592 		struct rte_ring *ptr = rte_ring_lookup(name);
1593 		if (ptr != NULL) {
1594 			printf("  - Name (%s) on socket (%d)\n"
1595 				"  - flags:\n"
1596 				"\t  -- Single Producer Enqueue (%u)\n"
1597 				"\t  -- Single Consumer Dequeue (%u)\n",
1598 				ptr->name,
1599 				ptr->memzone->socket_id,
1600 				ptr->flags & RING_F_SP_ENQ,
1601 				ptr->flags & RING_F_SC_DEQ);
1602 			printf("  - size (%u) mask (0x%x) capacity (%u)\n",
1603 				ptr->size,
1604 				ptr->mask,
1605 				ptr->capacity);
1606 			printf("  - count (%u) free count (%u)\n",
1607 				rte_ring_count(ptr),
1608 				rte_ring_free_count(ptr));
1609 			printf("  - full (%d) empty (%d)\n",
1610 				rte_ring_full(ptr),
1611 				rte_ring_empty(ptr));
1612 
1613 			STATS_BDR_STR(50, "");
1614 			return;
1615 		}
1616 	}
1617 
1618 	rte_ring_list_dump(stdout);
1619 }
1620 
1621 static void
1622 show_mempool(char *name)
1623 {
1624 	snprintf(bdr_str, MAX_STRING_LEN, " show - MEMPOOL ");
1625 	STATS_BDR_STR(10, bdr_str);
1626 
1627 	if (name != NULL) {
1628 		struct rte_mempool *ptr = rte_mempool_lookup(name);
1629 		if (ptr != NULL) {
1630 			struct rte_mempool_ops *ops;
1631 			uint64_t flags = ptr->flags;
1632 
1633 			ops = rte_mempool_get_ops(ptr->ops_index);
1634 			printf("  - Name: %s on socket %d\n"
1635 				"  - flags:\n"
1636 				"\t  -- No spread (%c)\n"
1637 				"\t  -- No cache align (%c)\n"
1638 				"\t  -- SP put (%c), SC get (%c)\n"
1639 				"\t  -- Pool created (%c)\n"
1640 				"\t  -- No IOVA config (%c)\n"
1641 				"\t  -- Not used for IO (%c)\n",
1642 				ptr->name,
1643 				ptr->socket_id,
1644 				(flags & RTE_MEMPOOL_F_NO_SPREAD) ? 'y' : 'n',
1645 				(flags & RTE_MEMPOOL_F_NO_CACHE_ALIGN) ? 'y' : 'n',
1646 				(flags & RTE_MEMPOOL_F_SP_PUT) ? 'y' : 'n',
1647 				(flags & RTE_MEMPOOL_F_SC_GET) ? 'y' : 'n',
1648 				(flags & RTE_MEMPOOL_F_POOL_CREATED) ? 'y' : 'n',
1649 				(flags & RTE_MEMPOOL_F_NO_IOVA_CONTIG) ? 'y' : 'n',
1650 				(flags & RTE_MEMPOOL_F_NON_IO) ? 'y' : 'n');
1651 			printf("  - Size %u Cache %u element %u\n"
1652 				"  - header %u trailer %u\n"
1653 				"  - private data size %u\n",
1654 				ptr->size,
1655 				ptr->cache_size,
1656 				ptr->elt_size,
1657 				ptr->header_size,
1658 				ptr->trailer_size,
1659 				ptr->private_data_size);
1660 			printf("  - memezone - socket %d\n",
1661 				ptr->mz->socket_id);
1662 			printf("  - Count: avail (%u), in use (%u)\n",
1663 				rte_mempool_avail_count(ptr),
1664 				rte_mempool_in_use_count(ptr));
1665 			printf("  - ops_index %d ops_name %s\n",
1666 				ptr->ops_index, ops ? ops->name : "NA");
1667 
1668 			return;
1669 		}
1670 	}
1671 
1672 	rte_mempool_list_dump(stdout);
1673 }
1674 
1675 static void
1676 mempool_itr_obj(struct rte_mempool *mp, void *opaque,
1677 		void *obj, unsigned int obj_idx)
1678 {
1679 	printf("  - obj_idx %u opaque %p obj %p\n",
1680 			obj_idx, opaque, obj);
1681 
1682 	if (obj)
1683 		rte_hexdump(stdout, " Obj Content",
1684 				obj, (mp->elt_size > 256)?256:mp->elt_size);
1685 }
1686 
1687 static void
1688 iter_mempool(char *name)
1689 {
1690 	snprintf(bdr_str, MAX_STRING_LEN, " iter - MEMPOOL ");
1691 	STATS_BDR_STR(10, bdr_str);
1692 
1693 	if (name != NULL) {
1694 		struct rte_mempool *ptr = rte_mempool_lookup(name);
1695 		if (ptr != NULL) {
1696 			/* iterate each object */
1697 			uint32_t ret = rte_mempool_obj_iter(ptr,
1698 					mempool_itr_obj, NULL);
1699 			printf("\n  - iterated %u objects\n", ret);
1700 			return;
1701 		}
1702 	}
1703 }
1704 
1705 static void
1706 dump_regs(char *file_prefix)
1707 {
1708 #define MAX_FILE_NAME_SZ (MAX_LONG_OPT_SZ + 10)
1709 	char file_name[MAX_FILE_NAME_SZ];
1710 	struct rte_dev_reg_info reg_info;
1711 	struct rte_eth_dev_info dev_info;
1712 	unsigned char *buf_data;
1713 	size_t buf_size;
1714 	FILE *fp_regs;
1715 	uint16_t i;
1716 	int ret;
1717 
1718 	snprintf(bdr_str, MAX_STRING_LEN, " dump - Port REG");
1719 	STATS_BDR_STR(10, bdr_str);
1720 
1721 	RTE_ETH_FOREACH_DEV(i) {
1722 		/* Skip if port is not in mask */
1723 		if ((enabled_port_mask & (1ul << i)) == 0)
1724 			continue;
1725 
1726 		snprintf(bdr_str, MAX_STRING_LEN, " Port (%u)", i);
1727 		STATS_BDR_STR(5, bdr_str);
1728 
1729 		ret = rte_eth_dev_info_get(i, &dev_info);
1730 		if (ret) {
1731 			printf("Error getting device info: %d\n", ret);
1732 			continue;
1733 		}
1734 
1735 		memset(&reg_info, 0, sizeof(reg_info));
1736 		ret = rte_eth_dev_get_reg_info(i, &reg_info);
1737 		if (ret) {
1738 			printf("Error getting device reg info: %d\n", ret);
1739 			continue;
1740 		}
1741 
1742 		buf_size = reg_info.length * reg_info.width;
1743 		buf_data = malloc(buf_size);
1744 		if (buf_data == NULL) {
1745 			printf("Error allocating %zu bytes buffer\n", buf_size);
1746 			continue;
1747 		}
1748 
1749 		reg_info.data = buf_data;
1750 		reg_info.length = 0;
1751 		ret = rte_eth_dev_get_reg_info(i, &reg_info);
1752 		if (ret) {
1753 			printf("Error getting regs from device: %d\n", ret);
1754 			free(buf_data);
1755 			continue;
1756 		}
1757 
1758 		snprintf(file_name, MAX_FILE_NAME_SZ, "%s-port%u",
1759 				file_prefix, i);
1760 		fp_regs = fopen(file_name, "wb");
1761 		if (fp_regs == NULL) {
1762 			printf("Error during opening '%s' for writing: %s\n",
1763 					file_name, strerror(errno));
1764 		} else {
1765 			size_t nr_written;
1766 
1767 			nr_written = fwrite(buf_data, 1, buf_size, fp_regs);
1768 			if (nr_written != buf_size)
1769 				printf("Error during writing %s: %s\n",
1770 						file_prefix, strerror(errno));
1771 			else
1772 				printf("Device (%s) regs dumped successfully, "
1773 					"driver:%s version:0X%08X\n",
1774 					rte_dev_name(dev_info.device),
1775 					dev_info.driver_name, reg_info.version);
1776 
1777 			fclose(fp_regs);
1778 		}
1779 
1780 		free(buf_data);
1781 	}
1782 }
1783 
1784 static void
1785 show_version(void)
1786 {
1787 	snprintf(bdr_str, MAX_STRING_LEN, " show - DPDK version ");
1788 	STATS_BDR_STR(10, bdr_str);
1789 	printf("DPDK version: %s\n", rte_version());
1790 }
1791 
1792 static void
1793 show_firmware_version(void)
1794 {
1795 	char fw_version[ETHDEV_FWVERS_LEN];
1796 	uint16_t i;
1797 
1798 	snprintf(bdr_str, MAX_STRING_LEN, " show - firmware version ");
1799 	STATS_BDR_STR(10, bdr_str);
1800 
1801 	RTE_ETH_FOREACH_DEV(i) {
1802 		/* Skip if port is not in mask */
1803 		if ((enabled_port_mask & (1ul << i)) == 0)
1804 			continue;
1805 
1806 		if (rte_eth_dev_fw_version_get(i, fw_version,
1807 					       ETHDEV_FWVERS_LEN) == 0)
1808 			printf("Ethdev port %u firmware version: %s\n", i,
1809 				fw_version);
1810 		else
1811 			printf("Ethdev port %u firmware version: %s\n", i,
1812 				"not available");
1813 	}
1814 }
1815 
1816 static void
1817 show_port_rss_reta_info(void)
1818 {
1819 	struct rte_eth_rss_reta_entry64 reta_conf[RTE_RETA_CONF_GROUP_NUM + 1];
1820 	struct rte_eth_dev_info dev_info;
1821 	uint16_t i, idx, shift;
1822 	uint16_t num;
1823 	uint16_t id;
1824 	int ret;
1825 
1826 	RTE_ETH_FOREACH_DEV(id) {
1827 		/* Skip if port is not in mask */
1828 		if ((enabled_port_mask & (1ul << id)) == 0)
1829 			continue;
1830 
1831 		snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", id);
1832 		STATS_BDR_STR(5, bdr_str);
1833 
1834 		ret = rte_eth_dev_info_get(id, &dev_info);
1835 		if (ret != 0) {
1836 			fprintf(stderr, "Error getting device info: %s\n",
1837 				strerror(-ret));
1838 			return;
1839 		}
1840 
1841 		num = DIV_ROUND_UP(dev_info.reta_size, RTE_ETH_RETA_GROUP_SIZE);
1842 		memset(reta_conf, 0, sizeof(reta_conf));
1843 		for (i = 0; i < num; i++)
1844 			reta_conf[i].mask = ~0ULL;
1845 
1846 		ret = rte_eth_dev_rss_reta_query(id, reta_conf, dev_info.reta_size);
1847 		if (ret != 0) {
1848 			fprintf(stderr, "Error getting RSS RETA info: %s\n",
1849 				strerror(-ret));
1850 			return;
1851 		}
1852 
1853 		for (i = 0; i < dev_info.reta_size; i++) {
1854 			idx = i / RTE_ETH_RETA_GROUP_SIZE;
1855 			shift = i % RTE_ETH_RETA_GROUP_SIZE;
1856 			printf("RSS RETA configuration: hash index=%u, queue=%u\n",
1857 				i, reta_conf[idx].reta[shift]);
1858 		}
1859 	}
1860 }
1861 
1862 static void
1863 show_module_eeprom_info(void)
1864 {
1865 	unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE];
1866 	struct rte_eth_dev_module_info module_info;
1867 	struct rte_dev_eeprom_info eeprom_info;
1868 	uint16_t i;
1869 	int ret;
1870 
1871 	RTE_ETH_FOREACH_DEV(i) {
1872 		/* Skip if port is not in mask */
1873 		if ((enabled_port_mask & (1ul << i)) == 0)
1874 			continue;
1875 
1876 		snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i);
1877 		STATS_BDR_STR(5, bdr_str);
1878 
1879 		ret = rte_eth_dev_get_module_info(i, &module_info);
1880 		if (ret != 0) {
1881 			fprintf(stderr, "Module EEPROM information read error: %s\n",
1882 				strerror(-ret));
1883 			return;
1884 		}
1885 
1886 		eeprom_info.offset = 0;
1887 		eeprom_info.length = module_info.eeprom_len;
1888 		eeprom_info.data = bytes_eeprom;
1889 
1890 		ret = rte_eth_dev_get_module_eeprom(i, &eeprom_info);
1891 		if (ret != 0) {
1892 			fprintf(stderr, "Module EEPROM read error: %s\n",
1893 				strerror(-ret));
1894 			return;
1895 		}
1896 
1897 		rte_hexdump(stdout, "hexdump", eeprom_info.data,
1898 			    eeprom_info.length);
1899 		printf("Finish -- Port: %u MODULE EEPROM length: %d bytes\n",
1900 		       i, eeprom_info.length);
1901 	}
1902 }
1903 
1904 static void
1905 nic_rx_descriptor_display(uint16_t port_id, struct desc_param *desc)
1906 {
1907 	uint16_t queue_id = desc->queue_id;
1908 	uint16_t offset = desc->offset;
1909 	uint16_t num = desc->num;
1910 	int ret;
1911 
1912 	snprintf(bdr_str, MAX_STRING_LEN, " show - Rx descriptor ");
1913 	STATS_BDR_STR(10, bdr_str);
1914 
1915 	printf("Dump ethdev Rx descriptor for port %u, queue %u, offset %u, num %u\n",
1916 		port_id, queue_id, offset, num);
1917 
1918 	ret = rte_eth_rx_descriptor_dump(port_id, queue_id, offset, num,
1919 					 stdout);
1920 	if (ret < 0)
1921 		fprintf(stderr, "Error dumping ethdev Rx descriptor: %s\n",
1922 			strerror(-ret));
1923 }
1924 
1925 static void
1926 nic_tx_descriptor_display(uint16_t port_id, struct desc_param *desc)
1927 {
1928 	uint16_t queue_id = desc->queue_id;
1929 	uint16_t offset = desc->offset;
1930 	uint16_t num = desc->num;
1931 	int ret;
1932 
1933 	snprintf(bdr_str, MAX_STRING_LEN, " show - Tx descriptor ");
1934 	STATS_BDR_STR(10, bdr_str);
1935 
1936 	printf("Dump ethdev Tx descriptor for port %u, queue %u, offset %u, num %u\n",
1937 		port_id, queue_id, offset, num);
1938 
1939 	ret = rte_eth_tx_descriptor_dump(port_id, queue_id, offset, num,
1940 					 stdout);
1941 	if (ret < 0)
1942 		fprintf(stderr, "Error dumping ethdev Tx descriptor: %s\n",
1943 			strerror(-ret));
1944 }
1945 
1946 static void
1947 xstats_display(uint8_t dev_id,
1948 	  enum rte_event_dev_xstats_mode mode,
1949 	  uint8_t queue_port_id)
1950 {
1951 	int ret;
1952 	struct rte_event_dev_xstats_name *xstats_names;
1953 	uint64_t *ids;
1954 	uint64_t *values;
1955 	int size;
1956 	int i;
1957 
1958 	size = rte_event_dev_xstats_names_get(dev_id,
1959 					     mode,
1960 					     queue_port_id,
1961 					     NULL, /* names */
1962 					     NULL, /* ids */
1963 					     0);   /* num */
1964 
1965 	if (size < 0)
1966 		rte_panic("rte_event_dev_xstats_names_get err %d\n", size);
1967 
1968 	if (size == 0) {
1969 		printf(
1970 		"No stats available for this item, mode=%d, queue_port_id=%d\n",
1971 			mode, queue_port_id);
1972 		return;
1973 	}
1974 
1975 	/* Get memory to hold stat names, IDs, and values */
1976 	xstats_names = malloc(sizeof(struct rte_event_dev_xstats_name) * (unsigned int)size);
1977 	ids = malloc(sizeof(unsigned int) * size);
1978 
1979 	if (!xstats_names || !ids)
1980 		rte_panic("unable to alloc memory for stats retrieval\n");
1981 
1982 	ret = rte_event_dev_xstats_names_get(dev_id, mode, queue_port_id,
1983 					     xstats_names, ids,
1984 					     (unsigned int)size);
1985 	if (ret != size)
1986 		rte_panic("rte_event_dev_xstats_names_get err %d\n", ret);
1987 
1988 	values = malloc(sizeof(uint64_t) * size);
1989 	if (!values)
1990 		rte_panic("unable to alloc memory for stats retrieval\n");
1991 
1992 	ret = rte_event_dev_xstats_get(dev_id, mode, queue_port_id,
1993 					    ids, values, size);
1994 
1995 	if (ret != size)
1996 		rte_panic("rte_event_dev_xstats_get err %d\n", ret);
1997 
1998 	for (i = 0; i < size; i++) {
1999 		printf("id %"PRIu64"  %s = %"PRIu64"\n",
2000 			ids[i], &xstats_names[i].name[0], values[i]);
2001 	}
2002 
2003 	free(values);
2004 	free(xstats_names);
2005 	free(ids);
2006 
2007 }
2008 
2009 static void
2010 xstats_reset(uint8_t dev_id,
2011 	  enum rte_event_dev_xstats_mode mode,
2012 	  uint8_t queue_port_id)
2013 {
2014 	int ret;
2015 	struct rte_event_dev_xstats_name *xstats_names;
2016 	uint64_t *ids;
2017 	int size;
2018 
2019 	size = rte_event_dev_xstats_names_get(dev_id,
2020 					     mode,
2021 					     queue_port_id,
2022 					     NULL, /* names */
2023 					     NULL, /* ids */
2024 					     0);   /* num */
2025 
2026 	if (size < 0)
2027 		rte_panic("rte_event_dev_xstats_names_get err %d\n", size);
2028 
2029 	if (size == 0) {
2030 		printf(
2031 		"No stats available for this item, mode=%d, queue_port_id=%d\n",
2032 			mode, queue_port_id);
2033 		return;
2034 	}
2035 
2036 	/* Get memory to hold stat names, IDs, and values */
2037 	xstats_names = malloc(sizeof(struct rte_event_dev_xstats_name) * (unsigned int)size);
2038 	ids = malloc(sizeof(unsigned int) * size);
2039 
2040 	if (!xstats_names || !ids)
2041 		rte_panic("unable to alloc memory for stats retrieval\n");
2042 
2043 	ret = rte_event_dev_xstats_names_get(dev_id, mode, queue_port_id,
2044 					     xstats_names, ids,
2045 					     (unsigned int)size);
2046 	if (ret != size)
2047 		rte_panic("rte_event_dev_xstats_names_get err %d\n", ret);
2048 
2049 	rte_event_dev_xstats_reset(dev_id, mode, queue_port_id,
2050 					   ids, size);
2051 
2052 	free(xstats_names);
2053 	free(ids);
2054 
2055 }
2056 
2057 static unsigned int
2058 eventdev_xstats(void)
2059 {
2060 	unsigned int count = 0;
2061 	int i, j;
2062 
2063 	for (i = 0; i < rte_event_dev_count(); i++) {
2064 
2065 		if (eventdev_var[i].dump_xstats) {
2066 			++count;
2067 			int ret = rte_event_dev_dump(i, stdout);
2068 
2069 			if (ret)
2070 				rte_panic("dump failed with err=%d\n", ret);
2071 		}
2072 
2073 		if (eventdev_var[i].shw_device_xstats == 1) {
2074 			++count;
2075 			xstats_display(i, RTE_EVENT_DEV_XSTATS_DEVICE, 0);
2076 
2077 			if (eventdev_var[i].reset_xstats == 1)
2078 				xstats_reset(i, RTE_EVENT_DEV_XSTATS_DEVICE, 0);
2079 		}
2080 
2081 		if (eventdev_var[i].shw_all_ports == 1) {
2082 			++count;
2083 			for (j = 0; j < MAX_PORTS_QUEUES; j++) {
2084 				xstats_display(i, RTE_EVENT_DEV_XSTATS_PORT, j);
2085 
2086 				if (eventdev_var[i].reset_xstats == 1)
2087 					xstats_reset(i, RTE_EVENT_DEV_XSTATS_PORT, j);
2088 			}
2089 		} else {
2090 			if (eventdev_var[i].num_ports > 0)
2091 				++count;
2092 			for (j = 0; j < eventdev_var[i].num_ports; j++) {
2093 				xstats_display(i, RTE_EVENT_DEV_XSTATS_PORT,
2094 					eventdev_var[i].ports[j]);
2095 
2096 				if (eventdev_var[i].reset_xstats == 1)
2097 					xstats_reset(i, RTE_EVENT_DEV_XSTATS_PORT,
2098 							eventdev_var[i].ports[j]);
2099 			}
2100 		}
2101 
2102 		if (eventdev_var[i].shw_all_queues == 1) {
2103 			++count;
2104 			for (j = 0; j < MAX_PORTS_QUEUES; j++) {
2105 				xstats_display(i, RTE_EVENT_DEV_XSTATS_QUEUE, j);
2106 
2107 				if (eventdev_var[i].reset_xstats == 1)
2108 					xstats_reset(i, RTE_EVENT_DEV_XSTATS_QUEUE, j);
2109 			}
2110 		} else {
2111 			if (eventdev_var[i].num_queues > 0)
2112 				++count;
2113 			for (j = 0; j < eventdev_var[i].num_queues; j++) {
2114 				xstats_display(i, RTE_EVENT_DEV_XSTATS_QUEUE,
2115 						eventdev_var[i].queues[j]);
2116 
2117 				if (eventdev_var[i].reset_xstats == 1)
2118 					xstats_reset(i, RTE_EVENT_DEV_XSTATS_QUEUE,
2119 							eventdev_var[i].queues[j]);
2120 			}
2121 		}
2122 	}
2123 
2124 	return count;
2125 }
2126 
2127 int
2128 main(int argc, char **argv)
2129 {
2130 	int ret;
2131 	int i;
2132 	char c_flag[] = "-c1";
2133 	char n_flag[] = "-n4";
2134 	char mp_flag[] = "--proc-type=secondary";
2135 	char log_flag[] = "--log-level=6";
2136 	char *argp[argc + 4];
2137 	uint16_t nb_ports;
2138 
2139 	/* preparse app arguments */
2140 	ret = proc_info_preparse_args(argc, argv);
2141 	if (ret < 0) {
2142 		printf("Failed to parse arguments\n");
2143 		return -1;
2144 	}
2145 
2146 	argp[0] = argv[0];
2147 	argp[1] = c_flag;
2148 	argp[2] = n_flag;
2149 	argp[3] = mp_flag;
2150 	argp[4] = log_flag;
2151 
2152 	for (i = 1; i < argc; i++)
2153 		argp[i + 4] = argv[i];
2154 
2155 	argc += 4;
2156 
2157 	ret = rte_eal_init(argc, argp);
2158 	if (ret < 0)
2159 		rte_panic("Cannot init EAL\n");
2160 
2161 	argc -= ret;
2162 	argv += ret - 4;
2163 
2164 	if (!rte_eal_primary_proc_alive(NULL))
2165 		rte_exit(EXIT_FAILURE, "No primary DPDK process is running.\n");
2166 
2167 	/* parse app arguments */
2168 	ret = proc_info_parse_args(argc, argv);
2169 	if (ret < 0)
2170 		rte_exit(EXIT_FAILURE, "Invalid argument\n");
2171 
2172 	if (mem_info) {
2173 		meminfo_display();
2174 		goto cleanup;
2175 	}
2176 
2177 	if (eventdev_xstats() > 0)
2178 		goto cleanup;
2179 
2180 	nb_ports = rte_eth_dev_count_avail();
2181 	if (nb_ports == 0)
2182 		rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
2183 
2184 	/* If no port mask was specified, then show all non-owned ports */
2185 	if (enabled_port_mask == 0) {
2186 		RTE_ETH_FOREACH_DEV(i)
2187 			enabled_port_mask |= 1ul << i;
2188 	}
2189 
2190 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
2191 
2192 		/* Skip if port is not in mask */
2193 		if ((enabled_port_mask & (1ul << i)) == 0)
2194 			continue;
2195 
2196 		/* Skip if port is unused */
2197 		if (!rte_eth_dev_is_valid_port(i))
2198 			continue;
2199 
2200 		if (enable_stats)
2201 			nic_stats_display(i);
2202 		else if (enable_xstats)
2203 			nic_xstats_display(i);
2204 		else if (reset_stats)
2205 			nic_stats_clear(i);
2206 		else if (reset_xstats)
2207 			nic_xstats_clear(i);
2208 		else if (enable_xstats_name)
2209 			nic_xstats_by_name_display(i, xstats_name);
2210 		else if (nb_xstats_ids > 0)
2211 			nic_xstats_by_ids_display(i, xstats_ids,
2212 						  nb_xstats_ids);
2213 #ifdef RTE_LIB_METRICS
2214 		else if (enable_metrics)
2215 			metrics_display(i);
2216 #endif
2217 
2218 		if (enable_shw_rx_desc_dump)
2219 			nic_rx_descriptor_display(i, &rx_desc_param);
2220 		if (enable_shw_tx_desc_dump)
2221 			nic_tx_descriptor_display(i, &tx_desc_param);
2222 	}
2223 
2224 #ifdef RTE_LIB_METRICS
2225 	/* print port independent stats */
2226 	if (enable_metrics)
2227 		metrics_display(RTE_METRICS_GLOBAL);
2228 #endif
2229 
2230 	/* show information for PMD */
2231 	if (enable_shw_port)
2232 		show_port();
2233 	if (enable_shw_port_priv)
2234 		show_port_private_info();
2235 	if (enable_shw_tm)
2236 		show_tm();
2237 	if (enable_shw_crypto)
2238 		show_crypto();
2239 	if (enable_shw_ring)
2240 		show_ring(ring_name);
2241 	if (enable_shw_mempool)
2242 		show_mempool(mempool_name);
2243 	if (enable_iter_mempool)
2244 		iter_mempool(mempool_iter_name);
2245 	if (enable_dump_regs)
2246 		dump_regs(dump_regs_file_prefix);
2247 	if (enable_shw_version)
2248 		show_version();
2249 	if (enable_shw_fw_version)
2250 		show_firmware_version();
2251 	if (enable_shw_rss_reta)
2252 		show_port_rss_reta_info();
2253 	if (enable_shw_module_eeprom)
2254 		show_module_eeprom_info();
2255 
2256 	RTE_ETH_FOREACH_DEV(i)
2257 		rte_eth_dev_close(i);
2258 
2259 cleanup:
2260 	ret = rte_eal_cleanup();
2261 	if (ret)
2262 		printf("Error from rte_eal_cleanup(), %d\n", ret);
2263 
2264 	return 0;
2265 }
2266