cmdline.c revision ce3d555e
1/*-
2 *   BSD LICENSE
3 *
4 *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5 *   Copyright(c) 2014 6WIND S.A.
6 *   All rights reserved.
7 *
8 *   Redistribution and use in source and binary forms, with or without
9 *   modification, are permitted provided that the following conditions
10 *   are met:
11 *
12 *     * Redistributions of source code must retain the above copyright
13 *       notice, this list of conditions and the following disclaimer.
14 *     * Redistributions in binary form must reproduce the above copyright
15 *       notice, this list of conditions and the following disclaimer in
16 *       the documentation and/or other materials provided with the
17 *       distribution.
18 *     * Neither the name of Intel Corporation nor the names of its
19 *       contributors may be used to endorse or promote products derived
20 *       from this software without specific prior written permission.
21 *
22 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <stdarg.h>
36#include <errno.h>
37#include <stdio.h>
38#include <stdint.h>
39#include <stdarg.h>
40#include <string.h>
41#include <termios.h>
42#include <unistd.h>
43#include <inttypes.h>
44#ifndef __linux__
45#ifndef __FreeBSD__
46#include <net/socket.h>
47#else
48#include <sys/socket.h>
49#endif
50#endif
51#include <netinet/in.h>
52
53#include <sys/queue.h>
54
55#include <rte_common.h>
56#include <rte_byteorder.h>
57#include <rte_log.h>
58#include <rte_debug.h>
59#include <rte_cycles.h>
60#include <rte_memory.h>
61#include <rte_memzone.h>
62#include <rte_malloc.h>
63#include <rte_launch.h>
64#include <rte_eal.h>
65#include <rte_per_lcore.h>
66#include <rte_lcore.h>
67#include <rte_atomic.h>
68#include <rte_branch_prediction.h>
69#include <rte_ring.h>
70#include <rte_mempool.h>
71#include <rte_interrupts.h>
72#include <rte_pci.h>
73#include <rte_ether.h>
74#include <rte_ethdev.h>
75#include <rte_string_fns.h>
76#include <rte_devargs.h>
77#include <rte_eth_ctrl.h>
78
79#include <cmdline_rdline.h>
80#include <cmdline_parse.h>
81#include <cmdline_parse_num.h>
82#include <cmdline_parse_string.h>
83#include <cmdline_parse_ipaddr.h>
84#include <cmdline_parse_etheraddr.h>
85#include <cmdline_socket.h>
86#include <cmdline.h>
87#ifdef RTE_LIBRTE_PMD_BOND
88#include <rte_eth_bond.h>
89#endif
90#ifdef RTE_LIBRTE_IXGBE_PMD
91#include <rte_pmd_ixgbe.h>
92#endif
93#include "testpmd.h"
94
95static struct cmdline *testpmd_cl;
96
97static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue);
98
99/* *** Help command with introduction. *** */
100struct cmd_help_brief_result {
101	cmdline_fixed_string_t help;
102};
103
104static void cmd_help_brief_parsed(__attribute__((unused)) void *parsed_result,
105                                  struct cmdline *cl,
106                                  __attribute__((unused)) void *data)
107{
108	cmdline_printf(
109		cl,
110		"\n"
111		"Help is available for the following sections:\n\n"
112		"    help control    : Start and stop forwarding.\n"
113		"    help display    : Displaying port, stats and config "
114		"information.\n"
115		"    help config     : Configuration information.\n"
116		"    help ports      : Configuring ports.\n"
117		"    help registers  : Reading and setting port registers.\n"
118		"    help filters    : Filters configuration help.\n"
119		"    help all        : All of the above sections.\n\n"
120	);
121
122}
123
124cmdline_parse_token_string_t cmd_help_brief_help =
125	TOKEN_STRING_INITIALIZER(struct cmd_help_brief_result, help, "help");
126
127cmdline_parse_inst_t cmd_help_brief = {
128	.f = cmd_help_brief_parsed,
129	.data = NULL,
130	.help_str = "show help",
131	.tokens = {
132		(void *)&cmd_help_brief_help,
133		NULL,
134	},
135};
136
137/* *** Help command with help sections. *** */
138struct cmd_help_long_result {
139	cmdline_fixed_string_t help;
140	cmdline_fixed_string_t section;
141};
142
143static void cmd_help_long_parsed(void *parsed_result,
144                                 struct cmdline *cl,
145                                 __attribute__((unused)) void *data)
146{
147	int show_all = 0;
148	struct cmd_help_long_result *res = parsed_result;
149
150	if (!strcmp(res->section, "all"))
151		show_all = 1;
152
153	if (show_all || !strcmp(res->section, "control")) {
154
155		cmdline_printf(
156			cl,
157			"\n"
158			"Control forwarding:\n"
159			"-------------------\n\n"
160
161			"start\n"
162			"    Start packet forwarding with current configuration.\n\n"
163
164			"start tx_first\n"
165			"    Start packet forwarding with current config"
166			" after sending one burst of packets.\n\n"
167
168			"stop\n"
169			"    Stop packet forwarding, and display accumulated"
170			" statistics.\n\n"
171
172			"quit\n"
173			"    Quit to prompt.\n\n"
174		);
175	}
176
177	if (show_all || !strcmp(res->section, "display")) {
178
179		cmdline_printf(
180			cl,
181			"\n"
182			"Display:\n"
183			"--------\n\n"
184
185			"show port (info|stats|xstats|fdir|stat_qmap|dcb_tc) (port_id|all)\n"
186			"    Display information for port_id, or all.\n\n"
187
188			"show port X rss reta (size) (mask0,mask1,...)\n"
189			"    Display the rss redirection table entry indicated"
190			" by masks on port X. size is used to indicate the"
191			" hardware supported reta size\n\n"
192
193			"show port rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
194			"ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|"
195			"ipv6-other|l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex [key]\n"
196			"    Display the RSS hash functions and RSS hash key"
197			" of port X\n\n"
198
199			"clear port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\n"
200			"    Clear information for port_id, or all.\n\n"
201
202			"show (rxq|txq) info (port_id) (queue_id)\n"
203			"    Display information for configured RX/TX queue.\n\n"
204
205			"show config (rxtx|cores|fwd|txpkts)\n"
206			"    Display the given configuration.\n\n"
207
208			"read rxd (port_id) (queue_id) (rxd_id)\n"
209			"    Display an RX descriptor of a port RX queue.\n\n"
210
211			"read txd (port_id) (queue_id) (txd_id)\n"
212			"    Display a TX descriptor of a port TX queue.\n\n"
213		);
214	}
215
216	if (show_all || !strcmp(res->section, "config")) {
217		cmdline_printf(
218			cl,
219			"\n"
220			"Configuration:\n"
221			"--------------\n"
222			"Configuration changes only become active when"
223			" forwarding is started/restarted.\n\n"
224
225			"set default\n"
226			"    Reset forwarding to the default configuration.\n\n"
227
228			"set verbose (level)\n"
229			"    Set the debug verbosity level X.\n\n"
230
231			"set nbport (num)\n"
232			"    Set number of ports.\n\n"
233
234			"set nbcore (num)\n"
235			"    Set number of cores.\n\n"
236
237			"set coremask (mask)\n"
238			"    Set the forwarding cores hexadecimal mask.\n\n"
239
240			"set portmask (mask)\n"
241			"    Set the forwarding ports hexadecimal mask.\n\n"
242
243			"set burst (num)\n"
244			"    Set number of packets per burst.\n\n"
245
246			"set burst tx delay (microseconds) retry (num)\n"
247			"    Set the transmit delay time and number of retries,"
248			" effective when retry is enabled.\n\n"
249
250			"set txpkts (x[,y]*)\n"
251			"    Set the length of each segment of TXONLY"
252			" and optionally CSUM packets.\n\n"
253
254			"set txsplit (off|on|rand)\n"
255			"    Set the split policy for the TX packets."
256			" Right now only applicable for CSUM and TXONLY"
257			" modes\n\n"
258
259			"set corelist (x[,y]*)\n"
260			"    Set the list of forwarding cores.\n\n"
261
262			"set portlist (x[,y]*)\n"
263			"    Set the list of forwarding ports.\n\n"
264
265#ifdef RTE_LIBRTE_IXGBE_PMD
266			"set tx loopback (port_id) (on|off)\n"
267			"    Enable or disable tx loopback.\n\n"
268
269			"set all queues drop (port_id) (on|off)\n"
270			"    Set drop enable bit for all queues.\n\n"
271
272			"set vf split drop (port_id) (vf_id) (on|off)\n"
273			"    Set split drop enable bit for a VF from the PF.\n\n"
274
275			"set vf mac antispoof (port_id) (vf_id) (on|off).\n"
276			"    Set MAC antispoof for a VF from the PF.\n\n"
277#endif
278
279			"vlan set strip (on|off) (port_id)\n"
280			"    Set the VLAN strip on a port.\n\n"
281
282			"vlan set stripq (on|off) (port_id,queue_id)\n"
283			"    Set the VLAN strip for a queue on a port.\n\n"
284
285#ifdef RTE_LIBRTE_IXGBE_PMD
286			"set vf vlan stripq (port_id) (vf_id) (on|off)\n"
287			"    Set the VLAN strip for all queues in a pool for a VF from the PF.\n\n"
288
289			"set vf vlan insert (port_id) (vf_id) (vlan_id)\n"
290			"    Set VLAN insert for a VF from the PF.\n\n"
291
292			"set vf vlan antispoof (port_id) (vf_id) (on|off)\n"
293			"    Set VLAN antispoof for a VF from the PF.\n\n"
294#endif
295
296			"vlan set filter (on|off) (port_id)\n"
297			"    Set the VLAN filter on a port.\n\n"
298
299			"vlan set qinq (on|off) (port_id)\n"
300			"    Set the VLAN QinQ (extended queue in queue)"
301			" on a port.\n\n"
302
303			"vlan set (inner|outer) tpid (value) (port_id)\n"
304			"    Set the VLAN TPID for Packet Filtering on"
305			" a port\n\n"
306
307			"rx_vlan add (vlan_id|all) (port_id)\n"
308			"    Add a vlan_id, or all identifiers, to the set"
309			" of VLAN identifiers filtered by port_id.\n\n"
310
311			"rx_vlan rm (vlan_id|all) (port_id)\n"
312			"    Remove a vlan_id, or all identifiers, from the set"
313			" of VLAN identifiers filtered by port_id.\n\n"
314
315			"rx_vlan add (vlan_id) port (port_id) vf (vf_mask)\n"
316			"    Add a vlan_id, to the set of VLAN identifiers"
317			"filtered for VF(s) from port_id.\n\n"
318
319			"rx_vlan rm (vlan_id) port (port_id) vf (vf_mask)\n"
320			"    Remove a vlan_id, to the set of VLAN identifiers"
321			"filtered for VF(s) from port_id.\n\n"
322
323			"tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
324			"(inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|"
325			"imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)\n"
326			"   add a tunnel filter of a port.\n\n"
327
328			"tunnel_filter rm (port_id) (outer_mac) (inner_mac) (ip_addr) "
329			"(inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|"
330			"imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)\n"
331			"   remove a tunnel filter of a port.\n\n"
332
333			"rx_vxlan_port add (udp_port) (port_id)\n"
334			"    Add an UDP port for VXLAN packet filter on a port\n\n"
335
336			"rx_vxlan_port rm (udp_port) (port_id)\n"
337			"    Remove an UDP port for VXLAN packet filter on a port\n\n"
338
339			"tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n"
340			"    Set hardware insertion of VLAN IDs (single or double VLAN "
341			"depends on the number of VLAN IDs) in packets sent on a port.\n\n"
342
343			"tx_vlan set pvid port_id vlan_id (on|off)\n"
344			"    Set port based TX VLAN insertion.\n\n"
345
346			"tx_vlan reset (port_id)\n"
347			"    Disable hardware insertion of a VLAN header in"
348			" packets sent on a port.\n\n"
349
350			"csum set (ip|udp|tcp|sctp|outer-ip) (hw|sw) (port_id)\n"
351			"    Select hardware or software calculation of the"
352			" checksum when transmitting a packet using the"
353			" csum forward engine.\n"
354			"    ip|udp|tcp|sctp always concern the inner layer.\n"
355			"    outer-ip concerns the outer IP layer in"
356			" case the packet is recognized as a tunnel packet by"
357			" the forward engine (vxlan, gre and ipip are supported)\n"
358			"    Please check the NIC datasheet for HW limits.\n\n"
359
360			"csum parse-tunnel (on|off) (tx_port_id)\n"
361			"    If disabled, treat tunnel packets as non-tunneled"
362			" packets (treat inner headers as payload). The port\n"
363			"    argument is the port used for TX in csum forward"
364			" engine.\n\n"
365
366			"csum show (port_id)\n"
367			"    Display tx checksum offload configuration\n\n"
368
369			"tso set (segsize) (portid)\n"
370			"    Enable TCP Segmentation Offload in csum forward"
371			" engine.\n"
372			"    Please check the NIC datasheet for HW limits.\n\n"
373
374			"tso show (portid)"
375			"    Display the status of TCP Segmentation Offload.\n\n"
376
377			"set fwd (%s)\n"
378			"    Set packet forwarding mode.\n\n"
379
380			"mac_addr add (port_id) (XX:XX:XX:XX:XX:XX)\n"
381			"    Add a MAC address on port_id.\n\n"
382
383			"mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)\n"
384			"    Remove a MAC address from port_id.\n\n"
385
386			"mac_addr add port (port_id) vf (vf_id) (mac_address)\n"
387			"    Add a MAC address for a VF on the port.\n\n"
388
389#ifdef RTE_LIBRTE_IXGBE_PMD
390			"set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)\n"
391			"    Set the MAC address for a VF from the PF.\n\n"
392#endif
393
394			"set port (port_id) uta (mac_address|all) (on|off)\n"
395			"    Add/Remove a or all unicast hash filter(s)"
396			"from port X.\n\n"
397
398			"set promisc (port_id|all) (on|off)\n"
399			"    Set the promiscuous mode on port_id, or all.\n\n"
400
401			"set allmulti (port_id|all) (on|off)\n"
402			"    Set the allmulti mode on port_id, or all.\n\n"
403
404			"set flow_ctrl rx (on|off) tx (on|off) (high_water)"
405			" (low_water) (pause_time) (send_xon) mac_ctrl_frame_fwd"
406			" (on|off) autoneg (on|off) (port_id)\n"
407			"set flow_ctrl rx (on|off) (portid)\n"
408			"set flow_ctrl tx (on|off) (portid)\n"
409			"set flow_ctrl high_water (high_water) (portid)\n"
410			"set flow_ctrl low_water (low_water) (portid)\n"
411			"set flow_ctrl pause_time (pause_time) (portid)\n"
412			"set flow_ctrl send_xon (send_xon) (portid)\n"
413			"set flow_ctrl mac_ctrl_frame_fwd (on|off) (portid)\n"
414			"set flow_ctrl autoneg (on|off) (port_id)\n"
415			"    Set the link flow control parameter on a port.\n\n"
416
417			"set pfc_ctrl rx (on|off) tx (on|off) (high_water)"
418			" (low_water) (pause_time) (priority) (port_id)\n"
419			"    Set the priority flow control parameter on a"
420			" port.\n\n"
421
422			"set stat_qmap (tx|rx) (port_id) (queue_id) (qmapping)\n"
423			"    Set statistics mapping (qmapping 0..15) for RX/TX"
424			" queue on port.\n"
425			"    e.g., 'set stat_qmap rx 0 2 5' sets rx queue 2"
426			" on port 0 to mapping 5.\n\n"
427
428			"set port (port_id) vf (vf_id) rx|tx on|off\n"
429			"    Enable/Disable a VF receive/tranmit from a port\n\n"
430
431			"set port (port_id) vf (vf_id) (mac_addr)"
432			" (exact-mac#exact-mac-vlan#hashmac|hashmac-vlan) on|off\n"
433			"   Add/Remove unicast or multicast MAC addr filter"
434			" for a VF.\n\n"
435
436			"set port (port_id) vf (vf_id) rxmode (AUPE|ROPE|BAM"
437			"|MPE) (on|off)\n"
438			"    AUPE:accepts untagged VLAN;"
439			"ROPE:accept unicast hash\n\n"
440			"    BAM:accepts broadcast packets;"
441			"MPE:accepts all multicast packets\n\n"
442			"    Enable/Disable a VF receive mode of a port\n\n"
443
444			"set port (port_id) queue (queue_id) rate (rate_num)\n"
445			"    Set rate limit for a queue of a port\n\n"
446
447			"set port (port_id) vf (vf_id) rate (rate_num) "
448			"queue_mask (queue_mask_value)\n"
449			"    Set rate limit for queues in VF of a port\n\n"
450
451			"set port (port_id) mirror-rule (rule_id)"
452			" (pool-mirror-up|pool-mirror-down|vlan-mirror)"
453			" (poolmask|vlanid[,vlanid]*) dst-pool (pool_id) (on|off)\n"
454			"   Set pool or vlan type mirror rule on a port.\n"
455			"   e.g., 'set port 0 mirror-rule 0 vlan-mirror 0,1"
456			" dst-pool 0 on' enable mirror traffic with vlan 0,1"
457			" to pool 0.\n\n"
458
459			"set port (port_id) mirror-rule (rule_id)"
460			" (uplink-mirror|downlink-mirror) dst-pool"
461			" (pool_id) (on|off)\n"
462			"   Set uplink or downlink type mirror rule on a port.\n"
463			"   e.g., 'set port 0 mirror-rule 0 uplink-mirror dst-pool"
464			" 0 on' enable mirror income traffic to pool 0.\n\n"
465
466			"reset port (port_id) mirror-rule (rule_id)\n"
467			"   Reset a mirror rule.\n\n"
468
469			"set flush_rx (on|off)\n"
470			"   Flush (default) or don't flush RX streams before"
471			" forwarding. Mainly used with PCAP drivers.\n\n"
472
473			#ifdef RTE_NIC_BYPASS
474			"set bypass mode (normal|bypass|isolate) (port_id)\n"
475			"   Set the bypass mode for the lowest port on bypass enabled"
476			" NIC.\n\n"
477
478			"set bypass event (timeout|os_on|os_off|power_on|power_off) "
479			"mode (normal|bypass|isolate) (port_id)\n"
480			"   Set the event required to initiate specified bypass mode for"
481			" the lowest port on a bypass enabled NIC where:\n"
482			"       timeout   = enable bypass after watchdog timeout.\n"
483			"       os_on     = enable bypass when OS/board is powered on.\n"
484			"       os_off    = enable bypass when OS/board is powered off.\n"
485			"       power_on  = enable bypass when power supply is turned on.\n"
486			"       power_off = enable bypass when power supply is turned off."
487			"\n\n"
488
489			"set bypass timeout (0|1.5|2|3|4|8|16|32)\n"
490			"   Set the bypass watchdog timeout to 'n' seconds"
491			" where 0 = instant.\n\n"
492
493			"show bypass config (port_id)\n"
494			"   Show the bypass configuration for a bypass enabled NIC"
495			" using the lowest port on the NIC.\n\n"
496#endif
497#ifdef RTE_LIBRTE_PMD_BOND
498			"create bonded device (mode) (socket)\n"
499			"	Create a new bonded device with specific bonding mode and socket.\n\n"
500
501			"add bonding slave (slave_id) (port_id)\n"
502			"	Add a slave device to a bonded device.\n\n"
503
504			"remove bonding slave (slave_id) (port_id)\n"
505			"	Remove a slave device from a bonded device.\n\n"
506
507			"set bonding mode (value) (port_id)\n"
508			"	Set the bonding mode on a bonded device.\n\n"
509
510			"set bonding primary (slave_id) (port_id)\n"
511			"	Set the primary slave for a bonded device.\n\n"
512
513			"show bonding config (port_id)\n"
514			"	Show the bonding config for port_id.\n\n"
515
516			"set bonding mac_addr (port_id) (address)\n"
517			"	Set the MAC address of a bonded device.\n\n"
518
519			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
520			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
521
522			"set bonding mon_period (port_id) (value)\n"
523			"	Set the bonding link status monitoring polling period in ms.\n\n"
524#endif
525			"set link-up port (port_id)\n"
526			"	Set link up for a port.\n\n"
527
528			"set link-down port (port_id)\n"
529			"	Set link down for a port.\n\n"
530
531			"E-tag set insertion on port-tag-id (value)"
532			" port (port_id) vf (vf_id)\n"
533			"    Enable E-tag insertion for a VF on a port\n\n"
534
535			"E-tag set insertion off port (port_id) vf (vf_id)\n"
536			"    Disable E-tag insertion for a VF on a port\n\n"
537
538			"E-tag set stripping (on|off) port (port_id)\n"
539			"    Enable/disable E-tag stripping on a port\n\n"
540
541			"E-tag set forwarding (on|off) port (port_id)\n"
542			"    Enable/disable E-tag based forwarding"
543			" on a port\n\n"
544
545			"E-tag set filter add e-tag-id (value) dst-pool"
546			" (pool_id) port (port_id)\n"
547			"    Add an E-tag forwarding filter on a port\n\n"
548
549			"E-tag set filter del e-tag-id (value) port (port_id)\n"
550			"    Delete an E-tag forwarding filter on a port\n\n"
551
552			, list_pkt_forwarding_modes()
553		);
554	}
555
556	if (show_all || !strcmp(res->section, "ports")) {
557
558		cmdline_printf(
559			cl,
560			"\n"
561			"Port Operations:\n"
562			"----------------\n\n"
563
564			"port start (port_id|all)\n"
565			"    Start all ports or port_id.\n\n"
566
567			"port stop (port_id|all)\n"
568			"    Stop all ports or port_id.\n\n"
569
570			"port close (port_id|all)\n"
571			"    Close all ports or port_id.\n\n"
572
573			"port attach (ident)\n"
574			"    Attach physical or virtual dev by pci address or virtual device name\n\n"
575
576			"port detach (port_id)\n"
577			"    Detach physical or virtual dev by port_id\n\n"
578
579			"port config (port_id|all)"
580			" speed (10|100|1000|10000|25000|40000|50000|100000|auto)"
581			" duplex (half|full|auto)\n"
582			"    Set speed and duplex for all ports or port_id\n\n"
583
584			"port config all (rxq|txq|rxd|txd) (value)\n"
585			"    Set number for rxq/txq/rxd/txd.\n\n"
586
587			"port config all max-pkt-len (value)\n"
588			"    Set the max packet length.\n\n"
589
590			"port config all (crc-strip|scatter|rx-cksum|hw-vlan|hw-vlan-filter|"
591			"hw-vlan-strip|hw-vlan-extend|drop-en)"
592			" (on|off)\n"
593			"    Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en"
594			" for ports.\n\n"
595
596			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
597			"    Set the RSS mode.\n\n"
598
599			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
600			"    Set the RSS redirection table.\n\n"
601
602			"port config (port_id) dcb vt (on|off) (traffic_class)"
603			" pfc (on|off)\n"
604			"    Set the DCB mode.\n\n"
605
606			"port config all burst (value)\n"
607			"    Set the number of packets per burst.\n\n"
608
609			"port config all (txpt|txht|txwt|rxpt|rxht|rxwt)"
610			" (value)\n"
611			"    Set the ring prefetch/host/writeback threshold"
612			" for tx/rx queue.\n\n"
613
614			"port config all (txfreet|txrst|rxfreet) (value)\n"
615			"    Set free threshold for rx/tx, or set"
616			" tx rs bit threshold.\n\n"
617			"port config mtu X value\n"
618			"    Set the MTU of port X to a given value\n\n"
619
620			"port (port_id) (rxq|txq) (queue_id) (start|stop)\n"
621			"    Start/stop a rx/tx queue of port X. Only take effect"
622			" when port X is started\n\n"
623
624			"port config (port_id|all) l2-tunnel E-tag ether-type"
625			" (value)\n"
626			"    Set the value of E-tag ether-type.\n\n"
627
628			"port config (port_id|all) l2-tunnel E-tag"
629			" (enable|disable)\n"
630			"    Enable/disable the E-tag support.\n\n"
631		);
632	}
633
634	if (show_all || !strcmp(res->section, "registers")) {
635
636		cmdline_printf(
637			cl,
638			"\n"
639			"Registers:\n"
640			"----------\n\n"
641
642			"read reg (port_id) (address)\n"
643			"    Display value of a port register.\n\n"
644
645			"read regfield (port_id) (address) (bit_x) (bit_y)\n"
646			"    Display a port register bit field.\n\n"
647
648			"read regbit (port_id) (address) (bit_x)\n"
649			"    Display a single port register bit.\n\n"
650
651			"write reg (port_id) (address) (value)\n"
652			"    Set value of a port register.\n\n"
653
654			"write regfield (port_id) (address) (bit_x) (bit_y)"
655			" (value)\n"
656			"    Set bit field of a port register.\n\n"
657
658			"write regbit (port_id) (address) (bit_x) (value)\n"
659			"    Set single bit value of a port register.\n\n"
660		);
661	}
662	if (show_all || !strcmp(res->section, "filters")) {
663
664		cmdline_printf(
665			cl,
666			"\n"
667			"filters:\n"
668			"--------\n\n"
669
670			"ethertype_filter (port_id) (add|del)"
671			" (mac_addr|mac_ignr) (mac_address) ethertype"
672			" (ether_type) (drop|fwd) queue (queue_id)\n"
673			"    Add/Del an ethertype filter.\n\n"
674
675			"2tuple_filter (port_id) (add|del)"
676			" dst_port (dst_port_value) protocol (protocol_value)"
677			" mask (mask_value) tcp_flags (tcp_flags_value)"
678			" priority (prio_value) queue (queue_id)\n"
679			"    Add/Del a 2tuple filter.\n\n"
680
681			"5tuple_filter (port_id) (add|del)"
682			" dst_ip (dst_address) src_ip (src_address)"
683			" dst_port (dst_port_value) src_port (src_port_value)"
684			" protocol (protocol_value)"
685			" mask (mask_value) tcp_flags (tcp_flags_value)"
686			" priority (prio_value) queue (queue_id)\n"
687			"    Add/Del a 5tuple filter.\n\n"
688
689			"syn_filter (port_id) (add|del) priority (high|low) queue (queue_id)"
690			"    Add/Del syn filter.\n\n"
691
692			"flex_filter (port_id) (add|del) len (len_value)"
693			" bytes (bytes_value) mask (mask_value)"
694			" priority (prio_value) queue (queue_id)\n"
695			"    Add/Del a flex filter.\n\n"
696
697			"flow_director_filter (port_id) mode IP (add|del|update)"
698			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
699			" src (src_ip_address) dst (dst_ip_address)"
700			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
701			" vlan (vlan_value) flexbytes (flexbytes_value)"
702			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
703			" fd_id (fd_id_value)\n"
704			"    Add/Del an IP type flow director filter.\n\n"
705
706			"flow_director_filter (port_id) mode IP (add|del|update)"
707			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
708			" src (src_ip_address) (src_port)"
709			" dst (dst_ip_address) (dst_port)"
710			" tos (tos_value) ttl (ttl_value)"
711			" vlan (vlan_value) flexbytes (flexbytes_value)"
712			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
713			" fd_id (fd_id_value)\n"
714			"    Add/Del an UDP/TCP type flow director filter.\n\n"
715
716			"flow_director_filter (port_id) mode IP (add|del|update)"
717			" flow (ipv4-sctp|ipv6-sctp)"
718			" src (src_ip_address) (src_port)"
719			" dst (dst_ip_address) (dst_port)"
720			" tag (verification_tag) "
721			" tos (tos_value) ttl (ttl_value)"
722			" vlan (vlan_value)"
723			" flexbytes (flexbytes_value) (drop|fwd)"
724			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
725			"    Add/Del a SCTP type flow director filter.\n\n"
726
727			"flow_director_filter (port_id) mode IP (add|del|update)"
728			" flow l2_payload ether (ethertype)"
729			" flexbytes (flexbytes_value) (drop|fwd)"
730			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
731			"    Add/Del a l2 payload type flow director filter.\n\n"
732
733			"flow_director_filter (port_id) mode MAC-VLAN (add|del|update)"
734			" mac (mac_address) vlan (vlan_value)"
735			" flexbytes (flexbytes_value) (drop|fwd)"
736			" queue (queue_id) fd_id (fd_id_value)\n"
737			"    Add/Del a MAC-VLAN flow director filter.\n\n"
738
739			"flow_director_filter (port_id) mode Tunnel (add|del|update)"
740			" mac (mac_address) vlan (vlan_value)"
741			" tunnel (NVGRE|VxLAN) tunnel-id (tunnel_id_value)"
742			" flexbytes (flexbytes_value) (drop|fwd)"
743			" queue (queue_id) fd_id (fd_id_value)\n"
744			"    Add/Del a Tunnel flow director filter.\n\n"
745
746			"flush_flow_director (port_id)\n"
747			"    Flush all flow director entries of a device.\n\n"
748
749			"flow_director_mask (port_id) mode IP vlan (vlan_value)"
750			" src_mask (ipv4_src) (ipv6_src) (src_port)"
751			" dst_mask (ipv4_dst) (ipv6_dst) (dst_port)\n"
752			"    Set flow director IP mask.\n\n"
753
754			"flow_director_mask (port_id) mode MAC-VLAN"
755			" vlan (vlan_value)\n"
756			"    Set flow director MAC-VLAN mask.\n\n"
757
758			"flow_director_mask (port_id) mode Tunnel"
759			" vlan (vlan_value) mac (mac_value)"
760			" tunnel-type (tunnel_type_value)"
761			" tunnel-id (tunnel_id_value)\n"
762			"    Set flow director Tunnel mask.\n\n"
763
764			"flow_director_flex_mask (port_id)"
765			" flow (none|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|"
766			"ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|l2_payload|all)"
767			" (mask)\n"
768			"    Configure mask of flex payload.\n\n"
769
770			"flow_director_flex_payload (port_id)"
771			" (raw|l2|l3|l4) (config)\n"
772			"    Configure flex payload selection.\n\n"
773
774			"get_sym_hash_ena_per_port (port_id)\n"
775			"    get symmetric hash enable configuration per port.\n\n"
776
777			"set_sym_hash_ena_per_port (port_id) (enable|disable)\n"
778			"    set symmetric hash enable configuration per port"
779			" to enable or disable.\n\n"
780
781			"get_hash_global_config (port_id)\n"
782			"    Get the global configurations of hash filters.\n\n"
783
784			"set_hash_global_config (port_id) (toeplitz|simple_xor|default)"
785			" (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
786			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)"
787			" (enable|disable)\n"
788			"    Set the global configurations of hash filters.\n\n"
789
790			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
791			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
792			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
793			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
794			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
795			"ipv6-next-header|udp-src-port|udp-dst-port|"
796			"tcp-src-port|tcp-dst-port|sctp-src-port|"
797			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
798			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
799			"fld-8th|none) (select|add)\n"
800			"    Set the input set for hash.\n\n"
801
802			"set_fdir_input_set (port_id) "
803			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
804			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
805			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
806			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
807			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
808			"udp-dst-port|tcp-src-port|tcp-dst-port|"
809			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
810			" (select|add)\n"
811			"    Set the input set for FDir.\n\n"
812		);
813	}
814}
815
816cmdline_parse_token_string_t cmd_help_long_help =
817	TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, help, "help");
818
819cmdline_parse_token_string_t cmd_help_long_section =
820	TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, section,
821			"all#control#display#config#"
822			"ports#registers#filters");
823
824cmdline_parse_inst_t cmd_help_long = {
825	.f = cmd_help_long_parsed,
826	.data = NULL,
827	.help_str = "show help",
828	.tokens = {
829		(void *)&cmd_help_long_help,
830		(void *)&cmd_help_long_section,
831		NULL,
832	},
833};
834
835
836/* *** start/stop/close all ports *** */
837struct cmd_operate_port_result {
838	cmdline_fixed_string_t keyword;
839	cmdline_fixed_string_t name;
840	cmdline_fixed_string_t value;
841};
842
843static void cmd_operate_port_parsed(void *parsed_result,
844				__attribute__((unused)) struct cmdline *cl,
845				__attribute__((unused)) void *data)
846{
847	struct cmd_operate_port_result *res = parsed_result;
848
849	if (!strcmp(res->name, "start"))
850		start_port(RTE_PORT_ALL);
851	else if (!strcmp(res->name, "stop"))
852		stop_port(RTE_PORT_ALL);
853	else if (!strcmp(res->name, "close"))
854		close_port(RTE_PORT_ALL);
855	else
856		printf("Unknown parameter\n");
857}
858
859cmdline_parse_token_string_t cmd_operate_port_all_cmd =
860	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, keyword,
861								"port");
862cmdline_parse_token_string_t cmd_operate_port_all_port =
863	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, name,
864						"start#stop#close");
865cmdline_parse_token_string_t cmd_operate_port_all_all =
866	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, value, "all");
867
868cmdline_parse_inst_t cmd_operate_port = {
869	.f = cmd_operate_port_parsed,
870	.data = NULL,
871	.help_str = "port start|stop|close all: start/stop/close all ports",
872	.tokens = {
873		(void *)&cmd_operate_port_all_cmd,
874		(void *)&cmd_operate_port_all_port,
875		(void *)&cmd_operate_port_all_all,
876		NULL,
877	},
878};
879
880/* *** start/stop/close specific port *** */
881struct cmd_operate_specific_port_result {
882	cmdline_fixed_string_t keyword;
883	cmdline_fixed_string_t name;
884	uint8_t value;
885};
886
887static void cmd_operate_specific_port_parsed(void *parsed_result,
888			__attribute__((unused)) struct cmdline *cl,
889				__attribute__((unused)) void *data)
890{
891	struct cmd_operate_specific_port_result *res = parsed_result;
892
893	if (!strcmp(res->name, "start"))
894		start_port(res->value);
895	else if (!strcmp(res->name, "stop"))
896		stop_port(res->value);
897	else if (!strcmp(res->name, "close"))
898		close_port(res->value);
899	else
900		printf("Unknown parameter\n");
901}
902
903cmdline_parse_token_string_t cmd_operate_specific_port_cmd =
904	TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
905							keyword, "port");
906cmdline_parse_token_string_t cmd_operate_specific_port_port =
907	TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
908						name, "start#stop#close");
909cmdline_parse_token_num_t cmd_operate_specific_port_id =
910	TOKEN_NUM_INITIALIZER(struct cmd_operate_specific_port_result,
911							value, UINT8);
912
913cmdline_parse_inst_t cmd_operate_specific_port = {
914	.f = cmd_operate_specific_port_parsed,
915	.data = NULL,
916	.help_str = "port start|stop|close X: start/stop/close port X",
917	.tokens = {
918		(void *)&cmd_operate_specific_port_cmd,
919		(void *)&cmd_operate_specific_port_port,
920		(void *)&cmd_operate_specific_port_id,
921		NULL,
922	},
923};
924
925/* *** attach a specified port *** */
926struct cmd_operate_attach_port_result {
927	cmdline_fixed_string_t port;
928	cmdline_fixed_string_t keyword;
929	cmdline_fixed_string_t identifier;
930};
931
932static void cmd_operate_attach_port_parsed(void *parsed_result,
933				__attribute__((unused)) struct cmdline *cl,
934				__attribute__((unused)) void *data)
935{
936	struct cmd_operate_attach_port_result *res = parsed_result;
937
938	if (!strcmp(res->keyword, "attach"))
939		attach_port(res->identifier);
940	else
941		printf("Unknown parameter\n");
942}
943
944cmdline_parse_token_string_t cmd_operate_attach_port_port =
945	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
946			port, "port");
947cmdline_parse_token_string_t cmd_operate_attach_port_keyword =
948	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
949			keyword, "attach");
950cmdline_parse_token_string_t cmd_operate_attach_port_identifier =
951	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
952			identifier, NULL);
953
954cmdline_parse_inst_t cmd_operate_attach_port = {
955	.f = cmd_operate_attach_port_parsed,
956	.data = NULL,
957	.help_str = "port attach identifier, "
958		"identifier: pci address or virtual dev name",
959	.tokens = {
960		(void *)&cmd_operate_attach_port_port,
961		(void *)&cmd_operate_attach_port_keyword,
962		(void *)&cmd_operate_attach_port_identifier,
963		NULL,
964	},
965};
966
967/* *** detach a specified port *** */
968struct cmd_operate_detach_port_result {
969	cmdline_fixed_string_t port;
970	cmdline_fixed_string_t keyword;
971	uint8_t port_id;
972};
973
974static void cmd_operate_detach_port_parsed(void *parsed_result,
975				__attribute__((unused)) struct cmdline *cl,
976				__attribute__((unused)) void *data)
977{
978	struct cmd_operate_detach_port_result *res = parsed_result;
979
980	if (!strcmp(res->keyword, "detach"))
981		detach_port(res->port_id);
982	else
983		printf("Unknown parameter\n");
984}
985
986cmdline_parse_token_string_t cmd_operate_detach_port_port =
987	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
988			port, "port");
989cmdline_parse_token_string_t cmd_operate_detach_port_keyword =
990	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
991			keyword, "detach");
992cmdline_parse_token_num_t cmd_operate_detach_port_port_id =
993	TOKEN_NUM_INITIALIZER(struct cmd_operate_detach_port_result,
994			port_id, UINT8);
995
996cmdline_parse_inst_t cmd_operate_detach_port = {
997	.f = cmd_operate_detach_port_parsed,
998	.data = NULL,
999	.help_str = "port detach port_id",
1000	.tokens = {
1001		(void *)&cmd_operate_detach_port_port,
1002		(void *)&cmd_operate_detach_port_keyword,
1003		(void *)&cmd_operate_detach_port_port_id,
1004		NULL,
1005	},
1006};
1007
1008/* *** configure speed for all ports *** */
1009struct cmd_config_speed_all {
1010	cmdline_fixed_string_t port;
1011	cmdline_fixed_string_t keyword;
1012	cmdline_fixed_string_t all;
1013	cmdline_fixed_string_t item1;
1014	cmdline_fixed_string_t item2;
1015	cmdline_fixed_string_t value1;
1016	cmdline_fixed_string_t value2;
1017};
1018
1019static int
1020parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
1021{
1022
1023	int duplex;
1024
1025	if (!strcmp(duplexstr, "half")) {
1026		duplex = ETH_LINK_HALF_DUPLEX;
1027	} else if (!strcmp(duplexstr, "full")) {
1028		duplex = ETH_LINK_FULL_DUPLEX;
1029	} else if (!strcmp(duplexstr, "auto")) {
1030		duplex = ETH_LINK_FULL_DUPLEX;
1031	} else {
1032		printf("Unknown duplex parameter\n");
1033		return -1;
1034	}
1035
1036	if (!strcmp(speedstr, "10")) {
1037		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
1038				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
1039	} else if (!strcmp(speedstr, "100")) {
1040		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
1041				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
1042	} else {
1043		if (duplex != ETH_LINK_FULL_DUPLEX) {
1044			printf("Invalid speed/duplex parameters\n");
1045			return -1;
1046		}
1047		if (!strcmp(speedstr, "1000")) {
1048			*speed = ETH_LINK_SPEED_1G;
1049		} else if (!strcmp(speedstr, "10000")) {
1050			*speed = ETH_LINK_SPEED_10G;
1051		} else if (!strcmp(speedstr, "25000")) {
1052			*speed = ETH_LINK_SPEED_25G;
1053		} else if (!strcmp(speedstr, "40000")) {
1054			*speed = ETH_LINK_SPEED_40G;
1055		} else if (!strcmp(speedstr, "50000")) {
1056			*speed = ETH_LINK_SPEED_50G;
1057		} else if (!strcmp(speedstr, "100000")) {
1058			*speed = ETH_LINK_SPEED_100G;
1059		} else if (!strcmp(speedstr, "auto")) {
1060			*speed = ETH_LINK_SPEED_AUTONEG;
1061		} else {
1062			printf("Unknown speed parameter\n");
1063			return -1;
1064		}
1065	}
1066
1067	return 0;
1068}
1069
1070static void
1071cmd_config_speed_all_parsed(void *parsed_result,
1072			__attribute__((unused)) struct cmdline *cl,
1073			__attribute__((unused)) void *data)
1074{
1075	struct cmd_config_speed_all *res = parsed_result;
1076	uint32_t link_speed;
1077	portid_t pid;
1078
1079	if (!all_ports_stopped()) {
1080		printf("Please stop all ports first\n");
1081		return;
1082	}
1083
1084	if (parse_and_check_speed_duplex(res->value1, res->value2,
1085			&link_speed) < 0)
1086		return;
1087
1088	FOREACH_PORT(pid, ports) {
1089		ports[pid].dev_conf.link_speeds = link_speed;
1090	}
1091
1092	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1093}
1094
1095cmdline_parse_token_string_t cmd_config_speed_all_port =
1096	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, port, "port");
1097cmdline_parse_token_string_t cmd_config_speed_all_keyword =
1098	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, keyword,
1099							"config");
1100cmdline_parse_token_string_t cmd_config_speed_all_all =
1101	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, all, "all");
1102cmdline_parse_token_string_t cmd_config_speed_all_item1 =
1103	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
1104cmdline_parse_token_string_t cmd_config_speed_all_value1 =
1105	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
1106				"10#100#1000#10000#25000#40000#50000#100000#auto");
1107cmdline_parse_token_string_t cmd_config_speed_all_item2 =
1108	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
1109cmdline_parse_token_string_t cmd_config_speed_all_value2 =
1110	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value2,
1111						"half#full#auto");
1112
1113cmdline_parse_inst_t cmd_config_speed_all = {
1114	.f = cmd_config_speed_all_parsed,
1115	.data = NULL,
1116	.help_str = "port config all speed "
1117		"10|100|1000|10000|25000|40000|50000|100000|auto duplex "
1118							"half|full|auto",
1119	.tokens = {
1120		(void *)&cmd_config_speed_all_port,
1121		(void *)&cmd_config_speed_all_keyword,
1122		(void *)&cmd_config_speed_all_all,
1123		(void *)&cmd_config_speed_all_item1,
1124		(void *)&cmd_config_speed_all_value1,
1125		(void *)&cmd_config_speed_all_item2,
1126		(void *)&cmd_config_speed_all_value2,
1127		NULL,
1128	},
1129};
1130
1131/* *** configure speed for specific port *** */
1132struct cmd_config_speed_specific {
1133	cmdline_fixed_string_t port;
1134	cmdline_fixed_string_t keyword;
1135	uint8_t id;
1136	cmdline_fixed_string_t item1;
1137	cmdline_fixed_string_t item2;
1138	cmdline_fixed_string_t value1;
1139	cmdline_fixed_string_t value2;
1140};
1141
1142static void
1143cmd_config_speed_specific_parsed(void *parsed_result,
1144				__attribute__((unused)) struct cmdline *cl,
1145				__attribute__((unused)) void *data)
1146{
1147	struct cmd_config_speed_specific *res = parsed_result;
1148	uint32_t link_speed;
1149
1150	if (!all_ports_stopped()) {
1151		printf("Please stop all ports first\n");
1152		return;
1153	}
1154
1155	if (port_id_is_invalid(res->id, ENABLED_WARN))
1156		return;
1157
1158	if (parse_and_check_speed_duplex(res->value1, res->value2,
1159			&link_speed) < 0)
1160		return;
1161
1162	ports[res->id].dev_conf.link_speeds = link_speed;
1163
1164	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1165}
1166
1167
1168cmdline_parse_token_string_t cmd_config_speed_specific_port =
1169	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, port,
1170								"port");
1171cmdline_parse_token_string_t cmd_config_speed_specific_keyword =
1172	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, keyword,
1173								"config");
1174cmdline_parse_token_num_t cmd_config_speed_specific_id =
1175	TOKEN_NUM_INITIALIZER(struct cmd_config_speed_specific, id, UINT8);
1176cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
1177	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item1,
1178								"speed");
1179cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
1180	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
1181				"10#100#1000#10000#25000#40000#50000#100000#auto");
1182cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
1183	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
1184								"duplex");
1185cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
1186	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value2,
1187							"half#full#auto");
1188
1189cmdline_parse_inst_t cmd_config_speed_specific = {
1190	.f = cmd_config_speed_specific_parsed,
1191	.data = NULL,
1192	.help_str = "port config X speed "
1193		"10|100|1000|10000|25000|40000|50000|100000|auto duplex "
1194							"half|full|auto",
1195	.tokens = {
1196		(void *)&cmd_config_speed_specific_port,
1197		(void *)&cmd_config_speed_specific_keyword,
1198		(void *)&cmd_config_speed_specific_id,
1199		(void *)&cmd_config_speed_specific_item1,
1200		(void *)&cmd_config_speed_specific_value1,
1201		(void *)&cmd_config_speed_specific_item2,
1202		(void *)&cmd_config_speed_specific_value2,
1203		NULL,
1204	},
1205};
1206
1207/* *** configure txq/rxq, txd/rxd *** */
1208struct cmd_config_rx_tx {
1209	cmdline_fixed_string_t port;
1210	cmdline_fixed_string_t keyword;
1211	cmdline_fixed_string_t all;
1212	cmdline_fixed_string_t name;
1213	uint16_t value;
1214};
1215
1216static void
1217cmd_config_rx_tx_parsed(void *parsed_result,
1218			__attribute__((unused)) struct cmdline *cl,
1219			__attribute__((unused)) void *data)
1220{
1221	struct cmd_config_rx_tx *res = parsed_result;
1222
1223	if (!all_ports_stopped()) {
1224		printf("Please stop all ports first\n");
1225		return;
1226	}
1227	if (!strcmp(res->name, "rxq")) {
1228		if (!res->value && !nb_txq) {
1229			printf("Warning: Either rx or tx queues should be non zero\n");
1230			return;
1231		}
1232		nb_rxq = res->value;
1233	}
1234	else if (!strcmp(res->name, "txq")) {
1235		if (!res->value && !nb_rxq) {
1236			printf("Warning: Either rx or tx queues should be non zero\n");
1237			return;
1238		}
1239		nb_txq = res->value;
1240	}
1241	else if (!strcmp(res->name, "rxd")) {
1242		if (res->value <= 0 || res->value > RTE_TEST_RX_DESC_MAX) {
1243			printf("rxd %d invalid - must be > 0 && <= %d\n",
1244					res->value, RTE_TEST_RX_DESC_MAX);
1245			return;
1246		}
1247		nb_rxd = res->value;
1248	} else if (!strcmp(res->name, "txd")) {
1249		if (res->value <= 0 || res->value > RTE_TEST_TX_DESC_MAX) {
1250			printf("txd %d invalid - must be > 0 && <= %d\n",
1251					res->value, RTE_TEST_TX_DESC_MAX);
1252			return;
1253		}
1254		nb_txd = res->value;
1255	} else {
1256		printf("Unknown parameter\n");
1257		return;
1258	}
1259
1260	fwd_config_setup();
1261
1262	init_port_config();
1263
1264	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1265}
1266
1267cmdline_parse_token_string_t cmd_config_rx_tx_port =
1268	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, port, "port");
1269cmdline_parse_token_string_t cmd_config_rx_tx_keyword =
1270	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, keyword, "config");
1271cmdline_parse_token_string_t cmd_config_rx_tx_all =
1272	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, all, "all");
1273cmdline_parse_token_string_t cmd_config_rx_tx_name =
1274	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, name,
1275						"rxq#txq#rxd#txd");
1276cmdline_parse_token_num_t cmd_config_rx_tx_value =
1277	TOKEN_NUM_INITIALIZER(struct cmd_config_rx_tx, value, UINT16);
1278
1279cmdline_parse_inst_t cmd_config_rx_tx = {
1280	.f = cmd_config_rx_tx_parsed,
1281	.data = NULL,
1282	.help_str = "port config all rxq|txq|rxd|txd value",
1283	.tokens = {
1284		(void *)&cmd_config_rx_tx_port,
1285		(void *)&cmd_config_rx_tx_keyword,
1286		(void *)&cmd_config_rx_tx_all,
1287		(void *)&cmd_config_rx_tx_name,
1288		(void *)&cmd_config_rx_tx_value,
1289		NULL,
1290	},
1291};
1292
1293/* *** config max packet length *** */
1294struct cmd_config_max_pkt_len_result {
1295	cmdline_fixed_string_t port;
1296	cmdline_fixed_string_t keyword;
1297	cmdline_fixed_string_t all;
1298	cmdline_fixed_string_t name;
1299	uint32_t value;
1300};
1301
1302static void
1303cmd_config_max_pkt_len_parsed(void *parsed_result,
1304				__attribute__((unused)) struct cmdline *cl,
1305				__attribute__((unused)) void *data)
1306{
1307	struct cmd_config_max_pkt_len_result *res = parsed_result;
1308
1309	if (!all_ports_stopped()) {
1310		printf("Please stop all ports first\n");
1311		return;
1312	}
1313
1314	if (!strcmp(res->name, "max-pkt-len")) {
1315		if (res->value < ETHER_MIN_LEN) {
1316			printf("max-pkt-len can not be less than %d\n",
1317							ETHER_MIN_LEN);
1318			return;
1319		}
1320		if (res->value == rx_mode.max_rx_pkt_len)
1321			return;
1322
1323		rx_mode.max_rx_pkt_len = res->value;
1324		if (res->value > ETHER_MAX_LEN)
1325			rx_mode.jumbo_frame = 1;
1326		else
1327			rx_mode.jumbo_frame = 0;
1328	} else {
1329		printf("Unknown parameter\n");
1330		return;
1331	}
1332
1333	init_port_config();
1334
1335	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1336}
1337
1338cmdline_parse_token_string_t cmd_config_max_pkt_len_port =
1339	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, port,
1340								"port");
1341cmdline_parse_token_string_t cmd_config_max_pkt_len_keyword =
1342	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, keyword,
1343								"config");
1344cmdline_parse_token_string_t cmd_config_max_pkt_len_all =
1345	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, all,
1346								"all");
1347cmdline_parse_token_string_t cmd_config_max_pkt_len_name =
1348	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, name,
1349								"max-pkt-len");
1350cmdline_parse_token_num_t cmd_config_max_pkt_len_value =
1351	TOKEN_NUM_INITIALIZER(struct cmd_config_max_pkt_len_result, value,
1352								UINT32);
1353
1354cmdline_parse_inst_t cmd_config_max_pkt_len = {
1355	.f = cmd_config_max_pkt_len_parsed,
1356	.data = NULL,
1357	.help_str = "port config all max-pkt-len value",
1358	.tokens = {
1359		(void *)&cmd_config_max_pkt_len_port,
1360		(void *)&cmd_config_max_pkt_len_keyword,
1361		(void *)&cmd_config_max_pkt_len_all,
1362		(void *)&cmd_config_max_pkt_len_name,
1363		(void *)&cmd_config_max_pkt_len_value,
1364		NULL,
1365	},
1366};
1367
1368/* *** configure port MTU *** */
1369struct cmd_config_mtu_result {
1370	cmdline_fixed_string_t port;
1371	cmdline_fixed_string_t keyword;
1372	cmdline_fixed_string_t mtu;
1373	uint8_t port_id;
1374	uint16_t value;
1375};
1376
1377static void
1378cmd_config_mtu_parsed(void *parsed_result,
1379		      __attribute__((unused)) struct cmdline *cl,
1380		      __attribute__((unused)) void *data)
1381{
1382	struct cmd_config_mtu_result *res = parsed_result;
1383
1384	if (res->value < ETHER_MIN_LEN) {
1385		printf("mtu cannot be less than %d\n", ETHER_MIN_LEN);
1386		return;
1387	}
1388	port_mtu_set(res->port_id, res->value);
1389}
1390
1391cmdline_parse_token_string_t cmd_config_mtu_port =
1392	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, port,
1393				 "port");
1394cmdline_parse_token_string_t cmd_config_mtu_keyword =
1395	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
1396				 "config");
1397cmdline_parse_token_string_t cmd_config_mtu_mtu =
1398	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
1399				 "mtu");
1400cmdline_parse_token_num_t cmd_config_mtu_port_id =
1401	TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, port_id, UINT8);
1402cmdline_parse_token_num_t cmd_config_mtu_value =
1403	TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, value, UINT16);
1404
1405cmdline_parse_inst_t cmd_config_mtu = {
1406	.f = cmd_config_mtu_parsed,
1407	.data = NULL,
1408	.help_str = "port config mtu port_id value",
1409	.tokens = {
1410		(void *)&cmd_config_mtu_port,
1411		(void *)&cmd_config_mtu_keyword,
1412		(void *)&cmd_config_mtu_mtu,
1413		(void *)&cmd_config_mtu_port_id,
1414		(void *)&cmd_config_mtu_value,
1415		NULL,
1416	},
1417};
1418
1419/* *** configure rx mode *** */
1420struct cmd_config_rx_mode_flag {
1421	cmdline_fixed_string_t port;
1422	cmdline_fixed_string_t keyword;
1423	cmdline_fixed_string_t all;
1424	cmdline_fixed_string_t name;
1425	cmdline_fixed_string_t value;
1426};
1427
1428static void
1429cmd_config_rx_mode_flag_parsed(void *parsed_result,
1430				__attribute__((unused)) struct cmdline *cl,
1431				__attribute__((unused)) void *data)
1432{
1433	struct cmd_config_rx_mode_flag *res = parsed_result;
1434
1435	if (!all_ports_stopped()) {
1436		printf("Please stop all ports first\n");
1437		return;
1438	}
1439
1440	if (!strcmp(res->name, "crc-strip")) {
1441		if (!strcmp(res->value, "on"))
1442			rx_mode.hw_strip_crc = 1;
1443		else if (!strcmp(res->value, "off"))
1444			rx_mode.hw_strip_crc = 0;
1445		else {
1446			printf("Unknown parameter\n");
1447			return;
1448		}
1449	} else if (!strcmp(res->name, "scatter")) {
1450		if (!strcmp(res->value, "on"))
1451			rx_mode.enable_scatter = 1;
1452		else if (!strcmp(res->value, "off"))
1453			rx_mode.enable_scatter = 0;
1454		else {
1455			printf("Unknown parameter\n");
1456			return;
1457		}
1458	} else if (!strcmp(res->name, "rx-cksum")) {
1459		if (!strcmp(res->value, "on"))
1460			rx_mode.hw_ip_checksum = 1;
1461		else if (!strcmp(res->value, "off"))
1462			rx_mode.hw_ip_checksum = 0;
1463		else {
1464			printf("Unknown parameter\n");
1465			return;
1466		}
1467	} else if (!strcmp(res->name, "hw-vlan")) {
1468		if (!strcmp(res->value, "on")) {
1469			rx_mode.hw_vlan_filter = 1;
1470			rx_mode.hw_vlan_strip  = 1;
1471		}
1472		else if (!strcmp(res->value, "off")) {
1473			rx_mode.hw_vlan_filter = 0;
1474			rx_mode.hw_vlan_strip  = 0;
1475		}
1476		else {
1477			printf("Unknown parameter\n");
1478			return;
1479		}
1480	} else if (!strcmp(res->name, "hw-vlan-filter")) {
1481		if (!strcmp(res->value, "on"))
1482			rx_mode.hw_vlan_filter = 1;
1483		else if (!strcmp(res->value, "off"))
1484			rx_mode.hw_vlan_filter = 0;
1485		else {
1486			printf("Unknown parameter\n");
1487			return;
1488		}
1489	} else if (!strcmp(res->name, "hw-vlan-strip")) {
1490		if (!strcmp(res->value, "on"))
1491			rx_mode.hw_vlan_strip  = 1;
1492		else if (!strcmp(res->value, "off"))
1493			rx_mode.hw_vlan_strip  = 0;
1494		else {
1495			printf("Unknown parameter\n");
1496			return;
1497		}
1498	} else if (!strcmp(res->name, "hw-vlan-extend")) {
1499		if (!strcmp(res->value, "on"))
1500			rx_mode.hw_vlan_extend = 1;
1501		else if (!strcmp(res->value, "off"))
1502			rx_mode.hw_vlan_extend = 0;
1503		else {
1504			printf("Unknown parameter\n");
1505			return;
1506		}
1507	} else if (!strcmp(res->name, "drop-en")) {
1508		if (!strcmp(res->value, "on"))
1509			rx_drop_en = 1;
1510		else if (!strcmp(res->value, "off"))
1511			rx_drop_en = 0;
1512		else {
1513			printf("Unknown parameter\n");
1514			return;
1515		}
1516	} else {
1517		printf("Unknown parameter\n");
1518		return;
1519	}
1520
1521	init_port_config();
1522
1523	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1524}
1525
1526cmdline_parse_token_string_t cmd_config_rx_mode_flag_port =
1527	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, port, "port");
1528cmdline_parse_token_string_t cmd_config_rx_mode_flag_keyword =
1529	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, keyword,
1530								"config");
1531cmdline_parse_token_string_t cmd_config_rx_mode_flag_all =
1532	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all");
1533cmdline_parse_token_string_t cmd_config_rx_mode_flag_name =
1534	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name,
1535					"crc-strip#scatter#rx-cksum#hw-vlan#"
1536					"hw-vlan-filter#hw-vlan-strip#hw-vlan-extend");
1537cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
1538	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value,
1539							"on#off");
1540
1541cmdline_parse_inst_t cmd_config_rx_mode_flag = {
1542	.f = cmd_config_rx_mode_flag_parsed,
1543	.data = NULL,
1544	.help_str = "port config all crc-strip|scatter|rx-cksum|hw-vlan|"
1545		"hw-vlan-filter|hw-vlan-strip|hw-vlan-extend on|off",
1546	.tokens = {
1547		(void *)&cmd_config_rx_mode_flag_port,
1548		(void *)&cmd_config_rx_mode_flag_keyword,
1549		(void *)&cmd_config_rx_mode_flag_all,
1550		(void *)&cmd_config_rx_mode_flag_name,
1551		(void *)&cmd_config_rx_mode_flag_value,
1552		NULL,
1553	},
1554};
1555
1556/* *** configure rss *** */
1557struct cmd_config_rss {
1558	cmdline_fixed_string_t port;
1559	cmdline_fixed_string_t keyword;
1560	cmdline_fixed_string_t all;
1561	cmdline_fixed_string_t name;
1562	cmdline_fixed_string_t value;
1563};
1564
1565static void
1566cmd_config_rss_parsed(void *parsed_result,
1567			__attribute__((unused)) struct cmdline *cl,
1568			__attribute__((unused)) void *data)
1569{
1570	struct cmd_config_rss *res = parsed_result;
1571	struct rte_eth_rss_conf rss_conf;
1572	int diag;
1573	uint8_t i;
1574
1575	if (!strcmp(res->value, "all"))
1576		rss_conf.rss_hf = ETH_RSS_IP | ETH_RSS_TCP |
1577				ETH_RSS_UDP | ETH_RSS_SCTP |
1578					ETH_RSS_L2_PAYLOAD;
1579	else if (!strcmp(res->value, "ip"))
1580		rss_conf.rss_hf = ETH_RSS_IP;
1581	else if (!strcmp(res->value, "udp"))
1582		rss_conf.rss_hf = ETH_RSS_UDP;
1583	else if (!strcmp(res->value, "tcp"))
1584		rss_conf.rss_hf = ETH_RSS_TCP;
1585	else if (!strcmp(res->value, "sctp"))
1586		rss_conf.rss_hf = ETH_RSS_SCTP;
1587	else if (!strcmp(res->value, "ether"))
1588		rss_conf.rss_hf = ETH_RSS_L2_PAYLOAD;
1589	else if (!strcmp(res->value, "port"))
1590		rss_conf.rss_hf = ETH_RSS_PORT;
1591	else if (!strcmp(res->value, "vxlan"))
1592		rss_conf.rss_hf = ETH_RSS_VXLAN;
1593	else if (!strcmp(res->value, "geneve"))
1594		rss_conf.rss_hf = ETH_RSS_GENEVE;
1595	else if (!strcmp(res->value, "nvgre"))
1596		rss_conf.rss_hf = ETH_RSS_NVGRE;
1597	else if (!strcmp(res->value, "none"))
1598		rss_conf.rss_hf = 0;
1599	else {
1600		printf("Unknown parameter\n");
1601		return;
1602	}
1603	rss_conf.rss_key = NULL;
1604	for (i = 0; i < rte_eth_dev_count(); i++) {
1605		diag = rte_eth_dev_rss_hash_update(i, &rss_conf);
1606		if (diag < 0)
1607			printf("Configuration of RSS hash at ethernet port %d "
1608				"failed with error (%d): %s.\n",
1609				i, -diag, strerror(-diag));
1610	}
1611}
1612
1613cmdline_parse_token_string_t cmd_config_rss_port =
1614	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, port, "port");
1615cmdline_parse_token_string_t cmd_config_rss_keyword =
1616	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, keyword, "config");
1617cmdline_parse_token_string_t cmd_config_rss_all =
1618	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, all, "all");
1619cmdline_parse_token_string_t cmd_config_rss_name =
1620	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
1621cmdline_parse_token_string_t cmd_config_rss_value =
1622	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
1623		"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
1624
1625cmdline_parse_inst_t cmd_config_rss = {
1626	.f = cmd_config_rss_parsed,
1627	.data = NULL,
1628	.help_str = "port config all rss all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none",
1629	.tokens = {
1630		(void *)&cmd_config_rss_port,
1631		(void *)&cmd_config_rss_keyword,
1632		(void *)&cmd_config_rss_all,
1633		(void *)&cmd_config_rss_name,
1634		(void *)&cmd_config_rss_value,
1635		NULL,
1636	},
1637};
1638
1639/* *** configure rss hash key *** */
1640struct cmd_config_rss_hash_key {
1641	cmdline_fixed_string_t port;
1642	cmdline_fixed_string_t config;
1643	uint8_t port_id;
1644	cmdline_fixed_string_t rss_hash_key;
1645	cmdline_fixed_string_t rss_type;
1646	cmdline_fixed_string_t key;
1647};
1648
1649static uint8_t
1650hexa_digit_to_value(char hexa_digit)
1651{
1652	if ((hexa_digit >= '0') && (hexa_digit <= '9'))
1653		return (uint8_t) (hexa_digit - '0');
1654	if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
1655		return (uint8_t) ((hexa_digit - 'a') + 10);
1656	if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
1657		return (uint8_t) ((hexa_digit - 'A') + 10);
1658	/* Invalid hexa digit */
1659	return 0xFF;
1660}
1661
1662static uint8_t
1663parse_and_check_key_hexa_digit(char *key, int idx)
1664{
1665	uint8_t hexa_v;
1666
1667	hexa_v = hexa_digit_to_value(key[idx]);
1668	if (hexa_v == 0xFF)
1669		printf("invalid key: character %c at position %d is not a "
1670		       "valid hexa digit\n", key[idx], idx);
1671	return hexa_v;
1672}
1673
1674static void
1675cmd_config_rss_hash_key_parsed(void *parsed_result,
1676			       __attribute__((unused)) struct cmdline *cl,
1677			       __attribute__((unused)) void *data)
1678{
1679	struct cmd_config_rss_hash_key *res = parsed_result;
1680	uint8_t hash_key[RSS_HASH_KEY_LENGTH];
1681	uint8_t xdgt0;
1682	uint8_t xdgt1;
1683	int i;
1684	struct rte_eth_dev_info dev_info;
1685	uint8_t hash_key_size;
1686	uint32_t key_len;
1687
1688	memset(&dev_info, 0, sizeof(dev_info));
1689	rte_eth_dev_info_get(res->port_id, &dev_info);
1690	if (dev_info.hash_key_size > 0 &&
1691			dev_info.hash_key_size <= sizeof(hash_key))
1692		hash_key_size = dev_info.hash_key_size;
1693	else {
1694		printf("dev_info did not provide a valid hash key size\n");
1695		return;
1696	}
1697	/* Check the length of the RSS hash key */
1698	key_len = strlen(res->key);
1699	if (key_len != (hash_key_size * 2)) {
1700		printf("key length: %d invalid - key must be a string of %d"
1701			   " hexa-decimal numbers\n",
1702			   (int) key_len, hash_key_size * 2);
1703		return;
1704	}
1705	/* Translate RSS hash key into binary representation */
1706	for (i = 0; i < hash_key_size; i++) {
1707		xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
1708		if (xdgt0 == 0xFF)
1709			return;
1710		xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
1711		if (xdgt1 == 0xFF)
1712			return;
1713		hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
1714	}
1715	port_rss_hash_key_update(res->port_id, res->rss_type, hash_key,
1716			hash_key_size);
1717}
1718
1719cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
1720	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
1721cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
1722	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
1723				 "config");
1724cmdline_parse_token_num_t cmd_config_rss_hash_key_port_id =
1725	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id, UINT8);
1726cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
1727	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
1728				 rss_hash_key, "rss-hash-key");
1729cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_type =
1730	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_type,
1731				 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
1732				 "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
1733				 "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
1734				 "ipv6-tcp-ex#ipv6-udp-ex");
1735cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
1736	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
1737
1738cmdline_parse_inst_t cmd_config_rss_hash_key = {
1739	.f = cmd_config_rss_hash_key_parsed,
1740	.data = NULL,
1741	.help_str =
1742		"port config X rss-hash-key ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
1743		"ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
1744		"ipv6-sctp|ipv6-other|l2-payload|"
1745		"ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex "
1746		"<string of hexa digits (variable length, NIC dependent)>\n",
1747	.tokens = {
1748		(void *)&cmd_config_rss_hash_key_port,
1749		(void *)&cmd_config_rss_hash_key_config,
1750		(void *)&cmd_config_rss_hash_key_port_id,
1751		(void *)&cmd_config_rss_hash_key_rss_hash_key,
1752		(void *)&cmd_config_rss_hash_key_rss_type,
1753		(void *)&cmd_config_rss_hash_key_value,
1754		NULL,
1755	},
1756};
1757
1758/* *** configure port rxq/txq start/stop *** */
1759struct cmd_config_rxtx_queue {
1760	cmdline_fixed_string_t port;
1761	uint8_t portid;
1762	cmdline_fixed_string_t rxtxq;
1763	uint16_t qid;
1764	cmdline_fixed_string_t opname;
1765};
1766
1767static void
1768cmd_config_rxtx_queue_parsed(void *parsed_result,
1769			__attribute__((unused)) struct cmdline *cl,
1770			__attribute__((unused)) void *data)
1771{
1772	struct cmd_config_rxtx_queue *res = parsed_result;
1773	uint8_t isrx;
1774	uint8_t isstart;
1775	int ret = 0;
1776
1777	if (test_done == 0) {
1778		printf("Please stop forwarding first\n");
1779		return;
1780	}
1781
1782	if (port_id_is_invalid(res->portid, ENABLED_WARN))
1783		return;
1784
1785	if (port_is_started(res->portid) != 1) {
1786		printf("Please start port %u first\n", res->portid);
1787		return;
1788	}
1789
1790	if (!strcmp(res->rxtxq, "rxq"))
1791		isrx = 1;
1792	else if (!strcmp(res->rxtxq, "txq"))
1793		isrx = 0;
1794	else {
1795		printf("Unknown parameter\n");
1796		return;
1797	}
1798
1799	if (isrx && rx_queue_id_is_invalid(res->qid))
1800		return;
1801	else if (!isrx && tx_queue_id_is_invalid(res->qid))
1802		return;
1803
1804	if (!strcmp(res->opname, "start"))
1805		isstart = 1;
1806	else if (!strcmp(res->opname, "stop"))
1807		isstart = 0;
1808	else {
1809		printf("Unknown parameter\n");
1810		return;
1811	}
1812
1813	if (isstart && isrx)
1814		ret = rte_eth_dev_rx_queue_start(res->portid, res->qid);
1815	else if (!isstart && isrx)
1816		ret = rte_eth_dev_rx_queue_stop(res->portid, res->qid);
1817	else if (isstart && !isrx)
1818		ret = rte_eth_dev_tx_queue_start(res->portid, res->qid);
1819	else
1820		ret = rte_eth_dev_tx_queue_stop(res->portid, res->qid);
1821
1822	if (ret == -ENOTSUP)
1823		printf("Function not supported in PMD driver\n");
1824}
1825
1826cmdline_parse_token_string_t cmd_config_rxtx_queue_port =
1827	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, port, "port");
1828cmdline_parse_token_num_t cmd_config_rxtx_queue_portid =
1829	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, portid, UINT8);
1830cmdline_parse_token_string_t cmd_config_rxtx_queue_rxtxq =
1831	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, rxtxq, "rxq#txq");
1832cmdline_parse_token_num_t cmd_config_rxtx_queue_qid =
1833	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, qid, UINT16);
1834cmdline_parse_token_string_t cmd_config_rxtx_queue_opname =
1835	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, opname,
1836						"start#stop");
1837
1838cmdline_parse_inst_t cmd_config_rxtx_queue = {
1839	.f = cmd_config_rxtx_queue_parsed,
1840	.data = NULL,
1841	.help_str = "port X rxq|txq ID start|stop",
1842	.tokens = {
1843		(void *)&cmd_config_speed_all_port,
1844		(void *)&cmd_config_rxtx_queue_portid,
1845		(void *)&cmd_config_rxtx_queue_rxtxq,
1846		(void *)&cmd_config_rxtx_queue_qid,
1847		(void *)&cmd_config_rxtx_queue_opname,
1848		NULL,
1849	},
1850};
1851
1852/* *** Configure RSS RETA *** */
1853struct cmd_config_rss_reta {
1854	cmdline_fixed_string_t port;
1855	cmdline_fixed_string_t keyword;
1856	uint8_t port_id;
1857	cmdline_fixed_string_t name;
1858	cmdline_fixed_string_t list_name;
1859	cmdline_fixed_string_t list_of_items;
1860};
1861
1862static int
1863parse_reta_config(const char *str,
1864		  struct rte_eth_rss_reta_entry64 *reta_conf,
1865		  uint16_t nb_entries)
1866{
1867	int i;
1868	unsigned size;
1869	uint16_t hash_index, idx, shift;
1870	uint16_t nb_queue;
1871	char s[256];
1872	const char *p, *p0 = str;
1873	char *end;
1874	enum fieldnames {
1875		FLD_HASH_INDEX = 0,
1876		FLD_QUEUE,
1877		_NUM_FLD
1878	};
1879	unsigned long int_fld[_NUM_FLD];
1880	char *str_fld[_NUM_FLD];
1881
1882	while ((p = strchr(p0,'(')) != NULL) {
1883		++p;
1884		if((p0 = strchr(p,')')) == NULL)
1885			return -1;
1886
1887		size = p0 - p;
1888		if(size >= sizeof(s))
1889			return -1;
1890
1891		snprintf(s, sizeof(s), "%.*s", size, p);
1892		if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
1893			return -1;
1894		for (i = 0; i < _NUM_FLD; i++) {
1895			errno = 0;
1896			int_fld[i] = strtoul(str_fld[i], &end, 0);
1897			if (errno != 0 || end == str_fld[i] ||
1898					int_fld[i] > 65535)
1899				return -1;
1900		}
1901
1902		hash_index = (uint16_t)int_fld[FLD_HASH_INDEX];
1903		nb_queue = (uint16_t)int_fld[FLD_QUEUE];
1904
1905		if (hash_index >= nb_entries) {
1906			printf("Invalid RETA hash index=%d\n", hash_index);
1907			return -1;
1908		}
1909
1910		idx = hash_index / RTE_RETA_GROUP_SIZE;
1911		shift = hash_index % RTE_RETA_GROUP_SIZE;
1912		reta_conf[idx].mask |= (1ULL << shift);
1913		reta_conf[idx].reta[shift] = nb_queue;
1914	}
1915
1916	return 0;
1917}
1918
1919static void
1920cmd_set_rss_reta_parsed(void *parsed_result,
1921			__attribute__((unused)) struct cmdline *cl,
1922			__attribute__((unused)) void *data)
1923{
1924	int ret;
1925	struct rte_eth_dev_info dev_info;
1926	struct rte_eth_rss_reta_entry64 reta_conf[8];
1927	struct cmd_config_rss_reta *res = parsed_result;
1928
1929	memset(&dev_info, 0, sizeof(dev_info));
1930	rte_eth_dev_info_get(res->port_id, &dev_info);
1931	if (dev_info.reta_size == 0) {
1932		printf("Redirection table size is 0 which is "
1933					"invalid for RSS\n");
1934		return;
1935	} else
1936		printf("The reta size of port %d is %u\n",
1937			res->port_id, dev_info.reta_size);
1938	if (dev_info.reta_size > ETH_RSS_RETA_SIZE_512) {
1939		printf("Currently do not support more than %u entries of "
1940			"redirection table\n", ETH_RSS_RETA_SIZE_512);
1941		return;
1942	}
1943
1944	memset(reta_conf, 0, sizeof(reta_conf));
1945	if (!strcmp(res->list_name, "reta")) {
1946		if (parse_reta_config(res->list_of_items, reta_conf,
1947						dev_info.reta_size)) {
1948			printf("Invalid RSS Redirection Table "
1949					"config entered\n");
1950			return;
1951		}
1952		ret = rte_eth_dev_rss_reta_update(res->port_id,
1953				reta_conf, dev_info.reta_size);
1954		if (ret != 0)
1955			printf("Bad redirection table parameter, "
1956					"return code = %d \n", ret);
1957	}
1958}
1959
1960cmdline_parse_token_string_t cmd_config_rss_reta_port =
1961	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, port, "port");
1962cmdline_parse_token_string_t cmd_config_rss_reta_keyword =
1963	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, keyword, "config");
1964cmdline_parse_token_num_t cmd_config_rss_reta_port_id =
1965	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_reta, port_id, UINT8);
1966cmdline_parse_token_string_t cmd_config_rss_reta_name =
1967	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, name, "rss");
1968cmdline_parse_token_string_t cmd_config_rss_reta_list_name =
1969	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_name, "reta");
1970cmdline_parse_token_string_t cmd_config_rss_reta_list_of_items =
1971        TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_of_items,
1972                                 NULL);
1973cmdline_parse_inst_t cmd_config_rss_reta = {
1974	.f = cmd_set_rss_reta_parsed,
1975	.data = NULL,
1976	.help_str = "port config X rss reta (hash,queue)[,(hash,queue)]",
1977	.tokens = {
1978		(void *)&cmd_config_rss_reta_port,
1979		(void *)&cmd_config_rss_reta_keyword,
1980		(void *)&cmd_config_rss_reta_port_id,
1981		(void *)&cmd_config_rss_reta_name,
1982		(void *)&cmd_config_rss_reta_list_name,
1983		(void *)&cmd_config_rss_reta_list_of_items,
1984		NULL,
1985	},
1986};
1987
1988/* *** SHOW PORT RETA INFO *** */
1989struct cmd_showport_reta {
1990	cmdline_fixed_string_t show;
1991	cmdline_fixed_string_t port;
1992	uint8_t port_id;
1993	cmdline_fixed_string_t rss;
1994	cmdline_fixed_string_t reta;
1995	uint16_t size;
1996	cmdline_fixed_string_t list_of_items;
1997};
1998
1999static int
2000showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,
2001			   uint16_t nb_entries,
2002			   char *str)
2003{
2004	uint32_t size;
2005	const char *p, *p0 = str;
2006	char s[256];
2007	char *end;
2008	char *str_fld[8];
2009	uint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE;
2010	int ret;
2011
2012	p = strchr(p0, '(');
2013	if (p == NULL)
2014		return -1;
2015	p++;
2016	p0 = strchr(p, ')');
2017	if (p0 == NULL)
2018		return -1;
2019	size = p0 - p;
2020	if (size >= sizeof(s)) {
2021		printf("The string size exceeds the internal buffer size\n");
2022		return -1;
2023	}
2024	snprintf(s, sizeof(s), "%.*s", size, p);
2025	ret = rte_strsplit(s, sizeof(s), str_fld, num, ',');
2026	if (ret <= 0 || ret != num) {
2027		printf("The bits of masks do not match the number of "
2028					"reta entries: %u\n", num);
2029		return -1;
2030	}
2031	for (i = 0; i < ret; i++)
2032		conf[i].mask = (uint64_t)strtoul(str_fld[i], &end, 0);
2033
2034	return 0;
2035}
2036
2037static void
2038cmd_showport_reta_parsed(void *parsed_result,
2039			 __attribute__((unused)) struct cmdline *cl,
2040			 __attribute__((unused)) void *data)
2041{
2042	struct cmd_showport_reta *res = parsed_result;
2043	struct rte_eth_rss_reta_entry64 reta_conf[8];
2044	struct rte_eth_dev_info dev_info;
2045
2046	memset(&dev_info, 0, sizeof(dev_info));
2047	rte_eth_dev_info_get(res->port_id, &dev_info);
2048	if (dev_info.reta_size == 0 || res->size != dev_info.reta_size ||
2049				res->size > ETH_RSS_RETA_SIZE_512) {
2050		printf("Invalid redirection table size: %u\n", res->size);
2051		return;
2052	}
2053
2054	memset(reta_conf, 0, sizeof(reta_conf));
2055	if (showport_parse_reta_config(reta_conf, res->size,
2056				res->list_of_items) < 0) {
2057		printf("Invalid string: %s for reta masks\n",
2058					res->list_of_items);
2059		return;
2060	}
2061	port_rss_reta_info(res->port_id, reta_conf, res->size);
2062}
2063
2064cmdline_parse_token_string_t cmd_showport_reta_show =
2065	TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, show, "show");
2066cmdline_parse_token_string_t cmd_showport_reta_port =
2067	TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, port, "port");
2068cmdline_parse_token_num_t cmd_showport_reta_port_id =
2069	TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, port_id, UINT8);
2070cmdline_parse_token_string_t cmd_showport_reta_rss =
2071	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
2072cmdline_parse_token_string_t cmd_showport_reta_reta =
2073	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
2074cmdline_parse_token_num_t cmd_showport_reta_size =
2075	TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, size, UINT16);
2076cmdline_parse_token_string_t cmd_showport_reta_list_of_items =
2077	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta,
2078					list_of_items, NULL);
2079
2080cmdline_parse_inst_t cmd_showport_reta = {
2081	.f = cmd_showport_reta_parsed,
2082	.data = NULL,
2083	.help_str = "show port X rss reta (size) (mask0,mask1,...)",
2084	.tokens = {
2085		(void *)&cmd_showport_reta_show,
2086		(void *)&cmd_showport_reta_port,
2087		(void *)&cmd_showport_reta_port_id,
2088		(void *)&cmd_showport_reta_rss,
2089		(void *)&cmd_showport_reta_reta,
2090		(void *)&cmd_showport_reta_size,
2091		(void *)&cmd_showport_reta_list_of_items,
2092		NULL,
2093	},
2094};
2095
2096/* *** Show RSS hash configuration *** */
2097struct cmd_showport_rss_hash {
2098	cmdline_fixed_string_t show;
2099	cmdline_fixed_string_t port;
2100	uint8_t port_id;
2101	cmdline_fixed_string_t rss_hash;
2102	cmdline_fixed_string_t rss_type;
2103	cmdline_fixed_string_t key; /* optional argument */
2104};
2105
2106static void cmd_showport_rss_hash_parsed(void *parsed_result,
2107				__attribute__((unused)) struct cmdline *cl,
2108				void *show_rss_key)
2109{
2110	struct cmd_showport_rss_hash *res = parsed_result;
2111
2112	port_rss_hash_conf_show(res->port_id, res->rss_type,
2113				show_rss_key != NULL);
2114}
2115
2116cmdline_parse_token_string_t cmd_showport_rss_hash_show =
2117	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, show, "show");
2118cmdline_parse_token_string_t cmd_showport_rss_hash_port =
2119	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, port, "port");
2120cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
2121	TOKEN_NUM_INITIALIZER(struct cmd_showport_rss_hash, port_id, UINT8);
2122cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
2123	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
2124				 "rss-hash");
2125cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash_info =
2126	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_type,
2127				 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
2128				 "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
2129				 "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
2130				 "ipv6-tcp-ex#ipv6-udp-ex");
2131cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
2132	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
2133
2134cmdline_parse_inst_t cmd_showport_rss_hash = {
2135	.f = cmd_showport_rss_hash_parsed,
2136	.data = NULL,
2137	.help_str =
2138		"show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
2139		"ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
2140		"ipv6-sctp|ipv6-other|l2-payload|"
2141		"ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex (X = port number)\n",
2142	.tokens = {
2143		(void *)&cmd_showport_rss_hash_show,
2144		(void *)&cmd_showport_rss_hash_port,
2145		(void *)&cmd_showport_rss_hash_port_id,
2146		(void *)&cmd_showport_rss_hash_rss_hash,
2147		(void *)&cmd_showport_rss_hash_rss_hash_info,
2148		NULL,
2149	},
2150};
2151
2152cmdline_parse_inst_t cmd_showport_rss_hash_key = {
2153	.f = cmd_showport_rss_hash_parsed,
2154	.data = (void *)1,
2155	.help_str =
2156		"show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
2157		"ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
2158		"ipv6-sctp|ipv6-other|l2-payload|"
2159		"ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex key (X = port number)\n",
2160	.tokens = {
2161		(void *)&cmd_showport_rss_hash_show,
2162		(void *)&cmd_showport_rss_hash_port,
2163		(void *)&cmd_showport_rss_hash_port_id,
2164		(void *)&cmd_showport_rss_hash_rss_hash,
2165		(void *)&cmd_showport_rss_hash_rss_hash_info,
2166		(void *)&cmd_showport_rss_hash_rss_key,
2167		NULL,
2168	},
2169};
2170
2171/* *** Configure DCB *** */
2172struct cmd_config_dcb {
2173	cmdline_fixed_string_t port;
2174	cmdline_fixed_string_t config;
2175	uint8_t port_id;
2176	cmdline_fixed_string_t dcb;
2177	cmdline_fixed_string_t vt;
2178	cmdline_fixed_string_t vt_en;
2179	uint8_t num_tcs;
2180	cmdline_fixed_string_t pfc;
2181	cmdline_fixed_string_t pfc_en;
2182};
2183
2184static void
2185cmd_config_dcb_parsed(void *parsed_result,
2186                        __attribute__((unused)) struct cmdline *cl,
2187                        __attribute__((unused)) void *data)
2188{
2189	struct cmd_config_dcb *res = parsed_result;
2190	portid_t port_id = res->port_id;
2191	struct rte_port *port;
2192	uint8_t pfc_en;
2193	int ret;
2194
2195	port = &ports[port_id];
2196	/** Check if the port is not started **/
2197	if (port->port_status != RTE_PORT_STOPPED) {
2198		printf("Please stop port %d first\n", port_id);
2199		return;
2200	}
2201
2202	if ((res->num_tcs != ETH_4_TCS) && (res->num_tcs != ETH_8_TCS)) {
2203		printf("The invalid number of traffic class,"
2204			" only 4 or 8 allowed.\n");
2205		return;
2206	}
2207
2208	if (nb_fwd_lcores < res->num_tcs) {
2209		printf("nb_cores shouldn't be less than number of TCs.\n");
2210		return;
2211	}
2212	if (!strncmp(res->pfc_en, "on", 2))
2213		pfc_en = 1;
2214	else
2215		pfc_en = 0;
2216
2217	/* DCB in VT mode */
2218	if (!strncmp(res->vt_en, "on", 2))
2219		ret = init_port_dcb_config(port_id, DCB_VT_ENABLED,
2220				(enum rte_eth_nb_tcs)res->num_tcs,
2221				pfc_en);
2222	else
2223		ret = init_port_dcb_config(port_id, DCB_ENABLED,
2224				(enum rte_eth_nb_tcs)res->num_tcs,
2225				pfc_en);
2226
2227
2228	if (ret != 0) {
2229		printf("Cannot initialize network ports.\n");
2230		return;
2231	}
2232
2233	cmd_reconfig_device_queue(port_id, 1, 1);
2234}
2235
2236cmdline_parse_token_string_t cmd_config_dcb_port =
2237        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, port, "port");
2238cmdline_parse_token_string_t cmd_config_dcb_config =
2239        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, config, "config");
2240cmdline_parse_token_num_t cmd_config_dcb_port_id =
2241        TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, port_id, UINT8);
2242cmdline_parse_token_string_t cmd_config_dcb_dcb =
2243        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, dcb, "dcb");
2244cmdline_parse_token_string_t cmd_config_dcb_vt =
2245        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt, "vt");
2246cmdline_parse_token_string_t cmd_config_dcb_vt_en =
2247        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt_en, "on#off");
2248cmdline_parse_token_num_t cmd_config_dcb_num_tcs =
2249        TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, num_tcs, UINT8);
2250cmdline_parse_token_string_t cmd_config_dcb_pfc=
2251        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc, "pfc");
2252cmdline_parse_token_string_t cmd_config_dcb_pfc_en =
2253        TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc_en, "on#off");
2254
2255cmdline_parse_inst_t cmd_config_dcb = {
2256        .f = cmd_config_dcb_parsed,
2257        .data = NULL,
2258        .help_str = "port config port-id dcb vt on|off nb-tcs pfc on|off",
2259        .tokens = {
2260		(void *)&cmd_config_dcb_port,
2261		(void *)&cmd_config_dcb_config,
2262		(void *)&cmd_config_dcb_port_id,
2263		(void *)&cmd_config_dcb_dcb,
2264		(void *)&cmd_config_dcb_vt,
2265		(void *)&cmd_config_dcb_vt_en,
2266		(void *)&cmd_config_dcb_num_tcs,
2267		(void *)&cmd_config_dcb_pfc,
2268		(void *)&cmd_config_dcb_pfc_en,
2269                NULL,
2270        },
2271};
2272
2273/* *** configure number of packets per burst *** */
2274struct cmd_config_burst {
2275	cmdline_fixed_string_t port;
2276	cmdline_fixed_string_t keyword;
2277	cmdline_fixed_string_t all;
2278	cmdline_fixed_string_t name;
2279	uint16_t value;
2280};
2281
2282static void
2283cmd_config_burst_parsed(void *parsed_result,
2284			__attribute__((unused)) struct cmdline *cl,
2285			__attribute__((unused)) void *data)
2286{
2287	struct cmd_config_burst *res = parsed_result;
2288
2289	if (!all_ports_stopped()) {
2290		printf("Please stop all ports first\n");
2291		return;
2292	}
2293
2294	if (!strcmp(res->name, "burst")) {
2295		if (res->value < 1 || res->value > MAX_PKT_BURST) {
2296			printf("burst must be >= 1 && <= %d\n", MAX_PKT_BURST);
2297			return;
2298		}
2299		nb_pkt_per_burst = res->value;
2300	} else {
2301		printf("Unknown parameter\n");
2302		return;
2303	}
2304
2305	init_port_config();
2306
2307	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2308}
2309
2310cmdline_parse_token_string_t cmd_config_burst_port =
2311	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, port, "port");
2312cmdline_parse_token_string_t cmd_config_burst_keyword =
2313	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, keyword, "config");
2314cmdline_parse_token_string_t cmd_config_burst_all =
2315	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, all, "all");
2316cmdline_parse_token_string_t cmd_config_burst_name =
2317	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, name, "burst");
2318cmdline_parse_token_num_t cmd_config_burst_value =
2319	TOKEN_NUM_INITIALIZER(struct cmd_config_burst, value, UINT16);
2320
2321cmdline_parse_inst_t cmd_config_burst = {
2322	.f = cmd_config_burst_parsed,
2323	.data = NULL,
2324	.help_str = "port config all burst value",
2325	.tokens = {
2326		(void *)&cmd_config_burst_port,
2327		(void *)&cmd_config_burst_keyword,
2328		(void *)&cmd_config_burst_all,
2329		(void *)&cmd_config_burst_name,
2330		(void *)&cmd_config_burst_value,
2331		NULL,
2332	},
2333};
2334
2335/* *** configure rx/tx queues *** */
2336struct cmd_config_thresh {
2337	cmdline_fixed_string_t port;
2338	cmdline_fixed_string_t keyword;
2339	cmdline_fixed_string_t all;
2340	cmdline_fixed_string_t name;
2341	uint8_t value;
2342};
2343
2344static void
2345cmd_config_thresh_parsed(void *parsed_result,
2346			__attribute__((unused)) struct cmdline *cl,
2347			__attribute__((unused)) void *data)
2348{
2349	struct cmd_config_thresh *res = parsed_result;
2350
2351	if (!all_ports_stopped()) {
2352		printf("Please stop all ports first\n");
2353		return;
2354	}
2355
2356	if (!strcmp(res->name, "txpt"))
2357		tx_pthresh = res->value;
2358	else if(!strcmp(res->name, "txht"))
2359		tx_hthresh = res->value;
2360	else if(!strcmp(res->name, "txwt"))
2361		tx_wthresh = res->value;
2362	else if(!strcmp(res->name, "rxpt"))
2363		rx_pthresh = res->value;
2364	else if(!strcmp(res->name, "rxht"))
2365		rx_hthresh = res->value;
2366	else if(!strcmp(res->name, "rxwt"))
2367		rx_wthresh = res->value;
2368	else {
2369		printf("Unknown parameter\n");
2370		return;
2371	}
2372
2373	init_port_config();
2374
2375	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2376}
2377
2378cmdline_parse_token_string_t cmd_config_thresh_port =
2379	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, port, "port");
2380cmdline_parse_token_string_t cmd_config_thresh_keyword =
2381	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, keyword, "config");
2382cmdline_parse_token_string_t cmd_config_thresh_all =
2383	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, all, "all");
2384cmdline_parse_token_string_t cmd_config_thresh_name =
2385	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, name,
2386				"txpt#txht#txwt#rxpt#rxht#rxwt");
2387cmdline_parse_token_num_t cmd_config_thresh_value =
2388	TOKEN_NUM_INITIALIZER(struct cmd_config_thresh, value, UINT8);
2389
2390cmdline_parse_inst_t cmd_config_thresh = {
2391	.f = cmd_config_thresh_parsed,
2392	.data = NULL,
2393	.help_str = "port config all txpt|txht|txwt|rxpt|rxht|rxwt value",
2394	.tokens = {
2395		(void *)&cmd_config_thresh_port,
2396		(void *)&cmd_config_thresh_keyword,
2397		(void *)&cmd_config_thresh_all,
2398		(void *)&cmd_config_thresh_name,
2399		(void *)&cmd_config_thresh_value,
2400		NULL,
2401	},
2402};
2403
2404/* *** configure free/rs threshold *** */
2405struct cmd_config_threshold {
2406	cmdline_fixed_string_t port;
2407	cmdline_fixed_string_t keyword;
2408	cmdline_fixed_string_t all;
2409	cmdline_fixed_string_t name;
2410	uint16_t value;
2411};
2412
2413static void
2414cmd_config_threshold_parsed(void *parsed_result,
2415			__attribute__((unused)) struct cmdline *cl,
2416			__attribute__((unused)) void *data)
2417{
2418	struct cmd_config_threshold *res = parsed_result;
2419
2420	if (!all_ports_stopped()) {
2421		printf("Please stop all ports first\n");
2422		return;
2423	}
2424
2425	if (!strcmp(res->name, "txfreet"))
2426		tx_free_thresh = res->value;
2427	else if (!strcmp(res->name, "txrst"))
2428		tx_rs_thresh = res->value;
2429	else if (!strcmp(res->name, "rxfreet"))
2430		rx_free_thresh = res->value;
2431	else {
2432		printf("Unknown parameter\n");
2433		return;
2434	}
2435
2436	init_port_config();
2437
2438	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2439}
2440
2441cmdline_parse_token_string_t cmd_config_threshold_port =
2442	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, port, "port");
2443cmdline_parse_token_string_t cmd_config_threshold_keyword =
2444	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, keyword,
2445								"config");
2446cmdline_parse_token_string_t cmd_config_threshold_all =
2447	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, all, "all");
2448cmdline_parse_token_string_t cmd_config_threshold_name =
2449	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, name,
2450						"txfreet#txrst#rxfreet");
2451cmdline_parse_token_num_t cmd_config_threshold_value =
2452	TOKEN_NUM_INITIALIZER(struct cmd_config_threshold, value, UINT16);
2453
2454cmdline_parse_inst_t cmd_config_threshold = {
2455	.f = cmd_config_threshold_parsed,
2456	.data = NULL,
2457	.help_str = "port config all txfreet|txrst|rxfreet value",
2458	.tokens = {
2459		(void *)&cmd_config_threshold_port,
2460		(void *)&cmd_config_threshold_keyword,
2461		(void *)&cmd_config_threshold_all,
2462		(void *)&cmd_config_threshold_name,
2463		(void *)&cmd_config_threshold_value,
2464		NULL,
2465	},
2466};
2467
2468/* *** stop *** */
2469struct cmd_stop_result {
2470	cmdline_fixed_string_t stop;
2471};
2472
2473static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result,
2474			    __attribute__((unused)) struct cmdline *cl,
2475			    __attribute__((unused)) void *data)
2476{
2477	stop_packet_forwarding();
2478}
2479
2480cmdline_parse_token_string_t cmd_stop_stop =
2481	TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
2482
2483cmdline_parse_inst_t cmd_stop = {
2484	.f = cmd_stop_parsed,
2485	.data = NULL,
2486	.help_str = "stop - stop packet forwarding",
2487	.tokens = {
2488		(void *)&cmd_stop_stop,
2489		NULL,
2490	},
2491};
2492
2493/* *** SET CORELIST and PORTLIST CONFIGURATION *** */
2494
2495unsigned int
2496parse_item_list(char* str, const char* item_name, unsigned int max_items,
2497		unsigned int *parsed_items, int check_unique_values)
2498{
2499	unsigned int nb_item;
2500	unsigned int value;
2501	unsigned int i;
2502	unsigned int j;
2503	int value_ok;
2504	char c;
2505
2506	/*
2507	 * First parse all items in the list and store their value.
2508	 */
2509	value = 0;
2510	nb_item = 0;
2511	value_ok = 0;
2512	for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
2513		c = str[i];
2514		if ((c >= '0') && (c <= '9')) {
2515			value = (unsigned int) (value * 10 + (c - '0'));
2516			value_ok = 1;
2517			continue;
2518		}
2519		if (c != ',') {
2520			printf("character %c is not a decimal digit\n", c);
2521			return 0;
2522		}
2523		if (! value_ok) {
2524			printf("No valid value before comma\n");
2525			return 0;
2526		}
2527		if (nb_item < max_items) {
2528			parsed_items[nb_item] = value;
2529			value_ok = 0;
2530			value = 0;
2531		}
2532		nb_item++;
2533	}
2534	if (nb_item >= max_items) {
2535		printf("Number of %s = %u > %u (maximum items)\n",
2536		       item_name, nb_item + 1, max_items);
2537		return 0;
2538	}
2539	parsed_items[nb_item++] = value;
2540	if (! check_unique_values)
2541		return nb_item;
2542
2543	/*
2544	 * Then, check that all values in the list are differents.
2545	 * No optimization here...
2546	 */
2547	for (i = 0; i < nb_item; i++) {
2548		for (j = i + 1; j < nb_item; j++) {
2549			if (parsed_items[j] == parsed_items[i]) {
2550				printf("duplicated %s %u at index %u and %u\n",
2551				       item_name, parsed_items[i], i, j);
2552				return 0;
2553			}
2554		}
2555	}
2556	return nb_item;
2557}
2558
2559struct cmd_set_list_result {
2560	cmdline_fixed_string_t cmd_keyword;
2561	cmdline_fixed_string_t list_name;
2562	cmdline_fixed_string_t list_of_items;
2563};
2564
2565static void cmd_set_list_parsed(void *parsed_result,
2566				__attribute__((unused)) struct cmdline *cl,
2567				__attribute__((unused)) void *data)
2568{
2569	struct cmd_set_list_result *res;
2570	union {
2571		unsigned int lcorelist[RTE_MAX_LCORE];
2572		unsigned int portlist[RTE_MAX_ETHPORTS];
2573	} parsed_items;
2574	unsigned int nb_item;
2575
2576	if (test_done == 0) {
2577		printf("Please stop forwarding first\n");
2578		return;
2579	}
2580
2581	res = parsed_result;
2582	if (!strcmp(res->list_name, "corelist")) {
2583		nb_item = parse_item_list(res->list_of_items, "core",
2584					  RTE_MAX_LCORE,
2585					  parsed_items.lcorelist, 1);
2586		if (nb_item > 0) {
2587			set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
2588			fwd_config_setup();
2589		}
2590		return;
2591	}
2592	if (!strcmp(res->list_name, "portlist")) {
2593		nb_item = parse_item_list(res->list_of_items, "port",
2594					  RTE_MAX_ETHPORTS,
2595					  parsed_items.portlist, 1);
2596		if (nb_item > 0) {
2597			set_fwd_ports_list(parsed_items.portlist, nb_item);
2598			fwd_config_setup();
2599		}
2600	}
2601}
2602
2603cmdline_parse_token_string_t cmd_set_list_keyword =
2604	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
2605				 "set");
2606cmdline_parse_token_string_t cmd_set_list_name =
2607	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
2608				 "corelist#portlist");
2609cmdline_parse_token_string_t cmd_set_list_of_items =
2610	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
2611				 NULL);
2612
2613cmdline_parse_inst_t cmd_set_fwd_list = {
2614	.f = cmd_set_list_parsed,
2615	.data = NULL,
2616	.help_str = "set corelist|portlist x[,y]*",
2617	.tokens = {
2618		(void *)&cmd_set_list_keyword,
2619		(void *)&cmd_set_list_name,
2620		(void *)&cmd_set_list_of_items,
2621		NULL,
2622	},
2623};
2624
2625/* *** SET COREMASK and PORTMASK CONFIGURATION *** */
2626
2627struct cmd_setmask_result {
2628	cmdline_fixed_string_t set;
2629	cmdline_fixed_string_t mask;
2630	uint64_t hexavalue;
2631};
2632
2633static void cmd_set_mask_parsed(void *parsed_result,
2634				__attribute__((unused)) struct cmdline *cl,
2635				__attribute__((unused)) void *data)
2636{
2637	struct cmd_setmask_result *res = parsed_result;
2638
2639	if (test_done == 0) {
2640		printf("Please stop forwarding first\n");
2641		return;
2642	}
2643	if (!strcmp(res->mask, "coremask")) {
2644		set_fwd_lcores_mask(res->hexavalue);
2645		fwd_config_setup();
2646	} else if (!strcmp(res->mask, "portmask")) {
2647		set_fwd_ports_mask(res->hexavalue);
2648		fwd_config_setup();
2649	}
2650}
2651
2652cmdline_parse_token_string_t cmd_setmask_set =
2653	TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
2654cmdline_parse_token_string_t cmd_setmask_mask =
2655	TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
2656				 "coremask#portmask");
2657cmdline_parse_token_num_t cmd_setmask_value =
2658	TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, UINT64);
2659
2660cmdline_parse_inst_t cmd_set_fwd_mask = {
2661	.f = cmd_set_mask_parsed,
2662	.data = NULL,
2663	.help_str = "set coremask|portmask hexadecimal value",
2664	.tokens = {
2665		(void *)&cmd_setmask_set,
2666		(void *)&cmd_setmask_mask,
2667		(void *)&cmd_setmask_value,
2668		NULL,
2669	},
2670};
2671
2672/*
2673 * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
2674 */
2675struct cmd_set_result {
2676	cmdline_fixed_string_t set;
2677	cmdline_fixed_string_t what;
2678	uint16_t value;
2679};
2680
2681static void cmd_set_parsed(void *parsed_result,
2682			   __attribute__((unused)) struct cmdline *cl,
2683			   __attribute__((unused)) void *data)
2684{
2685	struct cmd_set_result *res = parsed_result;
2686	if (!strcmp(res->what, "nbport")) {
2687		set_fwd_ports_number(res->value);
2688		fwd_config_setup();
2689	} else if (!strcmp(res->what, "nbcore")) {
2690		set_fwd_lcores_number(res->value);
2691		fwd_config_setup();
2692	} else if (!strcmp(res->what, "burst"))
2693		set_nb_pkt_per_burst(res->value);
2694	else if (!strcmp(res->what, "verbose"))
2695		set_verbose_level(res->value);
2696}
2697
2698cmdline_parse_token_string_t cmd_set_set =
2699	TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
2700cmdline_parse_token_string_t cmd_set_what =
2701	TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
2702				 "nbport#nbcore#burst#verbose");
2703cmdline_parse_token_num_t cmd_set_value =
2704	TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
2705
2706cmdline_parse_inst_t cmd_set_numbers = {
2707	.f = cmd_set_parsed,
2708	.data = NULL,
2709	.help_str = "set nbport|nbcore|burst|verbose value",
2710	.tokens = {
2711		(void *)&cmd_set_set,
2712		(void *)&cmd_set_what,
2713		(void *)&cmd_set_value,
2714		NULL,
2715	},
2716};
2717
2718/* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
2719
2720struct cmd_set_txpkts_result {
2721	cmdline_fixed_string_t cmd_keyword;
2722	cmdline_fixed_string_t txpkts;
2723	cmdline_fixed_string_t seg_lengths;
2724};
2725
2726static void
2727cmd_set_txpkts_parsed(void *parsed_result,
2728		      __attribute__((unused)) struct cmdline *cl,
2729		      __attribute__((unused)) void *data)
2730{
2731	struct cmd_set_txpkts_result *res;
2732	unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
2733	unsigned int nb_segs;
2734
2735	res = parsed_result;
2736	nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
2737				  RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
2738	if (nb_segs > 0)
2739		set_tx_pkt_segments(seg_lengths, nb_segs);
2740}
2741
2742cmdline_parse_token_string_t cmd_set_txpkts_keyword =
2743	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2744				 cmd_keyword, "set");
2745cmdline_parse_token_string_t cmd_set_txpkts_name =
2746	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2747				 txpkts, "txpkts");
2748cmdline_parse_token_string_t cmd_set_txpkts_lengths =
2749	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2750				 seg_lengths, NULL);
2751
2752cmdline_parse_inst_t cmd_set_txpkts = {
2753	.f = cmd_set_txpkts_parsed,
2754	.data = NULL,
2755	.help_str = "set txpkts x[,y]*",
2756	.tokens = {
2757		(void *)&cmd_set_txpkts_keyword,
2758		(void *)&cmd_set_txpkts_name,
2759		(void *)&cmd_set_txpkts_lengths,
2760		NULL,
2761	},
2762};
2763
2764/* *** SET COPY AND SPLIT POLICY ON TX PACKETS *** */
2765
2766struct cmd_set_txsplit_result {
2767	cmdline_fixed_string_t cmd_keyword;
2768	cmdline_fixed_string_t txsplit;
2769	cmdline_fixed_string_t mode;
2770};
2771
2772static void
2773cmd_set_txsplit_parsed(void *parsed_result,
2774		      __attribute__((unused)) struct cmdline *cl,
2775		      __attribute__((unused)) void *data)
2776{
2777	struct cmd_set_txsplit_result *res;
2778
2779	res = parsed_result;
2780	set_tx_pkt_split(res->mode);
2781}
2782
2783cmdline_parse_token_string_t cmd_set_txsplit_keyword =
2784	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2785				 cmd_keyword, "set");
2786cmdline_parse_token_string_t cmd_set_txsplit_name =
2787	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2788				 txsplit, "txsplit");
2789cmdline_parse_token_string_t cmd_set_txsplit_mode =
2790	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2791				 mode, NULL);
2792
2793cmdline_parse_inst_t cmd_set_txsplit = {
2794	.f = cmd_set_txsplit_parsed,
2795	.data = NULL,
2796	.help_str = "set txsplit on|off|rand",
2797	.tokens = {
2798		(void *)&cmd_set_txsplit_keyword,
2799		(void *)&cmd_set_txsplit_name,
2800		(void *)&cmd_set_txsplit_mode,
2801		NULL,
2802	},
2803};
2804
2805/* *** CONFIG TX QUEUE FLAGS *** */
2806
2807struct cmd_config_txqflags_result {
2808	cmdline_fixed_string_t port;
2809	cmdline_fixed_string_t config;
2810	cmdline_fixed_string_t all;
2811	cmdline_fixed_string_t what;
2812	int32_t hexvalue;
2813};
2814
2815static void cmd_config_txqflags_parsed(void *parsed_result,
2816				__attribute__((unused)) struct cmdline *cl,
2817				__attribute__((unused)) void *data)
2818{
2819	struct cmd_config_txqflags_result *res = parsed_result;
2820
2821	if (!all_ports_stopped()) {
2822		printf("Please stop all ports first\n");
2823		return;
2824	}
2825
2826	if (strcmp(res->what, "txqflags")) {
2827		printf("Unknown parameter\n");
2828		return;
2829	}
2830
2831	if (res->hexvalue >= 0) {
2832		txq_flags = res->hexvalue;
2833	} else {
2834		printf("txqflags must be >= 0\n");
2835		return;
2836	}
2837
2838	init_port_config();
2839
2840	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2841}
2842
2843cmdline_parse_token_string_t cmd_config_txqflags_port =
2844	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, port,
2845				 "port");
2846cmdline_parse_token_string_t cmd_config_txqflags_config =
2847	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, config,
2848				 "config");
2849cmdline_parse_token_string_t cmd_config_txqflags_all =
2850	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, all,
2851				 "all");
2852cmdline_parse_token_string_t cmd_config_txqflags_what =
2853	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, what,
2854				 "txqflags");
2855cmdline_parse_token_num_t cmd_config_txqflags_value =
2856	TOKEN_NUM_INITIALIZER(struct cmd_config_txqflags_result,
2857				hexvalue, INT32);
2858
2859cmdline_parse_inst_t cmd_config_txqflags = {
2860	.f = cmd_config_txqflags_parsed,
2861	.data = NULL,
2862	.help_str = "port config all txqflags value",
2863	.tokens = {
2864		(void *)&cmd_config_txqflags_port,
2865		(void *)&cmd_config_txqflags_config,
2866		(void *)&cmd_config_txqflags_all,
2867		(void *)&cmd_config_txqflags_what,
2868		(void *)&cmd_config_txqflags_value,
2869		NULL,
2870	},
2871};
2872
2873/* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
2874struct cmd_rx_vlan_filter_all_result {
2875	cmdline_fixed_string_t rx_vlan;
2876	cmdline_fixed_string_t what;
2877	cmdline_fixed_string_t all;
2878	uint8_t port_id;
2879};
2880
2881static void
2882cmd_rx_vlan_filter_all_parsed(void *parsed_result,
2883			      __attribute__((unused)) struct cmdline *cl,
2884			      __attribute__((unused)) void *data)
2885{
2886	struct cmd_rx_vlan_filter_all_result *res = parsed_result;
2887
2888	if (!strcmp(res->what, "add"))
2889		rx_vlan_all_filter_set(res->port_id, 1);
2890	else
2891		rx_vlan_all_filter_set(res->port_id, 0);
2892}
2893
2894cmdline_parse_token_string_t cmd_rx_vlan_filter_all_rx_vlan =
2895	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2896				 rx_vlan, "rx_vlan");
2897cmdline_parse_token_string_t cmd_rx_vlan_filter_all_what =
2898	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2899				 what, "add#rm");
2900cmdline_parse_token_string_t cmd_rx_vlan_filter_all_all =
2901	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2902				 all, "all");
2903cmdline_parse_token_num_t cmd_rx_vlan_filter_all_portid =
2904	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2905			      port_id, UINT8);
2906
2907cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
2908	.f = cmd_rx_vlan_filter_all_parsed,
2909	.data = NULL,
2910	.help_str = "add/remove all identifiers to/from the set of VLAN "
2911	"Identifiers filtered by a port",
2912	.tokens = {
2913		(void *)&cmd_rx_vlan_filter_all_rx_vlan,
2914		(void *)&cmd_rx_vlan_filter_all_what,
2915		(void *)&cmd_rx_vlan_filter_all_all,
2916		(void *)&cmd_rx_vlan_filter_all_portid,
2917		NULL,
2918	},
2919};
2920
2921/* *** VLAN OFFLOAD SET ON A PORT *** */
2922struct cmd_vlan_offload_result {
2923	cmdline_fixed_string_t vlan;
2924	cmdline_fixed_string_t set;
2925	cmdline_fixed_string_t vlan_type;
2926	cmdline_fixed_string_t what;
2927	cmdline_fixed_string_t on;
2928	cmdline_fixed_string_t port_id;
2929};
2930
2931static void
2932cmd_vlan_offload_parsed(void *parsed_result,
2933			  __attribute__((unused)) struct cmdline *cl,
2934			  __attribute__((unused)) void *data)
2935{
2936	int on;
2937	struct cmd_vlan_offload_result *res = parsed_result;
2938	char *str;
2939	int i, len = 0;
2940	portid_t port_id = 0;
2941	unsigned int tmp;
2942
2943	str = res->port_id;
2944	len = strnlen(str, STR_TOKEN_SIZE);
2945	i = 0;
2946	/* Get port_id first */
2947	while(i < len){
2948		if(str[i] == ',')
2949			break;
2950
2951		i++;
2952	}
2953	str[i]='\0';
2954	tmp = strtoul(str, NULL, 0);
2955	/* If port_id greater that what portid_t can represent, return */
2956	if(tmp >= RTE_MAX_ETHPORTS)
2957		return;
2958	port_id = (portid_t)tmp;
2959
2960	if (!strcmp(res->on, "on"))
2961		on = 1;
2962	else
2963		on = 0;
2964
2965	if (!strcmp(res->what, "strip"))
2966		rx_vlan_strip_set(port_id,  on);
2967	else if(!strcmp(res->what, "stripq")){
2968		uint16_t queue_id = 0;
2969
2970		/* No queue_id, return */
2971		if(i + 1 >= len) {
2972			printf("must specify (port,queue_id)\n");
2973			return;
2974		}
2975		tmp = strtoul(str + i + 1, NULL, 0);
2976		/* If queue_id greater that what 16-bits can represent, return */
2977		if(tmp > 0xffff)
2978			return;
2979
2980		queue_id = (uint16_t)tmp;
2981		rx_vlan_strip_set_on_queue(port_id, queue_id, on);
2982	}
2983	else if (!strcmp(res->what, "filter"))
2984		rx_vlan_filter_set(port_id, on);
2985	else
2986		vlan_extend_set(port_id, on);
2987
2988	return;
2989}
2990
2991cmdline_parse_token_string_t cmd_vlan_offload_vlan =
2992	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2993				 vlan, "vlan");
2994cmdline_parse_token_string_t cmd_vlan_offload_set =
2995	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2996				 set, "set");
2997cmdline_parse_token_string_t cmd_vlan_offload_what =
2998	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2999				 what, "strip#filter#qinq#stripq");
3000cmdline_parse_token_string_t cmd_vlan_offload_on =
3001	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
3002			      on, "on#off");
3003cmdline_parse_token_string_t cmd_vlan_offload_portid =
3004	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
3005			      port_id, NULL);
3006
3007cmdline_parse_inst_t cmd_vlan_offload = {
3008	.f = cmd_vlan_offload_parsed,
3009	.data = NULL,
3010	.help_str = "set strip|filter|qinq|stripq on|off port_id[,queue_id], filter/strip for rx side"
3011	" qinq(extended) for both rx/tx sides ",
3012	.tokens = {
3013		(void *)&cmd_vlan_offload_vlan,
3014		(void *)&cmd_vlan_offload_set,
3015		(void *)&cmd_vlan_offload_what,
3016		(void *)&cmd_vlan_offload_on,
3017		(void *)&cmd_vlan_offload_portid,
3018		NULL,
3019	},
3020};
3021
3022/* *** VLAN TPID SET ON A PORT *** */
3023struct cmd_vlan_tpid_result {
3024	cmdline_fixed_string_t vlan;
3025	cmdline_fixed_string_t set;
3026	cmdline_fixed_string_t vlan_type;
3027	cmdline_fixed_string_t what;
3028	uint16_t tp_id;
3029	uint8_t port_id;
3030};
3031
3032static void
3033cmd_vlan_tpid_parsed(void *parsed_result,
3034			  __attribute__((unused)) struct cmdline *cl,
3035			  __attribute__((unused)) void *data)
3036{
3037	struct cmd_vlan_tpid_result *res = parsed_result;
3038	enum rte_vlan_type vlan_type;
3039
3040	if (!strcmp(res->vlan_type, "inner"))
3041		vlan_type = ETH_VLAN_TYPE_INNER;
3042	else if (!strcmp(res->vlan_type, "outer"))
3043		vlan_type = ETH_VLAN_TYPE_OUTER;
3044	else {
3045		printf("Unknown vlan type\n");
3046		return;
3047	}
3048	vlan_tpid_set(res->port_id, vlan_type, res->tp_id);
3049}
3050
3051cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
3052	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3053				 vlan, "vlan");
3054cmdline_parse_token_string_t cmd_vlan_tpid_set =
3055	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3056				 set, "set");
3057cmdline_parse_token_string_t cmd_vlan_type =
3058	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3059				 vlan_type, "inner#outer");
3060cmdline_parse_token_string_t cmd_vlan_tpid_what =
3061	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3062				 what, "tpid");
3063cmdline_parse_token_num_t cmd_vlan_tpid_tpid =
3064	TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
3065			      tp_id, UINT16);
3066cmdline_parse_token_num_t cmd_vlan_tpid_portid =
3067	TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
3068			      port_id, UINT8);
3069
3070cmdline_parse_inst_t cmd_vlan_tpid = {
3071	.f = cmd_vlan_tpid_parsed,
3072	.data = NULL,
3073	.help_str = "set inner|outer tpid tp_id port_id, set the VLAN "
3074		    "Ether type",
3075	.tokens = {
3076		(void *)&cmd_vlan_tpid_vlan,
3077		(void *)&cmd_vlan_tpid_set,
3078		(void *)&cmd_vlan_type,
3079		(void *)&cmd_vlan_tpid_what,
3080		(void *)&cmd_vlan_tpid_tpid,
3081		(void *)&cmd_vlan_tpid_portid,
3082		NULL,
3083	},
3084};
3085
3086/* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
3087struct cmd_rx_vlan_filter_result {
3088	cmdline_fixed_string_t rx_vlan;
3089	cmdline_fixed_string_t what;
3090	uint16_t vlan_id;
3091	uint8_t port_id;
3092};
3093
3094static void
3095cmd_rx_vlan_filter_parsed(void *parsed_result,
3096			  __attribute__((unused)) struct cmdline *cl,
3097			  __attribute__((unused)) void *data)
3098{
3099	struct cmd_rx_vlan_filter_result *res = parsed_result;
3100
3101	if (!strcmp(res->what, "add"))
3102		rx_vft_set(res->port_id, res->vlan_id, 1);
3103	else
3104		rx_vft_set(res->port_id, res->vlan_id, 0);
3105}
3106
3107cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
3108	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
3109				 rx_vlan, "rx_vlan");
3110cmdline_parse_token_string_t cmd_rx_vlan_filter_what =
3111	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
3112				 what, "add#rm");
3113cmdline_parse_token_num_t cmd_rx_vlan_filter_vlanid =
3114	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
3115			      vlan_id, UINT16);
3116cmdline_parse_token_num_t cmd_rx_vlan_filter_portid =
3117	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
3118			      port_id, UINT8);
3119
3120cmdline_parse_inst_t cmd_rx_vlan_filter = {
3121	.f = cmd_rx_vlan_filter_parsed,
3122	.data = NULL,
3123	.help_str = "add/remove a VLAN identifier to/from the set of VLAN "
3124	"Identifiers filtered by a port",
3125	.tokens = {
3126		(void *)&cmd_rx_vlan_filter_rx_vlan,
3127		(void *)&cmd_rx_vlan_filter_what,
3128		(void *)&cmd_rx_vlan_filter_vlanid,
3129		(void *)&cmd_rx_vlan_filter_portid,
3130		NULL,
3131	},
3132};
3133
3134/* *** ENABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
3135struct cmd_tx_vlan_set_result {
3136	cmdline_fixed_string_t tx_vlan;
3137	cmdline_fixed_string_t set;
3138	uint8_t port_id;
3139	uint16_t vlan_id;
3140};
3141
3142static void
3143cmd_tx_vlan_set_parsed(void *parsed_result,
3144		       __attribute__((unused)) struct cmdline *cl,
3145		       __attribute__((unused)) void *data)
3146{
3147	struct cmd_tx_vlan_set_result *res = parsed_result;
3148
3149	tx_vlan_set(res->port_id, res->vlan_id);
3150}
3151
3152cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan =
3153	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
3154				 tx_vlan, "tx_vlan");
3155cmdline_parse_token_string_t cmd_tx_vlan_set_set =
3156	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
3157				 set, "set");
3158cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
3159	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
3160			      port_id, UINT8);
3161cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid =
3162	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
3163			      vlan_id, UINT16);
3164
3165cmdline_parse_inst_t cmd_tx_vlan_set = {
3166	.f = cmd_tx_vlan_set_parsed,
3167	.data = NULL,
3168	.help_str = "enable hardware insertion of a single VLAN header "
3169		"with a given TAG Identifier in packets sent on a port",
3170	.tokens = {
3171		(void *)&cmd_tx_vlan_set_tx_vlan,
3172		(void *)&cmd_tx_vlan_set_set,
3173		(void *)&cmd_tx_vlan_set_portid,
3174		(void *)&cmd_tx_vlan_set_vlanid,
3175		NULL,
3176	},
3177};
3178
3179/* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
3180struct cmd_tx_vlan_set_qinq_result {
3181	cmdline_fixed_string_t tx_vlan;
3182	cmdline_fixed_string_t set;
3183	uint8_t port_id;
3184	uint16_t vlan_id;
3185	uint16_t vlan_id_outer;
3186};
3187
3188static void
3189cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
3190			    __attribute__((unused)) struct cmdline *cl,
3191			    __attribute__((unused)) void *data)
3192{
3193	struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
3194
3195	tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
3196}
3197
3198cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
3199	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3200		tx_vlan, "tx_vlan");
3201cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
3202	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3203		set, "set");
3204cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
3205	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3206		port_id, UINT8);
3207cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
3208	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3209		vlan_id, UINT16);
3210cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
3211	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3212		vlan_id_outer, UINT16);
3213
3214cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
3215	.f = cmd_tx_vlan_set_qinq_parsed,
3216	.data = NULL,
3217	.help_str = "enable hardware insertion of double VLAN header "
3218		"with given TAG Identifiers in packets sent on a port",
3219	.tokens = {
3220		(void *)&cmd_tx_vlan_set_qinq_tx_vlan,
3221		(void *)&cmd_tx_vlan_set_qinq_set,
3222		(void *)&cmd_tx_vlan_set_qinq_portid,
3223		(void *)&cmd_tx_vlan_set_qinq_vlanid,
3224		(void *)&cmd_tx_vlan_set_qinq_vlanid_outer,
3225		NULL,
3226	},
3227};
3228
3229/* *** ENABLE/DISABLE PORT BASED TX VLAN INSERTION *** */
3230struct cmd_tx_vlan_set_pvid_result {
3231	cmdline_fixed_string_t tx_vlan;
3232	cmdline_fixed_string_t set;
3233	cmdline_fixed_string_t pvid;
3234	uint8_t port_id;
3235	uint16_t vlan_id;
3236	cmdline_fixed_string_t mode;
3237};
3238
3239static void
3240cmd_tx_vlan_set_pvid_parsed(void *parsed_result,
3241			    __attribute__((unused)) struct cmdline *cl,
3242			    __attribute__((unused)) void *data)
3243{
3244	struct cmd_tx_vlan_set_pvid_result *res = parsed_result;
3245
3246	if (strcmp(res->mode, "on") == 0)
3247		tx_vlan_pvid_set(res->port_id, res->vlan_id, 1);
3248	else
3249		tx_vlan_pvid_set(res->port_id, res->vlan_id, 0);
3250}
3251
3252cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_tx_vlan =
3253	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3254				 tx_vlan, "tx_vlan");
3255cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_set =
3256	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3257				 set, "set");
3258cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_pvid =
3259	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3260				 pvid, "pvid");
3261cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_port_id =
3262	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3263			     port_id, UINT8);
3264cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_vlan_id =
3265	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3266			      vlan_id, UINT16);
3267cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_mode =
3268	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3269				 mode, "on#off");
3270
3271cmdline_parse_inst_t cmd_tx_vlan_set_pvid = {
3272	.f = cmd_tx_vlan_set_pvid_parsed,
3273	.data = NULL,
3274	.help_str = "tx_vlan set pvid port_id vlan_id (on|off)",
3275	.tokens = {
3276		(void *)&cmd_tx_vlan_set_pvid_tx_vlan,
3277		(void *)&cmd_tx_vlan_set_pvid_set,
3278		(void *)&cmd_tx_vlan_set_pvid_pvid,
3279		(void *)&cmd_tx_vlan_set_pvid_port_id,
3280		(void *)&cmd_tx_vlan_set_pvid_vlan_id,
3281		(void *)&cmd_tx_vlan_set_pvid_mode,
3282		NULL,
3283	},
3284};
3285
3286/* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
3287struct cmd_tx_vlan_reset_result {
3288	cmdline_fixed_string_t tx_vlan;
3289	cmdline_fixed_string_t reset;
3290	uint8_t port_id;
3291};
3292
3293static void
3294cmd_tx_vlan_reset_parsed(void *parsed_result,
3295			 __attribute__((unused)) struct cmdline *cl,
3296			 __attribute__((unused)) void *data)
3297{
3298	struct cmd_tx_vlan_reset_result *res = parsed_result;
3299
3300	tx_vlan_reset(res->port_id);
3301}
3302
3303cmdline_parse_token_string_t cmd_tx_vlan_reset_tx_vlan =
3304	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
3305				 tx_vlan, "tx_vlan");
3306cmdline_parse_token_string_t cmd_tx_vlan_reset_reset =
3307	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
3308				 reset, "reset");
3309cmdline_parse_token_num_t cmd_tx_vlan_reset_portid =
3310	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_reset_result,
3311			      port_id, UINT8);
3312
3313cmdline_parse_inst_t cmd_tx_vlan_reset = {
3314	.f = cmd_tx_vlan_reset_parsed,
3315	.data = NULL,
3316	.help_str = "disable hardware insertion of a VLAN header in packets "
3317	"sent on a port",
3318	.tokens = {
3319		(void *)&cmd_tx_vlan_reset_tx_vlan,
3320		(void *)&cmd_tx_vlan_reset_reset,
3321		(void *)&cmd_tx_vlan_reset_portid,
3322		NULL,
3323	},
3324};
3325
3326
3327/* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
3328struct cmd_csum_result {
3329	cmdline_fixed_string_t csum;
3330	cmdline_fixed_string_t mode;
3331	cmdline_fixed_string_t proto;
3332	cmdline_fixed_string_t hwsw;
3333	uint8_t port_id;
3334};
3335
3336static void
3337csum_show(int port_id)
3338{
3339	struct rte_eth_dev_info dev_info;
3340	uint16_t ol_flags;
3341
3342	ol_flags = ports[port_id].tx_ol_flags;
3343	printf("Parse tunnel is %s\n",
3344		(ol_flags & TESTPMD_TX_OFFLOAD_PARSE_TUNNEL) ? "on" : "off");
3345	printf("IP checksum offload is %s\n",
3346		(ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) ? "hw" : "sw");
3347	printf("UDP checksum offload is %s\n",
3348		(ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) ? "hw" : "sw");
3349	printf("TCP checksum offload is %s\n",
3350		(ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw");
3351	printf("SCTP checksum offload is %s\n",
3352		(ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw");
3353	printf("Outer-Ip checksum offload is %s\n",
3354		(ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) ? "hw" : "sw");
3355
3356	/* display warnings if configuration is not supported by the NIC */
3357	rte_eth_dev_info_get(port_id, &dev_info);
3358	if ((ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) &&
3359		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) {
3360		printf("Warning: hardware IP checksum enabled but not "
3361			"supported by port %d\n", port_id);
3362	}
3363	if ((ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) &&
3364		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) {
3365		printf("Warning: hardware UDP checksum enabled but not "
3366			"supported by port %d\n", port_id);
3367	}
3368	if ((ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) &&
3369		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) {
3370		printf("Warning: hardware TCP checksum enabled but not "
3371			"supported by port %d\n", port_id);
3372	}
3373	if ((ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) &&
3374		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) == 0) {
3375		printf("Warning: hardware SCTP checksum enabled but not "
3376			"supported by port %d\n", port_id);
3377	}
3378	if ((ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) &&
3379		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) == 0) {
3380		printf("Warning: hardware outer IP checksum enabled but not "
3381			"supported by port %d\n", port_id);
3382	}
3383}
3384
3385static void
3386cmd_csum_parsed(void *parsed_result,
3387		       __attribute__((unused)) struct cmdline *cl,
3388		       __attribute__((unused)) void *data)
3389{
3390	struct cmd_csum_result *res = parsed_result;
3391	int hw = 0;
3392	uint16_t mask = 0;
3393
3394	if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
3395		printf("invalid port %d\n", res->port_id);
3396		return;
3397	}
3398
3399	if (!strcmp(res->mode, "set")) {
3400
3401		if (!strcmp(res->hwsw, "hw"))
3402			hw = 1;
3403
3404		if (!strcmp(res->proto, "ip")) {
3405			mask = TESTPMD_TX_OFFLOAD_IP_CKSUM;
3406		} else if (!strcmp(res->proto, "udp")) {
3407			mask = TESTPMD_TX_OFFLOAD_UDP_CKSUM;
3408		} else if (!strcmp(res->proto, "tcp")) {
3409			mask = TESTPMD_TX_OFFLOAD_TCP_CKSUM;
3410		} else if (!strcmp(res->proto, "sctp")) {
3411			mask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM;
3412		} else if (!strcmp(res->proto, "outer-ip")) {
3413			mask = TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM;
3414		}
3415
3416		if (hw)
3417			ports[res->port_id].tx_ol_flags |= mask;
3418		else
3419			ports[res->port_id].tx_ol_flags &= (~mask);
3420	}
3421	csum_show(res->port_id);
3422}
3423
3424cmdline_parse_token_string_t cmd_csum_csum =
3425	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3426				csum, "csum");
3427cmdline_parse_token_string_t cmd_csum_mode =
3428	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3429				mode, "set");
3430cmdline_parse_token_string_t cmd_csum_proto =
3431	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3432				proto, "ip#tcp#udp#sctp#outer-ip");
3433cmdline_parse_token_string_t cmd_csum_hwsw =
3434	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3435				hwsw, "hw#sw");
3436cmdline_parse_token_num_t cmd_csum_portid =
3437	TOKEN_NUM_INITIALIZER(struct cmd_csum_result,
3438				port_id, UINT8);
3439
3440cmdline_parse_inst_t cmd_csum_set = {
3441	.f = cmd_csum_parsed,
3442	.data = NULL,
3443	.help_str = "enable/disable hardware calculation of L3/L4 checksum when "
3444		"using csum forward engine: csum set ip|tcp|udp|sctp|outer-ip hw|sw <port>",
3445	.tokens = {
3446		(void *)&cmd_csum_csum,
3447		(void *)&cmd_csum_mode,
3448		(void *)&cmd_csum_proto,
3449		(void *)&cmd_csum_hwsw,
3450		(void *)&cmd_csum_portid,
3451		NULL,
3452	},
3453};
3454
3455cmdline_parse_token_string_t cmd_csum_mode_show =
3456	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3457				mode, "show");
3458
3459cmdline_parse_inst_t cmd_csum_show = {
3460	.f = cmd_csum_parsed,
3461	.data = NULL,
3462	.help_str = "show checksum offload configuration: csum show <port>",
3463	.tokens = {
3464		(void *)&cmd_csum_csum,
3465		(void *)&cmd_csum_mode_show,
3466		(void *)&cmd_csum_portid,
3467		NULL,
3468	},
3469};
3470
3471/* Enable/disable tunnel parsing */
3472struct cmd_csum_tunnel_result {
3473	cmdline_fixed_string_t csum;
3474	cmdline_fixed_string_t parse;
3475	cmdline_fixed_string_t onoff;
3476	uint8_t port_id;
3477};
3478
3479static void
3480cmd_csum_tunnel_parsed(void *parsed_result,
3481		       __attribute__((unused)) struct cmdline *cl,
3482		       __attribute__((unused)) void *data)
3483{
3484	struct cmd_csum_tunnel_result *res = parsed_result;
3485
3486	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3487		return;
3488
3489	if (!strcmp(res->onoff, "on"))
3490		ports[res->port_id].tx_ol_flags |=
3491			TESTPMD_TX_OFFLOAD_PARSE_TUNNEL;
3492	else
3493		ports[res->port_id].tx_ol_flags &=
3494			(~TESTPMD_TX_OFFLOAD_PARSE_TUNNEL);
3495
3496	csum_show(res->port_id);
3497}
3498
3499cmdline_parse_token_string_t cmd_csum_tunnel_csum =
3500	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3501				csum, "csum");
3502cmdline_parse_token_string_t cmd_csum_tunnel_parse =
3503	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3504				parse, "parse_tunnel");
3505cmdline_parse_token_string_t cmd_csum_tunnel_onoff =
3506	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3507				onoff, "on#off");
3508cmdline_parse_token_num_t cmd_csum_tunnel_portid =
3509	TOKEN_NUM_INITIALIZER(struct cmd_csum_tunnel_result,
3510				port_id, UINT8);
3511
3512cmdline_parse_inst_t cmd_csum_tunnel = {
3513	.f = cmd_csum_tunnel_parsed,
3514	.data = NULL,
3515	.help_str = "enable/disable parsing of tunnels for csum engine: "
3516	"csum parse_tunnel on|off <tx-port>",
3517	.tokens = {
3518		(void *)&cmd_csum_tunnel_csum,
3519		(void *)&cmd_csum_tunnel_parse,
3520		(void *)&cmd_csum_tunnel_onoff,
3521		(void *)&cmd_csum_tunnel_portid,
3522		NULL,
3523	},
3524};
3525
3526/* *** ENABLE HARDWARE SEGMENTATION IN TX NON-TUNNELED PACKETS *** */
3527struct cmd_tso_set_result {
3528	cmdline_fixed_string_t tso;
3529	cmdline_fixed_string_t mode;
3530	uint16_t tso_segsz;
3531	uint8_t port_id;
3532};
3533
3534static void
3535cmd_tso_set_parsed(void *parsed_result,
3536		       __attribute__((unused)) struct cmdline *cl,
3537		       __attribute__((unused)) void *data)
3538{
3539	struct cmd_tso_set_result *res = parsed_result;
3540	struct rte_eth_dev_info dev_info;
3541
3542	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3543		return;
3544
3545	if (!strcmp(res->mode, "set"))
3546		ports[res->port_id].tso_segsz = res->tso_segsz;
3547
3548	if (ports[res->port_id].tso_segsz == 0)
3549		printf("TSO for non-tunneled packets is disabled\n");
3550	else
3551		printf("TSO segment size for non-tunneled packets is %d\n",
3552			ports[res->port_id].tso_segsz);
3553
3554	/* display warnings if configuration is not supported by the NIC */
3555	rte_eth_dev_info_get(res->port_id, &dev_info);
3556	if ((ports[res->port_id].tso_segsz != 0) &&
3557		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) {
3558		printf("Warning: TSO enabled but not "
3559			"supported by port %d\n", res->port_id);
3560	}
3561}
3562
3563cmdline_parse_token_string_t cmd_tso_set_tso =
3564	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3565				tso, "tso");
3566cmdline_parse_token_string_t cmd_tso_set_mode =
3567	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3568				mode, "set");
3569cmdline_parse_token_num_t cmd_tso_set_tso_segsz =
3570	TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
3571				tso_segsz, UINT16);
3572cmdline_parse_token_num_t cmd_tso_set_portid =
3573	TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
3574				port_id, UINT8);
3575
3576cmdline_parse_inst_t cmd_tso_set = {
3577	.f = cmd_tso_set_parsed,
3578	.data = NULL,
3579	.help_str = "Set TSO segment size of non-tunneled packets "
3580	"for csum engine (0 to disable): tso set <tso_segsz> <port>",
3581	.tokens = {
3582		(void *)&cmd_tso_set_tso,
3583		(void *)&cmd_tso_set_mode,
3584		(void *)&cmd_tso_set_tso_segsz,
3585		(void *)&cmd_tso_set_portid,
3586		NULL,
3587	},
3588};
3589
3590cmdline_parse_token_string_t cmd_tso_show_mode =
3591	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3592				mode, "show");
3593
3594
3595cmdline_parse_inst_t cmd_tso_show = {
3596	.f = cmd_tso_set_parsed,
3597	.data = NULL,
3598	.help_str = "Show TSO segment size of non-tunneled packets "
3599	"for csum engine: tso show <port>",
3600	.tokens = {
3601		(void *)&cmd_tso_set_tso,
3602		(void *)&cmd_tso_show_mode,
3603		(void *)&cmd_tso_set_portid,
3604		NULL,
3605	},
3606};
3607
3608/* *** ENABLE HARDWARE SEGMENTATION IN TX TUNNELED PACKETS *** */
3609struct cmd_tunnel_tso_set_result {
3610	cmdline_fixed_string_t tso;
3611	cmdline_fixed_string_t mode;
3612	uint16_t tso_segsz;
3613	uint8_t port_id;
3614};
3615
3616static void
3617check_tunnel_tso_nic_support(uint8_t port_id)
3618{
3619	struct rte_eth_dev_info dev_info;
3620
3621	rte_eth_dev_info_get(port_id, &dev_info);
3622	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO))
3623		printf("Warning: TSO enabled but VXLAN TUNNEL TSO not "
3624		       "supported by port %d\n", port_id);
3625	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GRE_TNL_TSO))
3626		printf("Warning: TSO enabled but GRE TUNNEL TSO not "
3627			"supported by port %d\n", port_id);
3628	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPIP_TNL_TSO))
3629		printf("Warning: TSO enabled but IPIP TUNNEL TSO not "
3630		       "supported by port %d\n", port_id);
3631	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GENEVE_TNL_TSO))
3632		printf("Warning: TSO enabled but GENEVE TUNNEL TSO not "
3633		       "supported by port %d\n", port_id);
3634}
3635
3636static void
3637cmd_tunnel_tso_set_parsed(void *parsed_result,
3638			  __attribute__((unused)) struct cmdline *cl,
3639			  __attribute__((unused)) void *data)
3640{
3641	struct cmd_tunnel_tso_set_result *res = parsed_result;
3642
3643	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3644		return;
3645
3646	if (!strcmp(res->mode, "set"))
3647		ports[res->port_id].tunnel_tso_segsz = res->tso_segsz;
3648
3649	if (ports[res->port_id].tunnel_tso_segsz == 0)
3650		printf("TSO for tunneled packets is disabled\n");
3651	else {
3652		printf("TSO segment size for tunneled packets is %d\n",
3653			ports[res->port_id].tunnel_tso_segsz);
3654
3655		/* Below conditions are needed to make it work:
3656		 * (1) tunnel TSO is supported by the NIC;
3657		 * (2) "csum parse_tunnel" must be set so that tunneled pkts
3658		 * are recognized;
3659		 * (3) for tunneled pkts with outer L3 of IPv4,
3660		 * "csum set outer-ip" must be set to hw, because after tso,
3661		 * total_len of outer IP header is changed, and the checksum
3662		 * of outer IP header calculated by sw should be wrong; that
3663		 * is not necessary for IPv6 tunneled pkts because there's no
3664		 * checksum in IP header anymore.
3665		 */
3666		check_tunnel_tso_nic_support(res->port_id);
3667
3668		if (!(ports[res->port_id].tx_ol_flags &
3669		      TESTPMD_TX_OFFLOAD_PARSE_TUNNEL))
3670			printf("Warning: csum parse_tunnel must be set "
3671				"so that tunneled packets are recognized\n");
3672		if (!(ports[res->port_id].tx_ol_flags &
3673		      TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM))
3674			printf("Warning: csum set outer-ip must be set to hw "
3675				"if outer L3 is IPv4; not necessary for IPv6\n");
3676	}
3677}
3678
3679cmdline_parse_token_string_t cmd_tunnel_tso_set_tso =
3680	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
3681				tso, "tunnel_tso");
3682cmdline_parse_token_string_t cmd_tunnel_tso_set_mode =
3683	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
3684				mode, "set");
3685cmdline_parse_token_num_t cmd_tunnel_tso_set_tso_segsz =
3686	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_tso_set_result,
3687				tso_segsz, UINT16);
3688cmdline_parse_token_num_t cmd_tunnel_tso_set_portid =
3689	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_tso_set_result,
3690				port_id, UINT8);
3691
3692cmdline_parse_inst_t cmd_tunnel_tso_set = {
3693	.f = cmd_tunnel_tso_set_parsed,
3694	.data = NULL,
3695	.help_str = "Set TSO segment size of tunneled packets for csum engine "
3696	"(0 to disable): tunnel_tso set <tso_segsz> <port>",
3697	.tokens = {
3698		(void *)&cmd_tunnel_tso_set_tso,
3699		(void *)&cmd_tunnel_tso_set_mode,
3700		(void *)&cmd_tunnel_tso_set_tso_segsz,
3701		(void *)&cmd_tunnel_tso_set_portid,
3702		NULL,
3703	},
3704};
3705
3706cmdline_parse_token_string_t cmd_tunnel_tso_show_mode =
3707	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
3708				mode, "show");
3709
3710
3711cmdline_parse_inst_t cmd_tunnel_tso_show = {
3712	.f = cmd_tunnel_tso_set_parsed,
3713	.data = NULL,
3714	.help_str = "Show TSO segment size of tunneled packets "
3715	"for csum engine: tunnel_tso show <port>",
3716	.tokens = {
3717		(void *)&cmd_tunnel_tso_set_tso,
3718		(void *)&cmd_tunnel_tso_show_mode,
3719		(void *)&cmd_tunnel_tso_set_portid,
3720		NULL,
3721	},
3722};
3723
3724/* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
3725struct cmd_set_flush_rx {
3726	cmdline_fixed_string_t set;
3727	cmdline_fixed_string_t flush_rx;
3728	cmdline_fixed_string_t mode;
3729};
3730
3731static void
3732cmd_set_flush_rx_parsed(void *parsed_result,
3733		__attribute__((unused)) struct cmdline *cl,
3734		__attribute__((unused)) void *data)
3735{
3736	struct cmd_set_flush_rx *res = parsed_result;
3737	no_flush_rx = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
3738}
3739
3740cmdline_parse_token_string_t cmd_setflushrx_set =
3741	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3742			set, "set");
3743cmdline_parse_token_string_t cmd_setflushrx_flush_rx =
3744	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3745			flush_rx, "flush_rx");
3746cmdline_parse_token_string_t cmd_setflushrx_mode =
3747	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3748			mode, "on#off");
3749
3750
3751cmdline_parse_inst_t cmd_set_flush_rx = {
3752	.f = cmd_set_flush_rx_parsed,
3753	.help_str = "set flush_rx on|off: enable/disable flush on rx streams",
3754	.data = NULL,
3755	.tokens = {
3756		(void *)&cmd_setflushrx_set,
3757		(void *)&cmd_setflushrx_flush_rx,
3758		(void *)&cmd_setflushrx_mode,
3759		NULL,
3760	},
3761};
3762
3763/* *** ENABLE/DISABLE LINK STATUS CHECK *** */
3764struct cmd_set_link_check {
3765	cmdline_fixed_string_t set;
3766	cmdline_fixed_string_t link_check;
3767	cmdline_fixed_string_t mode;
3768};
3769
3770static void
3771cmd_set_link_check_parsed(void *parsed_result,
3772		__attribute__((unused)) struct cmdline *cl,
3773		__attribute__((unused)) void *data)
3774{
3775	struct cmd_set_link_check *res = parsed_result;
3776	no_link_check = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
3777}
3778
3779cmdline_parse_token_string_t cmd_setlinkcheck_set =
3780	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3781			set, "set");
3782cmdline_parse_token_string_t cmd_setlinkcheck_link_check =
3783	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3784			link_check, "link_check");
3785cmdline_parse_token_string_t cmd_setlinkcheck_mode =
3786	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3787			mode, "on#off");
3788
3789
3790cmdline_parse_inst_t cmd_set_link_check = {
3791	.f = cmd_set_link_check_parsed,
3792	.help_str = "set link_check on|off: enable/disable link status check "
3793	            "when starting/stopping a port",
3794	.data = NULL,
3795	.tokens = {
3796		(void *)&cmd_setlinkcheck_set,
3797		(void *)&cmd_setlinkcheck_link_check,
3798		(void *)&cmd_setlinkcheck_mode,
3799		NULL,
3800	},
3801};
3802
3803#ifdef RTE_NIC_BYPASS
3804/* *** SET NIC BYPASS MODE *** */
3805struct cmd_set_bypass_mode_result {
3806	cmdline_fixed_string_t set;
3807	cmdline_fixed_string_t bypass;
3808	cmdline_fixed_string_t mode;
3809	cmdline_fixed_string_t value;
3810	uint8_t port_id;
3811};
3812
3813static void
3814cmd_set_bypass_mode_parsed(void *parsed_result,
3815		__attribute__((unused)) struct cmdline *cl,
3816		__attribute__((unused)) void *data)
3817{
3818	struct cmd_set_bypass_mode_result *res = parsed_result;
3819	portid_t port_id = res->port_id;
3820	uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
3821
3822	if (!strcmp(res->value, "bypass"))
3823		bypass_mode = RTE_BYPASS_MODE_BYPASS;
3824	else if (!strcmp(res->value, "isolate"))
3825		bypass_mode = RTE_BYPASS_MODE_ISOLATE;
3826	else
3827		bypass_mode = RTE_BYPASS_MODE_NORMAL;
3828
3829	/* Set the bypass mode for the relevant port. */
3830	if (0 != rte_eth_dev_bypass_state_set(port_id, &bypass_mode)) {
3831		printf("\t Failed to set bypass mode for port = %d.\n", port_id);
3832	}
3833}
3834
3835cmdline_parse_token_string_t cmd_setbypass_mode_set =
3836	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3837			set, "set");
3838cmdline_parse_token_string_t cmd_setbypass_mode_bypass =
3839	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3840			bypass, "bypass");
3841cmdline_parse_token_string_t cmd_setbypass_mode_mode =
3842	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3843			mode, "mode");
3844cmdline_parse_token_string_t cmd_setbypass_mode_value =
3845	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3846			value, "normal#bypass#isolate");
3847cmdline_parse_token_num_t cmd_setbypass_mode_port =
3848	TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_mode_result,
3849				port_id, UINT8);
3850
3851cmdline_parse_inst_t cmd_set_bypass_mode = {
3852	.f = cmd_set_bypass_mode_parsed,
3853	.help_str = "set bypass mode (normal|bypass|isolate) (port_id): "
3854	            "Set the NIC bypass mode for port_id",
3855	.data = NULL,
3856	.tokens = {
3857		(void *)&cmd_setbypass_mode_set,
3858		(void *)&cmd_setbypass_mode_bypass,
3859		(void *)&cmd_setbypass_mode_mode,
3860		(void *)&cmd_setbypass_mode_value,
3861		(void *)&cmd_setbypass_mode_port,
3862		NULL,
3863	},
3864};
3865
3866/* *** SET NIC BYPASS EVENT *** */
3867struct cmd_set_bypass_event_result {
3868	cmdline_fixed_string_t set;
3869	cmdline_fixed_string_t bypass;
3870	cmdline_fixed_string_t event;
3871	cmdline_fixed_string_t event_value;
3872	cmdline_fixed_string_t mode;
3873	cmdline_fixed_string_t mode_value;
3874	uint8_t port_id;
3875};
3876
3877static void
3878cmd_set_bypass_event_parsed(void *parsed_result,
3879		__attribute__((unused)) struct cmdline *cl,
3880		__attribute__((unused)) void *data)
3881{
3882	int32_t rc;
3883	struct cmd_set_bypass_event_result *res = parsed_result;
3884	portid_t port_id = res->port_id;
3885	uint32_t bypass_event = RTE_BYPASS_EVENT_NONE;
3886	uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
3887
3888	if (!strcmp(res->event_value, "timeout"))
3889		bypass_event = RTE_BYPASS_EVENT_TIMEOUT;
3890	else if (!strcmp(res->event_value, "os_on"))
3891		bypass_event = RTE_BYPASS_EVENT_OS_ON;
3892	else if (!strcmp(res->event_value, "os_off"))
3893		bypass_event = RTE_BYPASS_EVENT_OS_OFF;
3894	else if (!strcmp(res->event_value, "power_on"))
3895		bypass_event = RTE_BYPASS_EVENT_POWER_ON;
3896	else if (!strcmp(res->event_value, "power_off"))
3897		bypass_event = RTE_BYPASS_EVENT_POWER_OFF;
3898	else
3899		bypass_event = RTE_BYPASS_EVENT_NONE;
3900
3901	if (!strcmp(res->mode_value, "bypass"))
3902		bypass_mode = RTE_BYPASS_MODE_BYPASS;
3903	else if (!strcmp(res->mode_value, "isolate"))
3904		bypass_mode = RTE_BYPASS_MODE_ISOLATE;
3905	else
3906		bypass_mode = RTE_BYPASS_MODE_NORMAL;
3907
3908	/* Set the watchdog timeout. */
3909	if (bypass_event == RTE_BYPASS_EVENT_TIMEOUT) {
3910
3911		rc = -EINVAL;
3912		if (!RTE_BYPASS_TMT_VALID(bypass_timeout) ||
3913				(rc = rte_eth_dev_wd_timeout_store(port_id,
3914				bypass_timeout)) != 0) {
3915			printf("Failed to set timeout value %u "
3916				"for port %d, errto code: %d.\n",
3917				bypass_timeout, port_id, rc);
3918		}
3919	}
3920
3921	/* Set the bypass event to transition to bypass mode. */
3922	if (0 != rte_eth_dev_bypass_event_store(port_id,
3923			bypass_event, bypass_mode)) {
3924		printf("\t Failed to set bypass event for port = %d.\n", port_id);
3925	}
3926
3927}
3928
3929cmdline_parse_token_string_t cmd_setbypass_event_set =
3930	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3931			set, "set");
3932cmdline_parse_token_string_t cmd_setbypass_event_bypass =
3933	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3934			bypass, "bypass");
3935cmdline_parse_token_string_t cmd_setbypass_event_event =
3936	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3937			event, "event");
3938cmdline_parse_token_string_t cmd_setbypass_event_event_value =
3939	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3940			event_value, "none#timeout#os_off#os_on#power_on#power_off");
3941cmdline_parse_token_string_t cmd_setbypass_event_mode =
3942	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3943			mode, "mode");
3944cmdline_parse_token_string_t cmd_setbypass_event_mode_value =
3945	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3946			mode_value, "normal#bypass#isolate");
3947cmdline_parse_token_num_t cmd_setbypass_event_port =
3948	TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_event_result,
3949				port_id, UINT8);
3950
3951cmdline_parse_inst_t cmd_set_bypass_event = {
3952	.f = cmd_set_bypass_event_parsed,
3953	.help_str = "set bypass event (timeout|os_on|os_off|power_on|power_off) "
3954	            "mode (normal|bypass|isolate) (port_id): "
3955	            "Set the NIC bypass event mode for port_id",
3956	.data = NULL,
3957	.tokens = {
3958		(void *)&cmd_setbypass_event_set,
3959		(void *)&cmd_setbypass_event_bypass,
3960		(void *)&cmd_setbypass_event_event,
3961		(void *)&cmd_setbypass_event_event_value,
3962		(void *)&cmd_setbypass_event_mode,
3963		(void *)&cmd_setbypass_event_mode_value,
3964		(void *)&cmd_setbypass_event_port,
3965		NULL,
3966	},
3967};
3968
3969
3970/* *** SET NIC BYPASS TIMEOUT *** */
3971struct cmd_set_bypass_timeout_result {
3972	cmdline_fixed_string_t set;
3973	cmdline_fixed_string_t bypass;
3974	cmdline_fixed_string_t timeout;
3975	cmdline_fixed_string_t value;
3976};
3977
3978static void
3979cmd_set_bypass_timeout_parsed(void *parsed_result,
3980		__attribute__((unused)) struct cmdline *cl,
3981		__attribute__((unused)) void *data)
3982{
3983	struct cmd_set_bypass_timeout_result *res = parsed_result;
3984
3985	if (!strcmp(res->value, "1.5"))
3986		bypass_timeout = RTE_BYPASS_TMT_1_5_SEC;
3987	else if (!strcmp(res->value, "2"))
3988		bypass_timeout = RTE_BYPASS_TMT_2_SEC;
3989	else if (!strcmp(res->value, "3"))
3990		bypass_timeout = RTE_BYPASS_TMT_3_SEC;
3991	else if (!strcmp(res->value, "4"))
3992		bypass_timeout = RTE_BYPASS_TMT_4_SEC;
3993	else if (!strcmp(res->value, "8"))
3994		bypass_timeout = RTE_BYPASS_TMT_8_SEC;
3995	else if (!strcmp(res->value, "16"))
3996		bypass_timeout = RTE_BYPASS_TMT_16_SEC;
3997	else if (!strcmp(res->value, "32"))
3998		bypass_timeout = RTE_BYPASS_TMT_32_SEC;
3999	else
4000		bypass_timeout = RTE_BYPASS_TMT_OFF;
4001}
4002
4003cmdline_parse_token_string_t cmd_setbypass_timeout_set =
4004	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4005			set, "set");
4006cmdline_parse_token_string_t cmd_setbypass_timeout_bypass =
4007	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4008			bypass, "bypass");
4009cmdline_parse_token_string_t cmd_setbypass_timeout_timeout =
4010	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4011			timeout, "timeout");
4012cmdline_parse_token_string_t cmd_setbypass_timeout_value =
4013	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4014			value, "0#1.5#2#3#4#8#16#32");
4015
4016cmdline_parse_inst_t cmd_set_bypass_timeout = {
4017	.f = cmd_set_bypass_timeout_parsed,
4018	.help_str = "set bypass timeout (0|1.5|2|3|4|8|16|32) seconds: "
4019	            "Set the NIC bypass watchdog timeout",
4020	.data = NULL,
4021	.tokens = {
4022		(void *)&cmd_setbypass_timeout_set,
4023		(void *)&cmd_setbypass_timeout_bypass,
4024		(void *)&cmd_setbypass_timeout_timeout,
4025		(void *)&cmd_setbypass_timeout_value,
4026		NULL,
4027	},
4028};
4029
4030/* *** SHOW NIC BYPASS MODE *** */
4031struct cmd_show_bypass_config_result {
4032	cmdline_fixed_string_t show;
4033	cmdline_fixed_string_t bypass;
4034	cmdline_fixed_string_t config;
4035	uint8_t port_id;
4036};
4037
4038static void
4039cmd_show_bypass_config_parsed(void *parsed_result,
4040		__attribute__((unused)) struct cmdline *cl,
4041		__attribute__((unused)) void *data)
4042{
4043	struct cmd_show_bypass_config_result *res = parsed_result;
4044	uint32_t event_mode;
4045	uint32_t bypass_mode;
4046	portid_t port_id = res->port_id;
4047	uint32_t timeout = bypass_timeout;
4048	int i;
4049
4050	static const char * const timeouts[RTE_BYPASS_TMT_NUM] =
4051		{"off", "1.5", "2", "3", "4", "8", "16", "32"};
4052	static const char * const modes[RTE_BYPASS_MODE_NUM] =
4053		{"UNKNOWN", "normal", "bypass", "isolate"};
4054	static const char * const events[RTE_BYPASS_EVENT_NUM] = {
4055		"NONE",
4056		"OS/board on",
4057		"power supply on",
4058		"OS/board off",
4059		"power supply off",
4060		"timeout"};
4061	int num_events = (sizeof events) / (sizeof events[0]);
4062
4063	/* Display the bypass mode.*/
4064	if (0 != rte_eth_dev_bypass_state_show(port_id, &bypass_mode)) {
4065		printf("\tFailed to get bypass mode for port = %d\n", port_id);
4066		return;
4067	}
4068	else {
4069		if (!RTE_BYPASS_MODE_VALID(bypass_mode))
4070			bypass_mode = RTE_BYPASS_MODE_NONE;
4071
4072		printf("\tbypass mode    = %s\n",  modes[bypass_mode]);
4073	}
4074
4075	/* Display the bypass timeout.*/
4076	if (!RTE_BYPASS_TMT_VALID(timeout))
4077		timeout = RTE_BYPASS_TMT_OFF;
4078
4079	printf("\tbypass timeout = %s\n", timeouts[timeout]);
4080
4081	/* Display the bypass events and associated modes. */
4082	for (i = RTE_BYPASS_EVENT_START; i < num_events; i++) {
4083
4084		if (0 != rte_eth_dev_bypass_event_show(port_id, i, &event_mode)) {
4085			printf("\tFailed to get bypass mode for event = %s\n",
4086				events[i]);
4087		} else {
4088			if (!RTE_BYPASS_MODE_VALID(event_mode))
4089				event_mode = RTE_BYPASS_MODE_NONE;
4090
4091			printf("\tbypass event: %-16s = %s\n", events[i],
4092				modes[event_mode]);
4093		}
4094	}
4095}
4096
4097cmdline_parse_token_string_t cmd_showbypass_config_show =
4098	TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
4099			show, "show");
4100cmdline_parse_token_string_t cmd_showbypass_config_bypass =
4101	TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
4102			bypass, "bypass");
4103cmdline_parse_token_string_t cmd_showbypass_config_config =
4104	TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
4105			config, "config");
4106cmdline_parse_token_num_t cmd_showbypass_config_port =
4107	TOKEN_NUM_INITIALIZER(struct cmd_show_bypass_config_result,
4108				port_id, UINT8);
4109
4110cmdline_parse_inst_t cmd_show_bypass_config = {
4111	.f = cmd_show_bypass_config_parsed,
4112	.help_str = "show bypass config (port_id): "
4113	            "Show the NIC bypass config for port_id",
4114	.data = NULL,
4115	.tokens = {
4116		(void *)&cmd_showbypass_config_show,
4117		(void *)&cmd_showbypass_config_bypass,
4118		(void *)&cmd_showbypass_config_config,
4119		(void *)&cmd_showbypass_config_port,
4120		NULL,
4121	},
4122};
4123#endif
4124
4125#ifdef RTE_LIBRTE_PMD_BOND
4126/* *** SET BONDING MODE *** */
4127struct cmd_set_bonding_mode_result {
4128	cmdline_fixed_string_t set;
4129	cmdline_fixed_string_t bonding;
4130	cmdline_fixed_string_t mode;
4131	uint8_t value;
4132	uint8_t port_id;
4133};
4134
4135static void cmd_set_bonding_mode_parsed(void *parsed_result,
4136		__attribute__((unused))  struct cmdline *cl,
4137		__attribute__((unused)) void *data)
4138{
4139	struct cmd_set_bonding_mode_result *res = parsed_result;
4140	portid_t port_id = res->port_id;
4141
4142	/* Set the bonding mode for the relevant port. */
4143	if (0 != rte_eth_bond_mode_set(port_id, res->value))
4144		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
4145}
4146
4147cmdline_parse_token_string_t cmd_setbonding_mode_set =
4148TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
4149		set, "set");
4150cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
4151TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
4152		bonding, "bonding");
4153cmdline_parse_token_string_t cmd_setbonding_mode_mode =
4154TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
4155		mode, "mode");
4156cmdline_parse_token_num_t cmd_setbonding_mode_value =
4157TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
4158		value, UINT8);
4159cmdline_parse_token_num_t cmd_setbonding_mode_port =
4160TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
4161		port_id, UINT8);
4162
4163cmdline_parse_inst_t cmd_set_bonding_mode = {
4164		.f = cmd_set_bonding_mode_parsed,
4165		.help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
4166		.data = NULL,
4167		.tokens = {
4168				(void *) &cmd_setbonding_mode_set,
4169				(void *) &cmd_setbonding_mode_bonding,
4170				(void *) &cmd_setbonding_mode_mode,
4171				(void *) &cmd_setbonding_mode_value,
4172				(void *) &cmd_setbonding_mode_port,
4173				NULL
4174		}
4175};
4176
4177/* *** SET BALANCE XMIT POLICY *** */
4178struct cmd_set_bonding_balance_xmit_policy_result {
4179	cmdline_fixed_string_t set;
4180	cmdline_fixed_string_t bonding;
4181	cmdline_fixed_string_t balance_xmit_policy;
4182	uint8_t port_id;
4183	cmdline_fixed_string_t policy;
4184};
4185
4186static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
4187		__attribute__((unused))  struct cmdline *cl,
4188		__attribute__((unused)) void *data)
4189{
4190	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
4191	portid_t port_id = res->port_id;
4192	uint8_t policy;
4193
4194	if (!strcmp(res->policy, "l2")) {
4195		policy = BALANCE_XMIT_POLICY_LAYER2;
4196	} else if (!strcmp(res->policy, "l23")) {
4197		policy = BALANCE_XMIT_POLICY_LAYER23;
4198	} else if (!strcmp(res->policy, "l34")) {
4199		policy = BALANCE_XMIT_POLICY_LAYER34;
4200	} else {
4201		printf("\t Invalid xmit policy selection");
4202		return;
4203	}
4204
4205	/* Set the bonding mode for the relevant port. */
4206	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
4207		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
4208				port_id);
4209	}
4210}
4211
4212cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
4213TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4214		set, "set");
4215cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
4216TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4217		bonding, "bonding");
4218cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
4219TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4220		balance_xmit_policy, "balance_xmit_policy");
4221cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
4222TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4223		port_id, UINT8);
4224cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
4225TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4226		policy, "l2#l23#l34");
4227
4228cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
4229		.f = cmd_set_bonding_balance_xmit_policy_parsed,
4230		.help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
4231		.data = NULL,
4232		.tokens = {
4233				(void *)&cmd_setbonding_balance_xmit_policy_set,
4234				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
4235				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
4236				(void *)&cmd_setbonding_balance_xmit_policy_port,
4237				(void *)&cmd_setbonding_balance_xmit_policy_policy,
4238				NULL
4239		}
4240};
4241
4242/* *** SHOW NIC BONDING CONFIGURATION *** */
4243struct cmd_show_bonding_config_result {
4244	cmdline_fixed_string_t show;
4245	cmdline_fixed_string_t bonding;
4246	cmdline_fixed_string_t config;
4247	uint8_t port_id;
4248};
4249
4250static void cmd_show_bonding_config_parsed(void *parsed_result,
4251		__attribute__((unused))  struct cmdline *cl,
4252		__attribute__((unused)) void *data)
4253{
4254	struct cmd_show_bonding_config_result *res = parsed_result;
4255	int bonding_mode;
4256	uint8_t slaves[RTE_MAX_ETHPORTS];
4257	int num_slaves, num_active_slaves;
4258	int primary_id;
4259	int i;
4260	portid_t port_id = res->port_id;
4261
4262	/* Display the bonding mode.*/
4263	bonding_mode = rte_eth_bond_mode_get(port_id);
4264	if (bonding_mode < 0) {
4265		printf("\tFailed to get bonding mode for port = %d\n", port_id);
4266		return;
4267	} else
4268		printf("\tBonding mode: %d\n", bonding_mode);
4269
4270	if (bonding_mode == BONDING_MODE_BALANCE) {
4271		int balance_xmit_policy;
4272
4273		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
4274		if (balance_xmit_policy < 0) {
4275			printf("\tFailed to get balance xmit policy for port = %d\n",
4276					port_id);
4277			return;
4278		} else {
4279			printf("\tBalance Xmit Policy: ");
4280
4281			switch (balance_xmit_policy) {
4282			case BALANCE_XMIT_POLICY_LAYER2:
4283				printf("BALANCE_XMIT_POLICY_LAYER2");
4284				break;
4285			case BALANCE_XMIT_POLICY_LAYER23:
4286				printf("BALANCE_XMIT_POLICY_LAYER23");
4287				break;
4288			case BALANCE_XMIT_POLICY_LAYER34:
4289				printf("BALANCE_XMIT_POLICY_LAYER34");
4290				break;
4291			}
4292			printf("\n");
4293		}
4294	}
4295
4296	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
4297
4298	if (num_slaves < 0) {
4299		printf("\tFailed to get slave list for port = %d\n", port_id);
4300		return;
4301	}
4302	if (num_slaves > 0) {
4303		printf("\tSlaves (%d): [", num_slaves);
4304		for (i = 0; i < num_slaves - 1; i++)
4305			printf("%d ", slaves[i]);
4306
4307		printf("%d]\n", slaves[num_slaves - 1]);
4308	} else {
4309		printf("\tSlaves: []\n");
4310
4311	}
4312
4313	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
4314			RTE_MAX_ETHPORTS);
4315
4316	if (num_active_slaves < 0) {
4317		printf("\tFailed to get active slave list for port = %d\n", port_id);
4318		return;
4319	}
4320	if (num_active_slaves > 0) {
4321		printf("\tActive Slaves (%d): [", num_active_slaves);
4322		for (i = 0; i < num_active_slaves - 1; i++)
4323			printf("%d ", slaves[i]);
4324
4325		printf("%d]\n", slaves[num_active_slaves - 1]);
4326
4327	} else {
4328		printf("\tActive Slaves: []\n");
4329
4330	}
4331
4332	primary_id = rte_eth_bond_primary_get(port_id);
4333	if (primary_id < 0) {
4334		printf("\tFailed to get primary slave for port = %d\n", port_id);
4335		return;
4336	} else
4337		printf("\tPrimary: [%d]\n", primary_id);
4338
4339}
4340
4341cmdline_parse_token_string_t cmd_showbonding_config_show =
4342TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4343		show, "show");
4344cmdline_parse_token_string_t cmd_showbonding_config_bonding =
4345TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4346		bonding, "bonding");
4347cmdline_parse_token_string_t cmd_showbonding_config_config =
4348TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4349		config, "config");
4350cmdline_parse_token_num_t cmd_showbonding_config_port =
4351TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
4352		port_id, UINT8);
4353
4354cmdline_parse_inst_t cmd_show_bonding_config = {
4355		.f = cmd_show_bonding_config_parsed,
4356		.help_str =	"show bonding config (port_id): Show the bonding config for port_id",
4357		.data = NULL,
4358		.tokens = {
4359				(void *)&cmd_showbonding_config_show,
4360				(void *)&cmd_showbonding_config_bonding,
4361				(void *)&cmd_showbonding_config_config,
4362				(void *)&cmd_showbonding_config_port,
4363				NULL
4364		}
4365};
4366
4367/* *** SET BONDING PRIMARY *** */
4368struct cmd_set_bonding_primary_result {
4369	cmdline_fixed_string_t set;
4370	cmdline_fixed_string_t bonding;
4371	cmdline_fixed_string_t primary;
4372	uint8_t slave_id;
4373	uint8_t port_id;
4374};
4375
4376static void cmd_set_bonding_primary_parsed(void *parsed_result,
4377		__attribute__((unused))  struct cmdline *cl,
4378		__attribute__((unused)) void *data)
4379{
4380	struct cmd_set_bonding_primary_result *res = parsed_result;
4381	portid_t master_port_id = res->port_id;
4382	portid_t slave_port_id = res->slave_id;
4383
4384	/* Set the primary slave for a bonded device. */
4385	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
4386		printf("\t Failed to set primary slave for port = %d.\n",
4387				master_port_id);
4388		return;
4389	}
4390	init_port_config();
4391}
4392
4393cmdline_parse_token_string_t cmd_setbonding_primary_set =
4394TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4395		set, "set");
4396cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
4397TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4398		bonding, "bonding");
4399cmdline_parse_token_string_t cmd_setbonding_primary_primary =
4400TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4401		primary, "primary");
4402cmdline_parse_token_num_t cmd_setbonding_primary_slave =
4403TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
4404		slave_id, UINT8);
4405cmdline_parse_token_num_t cmd_setbonding_primary_port =
4406TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
4407		port_id, UINT8);
4408
4409cmdline_parse_inst_t cmd_set_bonding_primary = {
4410		.f = cmd_set_bonding_primary_parsed,
4411		.help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
4412		.data = NULL,
4413		.tokens = {
4414				(void *)&cmd_setbonding_primary_set,
4415				(void *)&cmd_setbonding_primary_bonding,
4416				(void *)&cmd_setbonding_primary_primary,
4417				(void *)&cmd_setbonding_primary_slave,
4418				(void *)&cmd_setbonding_primary_port,
4419				NULL
4420		}
4421};
4422
4423/* *** ADD SLAVE *** */
4424struct cmd_add_bonding_slave_result {
4425	cmdline_fixed_string_t add;
4426	cmdline_fixed_string_t bonding;
4427	cmdline_fixed_string_t slave;
4428	uint8_t slave_id;
4429	uint8_t port_id;
4430};
4431
4432static void cmd_add_bonding_slave_parsed(void *parsed_result,
4433		__attribute__((unused))  struct cmdline *cl,
4434		__attribute__((unused)) void *data)
4435{
4436	struct cmd_add_bonding_slave_result *res = parsed_result;
4437	portid_t master_port_id = res->port_id;
4438	portid_t slave_port_id = res->slave_id;
4439
4440	/* Set the primary slave for a bonded device. */
4441	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
4442		printf("\t Failed to add slave %d to master port = %d.\n",
4443				slave_port_id, master_port_id);
4444		return;
4445	}
4446	init_port_config();
4447	set_port_slave_flag(slave_port_id);
4448}
4449
4450cmdline_parse_token_string_t cmd_addbonding_slave_add =
4451TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4452		add, "add");
4453cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
4454TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4455		bonding, "bonding");
4456cmdline_parse_token_string_t cmd_addbonding_slave_slave =
4457TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4458		slave, "slave");
4459cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
4460TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
4461		slave_id, UINT8);
4462cmdline_parse_token_num_t cmd_addbonding_slave_port =
4463TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
4464		port_id, UINT8);
4465
4466cmdline_parse_inst_t cmd_add_bonding_slave = {
4467		.f = cmd_add_bonding_slave_parsed,
4468		.help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
4469		.data = NULL,
4470		.tokens = {
4471				(void *)&cmd_addbonding_slave_add,
4472				(void *)&cmd_addbonding_slave_bonding,
4473				(void *)&cmd_addbonding_slave_slave,
4474				(void *)&cmd_addbonding_slave_slaveid,
4475				(void *)&cmd_addbonding_slave_port,
4476				NULL
4477		}
4478};
4479
4480/* *** REMOVE SLAVE *** */
4481struct cmd_remove_bonding_slave_result {
4482	cmdline_fixed_string_t remove;
4483	cmdline_fixed_string_t bonding;
4484	cmdline_fixed_string_t slave;
4485	uint8_t slave_id;
4486	uint8_t port_id;
4487};
4488
4489static void cmd_remove_bonding_slave_parsed(void *parsed_result,
4490		__attribute__((unused))  struct cmdline *cl,
4491		__attribute__((unused)) void *data)
4492{
4493	struct cmd_remove_bonding_slave_result *res = parsed_result;
4494	portid_t master_port_id = res->port_id;
4495	portid_t slave_port_id = res->slave_id;
4496
4497	/* Set the primary slave for a bonded device. */
4498	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
4499		printf("\t Failed to remove slave %d from master port = %d.\n",
4500				slave_port_id, master_port_id);
4501		return;
4502	}
4503	init_port_config();
4504	clear_port_slave_flag(slave_port_id);
4505}
4506
4507cmdline_parse_token_string_t cmd_removebonding_slave_remove =
4508		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4509				remove, "remove");
4510cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
4511		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4512				bonding, "bonding");
4513cmdline_parse_token_string_t cmd_removebonding_slave_slave =
4514		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4515				slave, "slave");
4516cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
4517		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
4518				slave_id, UINT8);
4519cmdline_parse_token_num_t cmd_removebonding_slave_port =
4520		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
4521				port_id, UINT8);
4522
4523cmdline_parse_inst_t cmd_remove_bonding_slave = {
4524		.f = cmd_remove_bonding_slave_parsed,
4525		.help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
4526		.data = NULL,
4527		.tokens = {
4528				(void *)&cmd_removebonding_slave_remove,
4529				(void *)&cmd_removebonding_slave_bonding,
4530				(void *)&cmd_removebonding_slave_slave,
4531				(void *)&cmd_removebonding_slave_slaveid,
4532				(void *)&cmd_removebonding_slave_port,
4533				NULL
4534		}
4535};
4536
4537/* *** CREATE BONDED DEVICE *** */
4538struct cmd_create_bonded_device_result {
4539	cmdline_fixed_string_t create;
4540	cmdline_fixed_string_t bonded;
4541	cmdline_fixed_string_t device;
4542	uint8_t mode;
4543	uint8_t socket;
4544};
4545
4546static int bond_dev_num = 0;
4547
4548static void cmd_create_bonded_device_parsed(void *parsed_result,
4549		__attribute__((unused))  struct cmdline *cl,
4550		__attribute__((unused)) void *data)
4551{
4552	struct cmd_create_bonded_device_result *res = parsed_result;
4553	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
4554	int port_id;
4555
4556	if (test_done == 0) {
4557		printf("Please stop forwarding first\n");
4558		return;
4559	}
4560
4561	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bond_testpmd_%d",
4562			bond_dev_num++);
4563
4564	/* Create a new bonded device. */
4565	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
4566	if (port_id < 0) {
4567		printf("\t Failed to create bonded device.\n");
4568		return;
4569	} else {
4570		printf("Created new bonded device %s on (port %d).\n", ethdev_name,
4571				port_id);
4572
4573		/* Update number of ports */
4574		nb_ports = rte_eth_dev_count();
4575		reconfig(port_id, res->socket);
4576		rte_eth_promiscuous_enable(port_id);
4577		ports[port_id].enabled = 1;
4578	}
4579
4580}
4581
4582cmdline_parse_token_string_t cmd_createbonded_device_create =
4583		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4584				create, "create");
4585cmdline_parse_token_string_t cmd_createbonded_device_bonded =
4586		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4587				bonded, "bonded");
4588cmdline_parse_token_string_t cmd_createbonded_device_device =
4589		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4590				device, "device");
4591cmdline_parse_token_num_t cmd_createbonded_device_mode =
4592		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
4593				mode, UINT8);
4594cmdline_parse_token_num_t cmd_createbonded_device_socket =
4595		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
4596				socket, UINT8);
4597
4598cmdline_parse_inst_t cmd_create_bonded_device = {
4599		.f = cmd_create_bonded_device_parsed,
4600		.help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
4601		.data = NULL,
4602		.tokens = {
4603				(void *)&cmd_createbonded_device_create,
4604				(void *)&cmd_createbonded_device_bonded,
4605				(void *)&cmd_createbonded_device_device,
4606				(void *)&cmd_createbonded_device_mode,
4607				(void *)&cmd_createbonded_device_socket,
4608				NULL
4609		}
4610};
4611
4612/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
4613struct cmd_set_bond_mac_addr_result {
4614	cmdline_fixed_string_t set;
4615	cmdline_fixed_string_t bonding;
4616	cmdline_fixed_string_t mac_addr;
4617	uint8_t port_num;
4618	struct ether_addr address;
4619};
4620
4621static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
4622		__attribute__((unused))  struct cmdline *cl,
4623		__attribute__((unused)) void *data)
4624{
4625	struct cmd_set_bond_mac_addr_result *res = parsed_result;
4626	int ret;
4627
4628	if (port_id_is_invalid(res->port_num, ENABLED_WARN))
4629		return;
4630
4631	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
4632
4633	/* check the return value and print it if is < 0 */
4634	if (ret < 0)
4635		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
4636}
4637
4638cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
4639		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
4640cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
4641		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
4642				"bonding");
4643cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
4644		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
4645				"mac_addr");
4646cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
4647		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
4648cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
4649		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
4650
4651cmdline_parse_inst_t cmd_set_bond_mac_addr = {
4652		.f = cmd_set_bond_mac_addr_parsed,
4653		.data = (void *) 0,
4654		.help_str = "set bonding mac_addr (port_id) (address): ",
4655		.tokens = {
4656				(void *)&cmd_set_bond_mac_addr_set,
4657				(void *)&cmd_set_bond_mac_addr_bonding,
4658				(void *)&cmd_set_bond_mac_addr_mac,
4659				(void *)&cmd_set_bond_mac_addr_portnum,
4660				(void *)&cmd_set_bond_mac_addr_addr,
4661				NULL
4662		}
4663};
4664
4665
4666/* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
4667struct cmd_set_bond_mon_period_result {
4668	cmdline_fixed_string_t set;
4669	cmdline_fixed_string_t bonding;
4670	cmdline_fixed_string_t mon_period;
4671	uint8_t port_num;
4672	uint32_t period_ms;
4673};
4674
4675static void cmd_set_bond_mon_period_parsed(void *parsed_result,
4676		__attribute__((unused))  struct cmdline *cl,
4677		__attribute__((unused)) void *data)
4678{
4679	struct cmd_set_bond_mon_period_result *res = parsed_result;
4680	int ret;
4681
4682	if (res->port_num >= nb_ports) {
4683		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
4684		return;
4685	}
4686
4687	ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
4688
4689	/* check the return value and print it if is < 0 */
4690	if (ret < 0)
4691		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
4692}
4693
4694cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
4695		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4696				set, "set");
4697cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
4698		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4699				bonding, "bonding");
4700cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
4701		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4702				mon_period,	"mon_period");
4703cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
4704		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
4705				port_num, UINT8);
4706cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
4707		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
4708				period_ms, UINT32);
4709
4710cmdline_parse_inst_t cmd_set_bond_mon_period = {
4711		.f = cmd_set_bond_mon_period_parsed,
4712		.data = (void *) 0,
4713		.help_str = "set bonding mon_period (port_id) (period_ms): ",
4714		.tokens = {
4715				(void *)&cmd_set_bond_mon_period_set,
4716				(void *)&cmd_set_bond_mon_period_bonding,
4717				(void *)&cmd_set_bond_mon_period_mon_period,
4718				(void *)&cmd_set_bond_mon_period_portnum,
4719				(void *)&cmd_set_bond_mon_period_period_ms,
4720				NULL
4721		}
4722};
4723
4724#endif /* RTE_LIBRTE_PMD_BOND */
4725
4726/* *** SET FORWARDING MODE *** */
4727struct cmd_set_fwd_mode_result {
4728	cmdline_fixed_string_t set;
4729	cmdline_fixed_string_t fwd;
4730	cmdline_fixed_string_t mode;
4731};
4732
4733static void cmd_set_fwd_mode_parsed(void *parsed_result,
4734				    __attribute__((unused)) struct cmdline *cl,
4735				    __attribute__((unused)) void *data)
4736{
4737	struct cmd_set_fwd_mode_result *res = parsed_result;
4738
4739	retry_enabled = 0;
4740	set_pkt_forwarding_mode(res->mode);
4741}
4742
4743cmdline_parse_token_string_t cmd_setfwd_set =
4744	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
4745cmdline_parse_token_string_t cmd_setfwd_fwd =
4746	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
4747cmdline_parse_token_string_t cmd_setfwd_mode =
4748	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
4749		"" /* defined at init */);
4750
4751cmdline_parse_inst_t cmd_set_fwd_mode = {
4752	.f = cmd_set_fwd_mode_parsed,
4753	.data = NULL,
4754	.help_str = NULL, /* defined at init */
4755	.tokens = {
4756		(void *)&cmd_setfwd_set,
4757		(void *)&cmd_setfwd_fwd,
4758		(void *)&cmd_setfwd_mode,
4759		NULL,
4760	},
4761};
4762
4763static void cmd_set_fwd_mode_init(void)
4764{
4765	char *modes, *c;
4766	static char token[128];
4767	static char help[256];
4768	cmdline_parse_token_string_t *token_struct;
4769
4770	modes = list_pkt_forwarding_modes();
4771	snprintf(help, sizeof help, "set fwd %s - "
4772		"set packet forwarding mode", modes);
4773	cmd_set_fwd_mode.help_str = help;
4774
4775	/* string token separator is # */
4776	for (c = token; *modes != '\0'; modes++)
4777		if (*modes == '|')
4778			*c++ = '#';
4779		else
4780			*c++ = *modes;
4781	token_struct = (cmdline_parse_token_string_t*)cmd_set_fwd_mode.tokens[2];
4782	token_struct->string_data.str = token;
4783}
4784
4785/* *** SET RETRY FORWARDING MODE *** */
4786struct cmd_set_fwd_retry_mode_result {
4787	cmdline_fixed_string_t set;
4788	cmdline_fixed_string_t fwd;
4789	cmdline_fixed_string_t mode;
4790	cmdline_fixed_string_t retry;
4791};
4792
4793static void cmd_set_fwd_retry_mode_parsed(void *parsed_result,
4794			    __attribute__((unused)) struct cmdline *cl,
4795			    __attribute__((unused)) void *data)
4796{
4797	struct cmd_set_fwd_retry_mode_result *res = parsed_result;
4798
4799	retry_enabled = 1;
4800	set_pkt_forwarding_mode(res->mode);
4801}
4802
4803cmdline_parse_token_string_t cmd_setfwd_retry_set =
4804	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4805			set, "set");
4806cmdline_parse_token_string_t cmd_setfwd_retry_fwd =
4807	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4808			fwd, "fwd");
4809cmdline_parse_token_string_t cmd_setfwd_retry_mode =
4810	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4811			mode,
4812		"" /* defined at init */);
4813cmdline_parse_token_string_t cmd_setfwd_retry_retry =
4814	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4815			retry, "retry");
4816
4817cmdline_parse_inst_t cmd_set_fwd_retry_mode = {
4818	.f = cmd_set_fwd_retry_mode_parsed,
4819	.data = NULL,
4820	.help_str = NULL, /* defined at init */
4821	.tokens = {
4822		(void *)&cmd_setfwd_retry_set,
4823		(void *)&cmd_setfwd_retry_fwd,
4824		(void *)&cmd_setfwd_retry_mode,
4825		(void *)&cmd_setfwd_retry_retry,
4826		NULL,
4827	},
4828};
4829
4830static void cmd_set_fwd_retry_mode_init(void)
4831{
4832	char *modes, *c;
4833	static char token[128];
4834	static char help[256];
4835	cmdline_parse_token_string_t *token_struct;
4836
4837	modes = list_pkt_forwarding_retry_modes();
4838	snprintf(help, sizeof(help), "set fwd %s retry - "
4839		"set packet forwarding mode with retry", modes);
4840	cmd_set_fwd_retry_mode.help_str = help;
4841
4842	/* string token separator is # */
4843	for (c = token; *modes != '\0'; modes++)
4844		if (*modes == '|')
4845			*c++ = '#';
4846		else
4847			*c++ = *modes;
4848	token_struct = (cmdline_parse_token_string_t *)
4849		cmd_set_fwd_retry_mode.tokens[2];
4850	token_struct->string_data.str = token;
4851}
4852
4853/* *** SET BURST TX DELAY TIME RETRY NUMBER *** */
4854struct cmd_set_burst_tx_retry_result {
4855	cmdline_fixed_string_t set;
4856	cmdline_fixed_string_t burst;
4857	cmdline_fixed_string_t tx;
4858	cmdline_fixed_string_t delay;
4859	uint32_t time;
4860	cmdline_fixed_string_t retry;
4861	uint32_t retry_num;
4862};
4863
4864static void cmd_set_burst_tx_retry_parsed(void *parsed_result,
4865					__attribute__((unused)) struct cmdline *cl,
4866					__attribute__((unused)) void *data)
4867{
4868	struct cmd_set_burst_tx_retry_result *res = parsed_result;
4869
4870	if (!strcmp(res->set, "set") && !strcmp(res->burst, "burst")
4871		&& !strcmp(res->tx, "tx")) {
4872		if (!strcmp(res->delay, "delay"))
4873			burst_tx_delay_time = res->time;
4874		if (!strcmp(res->retry, "retry"))
4875			burst_tx_retry_num = res->retry_num;
4876	}
4877
4878}
4879
4880cmdline_parse_token_string_t cmd_set_burst_tx_retry_set =
4881	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, set, "set");
4882cmdline_parse_token_string_t cmd_set_burst_tx_retry_burst =
4883	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, burst,
4884				 "burst");
4885cmdline_parse_token_string_t cmd_set_burst_tx_retry_tx =
4886	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, tx, "tx");
4887cmdline_parse_token_string_t cmd_set_burst_tx_retry_delay =
4888	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, delay, "delay");
4889cmdline_parse_token_num_t cmd_set_burst_tx_retry_time =
4890	TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, time, UINT32);
4891cmdline_parse_token_string_t cmd_set_burst_tx_retry_retry =
4892	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry, "retry");
4893cmdline_parse_token_num_t cmd_set_burst_tx_retry_retry_num =
4894	TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry_num, UINT32);
4895
4896cmdline_parse_inst_t cmd_set_burst_tx_retry = {
4897	.f = cmd_set_burst_tx_retry_parsed,
4898	.help_str = "set burst tx delay (time_by_useconds) retry (retry_num)",
4899	.tokens = {
4900		(void *)&cmd_set_burst_tx_retry_set,
4901		(void *)&cmd_set_burst_tx_retry_burst,
4902		(void *)&cmd_set_burst_tx_retry_tx,
4903		(void *)&cmd_set_burst_tx_retry_delay,
4904		(void *)&cmd_set_burst_tx_retry_time,
4905		(void *)&cmd_set_burst_tx_retry_retry,
4906		(void *)&cmd_set_burst_tx_retry_retry_num,
4907		NULL,
4908	},
4909};
4910
4911/* *** SET PROMISC MODE *** */
4912struct cmd_set_promisc_mode_result {
4913	cmdline_fixed_string_t set;
4914	cmdline_fixed_string_t promisc;
4915	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
4916	uint8_t port_num;                /* valid if "allports" argument == 0 */
4917	cmdline_fixed_string_t mode;
4918};
4919
4920static void cmd_set_promisc_mode_parsed(void *parsed_result,
4921					__attribute__((unused)) struct cmdline *cl,
4922					void *allports)
4923{
4924	struct cmd_set_promisc_mode_result *res = parsed_result;
4925	int enable;
4926	portid_t i;
4927
4928	if (!strcmp(res->mode, "on"))
4929		enable = 1;
4930	else
4931		enable = 0;
4932
4933	/* all ports */
4934	if (allports) {
4935		FOREACH_PORT(i, ports) {
4936			if (enable)
4937				rte_eth_promiscuous_enable(i);
4938			else
4939				rte_eth_promiscuous_disable(i);
4940		}
4941	}
4942	else {
4943		if (enable)
4944			rte_eth_promiscuous_enable(res->port_num);
4945		else
4946			rte_eth_promiscuous_disable(res->port_num);
4947	}
4948}
4949
4950cmdline_parse_token_string_t cmd_setpromisc_set =
4951	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, set, "set");
4952cmdline_parse_token_string_t cmd_setpromisc_promisc =
4953	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, promisc,
4954				 "promisc");
4955cmdline_parse_token_string_t cmd_setpromisc_portall =
4956	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, port_all,
4957				 "all");
4958cmdline_parse_token_num_t cmd_setpromisc_portnum =
4959	TOKEN_NUM_INITIALIZER(struct cmd_set_promisc_mode_result, port_num,
4960			      UINT8);
4961cmdline_parse_token_string_t cmd_setpromisc_mode =
4962	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, mode,
4963				 "on#off");
4964
4965cmdline_parse_inst_t cmd_set_promisc_mode_all = {
4966	.f = cmd_set_promisc_mode_parsed,
4967	.data = (void *)1,
4968	.help_str = "set promisc all on|off: set promisc mode for all ports",
4969	.tokens = {
4970		(void *)&cmd_setpromisc_set,
4971		(void *)&cmd_setpromisc_promisc,
4972		(void *)&cmd_setpromisc_portall,
4973		(void *)&cmd_setpromisc_mode,
4974		NULL,
4975	},
4976};
4977
4978cmdline_parse_inst_t cmd_set_promisc_mode_one = {
4979	.f = cmd_set_promisc_mode_parsed,
4980	.data = (void *)0,
4981	.help_str = "set promisc X on|off: set promisc mode on port X",
4982	.tokens = {
4983		(void *)&cmd_setpromisc_set,
4984		(void *)&cmd_setpromisc_promisc,
4985		(void *)&cmd_setpromisc_portnum,
4986		(void *)&cmd_setpromisc_mode,
4987		NULL,
4988	},
4989};
4990
4991/* *** SET ALLMULTI MODE *** */
4992struct cmd_set_allmulti_mode_result {
4993	cmdline_fixed_string_t set;
4994	cmdline_fixed_string_t allmulti;
4995	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
4996	uint8_t port_num;                /* valid if "allports" argument == 0 */
4997	cmdline_fixed_string_t mode;
4998};
4999
5000static void cmd_set_allmulti_mode_parsed(void *parsed_result,
5001					__attribute__((unused)) struct cmdline *cl,
5002					void *allports)
5003{
5004	struct cmd_set_allmulti_mode_result *res = parsed_result;
5005	int enable;
5006	portid_t i;
5007
5008	if (!strcmp(res->mode, "on"))
5009		enable = 1;
5010	else
5011		enable = 0;
5012
5013	/* all ports */
5014	if (allports) {
5015		FOREACH_PORT(i, ports) {
5016			if (enable)
5017				rte_eth_allmulticast_enable(i);
5018			else
5019				rte_eth_allmulticast_disable(i);
5020		}
5021	}
5022	else {
5023		if (enable)
5024			rte_eth_allmulticast_enable(res->port_num);
5025		else
5026			rte_eth_allmulticast_disable(res->port_num);
5027	}
5028}
5029
5030cmdline_parse_token_string_t cmd_setallmulti_set =
5031	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, set, "set");
5032cmdline_parse_token_string_t cmd_setallmulti_allmulti =
5033	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, allmulti,
5034				 "allmulti");
5035cmdline_parse_token_string_t cmd_setallmulti_portall =
5036	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, port_all,
5037				 "all");
5038cmdline_parse_token_num_t cmd_setallmulti_portnum =
5039	TOKEN_NUM_INITIALIZER(struct cmd_set_allmulti_mode_result, port_num,
5040			      UINT8);
5041cmdline_parse_token_string_t cmd_setallmulti_mode =
5042	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, mode,
5043				 "on#off");
5044
5045cmdline_parse_inst_t cmd_set_allmulti_mode_all = {
5046	.f = cmd_set_allmulti_mode_parsed,
5047	.data = (void *)1,
5048	.help_str = "set allmulti all on|off: set allmulti mode for all ports",
5049	.tokens = {
5050		(void *)&cmd_setallmulti_set,
5051		(void *)&cmd_setallmulti_allmulti,
5052		(void *)&cmd_setallmulti_portall,
5053		(void *)&cmd_setallmulti_mode,
5054		NULL,
5055	},
5056};
5057
5058cmdline_parse_inst_t cmd_set_allmulti_mode_one = {
5059	.f = cmd_set_allmulti_mode_parsed,
5060	.data = (void *)0,
5061	.help_str = "set allmulti X on|off: set allmulti mode on port X",
5062	.tokens = {
5063		(void *)&cmd_setallmulti_set,
5064		(void *)&cmd_setallmulti_allmulti,
5065		(void *)&cmd_setallmulti_portnum,
5066		(void *)&cmd_setallmulti_mode,
5067		NULL,
5068	},
5069};
5070
5071/* *** SETUP ETHERNET LINK FLOW CONTROL *** */
5072struct cmd_link_flow_ctrl_set_result {
5073	cmdline_fixed_string_t set;
5074	cmdline_fixed_string_t flow_ctrl;
5075	cmdline_fixed_string_t rx;
5076	cmdline_fixed_string_t rx_lfc_mode;
5077	cmdline_fixed_string_t tx;
5078	cmdline_fixed_string_t tx_lfc_mode;
5079	cmdline_fixed_string_t mac_ctrl_frame_fwd;
5080	cmdline_fixed_string_t mac_ctrl_frame_fwd_mode;
5081	cmdline_fixed_string_t autoneg_str;
5082	cmdline_fixed_string_t autoneg;
5083	cmdline_fixed_string_t hw_str;
5084	uint32_t high_water;
5085	cmdline_fixed_string_t lw_str;
5086	uint32_t low_water;
5087	cmdline_fixed_string_t pt_str;
5088	uint16_t pause_time;
5089	cmdline_fixed_string_t xon_str;
5090	uint16_t send_xon;
5091	uint8_t  port_id;
5092};
5093
5094cmdline_parse_token_string_t cmd_lfc_set_set =
5095	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5096				set, "set");
5097cmdline_parse_token_string_t cmd_lfc_set_flow_ctrl =
5098	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5099				flow_ctrl, "flow_ctrl");
5100cmdline_parse_token_string_t cmd_lfc_set_rx =
5101	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5102				rx, "rx");
5103cmdline_parse_token_string_t cmd_lfc_set_rx_mode =
5104	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5105				rx_lfc_mode, "on#off");
5106cmdline_parse_token_string_t cmd_lfc_set_tx =
5107	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5108				tx, "tx");
5109cmdline_parse_token_string_t cmd_lfc_set_tx_mode =
5110	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5111				tx_lfc_mode, "on#off");
5112cmdline_parse_token_string_t cmd_lfc_set_high_water_str =
5113	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5114				hw_str, "high_water");
5115cmdline_parse_token_num_t cmd_lfc_set_high_water =
5116	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5117				high_water, UINT32);
5118cmdline_parse_token_string_t cmd_lfc_set_low_water_str =
5119	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5120				lw_str, "low_water");
5121cmdline_parse_token_num_t cmd_lfc_set_low_water =
5122	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5123				low_water, UINT32);
5124cmdline_parse_token_string_t cmd_lfc_set_pause_time_str =
5125	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5126				pt_str, "pause_time");
5127cmdline_parse_token_num_t cmd_lfc_set_pause_time =
5128	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5129				pause_time, UINT16);
5130cmdline_parse_token_string_t cmd_lfc_set_send_xon_str =
5131	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5132				xon_str, "send_xon");
5133cmdline_parse_token_num_t cmd_lfc_set_send_xon =
5134	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5135				send_xon, UINT16);
5136cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd_mode =
5137	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5138				mac_ctrl_frame_fwd, "mac_ctrl_frame_fwd");
5139cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd =
5140	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5141				mac_ctrl_frame_fwd_mode, "on#off");
5142cmdline_parse_token_string_t cmd_lfc_set_autoneg_str =
5143	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5144				autoneg_str, "autoneg");
5145cmdline_parse_token_string_t cmd_lfc_set_autoneg =
5146	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5147				autoneg, "on#off");
5148cmdline_parse_token_num_t cmd_lfc_set_portid =
5149	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5150				port_id, UINT8);
5151
5152/* forward declaration */
5153static void
5154cmd_link_flow_ctrl_set_parsed(void *parsed_result, struct cmdline *cl,
5155			      void *data);
5156
5157cmdline_parse_inst_t cmd_link_flow_control_set = {
5158	.f = cmd_link_flow_ctrl_set_parsed,
5159	.data = NULL,
5160	.help_str = "Configure the Ethernet flow control: set flow_ctrl rx on|off \
5161tx on|off high_water low_water pause_time send_xon mac_ctrl_frame_fwd on|off \
5162autoneg on|off port_id",
5163	.tokens = {
5164		(void *)&cmd_lfc_set_set,
5165		(void *)&cmd_lfc_set_flow_ctrl,
5166		(void *)&cmd_lfc_set_rx,
5167		(void *)&cmd_lfc_set_rx_mode,
5168		(void *)&cmd_lfc_set_tx,
5169		(void *)&cmd_lfc_set_tx_mode,
5170		(void *)&cmd_lfc_set_high_water,
5171		(void *)&cmd_lfc_set_low_water,
5172		(void *)&cmd_lfc_set_pause_time,
5173		(void *)&cmd_lfc_set_send_xon,
5174		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
5175		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
5176		(void *)&cmd_lfc_set_autoneg_str,
5177		(void *)&cmd_lfc_set_autoneg,
5178		(void *)&cmd_lfc_set_portid,
5179		NULL,
5180	},
5181};
5182
5183cmdline_parse_inst_t cmd_link_flow_control_set_rx = {
5184	.f = cmd_link_flow_ctrl_set_parsed,
5185	.data = (void *)&cmd_link_flow_control_set_rx,
5186	.help_str = "Change rx flow control parameter: set flow_ctrl "
5187		    "rx on|off port_id",
5188	.tokens = {
5189		(void *)&cmd_lfc_set_set,
5190		(void *)&cmd_lfc_set_flow_ctrl,
5191		(void *)&cmd_lfc_set_rx,
5192		(void *)&cmd_lfc_set_rx_mode,
5193		(void *)&cmd_lfc_set_portid,
5194		NULL,
5195	},
5196};
5197
5198cmdline_parse_inst_t cmd_link_flow_control_set_tx = {
5199	.f = cmd_link_flow_ctrl_set_parsed,
5200	.data = (void *)&cmd_link_flow_control_set_tx,
5201	.help_str = "Change tx flow control parameter: set flow_ctrl "
5202		    "tx on|off port_id",
5203	.tokens = {
5204		(void *)&cmd_lfc_set_set,
5205		(void *)&cmd_lfc_set_flow_ctrl,
5206		(void *)&cmd_lfc_set_tx,
5207		(void *)&cmd_lfc_set_tx_mode,
5208		(void *)&cmd_lfc_set_portid,
5209		NULL,
5210	},
5211};
5212
5213cmdline_parse_inst_t cmd_link_flow_control_set_hw = {
5214	.f = cmd_link_flow_ctrl_set_parsed,
5215	.data = (void *)&cmd_link_flow_control_set_hw,
5216	.help_str = "Change high water flow control parameter: set flow_ctrl "
5217		    "high_water value port_id",
5218	.tokens = {
5219		(void *)&cmd_lfc_set_set,
5220		(void *)&cmd_lfc_set_flow_ctrl,
5221		(void *)&cmd_lfc_set_high_water_str,
5222		(void *)&cmd_lfc_set_high_water,
5223		(void *)&cmd_lfc_set_portid,
5224		NULL,
5225	},
5226};
5227
5228cmdline_parse_inst_t cmd_link_flow_control_set_lw = {
5229	.f = cmd_link_flow_ctrl_set_parsed,
5230	.data = (void *)&cmd_link_flow_control_set_lw,
5231	.help_str = "Change low water flow control parameter: set flow_ctrl "
5232		    "low_water value port_id",
5233	.tokens = {
5234		(void *)&cmd_lfc_set_set,
5235		(void *)&cmd_lfc_set_flow_ctrl,
5236		(void *)&cmd_lfc_set_low_water_str,
5237		(void *)&cmd_lfc_set_low_water,
5238		(void *)&cmd_lfc_set_portid,
5239		NULL,
5240	},
5241};
5242
5243cmdline_parse_inst_t cmd_link_flow_control_set_pt = {
5244	.f = cmd_link_flow_ctrl_set_parsed,
5245	.data = (void *)&cmd_link_flow_control_set_pt,
5246	.help_str = "Change pause time flow control parameter: set flow_ctrl "
5247		    "pause_time value port_id",
5248	.tokens = {
5249		(void *)&cmd_lfc_set_set,
5250		(void *)&cmd_lfc_set_flow_ctrl,
5251		(void *)&cmd_lfc_set_pause_time_str,
5252		(void *)&cmd_lfc_set_pause_time,
5253		(void *)&cmd_lfc_set_portid,
5254		NULL,
5255	},
5256};
5257
5258cmdline_parse_inst_t cmd_link_flow_control_set_xon = {
5259	.f = cmd_link_flow_ctrl_set_parsed,
5260	.data = (void *)&cmd_link_flow_control_set_xon,
5261	.help_str = "Change send_xon flow control parameter: set flow_ctrl "
5262		    "send_xon value port_id",
5263	.tokens = {
5264		(void *)&cmd_lfc_set_set,
5265		(void *)&cmd_lfc_set_flow_ctrl,
5266		(void *)&cmd_lfc_set_send_xon_str,
5267		(void *)&cmd_lfc_set_send_xon,
5268		(void *)&cmd_lfc_set_portid,
5269		NULL,
5270	},
5271};
5272
5273cmdline_parse_inst_t cmd_link_flow_control_set_macfwd = {
5274	.f = cmd_link_flow_ctrl_set_parsed,
5275	.data = (void *)&cmd_link_flow_control_set_macfwd,
5276	.help_str = "Change mac ctrl fwd flow control parameter: set flow_ctrl "
5277		    "mac_ctrl_frame_fwd on|off port_id",
5278	.tokens = {
5279		(void *)&cmd_lfc_set_set,
5280		(void *)&cmd_lfc_set_flow_ctrl,
5281		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
5282		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
5283		(void *)&cmd_lfc_set_portid,
5284		NULL,
5285	},
5286};
5287
5288cmdline_parse_inst_t cmd_link_flow_control_set_autoneg = {
5289	.f = cmd_link_flow_ctrl_set_parsed,
5290	.data = (void *)&cmd_link_flow_control_set_autoneg,
5291	.help_str = "Change autoneg flow control parameter: set flow_ctrl "
5292		    "autoneg on|off port_id",
5293	.tokens = {
5294		(void *)&cmd_lfc_set_set,
5295		(void *)&cmd_lfc_set_flow_ctrl,
5296		(void *)&cmd_lfc_set_autoneg_str,
5297		(void *)&cmd_lfc_set_autoneg,
5298		(void *)&cmd_lfc_set_portid,
5299		NULL,
5300	},
5301};
5302
5303static void
5304cmd_link_flow_ctrl_set_parsed(void *parsed_result,
5305			      __attribute__((unused)) struct cmdline *cl,
5306			      void *data)
5307{
5308	struct cmd_link_flow_ctrl_set_result *res = parsed_result;
5309	cmdline_parse_inst_t *cmd = data;
5310	struct rte_eth_fc_conf fc_conf;
5311	int rx_fc_en = 0;
5312	int tx_fc_en = 0;
5313	int ret;
5314
5315	/*
5316	 * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
5317	 * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
5318	 * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
5319	 * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
5320	 */
5321	static enum rte_eth_fc_mode rx_tx_onoff_2_lfc_mode[2][2] = {
5322			{RTE_FC_NONE, RTE_FC_TX_PAUSE}, {RTE_FC_RX_PAUSE, RTE_FC_FULL}
5323	};
5324
5325	/* Partial command line, retrieve current configuration */
5326	if (cmd) {
5327		ret = rte_eth_dev_flow_ctrl_get(res->port_id, &fc_conf);
5328		if (ret != 0) {
5329			printf("cannot get current flow ctrl parameters, return"
5330			       "code = %d\n", ret);
5331			return;
5332		}
5333
5334		if ((fc_conf.mode == RTE_FC_RX_PAUSE) ||
5335		    (fc_conf.mode == RTE_FC_FULL))
5336			rx_fc_en = 1;
5337		if ((fc_conf.mode == RTE_FC_TX_PAUSE) ||
5338		    (fc_conf.mode == RTE_FC_FULL))
5339			tx_fc_en = 1;
5340	}
5341
5342	if (!cmd || cmd == &cmd_link_flow_control_set_rx)
5343		rx_fc_en = (!strcmp(res->rx_lfc_mode, "on")) ? 1 : 0;
5344
5345	if (!cmd || cmd == &cmd_link_flow_control_set_tx)
5346		tx_fc_en = (!strcmp(res->tx_lfc_mode, "on")) ? 1 : 0;
5347
5348	fc_conf.mode = rx_tx_onoff_2_lfc_mode[rx_fc_en][tx_fc_en];
5349
5350	if (!cmd || cmd == &cmd_link_flow_control_set_hw)
5351		fc_conf.high_water = res->high_water;
5352
5353	if (!cmd || cmd == &cmd_link_flow_control_set_lw)
5354		fc_conf.low_water = res->low_water;
5355
5356	if (!cmd || cmd == &cmd_link_flow_control_set_pt)
5357		fc_conf.pause_time = res->pause_time;
5358
5359	if (!cmd || cmd == &cmd_link_flow_control_set_xon)
5360		fc_conf.send_xon = res->send_xon;
5361
5362	if (!cmd || cmd == &cmd_link_flow_control_set_macfwd) {
5363		if (!strcmp(res->mac_ctrl_frame_fwd_mode, "on"))
5364			fc_conf.mac_ctrl_frame_fwd = 1;
5365		else
5366			fc_conf.mac_ctrl_frame_fwd = 0;
5367	}
5368
5369	if (!cmd || cmd == &cmd_link_flow_control_set_autoneg)
5370		fc_conf.autoneg = (!strcmp(res->autoneg, "on")) ? 1 : 0;
5371
5372	ret = rte_eth_dev_flow_ctrl_set(res->port_id, &fc_conf);
5373	if (ret != 0)
5374		printf("bad flow contrl parameter, return code = %d \n", ret);
5375}
5376
5377/* *** SETUP ETHERNET PIRORITY FLOW CONTROL *** */
5378struct cmd_priority_flow_ctrl_set_result {
5379	cmdline_fixed_string_t set;
5380	cmdline_fixed_string_t pfc_ctrl;
5381	cmdline_fixed_string_t rx;
5382	cmdline_fixed_string_t rx_pfc_mode;
5383	cmdline_fixed_string_t tx;
5384	cmdline_fixed_string_t tx_pfc_mode;
5385	uint32_t high_water;
5386	uint32_t low_water;
5387	uint16_t pause_time;
5388	uint8_t  priority;
5389	uint8_t  port_id;
5390};
5391
5392static void
5393cmd_priority_flow_ctrl_set_parsed(void *parsed_result,
5394		       __attribute__((unused)) struct cmdline *cl,
5395		       __attribute__((unused)) void *data)
5396{
5397	struct cmd_priority_flow_ctrl_set_result *res = parsed_result;
5398	struct rte_eth_pfc_conf pfc_conf;
5399	int rx_fc_enable, tx_fc_enable;
5400	int ret;
5401
5402	/*
5403	 * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
5404	 * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
5405	 * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
5406	 * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
5407	 */
5408	static enum rte_eth_fc_mode rx_tx_onoff_2_pfc_mode[2][2] = {
5409			{RTE_FC_NONE, RTE_FC_RX_PAUSE}, {RTE_FC_TX_PAUSE, RTE_FC_FULL}
5410	};
5411
5412	rx_fc_enable = (!strncmp(res->rx_pfc_mode, "on",2)) ? 1 : 0;
5413	tx_fc_enable = (!strncmp(res->tx_pfc_mode, "on",2)) ? 1 : 0;
5414	pfc_conf.fc.mode       = rx_tx_onoff_2_pfc_mode[rx_fc_enable][tx_fc_enable];
5415	pfc_conf.fc.high_water = res->high_water;
5416	pfc_conf.fc.low_water  = res->low_water;
5417	pfc_conf.fc.pause_time = res->pause_time;
5418	pfc_conf.priority      = res->priority;
5419
5420	ret = rte_eth_dev_priority_flow_ctrl_set(res->port_id, &pfc_conf);
5421	if (ret != 0)
5422		printf("bad priority flow contrl parameter, return code = %d \n", ret);
5423}
5424
5425cmdline_parse_token_string_t cmd_pfc_set_set =
5426	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5427				set, "set");
5428cmdline_parse_token_string_t cmd_pfc_set_flow_ctrl =
5429	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5430				pfc_ctrl, "pfc_ctrl");
5431cmdline_parse_token_string_t cmd_pfc_set_rx =
5432	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5433				rx, "rx");
5434cmdline_parse_token_string_t cmd_pfc_set_rx_mode =
5435	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5436				rx_pfc_mode, "on#off");
5437cmdline_parse_token_string_t cmd_pfc_set_tx =
5438	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5439				tx, "tx");
5440cmdline_parse_token_string_t cmd_pfc_set_tx_mode =
5441	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5442				tx_pfc_mode, "on#off");
5443cmdline_parse_token_num_t cmd_pfc_set_high_water =
5444	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5445				high_water, UINT32);
5446cmdline_parse_token_num_t cmd_pfc_set_low_water =
5447	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5448				low_water, UINT32);
5449cmdline_parse_token_num_t cmd_pfc_set_pause_time =
5450	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5451				pause_time, UINT16);
5452cmdline_parse_token_num_t cmd_pfc_set_priority =
5453	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5454				priority, UINT8);
5455cmdline_parse_token_num_t cmd_pfc_set_portid =
5456	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5457				port_id, UINT8);
5458
5459cmdline_parse_inst_t cmd_priority_flow_control_set = {
5460	.f = cmd_priority_flow_ctrl_set_parsed,
5461	.data = NULL,
5462	.help_str = "Configure the Ethernet priority flow control: set pfc_ctrl rx on|off\n\
5463			tx on|off high_water low_water pause_time priority port_id",
5464	.tokens = {
5465		(void *)&cmd_pfc_set_set,
5466		(void *)&cmd_pfc_set_flow_ctrl,
5467		(void *)&cmd_pfc_set_rx,
5468		(void *)&cmd_pfc_set_rx_mode,
5469		(void *)&cmd_pfc_set_tx,
5470		(void *)&cmd_pfc_set_tx_mode,
5471		(void *)&cmd_pfc_set_high_water,
5472		(void *)&cmd_pfc_set_low_water,
5473		(void *)&cmd_pfc_set_pause_time,
5474		(void *)&cmd_pfc_set_priority,
5475		(void *)&cmd_pfc_set_portid,
5476		NULL,
5477	},
5478};
5479
5480/* *** RESET CONFIGURATION *** */
5481struct cmd_reset_result {
5482	cmdline_fixed_string_t reset;
5483	cmdline_fixed_string_t def;
5484};
5485
5486static void cmd_reset_parsed(__attribute__((unused)) void *parsed_result,
5487			     struct cmdline *cl,
5488			     __attribute__((unused)) void *data)
5489{
5490	cmdline_printf(cl, "Reset to default forwarding configuration...\n");
5491	set_def_fwd_config();
5492}
5493
5494cmdline_parse_token_string_t cmd_reset_set =
5495	TOKEN_STRING_INITIALIZER(struct cmd_reset_result, reset, "set");
5496cmdline_parse_token_string_t cmd_reset_def =
5497	TOKEN_STRING_INITIALIZER(struct cmd_reset_result, def,
5498				 "default");
5499
5500cmdline_parse_inst_t cmd_reset = {
5501	.f = cmd_reset_parsed,
5502	.data = NULL,
5503	.help_str = "set default: reset default forwarding configuration",
5504	.tokens = {
5505		(void *)&cmd_reset_set,
5506		(void *)&cmd_reset_def,
5507		NULL,
5508	},
5509};
5510
5511/* *** START FORWARDING *** */
5512struct cmd_start_result {
5513	cmdline_fixed_string_t start;
5514};
5515
5516cmdline_parse_token_string_t cmd_start_start =
5517	TOKEN_STRING_INITIALIZER(struct cmd_start_result, start, "start");
5518
5519static void cmd_start_parsed(__attribute__((unused)) void *parsed_result,
5520			     __attribute__((unused)) struct cmdline *cl,
5521			     __attribute__((unused)) void *data)
5522{
5523	start_packet_forwarding(0);
5524}
5525
5526cmdline_parse_inst_t cmd_start = {
5527	.f = cmd_start_parsed,
5528	.data = NULL,
5529	.help_str = "start packet forwarding",
5530	.tokens = {
5531		(void *)&cmd_start_start,
5532		NULL,
5533	},
5534};
5535
5536/* *** START FORWARDING WITH ONE TX BURST FIRST *** */
5537struct cmd_start_tx_first_result {
5538	cmdline_fixed_string_t start;
5539	cmdline_fixed_string_t tx_first;
5540};
5541
5542static void
5543cmd_start_tx_first_parsed(__attribute__((unused)) void *parsed_result,
5544			  __attribute__((unused)) struct cmdline *cl,
5545			  __attribute__((unused)) void *data)
5546{
5547	start_packet_forwarding(1);
5548}
5549
5550cmdline_parse_token_string_t cmd_start_tx_first_start =
5551	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result, start,
5552				 "start");
5553cmdline_parse_token_string_t cmd_start_tx_first_tx_first =
5554	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result,
5555				 tx_first, "tx_first");
5556
5557cmdline_parse_inst_t cmd_start_tx_first = {
5558	.f = cmd_start_tx_first_parsed,
5559	.data = NULL,
5560	.help_str = "start packet forwarding, after sending 1 burst of packets",
5561	.tokens = {
5562		(void *)&cmd_start_tx_first_start,
5563		(void *)&cmd_start_tx_first_tx_first,
5564		NULL,
5565	},
5566};
5567
5568/* *** START FORWARDING WITH N TX BURST FIRST *** */
5569struct cmd_start_tx_first_n_result {
5570	cmdline_fixed_string_t start;
5571	cmdline_fixed_string_t tx_first;
5572	uint32_t tx_num;
5573};
5574
5575static void
5576cmd_start_tx_first_n_parsed(void *parsed_result,
5577			  __attribute__((unused)) struct cmdline *cl,
5578			  __attribute__((unused)) void *data)
5579{
5580	struct cmd_start_tx_first_n_result *res = parsed_result;
5581
5582	start_packet_forwarding(res->tx_num);
5583}
5584
5585cmdline_parse_token_string_t cmd_start_tx_first_n_start =
5586	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result,
5587			start, "start");
5588cmdline_parse_token_string_t cmd_start_tx_first_n_tx_first =
5589	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result,
5590			tx_first, "tx_first");
5591cmdline_parse_token_num_t cmd_start_tx_first_n_tx_num =
5592	TOKEN_NUM_INITIALIZER(struct cmd_start_tx_first_n_result,
5593			tx_num, UINT32);
5594
5595cmdline_parse_inst_t cmd_start_tx_first_n = {
5596	.f = cmd_start_tx_first_n_parsed,
5597	.data = NULL,
5598	.help_str = "start packet forwarding, after sending <num> "
5599		"bursts of packets",
5600	.tokens = {
5601		(void *)&cmd_start_tx_first_n_start,
5602		(void *)&cmd_start_tx_first_n_tx_first,
5603		(void *)&cmd_start_tx_first_n_tx_num,
5604		NULL,
5605	},
5606};
5607
5608/* *** SET LINK UP *** */
5609struct cmd_set_link_up_result {
5610	cmdline_fixed_string_t set;
5611	cmdline_fixed_string_t link_up;
5612	cmdline_fixed_string_t port;
5613	uint8_t port_id;
5614};
5615
5616cmdline_parse_token_string_t cmd_set_link_up_set =
5617	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, set, "set");
5618cmdline_parse_token_string_t cmd_set_link_up_link_up =
5619	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, link_up,
5620				"link-up");
5621cmdline_parse_token_string_t cmd_set_link_up_port =
5622	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, port, "port");
5623cmdline_parse_token_num_t cmd_set_link_up_port_id =
5624	TOKEN_NUM_INITIALIZER(struct cmd_set_link_up_result, port_id, UINT8);
5625
5626static void cmd_set_link_up_parsed(__attribute__((unused)) void *parsed_result,
5627			     __attribute__((unused)) struct cmdline *cl,
5628			     __attribute__((unused)) void *data)
5629{
5630	struct cmd_set_link_up_result *res = parsed_result;
5631	dev_set_link_up(res->port_id);
5632}
5633
5634cmdline_parse_inst_t cmd_set_link_up = {
5635	.f = cmd_set_link_up_parsed,
5636	.data = NULL,
5637	.help_str = "set link-up port (port id)",
5638	.tokens = {
5639		(void *)&cmd_set_link_up_set,
5640		(void *)&cmd_set_link_up_link_up,
5641		(void *)&cmd_set_link_up_port,
5642		(void *)&cmd_set_link_up_port_id,
5643		NULL,
5644	},
5645};
5646
5647/* *** SET LINK DOWN *** */
5648struct cmd_set_link_down_result {
5649	cmdline_fixed_string_t set;
5650	cmdline_fixed_string_t link_down;
5651	cmdline_fixed_string_t port;
5652	uint8_t port_id;
5653};
5654
5655cmdline_parse_token_string_t cmd_set_link_down_set =
5656	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, set, "set");
5657cmdline_parse_token_string_t cmd_set_link_down_link_down =
5658	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, link_down,
5659				"link-down");
5660cmdline_parse_token_string_t cmd_set_link_down_port =
5661	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, port, "port");
5662cmdline_parse_token_num_t cmd_set_link_down_port_id =
5663	TOKEN_NUM_INITIALIZER(struct cmd_set_link_down_result, port_id, UINT8);
5664
5665static void cmd_set_link_down_parsed(
5666				__attribute__((unused)) void *parsed_result,
5667				__attribute__((unused)) struct cmdline *cl,
5668				__attribute__((unused)) void *data)
5669{
5670	struct cmd_set_link_down_result *res = parsed_result;
5671	dev_set_link_down(res->port_id);
5672}
5673
5674cmdline_parse_inst_t cmd_set_link_down = {
5675	.f = cmd_set_link_down_parsed,
5676	.data = NULL,
5677	.help_str = "set link-down port (port id)",
5678	.tokens = {
5679		(void *)&cmd_set_link_down_set,
5680		(void *)&cmd_set_link_down_link_down,
5681		(void *)&cmd_set_link_down_port,
5682		(void *)&cmd_set_link_down_port_id,
5683		NULL,
5684	},
5685};
5686
5687/* *** SHOW CFG *** */
5688struct cmd_showcfg_result {
5689	cmdline_fixed_string_t show;
5690	cmdline_fixed_string_t cfg;
5691	cmdline_fixed_string_t what;
5692};
5693
5694static void cmd_showcfg_parsed(void *parsed_result,
5695			       __attribute__((unused)) struct cmdline *cl,
5696			       __attribute__((unused)) void *data)
5697{
5698	struct cmd_showcfg_result *res = parsed_result;
5699	if (!strcmp(res->what, "rxtx"))
5700		rxtx_config_display();
5701	else if (!strcmp(res->what, "cores"))
5702		fwd_lcores_config_display();
5703	else if (!strcmp(res->what, "fwd"))
5704		pkt_fwd_config_display(&cur_fwd_config);
5705	else if (!strcmp(res->what, "txpkts"))
5706		show_tx_pkt_segments();
5707}
5708
5709cmdline_parse_token_string_t cmd_showcfg_show =
5710	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, show, "show");
5711cmdline_parse_token_string_t cmd_showcfg_port =
5712	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
5713cmdline_parse_token_string_t cmd_showcfg_what =
5714	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
5715				 "rxtx#cores#fwd#txpkts");
5716
5717cmdline_parse_inst_t cmd_showcfg = {
5718	.f = cmd_showcfg_parsed,
5719	.data = NULL,
5720	.help_str = "show config rxtx|cores|fwd|txpkts",
5721	.tokens = {
5722		(void *)&cmd_showcfg_show,
5723		(void *)&cmd_showcfg_port,
5724		(void *)&cmd_showcfg_what,
5725		NULL,
5726	},
5727};
5728
5729/* *** SHOW ALL PORT INFO *** */
5730struct cmd_showportall_result {
5731	cmdline_fixed_string_t show;
5732	cmdline_fixed_string_t port;
5733	cmdline_fixed_string_t what;
5734	cmdline_fixed_string_t all;
5735};
5736
5737static void cmd_showportall_parsed(void *parsed_result,
5738				__attribute__((unused)) struct cmdline *cl,
5739				__attribute__((unused)) void *data)
5740{
5741	portid_t i;
5742
5743	struct cmd_showportall_result *res = parsed_result;
5744	if (!strcmp(res->show, "clear")) {
5745		if (!strcmp(res->what, "stats"))
5746			FOREACH_PORT(i, ports)
5747				nic_stats_clear(i);
5748		else if (!strcmp(res->what, "xstats"))
5749			FOREACH_PORT(i, ports)
5750				nic_xstats_clear(i);
5751	} else if (!strcmp(res->what, "info"))
5752		FOREACH_PORT(i, ports)
5753			port_infos_display(i);
5754	else if (!strcmp(res->what, "stats"))
5755		FOREACH_PORT(i, ports)
5756			nic_stats_display(i);
5757	else if (!strcmp(res->what, "xstats"))
5758		FOREACH_PORT(i, ports)
5759			nic_xstats_display(i);
5760	else if (!strcmp(res->what, "fdir"))
5761		FOREACH_PORT(i, ports)
5762			fdir_get_infos(i);
5763	else if (!strcmp(res->what, "stat_qmap"))
5764		FOREACH_PORT(i, ports)
5765			nic_stats_mapping_display(i);
5766	else if (!strcmp(res->what, "dcb_tc"))
5767		FOREACH_PORT(i, ports)
5768			port_dcb_info_display(i);
5769}
5770
5771cmdline_parse_token_string_t cmd_showportall_show =
5772	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, show,
5773				 "show#clear");
5774cmdline_parse_token_string_t cmd_showportall_port =
5775	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
5776cmdline_parse_token_string_t cmd_showportall_what =
5777	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
5778				 "info#stats#xstats#fdir#stat_qmap#dcb_tc");
5779cmdline_parse_token_string_t cmd_showportall_all =
5780	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
5781cmdline_parse_inst_t cmd_showportall = {
5782	.f = cmd_showportall_parsed,
5783	.data = NULL,
5784	.help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all",
5785	.tokens = {
5786		(void *)&cmd_showportall_show,
5787		(void *)&cmd_showportall_port,
5788		(void *)&cmd_showportall_what,
5789		(void *)&cmd_showportall_all,
5790		NULL,
5791	},
5792};
5793
5794/* *** SHOW PORT INFO *** */
5795struct cmd_showport_result {
5796	cmdline_fixed_string_t show;
5797	cmdline_fixed_string_t port;
5798	cmdline_fixed_string_t what;
5799	uint8_t portnum;
5800};
5801
5802static void cmd_showport_parsed(void *parsed_result,
5803				__attribute__((unused)) struct cmdline *cl,
5804				__attribute__((unused)) void *data)
5805{
5806	struct cmd_showport_result *res = parsed_result;
5807	if (!strcmp(res->show, "clear")) {
5808		if (!strcmp(res->what, "stats"))
5809			nic_stats_clear(res->portnum);
5810		else if (!strcmp(res->what, "xstats"))
5811			nic_xstats_clear(res->portnum);
5812	} else if (!strcmp(res->what, "info"))
5813		port_infos_display(res->portnum);
5814	else if (!strcmp(res->what, "stats"))
5815		nic_stats_display(res->portnum);
5816	else if (!strcmp(res->what, "xstats"))
5817		nic_xstats_display(res->portnum);
5818	else if (!strcmp(res->what, "fdir"))
5819		 fdir_get_infos(res->portnum);
5820	else if (!strcmp(res->what, "stat_qmap"))
5821		nic_stats_mapping_display(res->portnum);
5822	else if (!strcmp(res->what, "dcb_tc"))
5823		port_dcb_info_display(res->portnum);
5824}
5825
5826cmdline_parse_token_string_t cmd_showport_show =
5827	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, show,
5828				 "show#clear");
5829cmdline_parse_token_string_t cmd_showport_port =
5830	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
5831cmdline_parse_token_string_t cmd_showport_what =
5832	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
5833				 "info#stats#xstats#fdir#stat_qmap#dcb_tc");
5834cmdline_parse_token_num_t cmd_showport_portnum =
5835	TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, UINT8);
5836
5837cmdline_parse_inst_t cmd_showport = {
5838	.f = cmd_showport_parsed,
5839	.data = NULL,
5840	.help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc X (X = port number)",
5841	.tokens = {
5842		(void *)&cmd_showport_show,
5843		(void *)&cmd_showport_port,
5844		(void *)&cmd_showport_what,
5845		(void *)&cmd_showport_portnum,
5846		NULL,
5847	},
5848};
5849
5850/* *** SHOW QUEUE INFO *** */
5851struct cmd_showqueue_result {
5852	cmdline_fixed_string_t show;
5853	cmdline_fixed_string_t type;
5854	cmdline_fixed_string_t what;
5855	uint8_t portnum;
5856	uint16_t queuenum;
5857};
5858
5859static void
5860cmd_showqueue_parsed(void *parsed_result,
5861	__attribute__((unused)) struct cmdline *cl,
5862	__attribute__((unused)) void *data)
5863{
5864	struct cmd_showqueue_result *res = parsed_result;
5865
5866	if (!strcmp(res->type, "rxq"))
5867		rx_queue_infos_display(res->portnum, res->queuenum);
5868	else if (!strcmp(res->type, "txq"))
5869		tx_queue_infos_display(res->portnum, res->queuenum);
5870}
5871
5872cmdline_parse_token_string_t cmd_showqueue_show =
5873	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, show, "show");
5874cmdline_parse_token_string_t cmd_showqueue_type =
5875	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, type, "rxq#txq");
5876cmdline_parse_token_string_t cmd_showqueue_what =
5877	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, what, "info");
5878cmdline_parse_token_num_t cmd_showqueue_portnum =
5879	TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, portnum, UINT8);
5880cmdline_parse_token_num_t cmd_showqueue_queuenum =
5881	TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, queuenum, UINT16);
5882
5883cmdline_parse_inst_t cmd_showqueue = {
5884	.f = cmd_showqueue_parsed,
5885	.data = NULL,
5886	.help_str = "show rxq|txq info <port number> <queue_number>",
5887	.tokens = {
5888		(void *)&cmd_showqueue_show,
5889		(void *)&cmd_showqueue_type,
5890		(void *)&cmd_showqueue_what,
5891		(void *)&cmd_showqueue_portnum,
5892		(void *)&cmd_showqueue_queuenum,
5893		NULL,
5894	},
5895};
5896
5897/* *** READ PORT REGISTER *** */
5898struct cmd_read_reg_result {
5899	cmdline_fixed_string_t read;
5900	cmdline_fixed_string_t reg;
5901	uint8_t port_id;
5902	uint32_t reg_off;
5903};
5904
5905static void
5906cmd_read_reg_parsed(void *parsed_result,
5907		    __attribute__((unused)) struct cmdline *cl,
5908		    __attribute__((unused)) void *data)
5909{
5910	struct cmd_read_reg_result *res = parsed_result;
5911	port_reg_display(res->port_id, res->reg_off);
5912}
5913
5914cmdline_parse_token_string_t cmd_read_reg_read =
5915	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, read, "read");
5916cmdline_parse_token_string_t cmd_read_reg_reg =
5917	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, reg, "reg");
5918cmdline_parse_token_num_t cmd_read_reg_port_id =
5919	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, port_id, UINT8);
5920cmdline_parse_token_num_t cmd_read_reg_reg_off =
5921	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, reg_off, UINT32);
5922
5923cmdline_parse_inst_t cmd_read_reg = {
5924	.f = cmd_read_reg_parsed,
5925	.data = NULL,
5926	.help_str = "read reg port_id reg_off",
5927	.tokens = {
5928		(void *)&cmd_read_reg_read,
5929		(void *)&cmd_read_reg_reg,
5930		(void *)&cmd_read_reg_port_id,
5931		(void *)&cmd_read_reg_reg_off,
5932		NULL,
5933	},
5934};
5935
5936/* *** READ PORT REGISTER BIT FIELD *** */
5937struct cmd_read_reg_bit_field_result {
5938	cmdline_fixed_string_t read;
5939	cmdline_fixed_string_t regfield;
5940	uint8_t port_id;
5941	uint32_t reg_off;
5942	uint8_t bit1_pos;
5943	uint8_t bit2_pos;
5944};
5945
5946static void
5947cmd_read_reg_bit_field_parsed(void *parsed_result,
5948			      __attribute__((unused)) struct cmdline *cl,
5949			      __attribute__((unused)) void *data)
5950{
5951	struct cmd_read_reg_bit_field_result *res = parsed_result;
5952	port_reg_bit_field_display(res->port_id, res->reg_off,
5953				   res->bit1_pos, res->bit2_pos);
5954}
5955
5956cmdline_parse_token_string_t cmd_read_reg_bit_field_read =
5957	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result, read,
5958				 "read");
5959cmdline_parse_token_string_t cmd_read_reg_bit_field_regfield =
5960	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result,
5961				 regfield, "regfield");
5962cmdline_parse_token_num_t cmd_read_reg_bit_field_port_id =
5963	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, port_id,
5964			      UINT8);
5965cmdline_parse_token_num_t cmd_read_reg_bit_field_reg_off =
5966	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, reg_off,
5967			      UINT32);
5968cmdline_parse_token_num_t cmd_read_reg_bit_field_bit1_pos =
5969	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit1_pos,
5970			      UINT8);
5971cmdline_parse_token_num_t cmd_read_reg_bit_field_bit2_pos =
5972	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit2_pos,
5973			      UINT8);
5974
5975cmdline_parse_inst_t cmd_read_reg_bit_field = {
5976	.f = cmd_read_reg_bit_field_parsed,
5977	.data = NULL,
5978	.help_str = "read regfield port_id reg_off bit_x bit_y "
5979	"(read register bit field between bit_x and bit_y included)",
5980	.tokens = {
5981		(void *)&cmd_read_reg_bit_field_read,
5982		(void *)&cmd_read_reg_bit_field_regfield,
5983		(void *)&cmd_read_reg_bit_field_port_id,
5984		(void *)&cmd_read_reg_bit_field_reg_off,
5985		(void *)&cmd_read_reg_bit_field_bit1_pos,
5986		(void *)&cmd_read_reg_bit_field_bit2_pos,
5987		NULL,
5988	},
5989};
5990
5991/* *** READ PORT REGISTER BIT *** */
5992struct cmd_read_reg_bit_result {
5993	cmdline_fixed_string_t read;
5994	cmdline_fixed_string_t regbit;
5995	uint8_t port_id;
5996	uint32_t reg_off;
5997	uint8_t bit_pos;
5998};
5999
6000static void
6001cmd_read_reg_bit_parsed(void *parsed_result,
6002			__attribute__((unused)) struct cmdline *cl,
6003			__attribute__((unused)) void *data)
6004{
6005	struct cmd_read_reg_bit_result *res = parsed_result;
6006	port_reg_bit_display(res->port_id, res->reg_off, res->bit_pos);
6007}
6008
6009cmdline_parse_token_string_t cmd_read_reg_bit_read =
6010	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result, read, "read");
6011cmdline_parse_token_string_t cmd_read_reg_bit_regbit =
6012	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result,
6013				 regbit, "regbit");
6014cmdline_parse_token_num_t cmd_read_reg_bit_port_id =
6015	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, port_id, UINT8);
6016cmdline_parse_token_num_t cmd_read_reg_bit_reg_off =
6017	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, reg_off, UINT32);
6018cmdline_parse_token_num_t cmd_read_reg_bit_bit_pos =
6019	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, bit_pos, UINT8);
6020
6021cmdline_parse_inst_t cmd_read_reg_bit = {
6022	.f = cmd_read_reg_bit_parsed,
6023	.data = NULL,
6024	.help_str = "read regbit port_id reg_off bit_x (0 <= bit_x <= 31)",
6025	.tokens = {
6026		(void *)&cmd_read_reg_bit_read,
6027		(void *)&cmd_read_reg_bit_regbit,
6028		(void *)&cmd_read_reg_bit_port_id,
6029		(void *)&cmd_read_reg_bit_reg_off,
6030		(void *)&cmd_read_reg_bit_bit_pos,
6031		NULL,
6032	},
6033};
6034
6035/* *** WRITE PORT REGISTER *** */
6036struct cmd_write_reg_result {
6037	cmdline_fixed_string_t write;
6038	cmdline_fixed_string_t reg;
6039	uint8_t port_id;
6040	uint32_t reg_off;
6041	uint32_t value;
6042};
6043
6044static void
6045cmd_write_reg_parsed(void *parsed_result,
6046		     __attribute__((unused)) struct cmdline *cl,
6047		     __attribute__((unused)) void *data)
6048{
6049	struct cmd_write_reg_result *res = parsed_result;
6050	port_reg_set(res->port_id, res->reg_off, res->value);
6051}
6052
6053cmdline_parse_token_string_t cmd_write_reg_write =
6054	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, write, "write");
6055cmdline_parse_token_string_t cmd_write_reg_reg =
6056	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, reg, "reg");
6057cmdline_parse_token_num_t cmd_write_reg_port_id =
6058	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, port_id, UINT8);
6059cmdline_parse_token_num_t cmd_write_reg_reg_off =
6060	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, reg_off, UINT32);
6061cmdline_parse_token_num_t cmd_write_reg_value =
6062	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, value, UINT32);
6063
6064cmdline_parse_inst_t cmd_write_reg = {
6065	.f = cmd_write_reg_parsed,
6066	.data = NULL,
6067	.help_str = "write reg port_id reg_off reg_value",
6068	.tokens = {
6069		(void *)&cmd_write_reg_write,
6070		(void *)&cmd_write_reg_reg,
6071		(void *)&cmd_write_reg_port_id,
6072		(void *)&cmd_write_reg_reg_off,
6073		(void *)&cmd_write_reg_value,
6074		NULL,
6075	},
6076};
6077
6078/* *** WRITE PORT REGISTER BIT FIELD *** */
6079struct cmd_write_reg_bit_field_result {
6080	cmdline_fixed_string_t write;
6081	cmdline_fixed_string_t regfield;
6082	uint8_t port_id;
6083	uint32_t reg_off;
6084	uint8_t bit1_pos;
6085	uint8_t bit2_pos;
6086	uint32_t value;
6087};
6088
6089static void
6090cmd_write_reg_bit_field_parsed(void *parsed_result,
6091			       __attribute__((unused)) struct cmdline *cl,
6092			       __attribute__((unused)) void *data)
6093{
6094	struct cmd_write_reg_bit_field_result *res = parsed_result;
6095	port_reg_bit_field_set(res->port_id, res->reg_off,
6096			  res->bit1_pos, res->bit2_pos, res->value);
6097}
6098
6099cmdline_parse_token_string_t cmd_write_reg_bit_field_write =
6100	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result, write,
6101				 "write");
6102cmdline_parse_token_string_t cmd_write_reg_bit_field_regfield =
6103	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result,
6104				 regfield, "regfield");
6105cmdline_parse_token_num_t cmd_write_reg_bit_field_port_id =
6106	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, port_id,
6107			      UINT8);
6108cmdline_parse_token_num_t cmd_write_reg_bit_field_reg_off =
6109	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, reg_off,
6110			      UINT32);
6111cmdline_parse_token_num_t cmd_write_reg_bit_field_bit1_pos =
6112	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit1_pos,
6113			      UINT8);
6114cmdline_parse_token_num_t cmd_write_reg_bit_field_bit2_pos =
6115	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit2_pos,
6116			      UINT8);
6117cmdline_parse_token_num_t cmd_write_reg_bit_field_value =
6118	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, value,
6119			      UINT32);
6120
6121cmdline_parse_inst_t cmd_write_reg_bit_field = {
6122	.f = cmd_write_reg_bit_field_parsed,
6123	.data = NULL,
6124	.help_str = "write regfield port_id reg_off bit_x bit_y reg_value"
6125	"(set register bit field between bit_x and bit_y included)",
6126	.tokens = {
6127		(void *)&cmd_write_reg_bit_field_write,
6128		(void *)&cmd_write_reg_bit_field_regfield,
6129		(void *)&cmd_write_reg_bit_field_port_id,
6130		(void *)&cmd_write_reg_bit_field_reg_off,
6131		(void *)&cmd_write_reg_bit_field_bit1_pos,
6132		(void *)&cmd_write_reg_bit_field_bit2_pos,
6133		(void *)&cmd_write_reg_bit_field_value,
6134		NULL,
6135	},
6136};
6137
6138/* *** WRITE PORT REGISTER BIT *** */
6139struct cmd_write_reg_bit_result {
6140	cmdline_fixed_string_t write;
6141	cmdline_fixed_string_t regbit;
6142	uint8_t port_id;
6143	uint32_t reg_off;
6144	uint8_t bit_pos;
6145	uint8_t value;
6146};
6147
6148static void
6149cmd_write_reg_bit_parsed(void *parsed_result,
6150			 __attribute__((unused)) struct cmdline *cl,
6151			 __attribute__((unused)) void *data)
6152{
6153	struct cmd_write_reg_bit_result *res = parsed_result;
6154	port_reg_bit_set(res->port_id, res->reg_off, res->bit_pos, res->value);
6155}
6156
6157cmdline_parse_token_string_t cmd_write_reg_bit_write =
6158	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result, write,
6159				 "write");
6160cmdline_parse_token_string_t cmd_write_reg_bit_regbit =
6161	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result,
6162				 regbit, "regbit");
6163cmdline_parse_token_num_t cmd_write_reg_bit_port_id =
6164	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, port_id, UINT8);
6165cmdline_parse_token_num_t cmd_write_reg_bit_reg_off =
6166	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, reg_off, UINT32);
6167cmdline_parse_token_num_t cmd_write_reg_bit_bit_pos =
6168	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, bit_pos, UINT8);
6169cmdline_parse_token_num_t cmd_write_reg_bit_value =
6170	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, value, UINT8);
6171
6172cmdline_parse_inst_t cmd_write_reg_bit = {
6173	.f = cmd_write_reg_bit_parsed,
6174	.data = NULL,
6175	.help_str = "write regbit port_id reg_off bit_x 0/1 (0 <= bit_x <= 31)",
6176	.tokens = {
6177		(void *)&cmd_write_reg_bit_write,
6178		(void *)&cmd_write_reg_bit_regbit,
6179		(void *)&cmd_write_reg_bit_port_id,
6180		(void *)&cmd_write_reg_bit_reg_off,
6181		(void *)&cmd_write_reg_bit_bit_pos,
6182		(void *)&cmd_write_reg_bit_value,
6183		NULL,
6184	},
6185};
6186
6187/* *** READ A RING DESCRIPTOR OF A PORT RX/TX QUEUE *** */
6188struct cmd_read_rxd_txd_result {
6189	cmdline_fixed_string_t read;
6190	cmdline_fixed_string_t rxd_txd;
6191	uint8_t port_id;
6192	uint16_t queue_id;
6193	uint16_t desc_id;
6194};
6195
6196static void
6197cmd_read_rxd_txd_parsed(void *parsed_result,
6198			__attribute__((unused)) struct cmdline *cl,
6199			__attribute__((unused)) void *data)
6200{
6201	struct cmd_read_rxd_txd_result *res = parsed_result;
6202
6203	if (!strcmp(res->rxd_txd, "rxd"))
6204		rx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
6205	else if (!strcmp(res->rxd_txd, "txd"))
6206		tx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
6207}
6208
6209cmdline_parse_token_string_t cmd_read_rxd_txd_read =
6210	TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, read, "read");
6211cmdline_parse_token_string_t cmd_read_rxd_txd_rxd_txd =
6212	TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, rxd_txd,
6213				 "rxd#txd");
6214cmdline_parse_token_num_t cmd_read_rxd_txd_port_id =
6215	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, port_id, UINT8);
6216cmdline_parse_token_num_t cmd_read_rxd_txd_queue_id =
6217	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, queue_id, UINT16);
6218cmdline_parse_token_num_t cmd_read_rxd_txd_desc_id =
6219	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, desc_id, UINT16);
6220
6221cmdline_parse_inst_t cmd_read_rxd_txd = {
6222	.f = cmd_read_rxd_txd_parsed,
6223	.data = NULL,
6224	.help_str = "read rxd|txd port_id queue_id rxd_id",
6225	.tokens = {
6226		(void *)&cmd_read_rxd_txd_read,
6227		(void *)&cmd_read_rxd_txd_rxd_txd,
6228		(void *)&cmd_read_rxd_txd_port_id,
6229		(void *)&cmd_read_rxd_txd_queue_id,
6230		(void *)&cmd_read_rxd_txd_desc_id,
6231		NULL,
6232	},
6233};
6234
6235/* *** QUIT *** */
6236struct cmd_quit_result {
6237	cmdline_fixed_string_t quit;
6238};
6239
6240static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
6241			    struct cmdline *cl,
6242			    __attribute__((unused)) void *data)
6243{
6244	pmd_test_exit();
6245	cmdline_quit(cl);
6246}
6247
6248cmdline_parse_token_string_t cmd_quit_quit =
6249	TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
6250
6251cmdline_parse_inst_t cmd_quit = {
6252	.f = cmd_quit_parsed,
6253	.data = NULL,
6254	.help_str = "exit application",
6255	.tokens = {
6256		(void *)&cmd_quit_quit,
6257		NULL,
6258	},
6259};
6260
6261/* *** ADD/REMOVE MAC ADDRESS FROM A PORT *** */
6262struct cmd_mac_addr_result {
6263	cmdline_fixed_string_t mac_addr_cmd;
6264	cmdline_fixed_string_t what;
6265	uint8_t port_num;
6266	struct ether_addr address;
6267};
6268
6269static void cmd_mac_addr_parsed(void *parsed_result,
6270		__attribute__((unused)) struct cmdline *cl,
6271		__attribute__((unused)) void *data)
6272{
6273	struct cmd_mac_addr_result *res = parsed_result;
6274	int ret;
6275
6276	if (strcmp(res->what, "add") == 0)
6277		ret = rte_eth_dev_mac_addr_add(res->port_num, &res->address, 0);
6278	else
6279		ret = rte_eth_dev_mac_addr_remove(res->port_num, &res->address);
6280
6281	/* check the return value and print it if is < 0 */
6282	if(ret < 0)
6283		printf("mac_addr_cmd error: (%s)\n", strerror(-ret));
6284
6285}
6286
6287cmdline_parse_token_string_t cmd_mac_addr_cmd =
6288	TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, mac_addr_cmd,
6289				"mac_addr");
6290cmdline_parse_token_string_t cmd_mac_addr_what =
6291	TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, what,
6292				"add#remove");
6293cmdline_parse_token_num_t cmd_mac_addr_portnum =
6294		TOKEN_NUM_INITIALIZER(struct cmd_mac_addr_result, port_num, UINT8);
6295cmdline_parse_token_etheraddr_t cmd_mac_addr_addr =
6296		TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
6297
6298cmdline_parse_inst_t cmd_mac_addr = {
6299	.f = cmd_mac_addr_parsed,
6300	.data = (void *)0,
6301	.help_str = "mac_addr add|remove X <address>: "
6302			"add/remove MAC address on port X",
6303	.tokens = {
6304		(void *)&cmd_mac_addr_cmd,
6305		(void *)&cmd_mac_addr_what,
6306		(void *)&cmd_mac_addr_portnum,
6307		(void *)&cmd_mac_addr_addr,
6308		NULL,
6309	},
6310};
6311
6312
6313/* *** CONFIGURE QUEUE STATS COUNTER MAPPINGS *** */
6314struct cmd_set_qmap_result {
6315	cmdline_fixed_string_t set;
6316	cmdline_fixed_string_t qmap;
6317	cmdline_fixed_string_t what;
6318	uint8_t port_id;
6319	uint16_t queue_id;
6320	uint8_t map_value;
6321};
6322
6323static void
6324cmd_set_qmap_parsed(void *parsed_result,
6325		       __attribute__((unused)) struct cmdline *cl,
6326		       __attribute__((unused)) void *data)
6327{
6328	struct cmd_set_qmap_result *res = parsed_result;
6329	int is_rx = (strcmp(res->what, "tx") == 0) ? 0 : 1;
6330
6331	set_qmap(res->port_id, (uint8_t)is_rx, res->queue_id, res->map_value);
6332}
6333
6334cmdline_parse_token_string_t cmd_setqmap_set =
6335	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
6336				 set, "set");
6337cmdline_parse_token_string_t cmd_setqmap_qmap =
6338	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
6339				 qmap, "stat_qmap");
6340cmdline_parse_token_string_t cmd_setqmap_what =
6341	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
6342				 what,