app/testpmd: add description of queue info command
[dpdk.git] / app / test-pmd / cmdline.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 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
91 #include "testpmd.h"
92
93 static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue);
94
95 #ifdef RTE_NIC_BYPASS
96 uint8_t bypass_is_supported(portid_t port_id);
97 #endif
98
99 /* *** Help command with introduction. *** */
100 struct cmd_help_brief_result {
101         cmdline_fixed_string_t help;
102 };
103
104 static 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
124 cmdline_parse_token_string_t cmd_help_brief_help =
125         TOKEN_STRING_INITIALIZER(struct cmd_help_brief_result, help, "help");
126
127 cmdline_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. *** */
138 struct cmd_help_long_result {
139         cmdline_fixed_string_t help;
140         cmdline_fixed_string_t section;
141 };
142
143 static 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                         " in mac_retry forwarding mode.\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                         "vlan set strip (on|off) (port_id)\n"
266                         "    Set the VLAN strip on a port.\n\n"
267
268                         "vlan set stripq (on|off) (port_id,queue_id)\n"
269                         "    Set the VLAN strip for a queue on a port.\n\n"
270
271                         "vlan set filter (on|off) (port_id)\n"
272                         "    Set the VLAN filter on a port.\n\n"
273
274                         "vlan set qinq (on|off) (port_id)\n"
275                         "    Set the VLAN QinQ (extended queue in queue)"
276                         " on a port.\n\n"
277
278                         "vlan set tpid (value) (port_id)\n"
279                         "    Set the outer VLAN TPID for Packet Filtering on"
280                         " a port\n\n"
281
282                         "rx_vlan add (vlan_id|all) (port_id)\n"
283                         "    Add a vlan_id, or all identifiers, to the set"
284                         " of VLAN identifiers filtered by port_id.\n\n"
285
286                         "rx_vlan rm (vlan_id|all) (port_id)\n"
287                         "    Remove a vlan_id, or all identifiers, from the set"
288                         " of VLAN identifiers filtered by port_id.\n\n"
289
290                         "rx_vlan add (vlan_id) port (port_id) vf (vf_mask)\n"
291                         "    Add a vlan_id, to the set of VLAN identifiers"
292                         "filtered for VF(s) from port_id.\n\n"
293
294                         "rx_vlan rm (vlan_id) port (port_id) vf (vf_mask)\n"
295                         "    Remove a vlan_id, to the set of VLAN identifiers"
296                         "filtered for VF(s) from port_id.\n\n"
297
298                         "rx_vlan set tpid (value) (port_id)\n"
299                         "    Set the outer VLAN TPID for Packet Filtering on"
300                         " a port\n\n"
301
302                         "tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
303                         "(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
304                         "   add a tunnel filter of a port.\n\n"
305
306                         "tunnel_filter rm (port_id) (outer_mac) (inner_mac) (ip_addr) "
307                         "(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
308                         "   remove a tunnel filter of a port.\n\n"
309
310                         "rx_vxlan_port add (udp_port) (port_id)\n"
311                         "    Add an UDP port for VXLAN packet filter on a port\n\n"
312
313                         "rx_vxlan_port rm (udp_port) (port_id)\n"
314                         "    Remove an UDP port for VXLAN packet filter on a port\n\n"
315
316                         "tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n"
317                         "    Set hardware insertion of VLAN IDs (single or double VLAN "
318                         "depends on the number of VLAN IDs) in packets sent on a port.\n\n"
319
320                         "tx_vlan set pvid port_id vlan_id (on|off)\n"
321                         "    Set port based TX VLAN insertion.\n\n"
322
323                         "tx_vlan reset (port_id)\n"
324                         "    Disable hardware insertion of a VLAN header in"
325                         " packets sent on a port.\n\n"
326
327                         "csum set (ip|udp|tcp|sctp|outer-ip) (hw|sw) (port_id)\n"
328                         "    Select hardware or software calculation of the"
329                         " checksum when transmitting a packet using the"
330                         " csum forward engine.\n"
331                         "    ip|udp|tcp|sctp always concern the inner layer.\n"
332                         "    outer-ip concerns the outer IP layer in"
333                         " case the packet is recognized as a tunnel packet by"
334                         " the forward engine (vxlan, gre and ipip are supported)\n"
335                         "    Please check the NIC datasheet for HW limits.\n\n"
336
337                         "csum parse-tunnel (on|off) (tx_port_id)\n"
338                         "    If disabled, treat tunnel packets as non-tunneled"
339                         " packets (treat inner headers as payload). The port\n"
340                         "    argument is the port used for TX in csum forward"
341                         " engine.\n\n"
342
343                         "csum show (port_id)\n"
344                         "    Display tx checksum offload configuration\n\n"
345
346                         "tso set (segsize) (portid)\n"
347                         "    Enable TCP Segmentation Offload in csum forward"
348                         " engine.\n"
349                         "    Please check the NIC datasheet for HW limits.\n\n"
350
351                         "tso show (portid)"
352                         "    Display the status of TCP Segmentation Offload.\n\n"
353
354                         "set fwd (%s)\n"
355                         "    Set packet forwarding mode.\n\n"
356
357                         "mac_addr add (port_id) (XX:XX:XX:XX:XX:XX)\n"
358                         "    Add a MAC address on port_id.\n\n"
359
360                         "mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)\n"
361                         "    Remove a MAC address from port_id.\n\n"
362
363                         "mac_addr add port (port_id) vf (vf_id) (mac_address)\n"
364                         "    Add a MAC address for a VF on the port.\n\n"
365
366                         "set port (port_id) uta (mac_address|all) (on|off)\n"
367                         "    Add/Remove a or all unicast hash filter(s)"
368                         "from port X.\n\n"
369
370                         "set promisc (port_id|all) (on|off)\n"
371                         "    Set the promiscuous mode on port_id, or all.\n\n"
372
373                         "set allmulti (port_id|all) (on|off)\n"
374                         "    Set the allmulti mode on port_id, or all.\n\n"
375
376                         "set flow_ctrl rx (on|off) tx (on|off) (high_water)"
377                         " (low_water) (pause_time) (send_xon) mac_ctrl_frame_fwd"
378                         " (on|off) autoneg (on|off) (port_id)\n"
379                         "set flow_ctrl rx (on|off) (portid)\n"
380                         "set flow_ctrl tx (on|off) (portid)\n"
381                         "set flow_ctrl high_water (high_water) (portid)\n"
382                         "set flow_ctrl low_water (low_water) (portid)\n"
383                         "set flow_ctrl pause_time (pause_time) (portid)\n"
384                         "set flow_ctrl send_xon (send_xon) (portid)\n"
385                         "set flow_ctrl mac_ctrl_frame_fwd (on|off) (portid)\n"
386                         "set flow_ctrl autoneg (on|off) (port_id)\n"
387                         "    Set the link flow control parameter on a port.\n\n"
388
389                         "set pfc_ctrl rx (on|off) tx (on|off) (high_water)"
390                         " (low_water) (pause_time) (priority) (port_id)\n"
391                         "    Set the priority flow control parameter on a"
392                         " port.\n\n"
393
394                         "set stat_qmap (tx|rx) (port_id) (queue_id) (qmapping)\n"
395                         "    Set statistics mapping (qmapping 0..15) for RX/TX"
396                         " queue on port.\n"
397                         "    e.g., 'set stat_qmap rx 0 2 5' sets rx queue 2"
398                         " on port 0 to mapping 5.\n\n"
399
400                         "set port (port_id) vf (vf_id) rx|tx on|off\n"
401                         "    Enable/Disable a VF receive/tranmit from a port\n\n"
402
403                         "set port (port_id) vf (vf_id) (mac_addr)"
404                         " (exact-mac#exact-mac-vlan#hashmac|hashmac-vlan) on|off\n"
405                         "   Add/Remove unicast or multicast MAC addr filter"
406                         " for a VF.\n\n"
407
408                         "set port (port_id) vf (vf_id) rxmode (AUPE|ROPE|BAM"
409                         "|MPE) (on|off)\n"
410                         "    AUPE:accepts untagged VLAN;"
411                         "ROPE:accept unicast hash\n\n"
412                         "    BAM:accepts broadcast packets;"
413                         "MPE:accepts all multicast packets\n\n"
414                         "    Enable/Disable a VF receive mode of a port\n\n"
415
416                         "set port (port_id) queue (queue_id) rate (rate_num)\n"
417                         "    Set rate limit for a queue of a port\n\n"
418
419                         "set port (port_id) vf (vf_id) rate (rate_num) "
420                         "queue_mask (queue_mask_value)\n"
421                         "    Set rate limit for queues in VF of a port\n\n"
422
423                         "set port (port_id) mirror-rule (rule_id)"
424                         " (pool-mirror-up|pool-mirror-down|vlan-mirror)"
425                         " (poolmask|vlanid[,vlanid]*) dst-pool (pool_id) (on|off)\n"
426                         "   Set pool or vlan type mirror rule on a port.\n"
427                         "   e.g., 'set port 0 mirror-rule 0 vlan-mirror 0,1"
428                         " dst-pool 0 on' enable mirror traffic with vlan 0,1"
429                         " to pool 0.\n\n"
430
431                         "set port (port_id) mirror-rule (rule_id)"
432                         " (uplink-mirror|downlink-mirror) dst-pool"
433                         " (pool_id) (on|off)\n"
434                         "   Set uplink or downlink type mirror rule on a port.\n"
435                         "   e.g., 'set port 0 mirror-rule 0 uplink-mirror dst-pool"
436                         " 0 on' enable mirror income traffic to pool 0.\n\n"
437
438                         "reset port (port_id) mirror-rule (rule_id)\n"
439                         "   Reset a mirror rule.\n\n"
440
441                         "set flush_rx (on|off)\n"
442                         "   Flush (default) or don't flush RX streams before"
443                         " forwarding. Mainly used with PCAP drivers.\n\n"
444
445                         #ifdef RTE_NIC_BYPASS
446                         "set bypass mode (normal|bypass|isolate) (port_id)\n"
447                         "   Set the bypass mode for the lowest port on bypass enabled"
448                         " NIC.\n\n"
449
450                         "set bypass event (timeout|os_on|os_off|power_on|power_off) "
451                         "mode (normal|bypass|isolate) (port_id)\n"
452                         "   Set the event required to initiate specified bypass mode for"
453                         " the lowest port on a bypass enabled NIC where:\n"
454                         "       timeout   = enable bypass after watchdog timeout.\n"
455                         "       os_on     = enable bypass when OS/board is powered on.\n"
456                         "       os_off    = enable bypass when OS/board is powered off.\n"
457                         "       power_on  = enable bypass when power supply is turned on.\n"
458                         "       power_off = enable bypass when power supply is turned off."
459                         "\n\n"
460
461                         "set bypass timeout (0|1.5|2|3|4|8|16|32)\n"
462                         "   Set the bypass watchdog timeout to 'n' seconds"
463                         " where 0 = instant.\n\n"
464
465                         "show bypass config (port_id)\n"
466                         "   Show the bypass configuration for a bypass enabled NIC"
467                         " using the lowest port on the NIC.\n\n"
468 #endif
469 #ifdef RTE_LIBRTE_PMD_BOND
470                         "create bonded device (mode) (socket)\n"
471                         "       Create a new bonded device with specific bonding mode and socket.\n\n"
472
473                         "add bonding slave (slave_id) (port_id)\n"
474                         "       Add a slave device to a bonded device.\n\n"
475
476                         "remove bonding slave (slave_id) (port_id)\n"
477                         "       Remove a slave device from a bonded device.\n\n"
478
479                         "set bonding mode (value) (port_id)\n"
480                         "       Set the bonding mode on a bonded device.\n\n"
481
482                         "set bonding primary (slave_id) (port_id)\n"
483                         "       Set the primary slave for a bonded device.\n\n"
484
485                         "show bonding config (port_id)\n"
486                         "       Show the bonding config for port_id.\n\n"
487
488                         "set bonding mac_addr (port_id) (address)\n"
489                         "       Set the MAC address of a bonded device.\n\n"
490
491                         "set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
492                         "       Set the transmit balance policy for bonded device running in balance mode.\n\n"
493
494                         "set bonding mon_period (port_id) (value)\n"
495                         "       Set the bonding link status monitoring polling period in ms.\n\n"
496 #endif
497                         "set link-up port (port_id)\n"
498                         "       Set link up for a port.\n\n"
499
500                         "set link-down port (port_id)\n"
501                         "       Set link down for a port.\n\n"
502
503                         , list_pkt_forwarding_modes()
504                 );
505         }
506
507         if (show_all || !strcmp(res->section, "ports")) {
508
509                 cmdline_printf(
510                         cl,
511                         "\n"
512                         "Port Operations:\n"
513                         "----------------\n\n"
514
515                         "port start (port_id|all)\n"
516                         "    Start all ports or port_id.\n\n"
517
518                         "port stop (port_id|all)\n"
519                         "    Stop all ports or port_id.\n\n"
520
521                         "port close (port_id|all)\n"
522                         "    Close all ports or port_id.\n\n"
523
524                         "port attach (ident)\n"
525                         "    Attach physical or virtual dev by pci address or virtual device name\n\n"
526
527                         "port detach (port_id)\n"
528                         "    Detach physical or virtual dev by port_id\n\n"
529
530                         "port config (port_id|all)"
531                         " speed (10|100|1000|10000|40000|auto)"
532                         " duplex (half|full|auto)\n"
533                         "    Set speed and duplex for all ports or port_id\n\n"
534
535                         "port config all (rxq|txq|rxd|txd) (value)\n"
536                         "    Set number for rxq/txq/rxd/txd.\n\n"
537
538                         "port config all max-pkt-len (value)\n"
539                         "    Set the max packet length.\n\n"
540
541                         "port config all (crc-strip|rx-cksum|hw-vlan|hw-vlan-filter|"
542                         "hw-vlan-strip|hw-vlan-extend|drop-en)"
543                         " (on|off)\n"
544                         "    Set crc-strip/rx-checksum/hardware-vlan/drop_en"
545                         " for ports.\n\n"
546
547                         "port config all rss (all|ip|tcp|udp|sctp|ether|none)\n"
548                         "    Set the RSS mode.\n\n"
549
550                         "port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
551                         "    Set the RSS redirection table.\n\n"
552
553                         "port config (port_id) dcb vt (on|off) (traffic_class)"
554                         " pfc (on|off)\n"
555                         "    Set the DCB mode.\n\n"
556
557                         "port config all burst (value)\n"
558                         "    Set the number of packets per burst.\n\n"
559
560                         "port config all (txpt|txht|txwt|rxpt|rxht|rxwt)"
561                         " (value)\n"
562                         "    Set the ring prefetch/host/writeback threshold"
563                         " for tx/rx queue.\n\n"
564
565                         "port config all (txfreet|txrst|rxfreet) (value)\n"
566                         "    Set free threshold for rx/tx, or set"
567                         " tx rs bit threshold.\n\n"
568                         "port config mtu X value\n"
569                         "    Set the MTU of port X to a given value\n\n"
570
571                         "port (port_id) (rxq|txq) (queue_id) (start|stop)\n"
572                         "    Start/stop a rx/tx queue of port X. Only take effect"
573                         " when port X is started\n"
574                 );
575         }
576
577         if (show_all || !strcmp(res->section, "registers")) {
578
579                 cmdline_printf(
580                         cl,
581                         "\n"
582                         "Registers:\n"
583                         "----------\n\n"
584
585                         "read reg (port_id) (address)\n"
586                         "    Display value of a port register.\n\n"
587
588                         "read regfield (port_id) (address) (bit_x) (bit_y)\n"
589                         "    Display a port register bit field.\n\n"
590
591                         "read regbit (port_id) (address) (bit_x)\n"
592                         "    Display a single port register bit.\n\n"
593
594                         "write reg (port_id) (address) (value)\n"
595                         "    Set value of a port register.\n\n"
596
597                         "write regfield (port_id) (address) (bit_x) (bit_y)"
598                         " (value)\n"
599                         "    Set bit field of a port register.\n\n"
600
601                         "write regbit (port_id) (address) (bit_x) (value)\n"
602                         "    Set single bit value of a port register.\n\n"
603                 );
604         }
605         if (show_all || !strcmp(res->section, "filters")) {
606
607                 cmdline_printf(
608                         cl,
609                         "\n"
610                         "filters:\n"
611                         "--------\n\n"
612
613                         "ethertype_filter (port_id) (add|del)"
614                         " (mac_addr|mac_ignr) (mac_address) ethertype"
615                         " (ether_type) (drop|fwd) queue (queue_id)\n"
616                         "    Add/Del an ethertype filter.\n\n"
617
618                         "2tuple_filter (port_id) (add|del)"
619                         " dst_port (dst_port_value) protocol (protocol_value)"
620                         " mask (mask_value) tcp_flags (tcp_flags_value)"
621                         " priority (prio_value) queue (queue_id)\n"
622                         "    Add/Del a 2tuple filter.\n\n"
623
624                         "5tuple_filter (port_id) (add|del)"
625                         " dst_ip (dst_address) src_ip (src_address)"
626                         " dst_port (dst_port_value) src_port (src_port_value)"
627                         " protocol (protocol_value)"
628                         " mask (mask_value) tcp_flags (tcp_flags_value)"
629                         " priority (prio_value) queue (queue_id)\n"
630                         "    Add/Del a 5tuple filter.\n\n"
631
632                         "syn_filter (port_id) (add|del) priority (high|low) queue (queue_id)"
633                         "    Add/Del syn filter.\n\n"
634
635                         "flex_filter (port_id) (add|del) len (len_value)"
636                         " bytes (bytes_value) mask (mask_value)"
637                         " priority (prio_value) queue (queue_id)\n"
638                         "    Add/Del a flex filter.\n\n"
639
640                         "flow_director_filter (port_id) mode IP (add|del|update)"
641                         " flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
642                         " src (src_ip_address) dst (dst_ip_address)"
643                         " vlan (vlan_value) flexbytes (flexbytes_value)"
644                         " (drop|fwd) pf|vf(vf_id) queue (queue_id)"
645                         " fd_id (fd_id_value)\n"
646                         "    Add/Del an IP type flow director filter.\n\n"
647
648                         "flow_director_filter (port_id) mode IP (add|del|update)"
649                         " flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
650                         " src (src_ip_address) (src_port)"
651                         " dst (dst_ip_address) (dst_port)"
652                         " vlan (vlan_value) flexbytes (flexbytes_value)"
653                         " (drop|fwd) pf|vf(vf_id) queue (queue_id)"
654                         " fd_id (fd_id_value)\n"
655                         "    Add/Del an UDP/TCP type flow director filter.\n\n"
656
657                         "flow_director_filter (port_id) mode IP (add|del|update)"
658                         " flow (ipv4-sctp|ipv6-sctp)"
659                         " src (src_ip_address) (src_port)"
660                         " dst (dst_ip_address) (dst_port)"
661                         " tag (verification_tag) vlan (vlan_value)"
662                         " flexbytes (flexbytes_value) (drop|fwd)"
663                         " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
664                         "    Add/Del a SCTP type flow director filter.\n\n"
665
666                         "flow_director_filter (port_id) mode IP (add|del|update)"
667                         " flow l2_payload ether (ethertype)"
668                         " flexbytes (flexbytes_value) (drop|fwd)"
669                         " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
670                         "    Add/Del a l2 payload type flow director filter.\n\n"
671
672                         "flow_director_filter (port_id) mode MAC-VLAN (add|del|update)"
673                         " mac (mac_address) vlan (vlan_value)"
674                         " flexbytes (flexbytes_value) (drop|fwd)"
675                         " queue (queue_id) fd_id (fd_id_value)\n"
676                         "    Add/Del a MAC-VLAN flow director filter.\n\n"
677
678                         "flow_director_filter (port_id) mode Tunnel (add|del|update)"
679                         " mac (mac_address) vlan (vlan_value)"
680                         " tunnel (NVGRE|VxLAN) tunnel-id (tunnel_id_value)"
681                         " flexbytes (flexbytes_value) (drop|fwd)"
682                         " queue (queue_id) fd_id (fd_id_value)\n"
683                         "    Add/Del a Tunnel flow director filter.\n\n"
684
685                         "flush_flow_director (port_id)\n"
686                         "    Flush all flow director entries of a device.\n\n"
687
688                         "flow_director_mask (port_id) mode IP vlan (vlan_value)"
689                         " src_mask (ipv4_src) (ipv6_src) (src_port)"
690                         " dst_mask (ipv4_dst) (ipv6_dst) (dst_port)\n"
691                         "    Set flow director IP mask.\n\n"
692
693                         "flow_director_mask (port_id) mode MAC-VLAN"
694                         " vlan (vlan_value) mac (mac_value)\n"
695                         "    Set flow director MAC-VLAN mask.\n\n"
696
697                         "flow_director_mask (port_id) mode Tunnel"
698                         " vlan (vlan_value) mac (mac_value)"
699                         " tunnel-type (tunnel_type_value)"
700                         " tunnel-id (tunnel_id_value)\n"
701                         "    Set flow director Tunnel mask.\n\n"
702
703                         "flow_director_flex_mask (port_id)"
704                         " flow (none|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|"
705                         "ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|l2_payload|all)"
706                         " (mask)\n"
707                         "    Configure mask of flex payload.\n\n"
708
709                         "flow_director_flex_payload (port_id)"
710                         " (raw|l2|l3|l4) (config)\n"
711                         "    Configure flex payload selection.\n\n"
712
713                         "get_sym_hash_ena_per_port (port_id)\n"
714                         "    get symmetric hash enable configuration per port.\n\n"
715
716                         "set_sym_hash_ena_per_port (port_id) (enable|disable)\n"
717                         "    set symmetric hash enable configuration per port"
718                         " to enable or disable.\n\n"
719
720                         "get_hash_global_config (port_id)\n"
721                         "    Get the global configurations of hash filters.\n\n"
722
723                         "set_hash_global_config (port_id) (toeplitz|simple_xor|default)"
724                         " (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
725                         "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)"
726                         " (enable|disable)\n"
727                         "    Set the global configurations of hash filters.\n\n"
728
729                         "set_hash_input_set (port_id) (ipv4|ipv4-frag|"
730                         "ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
731                         "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
732                         "l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
733                         "dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
734                         "ipv6-next-header|udp-src-port|udp-dst-port|"
735                         "tcp-src-port|tcp-dst-port|sctp-src-port|"
736                         "sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
737                         "fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
738                         "fld-8th|none) (select|add)\n"
739                         "    Set the input set for hash.\n\n"
740
741                         "set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
742                         "ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
743                         "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
744                         "l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
745                         "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
746                         "sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
747                         "fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
748                         "fld-8th|none) (select|add)\n"
749                         "    Set the input set for FDir.\n\n"
750                 );
751         }
752 }
753
754 cmdline_parse_token_string_t cmd_help_long_help =
755         TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, help, "help");
756
757 cmdline_parse_token_string_t cmd_help_long_section =
758         TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, section,
759                         "all#control#display#config#"
760                         "ports#registers#filters");
761
762 cmdline_parse_inst_t cmd_help_long = {
763         .f = cmd_help_long_parsed,
764         .data = NULL,
765         .help_str = "show help",
766         .tokens = {
767                 (void *)&cmd_help_long_help,
768                 (void *)&cmd_help_long_section,
769                 NULL,
770         },
771 };
772
773
774 /* *** start/stop/close all ports *** */
775 struct cmd_operate_port_result {
776         cmdline_fixed_string_t keyword;
777         cmdline_fixed_string_t name;
778         cmdline_fixed_string_t value;
779 };
780
781 static void cmd_operate_port_parsed(void *parsed_result,
782                                 __attribute__((unused)) struct cmdline *cl,
783                                 __attribute__((unused)) void *data)
784 {
785         struct cmd_operate_port_result *res = parsed_result;
786
787         if (!strcmp(res->name, "start"))
788                 start_port(RTE_PORT_ALL);
789         else if (!strcmp(res->name, "stop"))
790                 stop_port(RTE_PORT_ALL);
791         else if (!strcmp(res->name, "close"))
792                 close_port(RTE_PORT_ALL);
793         else
794                 printf("Unknown parameter\n");
795 }
796
797 cmdline_parse_token_string_t cmd_operate_port_all_cmd =
798         TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, keyword,
799                                                                 "port");
800 cmdline_parse_token_string_t cmd_operate_port_all_port =
801         TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, name,
802                                                 "start#stop#close");
803 cmdline_parse_token_string_t cmd_operate_port_all_all =
804         TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, value, "all");
805
806 cmdline_parse_inst_t cmd_operate_port = {
807         .f = cmd_operate_port_parsed,
808         .data = NULL,
809         .help_str = "port start|stop|close all: start/stop/close all ports",
810         .tokens = {
811                 (void *)&cmd_operate_port_all_cmd,
812                 (void *)&cmd_operate_port_all_port,
813                 (void *)&cmd_operate_port_all_all,
814                 NULL,
815         },
816 };
817
818 /* *** start/stop/close specific port *** */
819 struct cmd_operate_specific_port_result {
820         cmdline_fixed_string_t keyword;
821         cmdline_fixed_string_t name;
822         uint8_t value;
823 };
824
825 static void cmd_operate_specific_port_parsed(void *parsed_result,
826                         __attribute__((unused)) struct cmdline *cl,
827                                 __attribute__((unused)) void *data)
828 {
829         struct cmd_operate_specific_port_result *res = parsed_result;
830
831         if (!strcmp(res->name, "start"))
832                 start_port(res->value);
833         else if (!strcmp(res->name, "stop"))
834                 stop_port(res->value);
835         else if (!strcmp(res->name, "close"))
836                 close_port(res->value);
837         else
838                 printf("Unknown parameter\n");
839 }
840
841 cmdline_parse_token_string_t cmd_operate_specific_port_cmd =
842         TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
843                                                         keyword, "port");
844 cmdline_parse_token_string_t cmd_operate_specific_port_port =
845         TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
846                                                 name, "start#stop#close");
847 cmdline_parse_token_num_t cmd_operate_specific_port_id =
848         TOKEN_NUM_INITIALIZER(struct cmd_operate_specific_port_result,
849                                                         value, UINT8);
850
851 cmdline_parse_inst_t cmd_operate_specific_port = {
852         .f = cmd_operate_specific_port_parsed,
853         .data = NULL,
854         .help_str = "port start|stop|close X: start/stop/close port X",
855         .tokens = {
856                 (void *)&cmd_operate_specific_port_cmd,
857                 (void *)&cmd_operate_specific_port_port,
858                 (void *)&cmd_operate_specific_port_id,
859                 NULL,
860         },
861 };
862
863 /* *** attach a specified port *** */
864 struct cmd_operate_attach_port_result {
865         cmdline_fixed_string_t port;
866         cmdline_fixed_string_t keyword;
867         cmdline_fixed_string_t identifier;
868 };
869
870 static void cmd_operate_attach_port_parsed(void *parsed_result,
871                                 __attribute__((unused)) struct cmdline *cl,
872                                 __attribute__((unused)) void *data)
873 {
874         struct cmd_operate_attach_port_result *res = parsed_result;
875
876         if (!strcmp(res->keyword, "attach"))
877                 attach_port(res->identifier);
878         else
879                 printf("Unknown parameter\n");
880 }
881
882 cmdline_parse_token_string_t cmd_operate_attach_port_port =
883         TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
884                         port, "port");
885 cmdline_parse_token_string_t cmd_operate_attach_port_keyword =
886         TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
887                         keyword, "attach");
888 cmdline_parse_token_string_t cmd_operate_attach_port_identifier =
889         TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
890                         identifier, NULL);
891
892 cmdline_parse_inst_t cmd_operate_attach_port = {
893         .f = cmd_operate_attach_port_parsed,
894         .data = NULL,
895         .help_str = "port attach identifier, "
896                 "identifier: pci address or virtual dev name",
897         .tokens = {
898                 (void *)&cmd_operate_attach_port_port,
899                 (void *)&cmd_operate_attach_port_keyword,
900                 (void *)&cmd_operate_attach_port_identifier,
901                 NULL,
902         },
903 };
904
905 /* *** detach a specified port *** */
906 struct cmd_operate_detach_port_result {
907         cmdline_fixed_string_t port;
908         cmdline_fixed_string_t keyword;
909         uint8_t port_id;
910 };
911
912 static void cmd_operate_detach_port_parsed(void *parsed_result,
913                                 __attribute__((unused)) struct cmdline *cl,
914                                 __attribute__((unused)) void *data)
915 {
916         struct cmd_operate_detach_port_result *res = parsed_result;
917
918         if (!strcmp(res->keyword, "detach"))
919                 detach_port(res->port_id);
920         else
921                 printf("Unknown parameter\n");
922 }
923
924 cmdline_parse_token_string_t cmd_operate_detach_port_port =
925         TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
926                         port, "port");
927 cmdline_parse_token_string_t cmd_operate_detach_port_keyword =
928         TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
929                         keyword, "detach");
930 cmdline_parse_token_num_t cmd_operate_detach_port_port_id =
931         TOKEN_NUM_INITIALIZER(struct cmd_operate_detach_port_result,
932                         port_id, UINT8);
933
934 cmdline_parse_inst_t cmd_operate_detach_port = {
935         .f = cmd_operate_detach_port_parsed,
936         .data = NULL,
937         .help_str = "port detach port_id",
938         .tokens = {
939                 (void *)&cmd_operate_detach_port_port,
940                 (void *)&cmd_operate_detach_port_keyword,
941                 (void *)&cmd_operate_detach_port_port_id,
942                 NULL,
943         },
944 };
945
946 /* *** configure speed for all ports *** */
947 struct cmd_config_speed_all {
948         cmdline_fixed_string_t port;
949         cmdline_fixed_string_t keyword;
950         cmdline_fixed_string_t all;
951         cmdline_fixed_string_t item1;
952         cmdline_fixed_string_t item2;
953         cmdline_fixed_string_t value1;
954         cmdline_fixed_string_t value2;
955 };
956
957 static void
958 cmd_config_speed_all_parsed(void *parsed_result,
959                         __attribute__((unused)) struct cmdline *cl,
960                         __attribute__((unused)) void *data)
961 {
962         struct cmd_config_speed_all *res = parsed_result;
963         uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
964         uint16_t link_duplex = 0;
965         portid_t pid;
966
967         if (!all_ports_stopped()) {
968                 printf("Please stop all ports first\n");
969                 return;
970         }
971
972         if (!strcmp(res->value1, "10"))
973                 link_speed = ETH_LINK_SPEED_10;
974         else if (!strcmp(res->value1, "100"))
975                 link_speed = ETH_LINK_SPEED_100;
976         else if (!strcmp(res->value1, "1000"))
977                 link_speed = ETH_LINK_SPEED_1000;
978         else if (!strcmp(res->value1, "10000"))
979                 link_speed = ETH_LINK_SPEED_10G;
980         else if (!strcmp(res->value1, "40000"))
981                 link_speed = ETH_LINK_SPEED_40G;
982         else if (!strcmp(res->value1, "auto"))
983                 link_speed = ETH_LINK_SPEED_AUTONEG;
984         else {
985                 printf("Unknown parameter\n");
986                 return;
987         }
988
989         if (!strcmp(res->value2, "half"))
990                 link_duplex = ETH_LINK_HALF_DUPLEX;
991         else if (!strcmp(res->value2, "full"))
992                 link_duplex = ETH_LINK_FULL_DUPLEX;
993         else if (!strcmp(res->value2, "auto"))
994                 link_duplex = ETH_LINK_AUTONEG_DUPLEX;
995         else {
996                 printf("Unknown parameter\n");
997                 return;
998         }
999
1000         FOREACH_PORT(pid, ports) {
1001                 ports[pid].dev_conf.link_speed = link_speed;
1002                 ports[pid].dev_conf.link_duplex = link_duplex;
1003         }
1004
1005         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1006 }
1007
1008 cmdline_parse_token_string_t cmd_config_speed_all_port =
1009         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, port, "port");
1010 cmdline_parse_token_string_t cmd_config_speed_all_keyword =
1011         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, keyword,
1012                                                         "config");
1013 cmdline_parse_token_string_t cmd_config_speed_all_all =
1014         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, all, "all");
1015 cmdline_parse_token_string_t cmd_config_speed_all_item1 =
1016         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
1017 cmdline_parse_token_string_t cmd_config_speed_all_value1 =
1018         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
1019                                                 "10#100#1000#10000#40000#auto");
1020 cmdline_parse_token_string_t cmd_config_speed_all_item2 =
1021         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
1022 cmdline_parse_token_string_t cmd_config_speed_all_value2 =
1023         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value2,
1024                                                 "half#full#auto");
1025
1026 cmdline_parse_inst_t cmd_config_speed_all = {
1027         .f = cmd_config_speed_all_parsed,
1028         .data = NULL,
1029         .help_str = "port config all speed 10|100|1000|10000|40000|auto duplex "
1030                                                         "half|full|auto",
1031         .tokens = {
1032                 (void *)&cmd_config_speed_all_port,
1033                 (void *)&cmd_config_speed_all_keyword,
1034                 (void *)&cmd_config_speed_all_all,
1035                 (void *)&cmd_config_speed_all_item1,
1036                 (void *)&cmd_config_speed_all_value1,
1037                 (void *)&cmd_config_speed_all_item2,
1038                 (void *)&cmd_config_speed_all_value2,
1039                 NULL,
1040         },
1041 };
1042
1043 /* *** configure speed for specific port *** */
1044 struct cmd_config_speed_specific {
1045         cmdline_fixed_string_t port;
1046         cmdline_fixed_string_t keyword;
1047         uint8_t id;
1048         cmdline_fixed_string_t item1;
1049         cmdline_fixed_string_t item2;
1050         cmdline_fixed_string_t value1;
1051         cmdline_fixed_string_t value2;
1052 };
1053
1054 static void
1055 cmd_config_speed_specific_parsed(void *parsed_result,
1056                                 __attribute__((unused)) struct cmdline *cl,
1057                                 __attribute__((unused)) void *data)
1058 {
1059         struct cmd_config_speed_specific *res = parsed_result;
1060         uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
1061         uint16_t link_duplex = 0;
1062
1063         if (!all_ports_stopped()) {
1064                 printf("Please stop all ports first\n");
1065                 return;
1066         }
1067
1068         if (port_id_is_invalid(res->id, ENABLED_WARN))
1069                 return;
1070
1071         if (!strcmp(res->value1, "10"))
1072                 link_speed = ETH_LINK_SPEED_10;
1073         else if (!strcmp(res->value1, "100"))
1074                 link_speed = ETH_LINK_SPEED_100;
1075         else if (!strcmp(res->value1, "1000"))
1076                 link_speed = ETH_LINK_SPEED_1000;
1077         else if (!strcmp(res->value1, "10000"))
1078                 link_speed = ETH_LINK_SPEED_10000;
1079         else if (!strcmp(res->value1, "40000"))
1080                 link_speed = ETH_LINK_SPEED_40G;
1081         else if (!strcmp(res->value1, "auto"))
1082                 link_speed = ETH_LINK_SPEED_AUTONEG;
1083         else {
1084                 printf("Unknown parameter\n");
1085                 return;
1086         }
1087
1088         if (!strcmp(res->value2, "half"))
1089                 link_duplex = ETH_LINK_HALF_DUPLEX;
1090         else if (!strcmp(res->value2, "full"))
1091                 link_duplex = ETH_LINK_FULL_DUPLEX;
1092         else if (!strcmp(res->value2, "auto"))
1093                 link_duplex = ETH_LINK_AUTONEG_DUPLEX;
1094         else {
1095                 printf("Unknown parameter\n");
1096                 return;
1097         }
1098
1099         ports[res->id].dev_conf.link_speed = link_speed;
1100         ports[res->id].dev_conf.link_duplex = link_duplex;
1101
1102         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1103 }
1104
1105
1106 cmdline_parse_token_string_t cmd_config_speed_specific_port =
1107         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, port,
1108                                                                 "port");
1109 cmdline_parse_token_string_t cmd_config_speed_specific_keyword =
1110         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, keyword,
1111                                                                 "config");
1112 cmdline_parse_token_num_t cmd_config_speed_specific_id =
1113         TOKEN_NUM_INITIALIZER(struct cmd_config_speed_specific, id, UINT8);
1114 cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
1115         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item1,
1116                                                                 "speed");
1117 cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
1118         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
1119                                                 "10#100#1000#10000#40000#auto");
1120 cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
1121         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
1122                                                                 "duplex");
1123 cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
1124         TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value2,
1125                                                         "half#full#auto");
1126
1127 cmdline_parse_inst_t cmd_config_speed_specific = {
1128         .f = cmd_config_speed_specific_parsed,
1129         .data = NULL,
1130         .help_str = "port config X speed 10|100|1000|10000|40000|auto duplex "
1131                                                         "half|full|auto",
1132         .tokens = {
1133                 (void *)&cmd_config_speed_specific_port,
1134                 (void *)&cmd_config_speed_specific_keyword,
1135                 (void *)&cmd_config_speed_specific_id,
1136                 (void *)&cmd_config_speed_specific_item1,
1137                 (void *)&cmd_config_speed_specific_value1,
1138                 (void *)&cmd_config_speed_specific_item2,
1139                 (void *)&cmd_config_speed_specific_value2,
1140                 NULL,
1141         },
1142 };
1143
1144 /* *** configure txq/rxq, txd/rxd *** */
1145 struct cmd_config_rx_tx {
1146         cmdline_fixed_string_t port;
1147         cmdline_fixed_string_t keyword;
1148         cmdline_fixed_string_t all;
1149         cmdline_fixed_string_t name;
1150         uint16_t value;
1151 };
1152
1153 static void
1154 cmd_config_rx_tx_parsed(void *parsed_result,
1155                         __attribute__((unused)) struct cmdline *cl,
1156                         __attribute__((unused)) void *data)
1157 {
1158         struct cmd_config_rx_tx *res = parsed_result;
1159
1160         if (!all_ports_stopped()) {
1161                 printf("Please stop all ports first\n");
1162                 return;
1163         }
1164
1165         if (!strcmp(res->name, "rxq")) {
1166                 if (res->value <= 0) {
1167                         printf("rxq %d invalid - must be > 0\n", res->value);
1168                         return;
1169                 }
1170                 nb_rxq = res->value;
1171         }
1172         else if (!strcmp(res->name, "txq")) {
1173                 if (res->value <= 0) {
1174                         printf("txq %d invalid - must be > 0\n", res->value);
1175                         return;
1176                 }
1177                 nb_txq = res->value;
1178         }
1179         else if (!strcmp(res->name, "rxd")) {
1180                 if (res->value <= 0 || res->value > RTE_TEST_RX_DESC_MAX) {
1181                         printf("rxd %d invalid - must be > 0 && <= %d\n",
1182                                         res->value, RTE_TEST_RX_DESC_MAX);
1183                         return;
1184                 }
1185                 nb_rxd = res->value;
1186         } else if (!strcmp(res->name, "txd")) {
1187                 if (res->value <= 0 || res->value > RTE_TEST_TX_DESC_MAX) {
1188                         printf("txd %d invalid - must be > 0 && <= %d\n",
1189                                         res->value, RTE_TEST_TX_DESC_MAX);
1190                         return;
1191                 }
1192                 nb_txd = res->value;
1193         } else {
1194                 printf("Unknown parameter\n");
1195                 return;
1196         }
1197
1198         init_port_config();
1199
1200         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1201 }
1202
1203 cmdline_parse_token_string_t cmd_config_rx_tx_port =
1204         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, port, "port");
1205 cmdline_parse_token_string_t cmd_config_rx_tx_keyword =
1206         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, keyword, "config");
1207 cmdline_parse_token_string_t cmd_config_rx_tx_all =
1208         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, all, "all");
1209 cmdline_parse_token_string_t cmd_config_rx_tx_name =
1210         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, name,
1211                                                 "rxq#txq#rxd#txd");
1212 cmdline_parse_token_num_t cmd_config_rx_tx_value =
1213         TOKEN_NUM_INITIALIZER(struct cmd_config_rx_tx, value, UINT16);
1214
1215 cmdline_parse_inst_t cmd_config_rx_tx = {
1216         .f = cmd_config_rx_tx_parsed,
1217         .data = NULL,
1218         .help_str = "port config all rxq|txq|rxd|txd value",
1219         .tokens = {
1220                 (void *)&cmd_config_rx_tx_port,
1221                 (void *)&cmd_config_rx_tx_keyword,
1222                 (void *)&cmd_config_rx_tx_all,
1223                 (void *)&cmd_config_rx_tx_name,
1224                 (void *)&cmd_config_rx_tx_value,
1225                 NULL,
1226         },
1227 };
1228
1229 /* *** config max packet length *** */
1230 struct cmd_config_max_pkt_len_result {
1231         cmdline_fixed_string_t port;
1232         cmdline_fixed_string_t keyword;
1233         cmdline_fixed_string_t all;
1234         cmdline_fixed_string_t name;
1235         uint32_t value;
1236 };
1237
1238 static void
1239 cmd_config_max_pkt_len_parsed(void *parsed_result,
1240                                 __attribute__((unused)) struct cmdline *cl,
1241                                 __attribute__((unused)) void *data)
1242 {
1243         struct cmd_config_max_pkt_len_result *res = parsed_result;
1244
1245         if (!all_ports_stopped()) {
1246                 printf("Please stop all ports first\n");
1247                 return;
1248         }
1249
1250         if (!strcmp(res->name, "max-pkt-len")) {
1251                 if (res->value < ETHER_MIN_LEN) {
1252                         printf("max-pkt-len can not be less than %d\n",
1253                                                         ETHER_MIN_LEN);
1254                         return;
1255                 }
1256                 if (res->value == rx_mode.max_rx_pkt_len)
1257                         return;
1258
1259                 rx_mode.max_rx_pkt_len = res->value;
1260                 if (res->value > ETHER_MAX_LEN)
1261                         rx_mode.jumbo_frame = 1;
1262                 else
1263                         rx_mode.jumbo_frame = 0;
1264         } else {
1265                 printf("Unknown parameter\n");
1266                 return;
1267         }
1268
1269         init_port_config();
1270
1271         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1272 }
1273
1274 cmdline_parse_token_string_t cmd_config_max_pkt_len_port =
1275         TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, port,
1276                                                                 "port");
1277 cmdline_parse_token_string_t cmd_config_max_pkt_len_keyword =
1278         TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, keyword,
1279                                                                 "config");
1280 cmdline_parse_token_string_t cmd_config_max_pkt_len_all =
1281         TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, all,
1282                                                                 "all");
1283 cmdline_parse_token_string_t cmd_config_max_pkt_len_name =
1284         TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, name,
1285                                                                 "max-pkt-len");
1286 cmdline_parse_token_num_t cmd_config_max_pkt_len_value =
1287         TOKEN_NUM_INITIALIZER(struct cmd_config_max_pkt_len_result, value,
1288                                                                 UINT32);
1289
1290 cmdline_parse_inst_t cmd_config_max_pkt_len = {
1291         .f = cmd_config_max_pkt_len_parsed,
1292         .data = NULL,
1293         .help_str = "port config all max-pkt-len value",
1294         .tokens = {
1295                 (void *)&cmd_config_max_pkt_len_port,
1296                 (void *)&cmd_config_max_pkt_len_keyword,
1297                 (void *)&cmd_config_max_pkt_len_all,
1298                 (void *)&cmd_config_max_pkt_len_name,
1299                 (void *)&cmd_config_max_pkt_len_value,
1300                 NULL,
1301         },
1302 };
1303
1304 /* *** configure port MTU *** */
1305 struct cmd_config_mtu_result {
1306         cmdline_fixed_string_t port;
1307         cmdline_fixed_string_t keyword;
1308         cmdline_fixed_string_t mtu;
1309         uint8_t port_id;
1310         uint16_t value;
1311 };
1312
1313 static void
1314 cmd_config_mtu_parsed(void *parsed_result,
1315                       __attribute__((unused)) struct cmdline *cl,
1316                       __attribute__((unused)) void *data)
1317 {
1318         struct cmd_config_mtu_result *res = parsed_result;
1319
1320         if (res->value < ETHER_MIN_LEN) {
1321                 printf("mtu cannot be less than %d\n", ETHER_MIN_LEN);
1322                 return;
1323         }
1324         port_mtu_set(res->port_id, res->value);
1325 }
1326
1327 cmdline_parse_token_string_t cmd_config_mtu_port =
1328         TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, port,
1329                                  "port");
1330 cmdline_parse_token_string_t cmd_config_mtu_keyword =
1331         TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
1332                                  "config");
1333 cmdline_parse_token_string_t cmd_config_mtu_mtu =
1334         TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
1335                                  "mtu");
1336 cmdline_parse_token_num_t cmd_config_mtu_port_id =
1337         TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, port_id, UINT8);
1338 cmdline_parse_token_num_t cmd_config_mtu_value =
1339         TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, value, UINT16);
1340
1341 cmdline_parse_inst_t cmd_config_mtu = {
1342         .f = cmd_config_mtu_parsed,
1343         .data = NULL,
1344         .help_str = "port config mtu value",
1345         .tokens = {
1346                 (void *)&cmd_config_mtu_port,
1347                 (void *)&cmd_config_mtu_keyword,
1348                 (void *)&cmd_config_mtu_mtu,
1349                 (void *)&cmd_config_mtu_port_id,
1350                 (void *)&cmd_config_mtu_value,
1351                 NULL,
1352         },
1353 };
1354
1355 /* *** configure rx mode *** */
1356 struct cmd_config_rx_mode_flag {
1357         cmdline_fixed_string_t port;
1358         cmdline_fixed_string_t keyword;
1359         cmdline_fixed_string_t all;
1360         cmdline_fixed_string_t name;
1361         cmdline_fixed_string_t value;
1362 };
1363
1364 static void
1365 cmd_config_rx_mode_flag_parsed(void *parsed_result,
1366                                 __attribute__((unused)) struct cmdline *cl,
1367                                 __attribute__((unused)) void *data)
1368 {
1369         struct cmd_config_rx_mode_flag *res = parsed_result;
1370
1371         if (!all_ports_stopped()) {
1372                 printf("Please stop all ports first\n");
1373                 return;
1374         }
1375
1376         if (!strcmp(res->name, "crc-strip")) {
1377                 if (!strcmp(res->value, "on"))
1378                         rx_mode.hw_strip_crc = 1;
1379                 else if (!strcmp(res->value, "off"))
1380                         rx_mode.hw_strip_crc = 0;
1381                 else {
1382                         printf("Unknown parameter\n");
1383                         return;
1384                 }
1385         } else if (!strcmp(res->name, "rx-cksum")) {
1386                 if (!strcmp(res->value, "on"))
1387                         rx_mode.hw_ip_checksum = 1;
1388                 else if (!strcmp(res->value, "off"))
1389                         rx_mode.hw_ip_checksum = 0;
1390                 else {
1391                         printf("Unknown parameter\n");
1392                         return;
1393                 }
1394         } else if (!strcmp(res->name, "hw-vlan")) {
1395                 if (!strcmp(res->value, "on")) {
1396                         rx_mode.hw_vlan_filter = 1;
1397                         rx_mode.hw_vlan_strip  = 1;
1398                 }
1399                 else if (!strcmp(res->value, "off")) {
1400                         rx_mode.hw_vlan_filter = 0;
1401                         rx_mode.hw_vlan_strip  = 0;
1402                 }
1403                 else {
1404                         printf("Unknown parameter\n");
1405                         return;
1406                 }
1407         } else if (!strcmp(res->name, "hw-vlan-filter")) {
1408                 if (!strcmp(res->value, "on"))
1409                         rx_mode.hw_vlan_filter = 1;
1410                 else if (!strcmp(res->value, "off"))
1411                         rx_mode.hw_vlan_filter = 0;
1412                 else {
1413                         printf("Unknown parameter\n");
1414                         return;
1415                 }
1416         } else if (!strcmp(res->name, "hw-vlan-strip")) {
1417                 if (!strcmp(res->value, "on"))
1418                         rx_mode.hw_vlan_strip  = 1;
1419                 else if (!strcmp(res->value, "off"))
1420                         rx_mode.hw_vlan_strip  = 0;
1421                 else {
1422                         printf("Unknown parameter\n");
1423                         return;
1424                 }
1425         } else if (!strcmp(res->name, "hw-vlan-extend")) {
1426                 if (!strcmp(res->value, "on"))
1427                         rx_mode.hw_vlan_extend = 1;
1428                 else if (!strcmp(res->value, "off"))
1429                         rx_mode.hw_vlan_extend = 0;
1430                 else {
1431                         printf("Unknown parameter\n");
1432                         return;
1433                 }
1434         } else if (!strcmp(res->name, "drop-en")) {
1435                 if (!strcmp(res->value, "on"))
1436                         rx_drop_en = 1;
1437                 else if (!strcmp(res->value, "off"))
1438                         rx_drop_en = 0;
1439                 else {
1440                         printf("Unknown parameter\n");
1441                         return;
1442                 }
1443         } else {
1444                 printf("Unknown parameter\n");
1445                 return;
1446         }
1447
1448         init_port_config();
1449
1450         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1451 }
1452
1453 cmdline_parse_token_string_t cmd_config_rx_mode_flag_port =
1454         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, port, "port");
1455 cmdline_parse_token_string_t cmd_config_rx_mode_flag_keyword =
1456         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, keyword,
1457                                                                 "config");
1458 cmdline_parse_token_string_t cmd_config_rx_mode_flag_all =
1459         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all");
1460 cmdline_parse_token_string_t cmd_config_rx_mode_flag_name =
1461         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name,
1462                                         "crc-strip#rx-cksum#hw-vlan#"
1463                                         "hw-vlan-filter#hw-vlan-strip#hw-vlan-extend");
1464 cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
1465         TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value,
1466                                                         "on#off");
1467
1468 cmdline_parse_inst_t cmd_config_rx_mode_flag = {
1469         .f = cmd_config_rx_mode_flag_parsed,
1470         .data = NULL,
1471         .help_str = "port config all crc-strip|rx-cksum|hw-vlan|"
1472                 "hw-vlan-filter|hw-vlan-strip|hw-vlan-extend on|off",
1473         .tokens = {
1474                 (void *)&cmd_config_rx_mode_flag_port,
1475                 (void *)&cmd_config_rx_mode_flag_keyword,
1476                 (void *)&cmd_config_rx_mode_flag_all,
1477                 (void *)&cmd_config_rx_mode_flag_name,
1478                 (void *)&cmd_config_rx_mode_flag_value,
1479                 NULL,
1480         },
1481 };
1482
1483 /* *** configure rss *** */
1484 struct cmd_config_rss {
1485         cmdline_fixed_string_t port;
1486         cmdline_fixed_string_t keyword;
1487         cmdline_fixed_string_t all;
1488         cmdline_fixed_string_t name;
1489         cmdline_fixed_string_t value;
1490 };
1491
1492 static void
1493 cmd_config_rss_parsed(void *parsed_result,
1494                         __attribute__((unused)) struct cmdline *cl,
1495                         __attribute__((unused)) void *data)
1496 {
1497         struct cmd_config_rss *res = parsed_result;
1498         struct rte_eth_rss_conf rss_conf;
1499         uint8_t i;
1500
1501         if (!strcmp(res->value, "all"))
1502                 rss_conf.rss_hf = ETH_RSS_IP | ETH_RSS_TCP |
1503                                 ETH_RSS_UDP | ETH_RSS_SCTP |
1504                                         ETH_RSS_L2_PAYLOAD;
1505         else if (!strcmp(res->value, "ip"))
1506                 rss_conf.rss_hf = ETH_RSS_IP;
1507         else if (!strcmp(res->value, "udp"))
1508                 rss_conf.rss_hf = ETH_RSS_UDP;
1509         else if (!strcmp(res->value, "tcp"))
1510                 rss_conf.rss_hf = ETH_RSS_TCP;
1511         else if (!strcmp(res->value, "sctp"))
1512                 rss_conf.rss_hf = ETH_RSS_SCTP;
1513         else if (!strcmp(res->value, "ether"))
1514                 rss_conf.rss_hf = ETH_RSS_L2_PAYLOAD;
1515         else if (!strcmp(res->value, "none"))
1516                 rss_conf.rss_hf = 0;
1517         else {
1518                 printf("Unknown parameter\n");
1519                 return;
1520         }
1521         rss_conf.rss_key = NULL;
1522         for (i = 0; i < rte_eth_dev_count(); i++)
1523                 rte_eth_dev_rss_hash_update(i, &rss_conf);
1524 }
1525
1526 cmdline_parse_token_string_t cmd_config_rss_port =
1527         TOKEN_STRING_INITIALIZER(struct cmd_config_rss, port, "port");
1528 cmdline_parse_token_string_t cmd_config_rss_keyword =
1529         TOKEN_STRING_INITIALIZER(struct cmd_config_rss, keyword, "config");
1530 cmdline_parse_token_string_t cmd_config_rss_all =
1531         TOKEN_STRING_INITIALIZER(struct cmd_config_rss, all, "all");
1532 cmdline_parse_token_string_t cmd_config_rss_name =
1533         TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
1534 cmdline_parse_token_string_t cmd_config_rss_value =
1535         TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
1536                 "all#ip#tcp#udp#sctp#ether#none");
1537
1538 cmdline_parse_inst_t cmd_config_rss = {
1539         .f = cmd_config_rss_parsed,
1540         .data = NULL,
1541         .help_str = "port config all rss all|ip|tcp|udp|sctp|ether|none",
1542         .tokens = {
1543                 (void *)&cmd_config_rss_port,
1544                 (void *)&cmd_config_rss_keyword,
1545                 (void *)&cmd_config_rss_all,
1546                 (void *)&cmd_config_rss_name,
1547                 (void *)&cmd_config_rss_value,
1548                 NULL,
1549         },
1550 };
1551
1552 /* *** configure rss hash key *** */
1553 struct cmd_config_rss_hash_key {
1554         cmdline_fixed_string_t port;
1555         cmdline_fixed_string_t config;
1556         uint8_t port_id;
1557         cmdline_fixed_string_t rss_hash_key;
1558         cmdline_fixed_string_t rss_type;
1559         cmdline_fixed_string_t key;
1560 };
1561
1562 #define RSS_HASH_KEY_LENGTH 40
1563 static uint8_t
1564 hexa_digit_to_value(char hexa_digit)
1565 {
1566         if ((hexa_digit >= '0') && (hexa_digit <= '9'))
1567                 return (uint8_t) (hexa_digit - '0');
1568         if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
1569                 return (uint8_t) ((hexa_digit - 'a') + 10);
1570         if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
1571                 return (uint8_t) ((hexa_digit - 'A') + 10);
1572         /* Invalid hexa digit */
1573         return 0xFF;
1574 }
1575
1576 static uint8_t
1577 parse_and_check_key_hexa_digit(char *key, int idx)
1578 {
1579         uint8_t hexa_v;
1580
1581         hexa_v = hexa_digit_to_value(key[idx]);
1582         if (hexa_v == 0xFF)
1583                 printf("invalid key: character %c at position %d is not a "
1584                        "valid hexa digit\n", key[idx], idx);
1585         return hexa_v;
1586 }
1587
1588 static void
1589 cmd_config_rss_hash_key_parsed(void *parsed_result,
1590                                __attribute__((unused)) struct cmdline *cl,
1591                                __attribute__((unused)) void *data)
1592 {
1593         struct cmd_config_rss_hash_key *res = parsed_result;
1594         uint8_t hash_key[RSS_HASH_KEY_LENGTH];
1595         uint8_t xdgt0;
1596         uint8_t xdgt1;
1597         int i;
1598
1599         /* Check the length of the RSS hash key */
1600         if (strlen(res->key) != (RSS_HASH_KEY_LENGTH * 2)) {
1601                 printf("key length: %d invalid - key must be a string of %d"
1602                        "hexa-decimal numbers\n", (int) strlen(res->key),
1603                        RSS_HASH_KEY_LENGTH * 2);
1604                 return;
1605         }
1606         /* Translate RSS hash key into binary representation */
1607         for (i = 0; i < RSS_HASH_KEY_LENGTH; i++) {
1608                 xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
1609                 if (xdgt0 == 0xFF)
1610                         return;
1611                 xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
1612                 if (xdgt1 == 0xFF)
1613                         return;
1614                 hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
1615         }
1616         port_rss_hash_key_update(res->port_id, res->rss_type, hash_key,
1617                                  RSS_HASH_KEY_LENGTH);
1618 }
1619
1620 cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
1621         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
1622 cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
1623         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
1624                                  "config");
1625 cmdline_parse_token_num_t cmd_config_rss_hash_key_port_id =
1626         TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id, UINT8);
1627 cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
1628         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
1629                                  rss_hash_key, "rss-hash-key");
1630 cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_type =
1631         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_type,
1632                                  "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
1633                                  "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
1634                                  "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
1635                                  "ipv6-tcp-ex#ipv6-udp-ex");
1636 cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
1637         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
1638
1639 cmdline_parse_inst_t cmd_config_rss_hash_key = {
1640         .f = cmd_config_rss_hash_key_parsed,
1641         .data = NULL,
1642         .help_str =
1643                 "port config X rss-hash-key ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
1644                 "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
1645                 "ipv6-sctp|ipv6-other|l2-payload|"
1646                 "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex 80 hexa digits\n",
1647         .tokens = {
1648                 (void *)&cmd_config_rss_hash_key_port,
1649                 (void *)&cmd_config_rss_hash_key_config,
1650                 (void *)&cmd_config_rss_hash_key_port_id,
1651                 (void *)&cmd_config_rss_hash_key_rss_hash_key,
1652                 (void *)&cmd_config_rss_hash_key_rss_type,
1653                 (void *)&cmd_config_rss_hash_key_value,
1654                 NULL,
1655         },
1656 };
1657
1658 /* *** configure port rxq/txq start/stop *** */
1659 struct cmd_config_rxtx_queue {
1660         cmdline_fixed_string_t port;
1661         uint8_t portid;
1662         cmdline_fixed_string_t rxtxq;
1663         uint16_t qid;
1664         cmdline_fixed_string_t opname;
1665 };
1666
1667 static void
1668 cmd_config_rxtx_queue_parsed(void *parsed_result,
1669                         __attribute__((unused)) struct cmdline *cl,
1670                         __attribute__((unused)) void *data)
1671 {
1672         struct cmd_config_rxtx_queue *res = parsed_result;
1673         uint8_t isrx;
1674         uint8_t isstart;
1675         int ret = 0;
1676
1677         if (test_done == 0) {
1678                 printf("Please stop forwarding first\n");
1679                 return;
1680         }
1681
1682         if (port_id_is_invalid(res->portid, ENABLED_WARN))
1683                 return;
1684
1685         if (port_is_started(res->portid) != 1) {
1686                 printf("Please start port %u first\n", res->portid);
1687                 return;
1688         }
1689
1690         if (!strcmp(res->rxtxq, "rxq"))
1691                 isrx = 1;
1692         else if (!strcmp(res->rxtxq, "txq"))
1693                 isrx = 0;
1694         else {
1695                 printf("Unknown parameter\n");
1696                 return;
1697         }
1698
1699         if (isrx && rx_queue_id_is_invalid(res->qid))
1700                 return;
1701         else if (!isrx && tx_queue_id_is_invalid(res->qid))
1702                 return;
1703
1704         if (!strcmp(res->opname, "start"))
1705                 isstart = 1;
1706         else if (!strcmp(res->opname, "stop"))
1707                 isstart = 0;
1708         else {
1709                 printf("Unknown parameter\n");
1710                 return;
1711         }
1712
1713         if (isstart && isrx)
1714                 ret = rte_eth_dev_rx_queue_start(res->portid, res->qid);
1715         else if (!isstart && isrx)
1716                 ret = rte_eth_dev_rx_queue_stop(res->portid, res->qid);
1717         else if (isstart && !isrx)
1718                 ret = rte_eth_dev_tx_queue_start(res->portid, res->qid);
1719         else
1720                 ret = rte_eth_dev_tx_queue_stop(res->portid, res->qid);
1721
1722         if (ret == -ENOTSUP)
1723                 printf("Function not supported in PMD driver\n");
1724 }
1725
1726 cmdline_parse_token_string_t cmd_config_rxtx_queue_port =
1727         TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, port, "port");
1728 cmdline_parse_token_num_t cmd_config_rxtx_queue_portid =
1729         TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, portid, UINT8);
1730 cmdline_parse_token_string_t cmd_config_rxtx_queue_rxtxq =
1731         TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, rxtxq, "rxq#txq");
1732 cmdline_parse_token_num_t cmd_config_rxtx_queue_qid =
1733         TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, qid, UINT16);
1734 cmdline_parse_token_string_t cmd_config_rxtx_queue_opname =
1735         TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, opname,
1736                                                 "start#stop");
1737
1738 cmdline_parse_inst_t cmd_config_rxtx_queue = {
1739         .f = cmd_config_rxtx_queue_parsed,
1740         .data = NULL,
1741         .help_str = "port X rxq|txq ID start|stop",
1742         .tokens = {
1743                 (void *)&cmd_config_speed_all_port,
1744                 (void *)&cmd_config_rxtx_queue_portid,
1745                 (void *)&cmd_config_rxtx_queue_rxtxq,
1746                 (void *)&cmd_config_rxtx_queue_qid,
1747                 (void *)&cmd_config_rxtx_queue_opname,
1748                 NULL,
1749         },
1750 };
1751
1752 /* *** Configure RSS RETA *** */
1753 struct cmd_config_rss_reta {
1754         cmdline_fixed_string_t port;
1755         cmdline_fixed_string_t keyword;
1756         uint8_t port_id;
1757         cmdline_fixed_string_t name;
1758         cmdline_fixed_string_t list_name;
1759         cmdline_fixed_string_t list_of_items;
1760 };
1761
1762 static int
1763 parse_reta_config(const char *str,
1764                   struct rte_eth_rss_reta_entry64 *reta_conf,
1765                   uint16_t nb_entries)
1766 {
1767         int i;
1768         unsigned size;
1769         uint16_t hash_index, idx, shift;
1770         uint8_t nb_queue;
1771         char s[256];
1772         const char *p, *p0 = str;
1773         char *end;
1774         enum fieldnames {
1775                 FLD_HASH_INDEX = 0,
1776                 FLD_QUEUE,
1777                 _NUM_FLD
1778         };
1779         unsigned long int_fld[_NUM_FLD];
1780         char *str_fld[_NUM_FLD];
1781
1782         while ((p = strchr(p0,'(')) != NULL) {
1783                 ++p;
1784                 if((p0 = strchr(p,')')) == NULL)
1785                         return -1;
1786
1787                 size = p0 - p;
1788                 if(size >= sizeof(s))
1789                         return -1;
1790
1791                 snprintf(s, sizeof(s), "%.*s", size, p);
1792                 if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
1793                         return -1;
1794                 for (i = 0; i < _NUM_FLD; i++) {
1795                         errno = 0;
1796                         int_fld[i] = strtoul(str_fld[i], &end, 0);
1797                         if (errno != 0 || end == str_fld[i] ||
1798                                         int_fld[i] > 65535)
1799                                 return -1;
1800                 }
1801
1802                 hash_index = (uint16_t)int_fld[FLD_HASH_INDEX];
1803                 nb_queue = (uint8_t)int_fld[FLD_QUEUE];
1804
1805                 if (hash_index >= nb_entries) {
1806                         printf("Invalid RETA hash index=%d\n", hash_index);
1807                         return -1;
1808                 }
1809
1810                 idx = hash_index / RTE_RETA_GROUP_SIZE;
1811                 shift = hash_index % RTE_RETA_GROUP_SIZE;
1812                 reta_conf[idx].mask |= (1ULL << shift);
1813                 reta_conf[idx].reta[shift] = nb_queue;
1814         }
1815
1816         return 0;
1817 }
1818
1819 static void
1820 cmd_set_rss_reta_parsed(void *parsed_result,
1821                         __attribute__((unused)) struct cmdline *cl,
1822                         __attribute__((unused)) void *data)
1823 {
1824         int ret;
1825         struct rte_eth_dev_info dev_info;
1826         struct rte_eth_rss_reta_entry64 reta_conf[8];
1827         struct cmd_config_rss_reta *res = parsed_result;
1828
1829         memset(&dev_info, 0, sizeof(dev_info));
1830         rte_eth_dev_info_get(res->port_id, &dev_info);
1831         if (dev_info.reta_size == 0) {
1832                 printf("Redirection table size is 0 which is "
1833                                         "invalid for RSS\n");
1834                 return;
1835         } else
1836                 printf("The reta size of port %d is %u\n",
1837                         res->port_id, dev_info.reta_size);
1838         if (dev_info.reta_size > ETH_RSS_RETA_SIZE_512) {
1839                 printf("Currently do not support more than %u entries of "
1840                         "redirection table\n", ETH_RSS_RETA_SIZE_512);
1841                 return;
1842         }
1843
1844         memset(reta_conf, 0, sizeof(reta_conf));
1845         if (!strcmp(res->list_name, "reta")) {
1846                 if (parse_reta_config(res->list_of_items, reta_conf,
1847                                                 dev_info.reta_size)) {
1848                         printf("Invalid RSS Redirection Table "
1849                                         "config entered\n");
1850                         return;
1851                 }
1852                 ret = rte_eth_dev_rss_reta_update(res->port_id,
1853                                 reta_conf, dev_info.reta_size);
1854                 if (ret != 0)
1855                         printf("Bad redirection table parameter, "
1856                                         "return code = %d \n", ret);
1857         }
1858 }
1859
1860 cmdline_parse_token_string_t cmd_config_rss_reta_port =
1861         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, port, "port");
1862 cmdline_parse_token_string_t cmd_config_rss_reta_keyword =
1863         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, keyword, "config");
1864 cmdline_parse_token_num_t cmd_config_rss_reta_port_id =
1865         TOKEN_NUM_INITIALIZER(struct cmd_config_rss_reta, port_id, UINT8);
1866 cmdline_parse_token_string_t cmd_config_rss_reta_name =
1867         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, name, "rss");
1868 cmdline_parse_token_string_t cmd_config_rss_reta_list_name =
1869         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_name, "reta");
1870 cmdline_parse_token_string_t cmd_config_rss_reta_list_of_items =
1871         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_of_items,
1872                                  NULL);
1873 cmdline_parse_inst_t cmd_config_rss_reta = {
1874         .f = cmd_set_rss_reta_parsed,
1875         .data = NULL,
1876         .help_str = "port config X rss reta (hash,queue)[,(hash,queue)]",
1877         .tokens = {
1878                 (void *)&cmd_config_rss_reta_port,
1879                 (void *)&cmd_config_rss_reta_keyword,
1880                 (void *)&cmd_config_rss_reta_port_id,
1881                 (void *)&cmd_config_rss_reta_name,
1882                 (void *)&cmd_config_rss_reta_list_name,
1883                 (void *)&cmd_config_rss_reta_list_of_items,
1884                 NULL,
1885         },
1886 };
1887
1888 /* *** SHOW PORT RETA INFO *** */
1889 struct cmd_showport_reta {
1890         cmdline_fixed_string_t show;
1891         cmdline_fixed_string_t port;
1892         uint8_t port_id;
1893         cmdline_fixed_string_t rss;
1894         cmdline_fixed_string_t reta;
1895         uint16_t size;
1896         cmdline_fixed_string_t list_of_items;
1897 };
1898
1899 static int
1900 showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,
1901                            uint16_t nb_entries,
1902                            char *str)
1903 {
1904         uint32_t size;
1905         const char *p, *p0 = str;
1906         char s[256];
1907         char *end;
1908         char *str_fld[8];
1909         uint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE;
1910         int ret;
1911
1912         p = strchr(p0, '(');
1913         if (p == NULL)
1914                 return -1;
1915         p++;
1916         p0 = strchr(p, ')');
1917         if (p0 == NULL)
1918                 return -1;
1919         size = p0 - p;
1920         if (size >= sizeof(s)) {
1921                 printf("The string size exceeds the internal buffer size\n");
1922                 return -1;
1923         }
1924         snprintf(s, sizeof(s), "%.*s", size, p);
1925         ret = rte_strsplit(s, sizeof(s), str_fld, num, ',');
1926         if (ret <= 0 || ret != num) {
1927                 printf("The bits of masks do not match the number of "
1928                                         "reta entries: %u\n", num);
1929                 return -1;
1930         }
1931         for (i = 0; i < ret; i++)
1932                 conf[i].mask = (uint64_t)strtoul(str_fld[i], &end, 0);
1933
1934         return 0;
1935 }
1936
1937 static void
1938 cmd_showport_reta_parsed(void *parsed_result,
1939                          __attribute__((unused)) struct cmdline *cl,
1940                          __attribute__((unused)) void *data)
1941 {
1942         struct cmd_showport_reta *res = parsed_result;
1943         struct rte_eth_rss_reta_entry64 reta_conf[8];
1944         struct rte_eth_dev_info dev_info;
1945
1946         memset(&dev_info, 0, sizeof(dev_info));
1947         rte_eth_dev_info_get(res->port_id, &dev_info);
1948         if (dev_info.reta_size == 0 || res->size != dev_info.reta_size ||
1949                                 res->size > ETH_RSS_RETA_SIZE_512) {
1950                 printf("Invalid redirection table size: %u\n", res->size);
1951                 return;
1952         }
1953
1954         memset(reta_conf, 0, sizeof(reta_conf));
1955         if (showport_parse_reta_config(reta_conf, res->size,
1956                                 res->list_of_items) < 0) {
1957                 printf("Invalid string: %s for reta masks\n",
1958                                         res->list_of_items);
1959                 return;
1960         }
1961         port_rss_reta_info(res->port_id, reta_conf, res->size);
1962 }
1963
1964 cmdline_parse_token_string_t cmd_showport_reta_show =
1965         TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, show, "show");
1966 cmdline_parse_token_string_t cmd_showport_reta_port =
1967         TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, port, "port");
1968 cmdline_parse_token_num_t cmd_showport_reta_port_id =
1969         TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, port_id, UINT8);
1970 cmdline_parse_token_string_t cmd_showport_reta_rss =
1971         TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
1972 cmdline_parse_token_string_t cmd_showport_reta_reta =
1973         TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
1974 cmdline_parse_token_num_t cmd_showport_reta_size =
1975         TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, size, UINT16);
1976 cmdline_parse_token_string_t cmd_showport_reta_list_of_items =
1977         TOKEN_STRING_INITIALIZER(struct cmd_showport_reta,
1978                                         list_of_items, NULL);
1979
1980 cmdline_parse_inst_t cmd_showport_reta = {
1981         .f = cmd_showport_reta_parsed,
1982         .data = NULL,
1983         .help_str = "show port X rss reta (size) (mask0,mask1,...)",
1984         .tokens = {
1985                 (void *)&cmd_showport_reta_show,
1986                 (void *)&cmd_showport_reta_port,
1987                 (void *)&cmd_showport_reta_port_id,
1988                 (void *)&cmd_showport_reta_rss,
1989                 (void *)&cmd_showport_reta_reta,
1990                 (void *)&cmd_showport_reta_size,
1991                 (void *)&cmd_showport_reta_list_of_items,
1992                 NULL,
1993         },
1994 };
1995
1996 /* *** Show RSS hash configuration *** */
1997 struct cmd_showport_rss_hash {
1998         cmdline_fixed_string_t show;
1999         cmdline_fixed_string_t port;
2000         uint8_t port_id;
2001         cmdline_fixed_string_t rss_hash;
2002         cmdline_fixed_string_t rss_type;
2003         cmdline_fixed_string_t key; /* optional argument */
2004 };
2005
2006 static void cmd_showport_rss_hash_parsed(void *parsed_result,
2007                                 __attribute__((unused)) struct cmdline *cl,
2008                                 void *show_rss_key)
2009 {
2010         struct cmd_showport_rss_hash *res = parsed_result;
2011
2012         port_rss_hash_conf_show(res->port_id, res->rss_type,
2013                                 show_rss_key != NULL);
2014 }
2015
2016 cmdline_parse_token_string_t cmd_showport_rss_hash_show =
2017         TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, show, "show");
2018 cmdline_parse_token_string_t cmd_showport_rss_hash_port =
2019         TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, port, "port");
2020 cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
2021         TOKEN_NUM_INITIALIZER(struct cmd_showport_rss_hash, port_id, UINT8);
2022 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
2023         TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
2024                                  "rss-hash");
2025 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash_info =
2026         TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_type,
2027                                  "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
2028                                  "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
2029                                  "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
2030                                  "ipv6-tcp-ex#ipv6-udp-ex");
2031 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
2032         TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
2033
2034 cmdline_parse_inst_t cmd_showport_rss_hash = {
2035         .f = cmd_showport_rss_hash_parsed,
2036         .data = NULL,
2037         .help_str =
2038                 "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
2039                 "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
2040                 "ipv6-sctp|ipv6-other|l2-payload|"
2041                 "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex (X = port number)\n",
2042         .tokens = {
2043                 (void *)&cmd_showport_rss_hash_show,
2044                 (void *)&cmd_showport_rss_hash_port,
2045                 (void *)&cmd_showport_rss_hash_port_id,
2046                 (void *)&cmd_showport_rss_hash_rss_hash,
2047                 (void *)&cmd_showport_rss_hash_rss_hash_info,
2048                 NULL,
2049         },
2050 };
2051
2052 cmdline_parse_inst_t cmd_showport_rss_hash_key = {
2053         .f = cmd_showport_rss_hash_parsed,
2054         .data = (void *)1,
2055         .help_str =
2056                 "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
2057                 "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
2058                 "ipv6-sctp|ipv6-other|l2-payload|"
2059                 "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex key (X = port number)\n",
2060         .tokens = {
2061                 (void *)&cmd_showport_rss_hash_show,
2062                 (void *)&cmd_showport_rss_hash_port,
2063                 (void *)&cmd_showport_rss_hash_port_id,
2064                 (void *)&cmd_showport_rss_hash_rss_hash,
2065                 (void *)&cmd_showport_rss_hash_rss_hash_info,
2066                 (void *)&cmd_showport_rss_hash_rss_key,
2067                 NULL,
2068         },
2069 };
2070
2071 /* *** Configure DCB *** */
2072 struct cmd_config_dcb {
2073         cmdline_fixed_string_t port;
2074         cmdline_fixed_string_t config;
2075         uint8_t port_id;
2076         cmdline_fixed_string_t dcb;
2077         cmdline_fixed_string_t vt;
2078         cmdline_fixed_string_t vt_en;
2079         uint8_t num_tcs;
2080         cmdline_fixed_string_t pfc;
2081         cmdline_fixed_string_t pfc_en;
2082 };
2083
2084 static void
2085 cmd_config_dcb_parsed(void *parsed_result,
2086                         __attribute__((unused)) struct cmdline *cl,
2087                         __attribute__((unused)) void *data)
2088 {
2089         struct cmd_config_dcb *res = parsed_result;
2090         portid_t port_id = res->port_id;
2091         struct rte_port *port;
2092         uint8_t pfc_en;
2093         int ret;
2094
2095         port = &ports[port_id];
2096         /** Check if the port is not started **/
2097         if (port->port_status != RTE_PORT_STOPPED) {
2098                 printf("Please stop port %d first\n", port_id);
2099                 return;
2100         }
2101
2102         if ((res->num_tcs != ETH_4_TCS) && (res->num_tcs != ETH_8_TCS)) {
2103                 printf("The invalid number of traffic class,"
2104                         " only 4 or 8 allowed.\n");
2105                 return;
2106         }
2107
2108         if (nb_fwd_lcores < res->num_tcs) {
2109                 printf("nb_cores shouldn't be less than number of TCs.\n");
2110                 return;
2111         }
2112         if (!strncmp(res->pfc_en, "on", 2))
2113                 pfc_en = 1;
2114         else
2115                 pfc_en = 0;
2116
2117         /* DCB in VT mode */
2118         if (!strncmp(res->vt_en, "on", 2))
2119                 ret = init_port_dcb_config(port_id, DCB_VT_ENABLED,
2120                                 (enum rte_eth_nb_tcs)res->num_tcs,
2121                                 pfc_en);
2122         else
2123                 ret = init_port_dcb_config(port_id, DCB_ENABLED,
2124                                 (enum rte_eth_nb_tcs)res->num_tcs,
2125                                 pfc_en);
2126
2127
2128         if (ret != 0) {
2129                 printf("Cannot initialize network ports.\n");
2130                 return;
2131         }
2132
2133         cmd_reconfig_device_queue(port_id, 1, 1);
2134 }
2135
2136 cmdline_parse_token_string_t cmd_config_dcb_port =
2137         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, port, "port");
2138 cmdline_parse_token_string_t cmd_config_dcb_config =
2139         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, config, "config");
2140 cmdline_parse_token_num_t cmd_config_dcb_port_id =
2141         TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, port_id, UINT8);
2142 cmdline_parse_token_string_t cmd_config_dcb_dcb =
2143         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, dcb, "dcb");
2144 cmdline_parse_token_string_t cmd_config_dcb_vt =
2145         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt, "vt");
2146 cmdline_parse_token_string_t cmd_config_dcb_vt_en =
2147         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt_en, "on#off");
2148 cmdline_parse_token_num_t cmd_config_dcb_num_tcs =
2149         TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, num_tcs, UINT8);
2150 cmdline_parse_token_string_t cmd_config_dcb_pfc=
2151         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc, "pfc");
2152 cmdline_parse_token_string_t cmd_config_dcb_pfc_en =
2153         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc_en, "on#off");
2154
2155 cmdline_parse_inst_t cmd_config_dcb = {
2156         .f = cmd_config_dcb_parsed,
2157         .data = NULL,
2158         .help_str = "port config port-id dcb vt on|off nb-tcs pfc on|off",
2159         .tokens = {
2160                 (void *)&cmd_config_dcb_port,
2161                 (void *)&cmd_config_dcb_config,
2162                 (void *)&cmd_config_dcb_port_id,
2163                 (void *)&cmd_config_dcb_dcb,
2164                 (void *)&cmd_config_dcb_vt,
2165                 (void *)&cmd_config_dcb_vt_en,
2166                 (void *)&cmd_config_dcb_num_tcs,
2167                 (void *)&cmd_config_dcb_pfc,
2168                 (void *)&cmd_config_dcb_pfc_en,
2169                 NULL,
2170         },
2171 };
2172
2173 /* *** configure number of packets per burst *** */
2174 struct cmd_config_burst {
2175         cmdline_fixed_string_t port;
2176         cmdline_fixed_string_t keyword;
2177         cmdline_fixed_string_t all;
2178         cmdline_fixed_string_t name;
2179         uint16_t value;
2180 };
2181
2182 static void
2183 cmd_config_burst_parsed(void *parsed_result,
2184                         __attribute__((unused)) struct cmdline *cl,
2185                         __attribute__((unused)) void *data)
2186 {
2187         struct cmd_config_burst *res = parsed_result;
2188
2189         if (!all_ports_stopped()) {
2190                 printf("Please stop all ports first\n");
2191                 return;
2192         }
2193
2194         if (!strcmp(res->name, "burst")) {
2195                 if (res->value < 1 || res->value > MAX_PKT_BURST) {
2196                         printf("burst must be >= 1 && <= %d\n", MAX_PKT_BURST);
2197                         return;
2198                 }
2199                 nb_pkt_per_burst = res->value;
2200         } else {
2201                 printf("Unknown parameter\n");
2202                 return;
2203         }
2204
2205         init_port_config();
2206
2207         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2208 }
2209
2210 cmdline_parse_token_string_t cmd_config_burst_port =
2211         TOKEN_STRING_INITIALIZER(struct cmd_config_burst, port, "port");
2212 cmdline_parse_token_string_t cmd_config_burst_keyword =
2213         TOKEN_STRING_INITIALIZER(struct cmd_config_burst, keyword, "config");
2214 cmdline_parse_token_string_t cmd_config_burst_all =
2215         TOKEN_STRING_INITIALIZER(struct cmd_config_burst, all, "all");
2216 cmdline_parse_token_string_t cmd_config_burst_name =
2217         TOKEN_STRING_INITIALIZER(struct cmd_config_burst, name, "burst");
2218 cmdline_parse_token_num_t cmd_config_burst_value =
2219         TOKEN_NUM_INITIALIZER(struct cmd_config_burst, value, UINT16);
2220
2221 cmdline_parse_inst_t cmd_config_burst = {
2222         .f = cmd_config_burst_parsed,
2223         .data = NULL,
2224         .help_str = "port config all burst value",
2225         .tokens = {
2226                 (void *)&cmd_config_burst_port,
2227                 (void *)&cmd_config_burst_keyword,
2228                 (void *)&cmd_config_burst_all,
2229                 (void *)&cmd_config_burst_name,
2230                 (void *)&cmd_config_burst_value,
2231                 NULL,
2232         },
2233 };
2234
2235 /* *** configure rx/tx queues *** */
2236 struct cmd_config_thresh {
2237         cmdline_fixed_string_t port;
2238         cmdline_fixed_string_t keyword;
2239         cmdline_fixed_string_t all;
2240         cmdline_fixed_string_t name;
2241         uint8_t value;
2242 };
2243
2244 static void
2245 cmd_config_thresh_parsed(void *parsed_result,
2246                         __attribute__((unused)) struct cmdline *cl,
2247                         __attribute__((unused)) void *data)
2248 {
2249         struct cmd_config_thresh *res = parsed_result;
2250
2251         if (!all_ports_stopped()) {
2252                 printf("Please stop all ports first\n");
2253                 return;
2254         }
2255
2256         if (!strcmp(res->name, "txpt"))
2257                 tx_pthresh = res->value;
2258         else if(!strcmp(res->name, "txht"))
2259                 tx_hthresh = res->value;
2260         else if(!strcmp(res->name, "txwt"))
2261                 tx_wthresh = res->value;
2262         else if(!strcmp(res->name, "rxpt"))
2263                 rx_pthresh = res->value;
2264         else if(!strcmp(res->name, "rxht"))
2265                 rx_hthresh = res->value;
2266         else if(!strcmp(res->name, "rxwt"))
2267                 rx_wthresh = res->value;
2268         else {
2269                 printf("Unknown parameter\n");
2270                 return;
2271         }
2272
2273         init_port_config();
2274
2275         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2276 }
2277
2278 cmdline_parse_token_string_t cmd_config_thresh_port =
2279         TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, port, "port");
2280 cmdline_parse_token_string_t cmd_config_thresh_keyword =
2281         TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, keyword, "config");
2282 cmdline_parse_token_string_t cmd_config_thresh_all =
2283         TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, all, "all");
2284 cmdline_parse_token_string_t cmd_config_thresh_name =
2285         TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, name,
2286                                 "txpt#txht#txwt#rxpt#rxht#rxwt");
2287 cmdline_parse_token_num_t cmd_config_thresh_value =
2288         TOKEN_NUM_INITIALIZER(struct cmd_config_thresh, value, UINT8);
2289
2290 cmdline_parse_inst_t cmd_config_thresh = {
2291         .f = cmd_config_thresh_parsed,
2292         .data = NULL,
2293         .help_str = "port config all txpt|txht|txwt|rxpt|rxht|rxwt value",
2294         .tokens = {
2295                 (void *)&cmd_config_thresh_port,
2296                 (void *)&cmd_config_thresh_keyword,
2297                 (void *)&cmd_config_thresh_all,
2298                 (void *)&cmd_config_thresh_name,
2299                 (void *)&cmd_config_thresh_value,
2300                 NULL,
2301         },
2302 };
2303
2304 /* *** configure free/rs threshold *** */
2305 struct cmd_config_threshold {
2306         cmdline_fixed_string_t port;
2307         cmdline_fixed_string_t keyword;
2308         cmdline_fixed_string_t all;
2309         cmdline_fixed_string_t name;
2310         uint16_t value;
2311 };
2312
2313 static void
2314 cmd_config_threshold_parsed(void *parsed_result,
2315                         __attribute__((unused)) struct cmdline *cl,
2316                         __attribute__((unused)) void *data)
2317 {
2318         struct cmd_config_threshold *res = parsed_result;
2319
2320         if (!all_ports_stopped()) {
2321                 printf("Please stop all ports first\n");
2322                 return;
2323         }
2324
2325         if (!strcmp(res->name, "txfreet"))
2326                 tx_free_thresh = res->value;
2327         else if (!strcmp(res->name, "txrst"))
2328                 tx_rs_thresh = res->value;
2329         else if (!strcmp(res->name, "rxfreet"))
2330                 rx_free_thresh = res->value;
2331         else {
2332                 printf("Unknown parameter\n");
2333                 return;
2334         }
2335
2336         init_port_config();
2337
2338         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2339 }
2340
2341 cmdline_parse_token_string_t cmd_config_threshold_port =
2342         TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, port, "port");
2343 cmdline_parse_token_string_t cmd_config_threshold_keyword =
2344         TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, keyword,
2345                                                                 "config");
2346 cmdline_parse_token_string_t cmd_config_threshold_all =
2347         TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, all, "all");
2348 cmdline_parse_token_string_t cmd_config_threshold_name =
2349         TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, name,
2350                                                 "txfreet#txrst#rxfreet");
2351 cmdline_parse_token_num_t cmd_config_threshold_value =
2352         TOKEN_NUM_INITIALIZER(struct cmd_config_threshold, value, UINT16);
2353
2354 cmdline_parse_inst_t cmd_config_threshold = {
2355         .f = cmd_config_threshold_parsed,
2356         .data = NULL,
2357         .help_str = "port config all txfreet|txrst|rxfreet value",
2358         .tokens = {
2359                 (void *)&cmd_config_threshold_port,
2360                 (void *)&cmd_config_threshold_keyword,
2361                 (void *)&cmd_config_threshold_all,
2362                 (void *)&cmd_config_threshold_name,
2363                 (void *)&cmd_config_threshold_value,
2364                 NULL,
2365         },
2366 };
2367
2368 /* *** stop *** */
2369 struct cmd_stop_result {
2370         cmdline_fixed_string_t stop;
2371 };
2372
2373 static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result,
2374                             __attribute__((unused)) struct cmdline *cl,
2375                             __attribute__((unused)) void *data)
2376 {
2377         stop_packet_forwarding();
2378 }
2379
2380 cmdline_parse_token_string_t cmd_stop_stop =
2381         TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
2382
2383 cmdline_parse_inst_t cmd_stop = {
2384         .f = cmd_stop_parsed,
2385         .data = NULL,
2386         .help_str = "stop - stop packet forwarding",
2387         .tokens = {
2388                 (void *)&cmd_stop_stop,
2389                 NULL,
2390         },
2391 };
2392
2393 /* *** SET CORELIST and PORTLIST CONFIGURATION *** */
2394
2395 unsigned int
2396 parse_item_list(char* str, const char* item_name, unsigned int max_items,
2397                 unsigned int *parsed_items, int check_unique_values)
2398 {
2399         unsigned int nb_item;
2400         unsigned int value;
2401         unsigned int i;
2402         unsigned int j;
2403         int value_ok;
2404         char c;
2405
2406         /*
2407          * First parse all items in the list and store their value.
2408          */
2409         value = 0;
2410         nb_item = 0;
2411         value_ok = 0;
2412         for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
2413                 c = str[i];
2414                 if ((c >= '0') && (c <= '9')) {
2415                         value = (unsigned int) (value * 10 + (c - '0'));
2416                         value_ok = 1;
2417                         continue;
2418                 }
2419                 if (c != ',') {
2420                         printf("character %c is not a decimal digit\n", c);
2421                         return (0);
2422                 }
2423                 if (! value_ok) {
2424                         printf("No valid value before comma\n");
2425                         return (0);
2426                 }
2427                 if (nb_item < max_items) {
2428                         parsed_items[nb_item] = value;
2429                         value_ok = 0;
2430                         value = 0;
2431                 }
2432                 nb_item++;
2433         }
2434         if (nb_item >= max_items) {
2435                 printf("Number of %s = %u > %u (maximum items)\n",
2436                        item_name, nb_item + 1, max_items);
2437                 return (0);
2438         }
2439         parsed_items[nb_item++] = value;
2440         if (! check_unique_values)
2441                 return (nb_item);
2442
2443         /*
2444          * Then, check that all values in the list are differents.
2445          * No optimization here...
2446          */
2447         for (i = 0; i < nb_item; i++) {
2448                 for (j = i + 1; j < nb_item; j++) {
2449                         if (parsed_items[j] == parsed_items[i]) {
2450                                 printf("duplicated %s %u at index %u and %u\n",
2451                                        item_name, parsed_items[i], i, j);
2452                                 return (0);
2453                         }
2454                 }
2455         }
2456         return (nb_item);
2457 }
2458
2459 struct cmd_set_list_result {
2460         cmdline_fixed_string_t cmd_keyword;
2461         cmdline_fixed_string_t list_name;
2462         cmdline_fixed_string_t list_of_items;
2463 };
2464
2465 static void cmd_set_list_parsed(void *parsed_result,
2466                                 __attribute__((unused)) struct cmdline *cl,
2467                                 __attribute__((unused)) void *data)
2468 {
2469         struct cmd_set_list_result *res;
2470         union {
2471                 unsigned int lcorelist[RTE_MAX_LCORE];
2472                 unsigned int portlist[RTE_MAX_ETHPORTS];
2473         } parsed_items;
2474         unsigned int nb_item;
2475
2476         if (test_done == 0) {
2477                 printf("Please stop forwarding first\n");
2478                 return;
2479         }
2480
2481         res = parsed_result;
2482         if (!strcmp(res->list_name, "corelist")) {
2483                 nb_item = parse_item_list(res->list_of_items, "core",
2484                                           RTE_MAX_LCORE,
2485                                           parsed_items.lcorelist, 1);
2486                 if (nb_item > 0)
2487                         set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
2488                 return;
2489         }
2490         if (!strcmp(res->list_name, "portlist")) {
2491                 nb_item = parse_item_list(res->list_of_items, "port",
2492                                           RTE_MAX_ETHPORTS,
2493                                           parsed_items.portlist, 1);
2494                 if (nb_item > 0)
2495                         set_fwd_ports_list(parsed_items.portlist, nb_item);
2496         }
2497 }
2498
2499 cmdline_parse_token_string_t cmd_set_list_keyword =
2500         TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
2501                                  "set");
2502 cmdline_parse_token_string_t cmd_set_list_name =
2503         TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
2504                                  "corelist#portlist");
2505 cmdline_parse_token_string_t cmd_set_list_of_items =
2506         TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
2507                                  NULL);
2508
2509 cmdline_parse_inst_t cmd_set_fwd_list = {
2510         .f = cmd_set_list_parsed,
2511         .data = NULL,
2512         .help_str = "set corelist|portlist x[,y]*",
2513         .tokens = {
2514                 (void *)&cmd_set_list_keyword,
2515                 (void *)&cmd_set_list_name,
2516                 (void *)&cmd_set_list_of_items,
2517                 NULL,
2518         },
2519 };
2520
2521 /* *** SET COREMASK and PORTMASK CONFIGURATION *** */
2522
2523 struct cmd_setmask_result {
2524         cmdline_fixed_string_t set;
2525         cmdline_fixed_string_t mask;
2526         uint64_t hexavalue;
2527 };
2528
2529 static void cmd_set_mask_parsed(void *parsed_result,
2530                                 __attribute__((unused)) struct cmdline *cl,
2531                                 __attribute__((unused)) void *data)
2532 {
2533         struct cmd_setmask_result *res = parsed_result;
2534
2535         if (test_done == 0) {
2536                 printf("Please stop forwarding first\n");
2537                 return;
2538         }
2539         if (!strcmp(res->mask, "coremask"))
2540                 set_fwd_lcores_mask(res->hexavalue);
2541         else if (!strcmp(res->mask, "portmask"))
2542                 set_fwd_ports_mask(res->hexavalue);
2543 }
2544
2545 cmdline_parse_token_string_t cmd_setmask_set =
2546         TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
2547 cmdline_parse_token_string_t cmd_setmask_mask =
2548         TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
2549                                  "coremask#portmask");
2550 cmdline_parse_token_num_t cmd_setmask_value =
2551         TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, UINT64);
2552
2553 cmdline_parse_inst_t cmd_set_fwd_mask = {
2554         .f = cmd_set_mask_parsed,
2555         .data = NULL,
2556         .help_str = "set coremask|portmask hexadecimal value",
2557         .tokens = {
2558                 (void *)&cmd_setmask_set,
2559                 (void *)&cmd_setmask_mask,
2560                 (void *)&cmd_setmask_value,
2561                 NULL,
2562         },
2563 };
2564
2565 /*
2566  * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
2567  */
2568 struct cmd_set_result {
2569         cmdline_fixed_string_t set;
2570         cmdline_fixed_string_t what;
2571         uint16_t value;
2572 };
2573
2574 static void cmd_set_parsed(void *parsed_result,
2575                            __attribute__((unused)) struct cmdline *cl,
2576                            __attribute__((unused)) void *data)
2577 {
2578         struct cmd_set_result *res = parsed_result;
2579         if (!strcmp(res->what, "nbport"))
2580                 set_fwd_ports_number(res->value);
2581         else if (!strcmp(res->what, "nbcore"))
2582                 set_fwd_lcores_number(res->value);
2583         else if (!strcmp(res->what, "burst"))
2584                 set_nb_pkt_per_burst(res->value);
2585         else if (!strcmp(res->what, "verbose"))
2586                 set_verbose_level(res->value);
2587 }
2588
2589 cmdline_parse_token_string_t cmd_set_set =
2590         TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
2591 cmdline_parse_token_string_t cmd_set_what =
2592         TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
2593                                  "nbport#nbcore#burst#verbose");
2594 cmdline_parse_token_num_t cmd_set_value =
2595         TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
2596
2597 cmdline_parse_inst_t cmd_set_numbers = {
2598         .f = cmd_set_parsed,
2599         .data = NULL,
2600         .help_str = "set nbport|nbcore|burst|verbose value",
2601         .tokens = {
2602                 (void *)&cmd_set_set,
2603                 (void *)&cmd_set_what,
2604                 (void *)&cmd_set_value,
2605                 NULL,
2606         },
2607 };
2608
2609 /* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
2610
2611 struct cmd_set_txpkts_result {
2612         cmdline_fixed_string_t cmd_keyword;
2613         cmdline_fixed_string_t txpkts;
2614         cmdline_fixed_string_t seg_lengths;
2615 };
2616
2617 static void
2618 cmd_set_txpkts_parsed(void *parsed_result,
2619                       __attribute__((unused)) struct cmdline *cl,
2620                       __attribute__((unused)) void *data)
2621 {
2622         struct cmd_set_txpkts_result *res;
2623         unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
2624         unsigned int nb_segs;
2625
2626         res = parsed_result;
2627         nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
2628                                   RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
2629         if (nb_segs > 0)
2630                 set_tx_pkt_segments(seg_lengths, nb_segs);
2631 }
2632
2633 cmdline_parse_token_string_t cmd_set_txpkts_keyword =
2634         TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2635                                  cmd_keyword, "set");
2636 cmdline_parse_token_string_t cmd_set_txpkts_name =
2637         TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2638                                  txpkts, "txpkts");
2639 cmdline_parse_token_string_t cmd_set_txpkts_lengths =
2640         TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2641                                  seg_lengths, NULL);
2642
2643 cmdline_parse_inst_t cmd_set_txpkts = {
2644         .f = cmd_set_txpkts_parsed,
2645         .data = NULL,
2646         .help_str = "set txpkts x[,y]*",
2647         .tokens = {
2648                 (void *)&cmd_set_txpkts_keyword,
2649                 (void *)&cmd_set_txpkts_name,
2650                 (void *)&cmd_set_txpkts_lengths,
2651                 NULL,
2652         },
2653 };
2654
2655 /* *** SET COPY AND SPLIT POLICY ON TX PACKETS *** */
2656
2657 struct cmd_set_txsplit_result {
2658         cmdline_fixed_string_t cmd_keyword;
2659         cmdline_fixed_string_t txsplit;
2660         cmdline_fixed_string_t mode;
2661 };
2662
2663 static void
2664 cmd_set_txsplit_parsed(void *parsed_result,
2665                       __attribute__((unused)) struct cmdline *cl,
2666                       __attribute__((unused)) void *data)
2667 {
2668         struct cmd_set_txsplit_result *res;
2669
2670         res = parsed_result;
2671         set_tx_pkt_split(res->mode);
2672 }
2673
2674 cmdline_parse_token_string_t cmd_set_txsplit_keyword =
2675         TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2676                                  cmd_keyword, "set");
2677 cmdline_parse_token_string_t cmd_set_txsplit_name =
2678         TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2679                                  txsplit, "txsplit");
2680 cmdline_parse_token_string_t cmd_set_txsplit_mode =
2681         TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2682                                  mode, NULL);
2683
2684 cmdline_parse_inst_t cmd_set_txsplit = {
2685         .f = cmd_set_txsplit_parsed,
2686         .data = NULL,
2687         .help_str = "set txsplit on|off|rand",
2688         .tokens = {
2689                 (void *)&cmd_set_txsplit_keyword,
2690                 (void *)&cmd_set_txsplit_name,
2691                 (void *)&cmd_set_txsplit_mode,
2692                 NULL,
2693         },
2694 };
2695
2696 /* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
2697 struct cmd_rx_vlan_filter_all_result {
2698         cmdline_fixed_string_t rx_vlan;
2699         cmdline_fixed_string_t what;
2700         cmdline_fixed_string_t all;
2701         uint8_t port_id;
2702 };
2703
2704 static void
2705 cmd_rx_vlan_filter_all_parsed(void *parsed_result,
2706                               __attribute__((unused)) struct cmdline *cl,
2707                               __attribute__((unused)) void *data)
2708 {
2709         struct cmd_rx_vlan_filter_all_result *res = parsed_result;
2710
2711         if (!strcmp(res->what, "add"))
2712                 rx_vlan_all_filter_set(res->port_id, 1);
2713         else
2714                 rx_vlan_all_filter_set(res->port_id, 0);
2715 }
2716
2717 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_rx_vlan =
2718         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2719                                  rx_vlan, "rx_vlan");
2720 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_what =
2721         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2722                                  what, "add#rm");
2723 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_all =
2724         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2725                                  all, "all");
2726 cmdline_parse_token_num_t cmd_rx_vlan_filter_all_portid =
2727         TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2728                               port_id, UINT8);
2729
2730 cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
2731         .f = cmd_rx_vlan_filter_all_parsed,
2732         .data = NULL,
2733         .help_str = "add/remove all identifiers to/from the set of VLAN "
2734         "Identifiers filtered by a port",
2735         .tokens = {
2736                 (void *)&cmd_rx_vlan_filter_all_rx_vlan,
2737                 (void *)&cmd_rx_vlan_filter_all_what,
2738                 (void *)&cmd_rx_vlan_filter_all_all,
2739                 (void *)&cmd_rx_vlan_filter_all_portid,
2740                 NULL,
2741         },
2742 };
2743
2744 /* *** VLAN OFFLOAD SET ON A PORT *** */
2745 struct cmd_vlan_offload_result {
2746         cmdline_fixed_string_t vlan;
2747         cmdline_fixed_string_t set;
2748         cmdline_fixed_string_t what;
2749         cmdline_fixed_string_t on;
2750         cmdline_fixed_string_t port_id;
2751 };
2752
2753 static void
2754 cmd_vlan_offload_parsed(void *parsed_result,
2755                           __attribute__((unused)) struct cmdline *cl,
2756                           __attribute__((unused)) void *data)
2757 {
2758         int on;
2759         struct cmd_vlan_offload_result *res = parsed_result;
2760         char *str;
2761         int i, len = 0;
2762         portid_t port_id = 0;
2763         unsigned int tmp;
2764
2765         str = res->port_id;
2766         len = strnlen(str, STR_TOKEN_SIZE);
2767         i = 0;
2768         /* Get port_id first */
2769         while(i < len){
2770                 if(str[i] == ',')
2771                         break;
2772
2773                 i++;
2774         }
2775         str[i]='\0';
2776         tmp = strtoul(str, NULL, 0);
2777         /* If port_id greater that what portid_t can represent, return */
2778         if(tmp >= RTE_MAX_ETHPORTS)
2779                 return;
2780         port_id = (portid_t)tmp;
2781
2782         if (!strcmp(res->on, "on"))
2783                 on = 1;
2784         else
2785                 on = 0;
2786
2787         if (!strcmp(res->what, "strip"))
2788                 rx_vlan_strip_set(port_id,  on);
2789         else if(!strcmp(res->what, "stripq")){
2790                 uint16_t queue_id = 0;
2791
2792                 /* No queue_id, return */
2793                 if(i + 1 >= len) {
2794                         printf("must specify (port,queue_id)\n");
2795                         return;
2796                 }
2797                 tmp = strtoul(str + i + 1, NULL, 0);
2798                 /* If queue_id greater that what 16-bits can represent, return */
2799                 if(tmp > 0xffff)
2800                         return;
2801
2802                 queue_id = (uint16_t)tmp;
2803                 rx_vlan_strip_set_on_queue(port_id, queue_id, on);
2804         }
2805         else if (!strcmp(res->what, "filter"))
2806                 rx_vlan_filter_set(port_id, on);
2807         else
2808                 vlan_extend_set(port_id, on);
2809
2810         return;
2811 }
2812
2813 cmdline_parse_token_string_t cmd_vlan_offload_vlan =
2814         TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2815                                  vlan, "vlan");
2816 cmdline_parse_token_string_t cmd_vlan_offload_set =
2817         TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2818                                  set, "set");
2819 cmdline_parse_token_string_t cmd_vlan_offload_what =
2820         TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2821                                  what, "strip#filter#qinq#stripq");
2822 cmdline_parse_token_string_t cmd_vlan_offload_on =
2823         TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2824                               on, "on#off");
2825 cmdline_parse_token_string_t cmd_vlan_offload_portid =
2826         TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2827                               port_id, NULL);
2828
2829 cmdline_parse_inst_t cmd_vlan_offload = {
2830         .f = cmd_vlan_offload_parsed,
2831         .data = NULL,
2832         .help_str = "set strip|filter|qinq|stripq on|off port_id[,queue_id], filter/strip for rx side"
2833         " qinq(extended) for both rx/tx sides ",
2834         .tokens = {
2835                 (void *)&cmd_vlan_offload_vlan,
2836                 (void *)&cmd_vlan_offload_set,
2837                 (void *)&cmd_vlan_offload_what,
2838                 (void *)&cmd_vlan_offload_on,
2839                 (void *)&cmd_vlan_offload_portid,
2840                 NULL,
2841         },
2842 };
2843
2844 /* *** VLAN TPID SET ON A PORT *** */
2845 struct cmd_vlan_tpid_result {
2846         cmdline_fixed_string_t vlan;
2847         cmdline_fixed_string_t set;
2848         cmdline_fixed_string_t what;
2849         uint16_t tp_id;
2850         uint8_t port_id;
2851 };
2852
2853 static void
2854 cmd_vlan_tpid_parsed(void *parsed_result,
2855                           __attribute__((unused)) struct cmdline *cl,
2856                           __attribute__((unused)) void *data)
2857 {
2858         struct cmd_vlan_tpid_result *res = parsed_result;
2859         vlan_tpid_set(res->port_id, res->tp_id);
2860         return;
2861 }
2862
2863 cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
2864         TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
2865                                  vlan, "vlan");
2866 cmdline_parse_token_string_t cmd_vlan_tpid_set =
2867         TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
2868                                  set, "set");
2869 cmdline_parse_token_string_t cmd_vlan_tpid_what =
2870         TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
2871                                  what, "tpid");
2872 cmdline_parse_token_num_t cmd_vlan_tpid_tpid =
2873         TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
2874                               tp_id, UINT16);
2875 cmdline_parse_token_num_t cmd_vlan_tpid_portid =
2876         TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
2877                               port_id, UINT8);
2878
2879 cmdline_parse_inst_t cmd_vlan_tpid = {
2880         .f = cmd_vlan_tpid_parsed,
2881         .data = NULL,
2882         .help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type",
2883         .tokens = {
2884                 (void *)&cmd_vlan_tpid_vlan,
2885                 (void *)&cmd_vlan_tpid_set,
2886                 (void *)&cmd_vlan_tpid_what,
2887                 (void *)&cmd_vlan_tpid_tpid,
2888                 (void *)&cmd_vlan_tpid_portid,
2889                 NULL,
2890         },
2891 };
2892
2893 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
2894 struct cmd_rx_vlan_filter_result {
2895         cmdline_fixed_string_t rx_vlan;
2896         cmdline_fixed_string_t what;
2897         uint16_t vlan_id;
2898         uint8_t port_id;
2899 };
2900
2901 static void
2902 cmd_rx_vlan_filter_parsed(void *parsed_result,
2903                           __attribute__((unused)) struct cmdline *cl,
2904                           __attribute__((unused)) void *data)
2905 {
2906         struct cmd_rx_vlan_filter_result *res = parsed_result;
2907
2908         if (!strcmp(res->what, "add"))
2909                 rx_vft_set(res->port_id, res->vlan_id, 1);
2910         else
2911                 rx_vft_set(res->port_id, res->vlan_id, 0);
2912 }
2913
2914 cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
2915         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
2916                                  rx_vlan, "rx_vlan");
2917 cmdline_parse_token_string_t cmd_rx_vlan_filter_what =
2918         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
2919                                  what, "add#rm");
2920 cmdline_parse_token_num_t cmd_rx_vlan_filter_vlanid =
2921         TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
2922                               vlan_id, UINT16);
2923 cmdline_parse_token_num_t cmd_rx_vlan_filter_portid =
2924         TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
2925                               port_id, UINT8);
2926
2927 cmdline_parse_inst_t cmd_rx_vlan_filter = {
2928         .f = cmd_rx_vlan_filter_parsed,
2929         .data = NULL,
2930         .help_str = "add/remove a VLAN identifier to/from the set of VLAN "
2931         "Identifiers filtered by a port",
2932         .tokens = {
2933                 (void *)&cmd_rx_vlan_filter_rx_vlan,
2934                 (void *)&cmd_rx_vlan_filter_what,
2935                 (void *)&cmd_rx_vlan_filter_vlanid,
2936                 (void *)&cmd_rx_vlan_filter_portid,
2937                 NULL,
2938         },
2939 };
2940
2941 /* *** ENABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
2942 struct cmd_tx_vlan_set_result {
2943         cmdline_fixed_string_t tx_vlan;
2944         cmdline_fixed_string_t set;
2945         uint8_t port_id;
2946         uint16_t vlan_id;
2947 };
2948
2949 static void
2950 cmd_tx_vlan_set_parsed(void *parsed_result,
2951                        __attribute__((unused)) struct cmdline *cl,
2952                        __attribute__((unused)) void *data)
2953 {
2954         struct cmd_tx_vlan_set_result *res = parsed_result;
2955         int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
2956
2957         if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) {
2958                 printf("Error, as QinQ has been enabled.\n");
2959                 return;
2960         }
2961
2962         tx_vlan_set(res->port_id, res->vlan_id);
2963 }
2964
2965 cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan =
2966         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
2967                                  tx_vlan, "tx_vlan");
2968 cmdline_parse_token_string_t cmd_tx_vlan_set_set =
2969         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
2970                                  set, "set");
2971 cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid =
2972         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
2973                               vlan_id, UINT16);
2974 cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
2975         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
2976                               port_id, UINT8);
2977
2978 cmdline_parse_inst_t cmd_tx_vlan_set = {
2979         .f = cmd_tx_vlan_set_parsed,
2980         .data = NULL,
2981         .help_str = "enable hardware insertion of a single VLAN header "
2982                 "with a given TAG Identifier in packets sent on a port",
2983         .tokens = {
2984                 (void *)&cmd_tx_vlan_set_tx_vlan,
2985                 (void *)&cmd_tx_vlan_set_set,
2986                 (void *)&cmd_tx_vlan_set_portid,
2987                 (void *)&cmd_tx_vlan_set_vlanid,
2988                 NULL,
2989         },
2990 };
2991
2992 /* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
2993 struct cmd_tx_vlan_set_qinq_result {
2994         cmdline_fixed_string_t tx_vlan;
2995         cmdline_fixed_string_t set;
2996         uint8_t port_id;
2997         uint16_t vlan_id;
2998         uint16_t vlan_id_outer;
2999 };
3000
3001 static void
3002 cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
3003                             __attribute__((unused)) struct cmdline *cl,
3004                             __attribute__((unused)) void *data)
3005 {
3006         struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
3007         int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
3008
3009         if (!(vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)) {
3010                 printf("Error, as QinQ hasn't been enabled.\n");
3011                 return;
3012         }
3013
3014         tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
3015 }
3016
3017 cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
3018         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3019                 tx_vlan, "tx_vlan");
3020 cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
3021         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3022                 set, "set");
3023 cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
3024         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3025                 port_id, UINT8);
3026 cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
3027         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3028                 vlan_id, UINT16);
3029 cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
3030         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3031                 vlan_id_outer, UINT16);
3032
3033 cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
3034         .f = cmd_tx_vlan_set_qinq_parsed,
3035         .data = NULL,
3036         .help_str = "enable hardware insertion of double VLAN header "
3037                 "with given TAG Identifiers in packets sent on a port",
3038         .tokens = {
3039                 (void *)&cmd_tx_vlan_set_qinq_tx_vlan,
3040                 (void *)&cmd_tx_vlan_set_qinq_set,
3041                 (void *)&cmd_tx_vlan_set_qinq_portid,
3042                 (void *)&cmd_tx_vlan_set_qinq_vlanid,
3043                 (void *)&cmd_tx_vlan_set_qinq_vlanid_outer,
3044                 NULL,
3045         },
3046 };
3047
3048 /* *** ENABLE/DISABLE PORT BASED TX VLAN INSERTION *** */
3049 struct cmd_tx_vlan_set_pvid_result {
3050         cmdline_fixed_string_t tx_vlan;
3051         cmdline_fixed_string_t set;
3052         cmdline_fixed_string_t pvid;
3053         uint8_t port_id;
3054         uint16_t vlan_id;
3055         cmdline_fixed_string_t mode;
3056 };
3057
3058 static void
3059 cmd_tx_vlan_set_pvid_parsed(void *parsed_result,
3060                             __attribute__((unused)) struct cmdline *cl,
3061                             __attribute__((unused)) void *data)
3062 {
3063         struct cmd_tx_vlan_set_pvid_result *res = parsed_result;
3064
3065         if (strcmp(res->mode, "on") == 0)
3066                 tx_vlan_pvid_set(res->port_id, res->vlan_id, 1);
3067         else
3068                 tx_vlan_pvid_set(res->port_id, res->vlan_id, 0);
3069 }
3070
3071 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_tx_vlan =
3072         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3073                                  tx_vlan, "tx_vlan");
3074 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_set =
3075         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3076                                  set, "set");
3077 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_pvid =
3078         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3079                                  pvid, "pvid");
3080 cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_port_id =
3081         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3082                              port_id, UINT8);
3083 cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_vlan_id =
3084         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3085                               vlan_id, UINT16);
3086 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_mode =
3087         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3088                                  mode, "on#off");
3089
3090 cmdline_parse_inst_t cmd_tx_vlan_set_pvid = {
3091         .f = cmd_tx_vlan_set_pvid_parsed,
3092         .data = NULL,
3093         .help_str = "tx_vlan set pvid port_id vlan_id (on|off)",
3094         .tokens = {
3095                 (void *)&cmd_tx_vlan_set_pvid_tx_vlan,
3096                 (void *)&cmd_tx_vlan_set_pvid_set,
3097                 (void *)&cmd_tx_vlan_set_pvid_pvid,
3098                 (void *)&cmd_tx_vlan_set_pvid_port_id,
3099                 (void *)&cmd_tx_vlan_set_pvid_vlan_id,
3100                 (void *)&cmd_tx_vlan_set_pvid_mode,
3101                 NULL,
3102         },
3103 };
3104
3105 /* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
3106 struct cmd_tx_vlan_reset_result {
3107         cmdline_fixed_string_t tx_vlan;
3108         cmdline_fixed_string_t reset;
3109         uint8_t port_id;
3110 };
3111
3112 static void
3113 cmd_tx_vlan_reset_parsed(void *parsed_result,
3114                          __attribute__((unused)) struct cmdline *cl,
3115                          __attribute__((unused)) void *data)
3116 {
3117         struct cmd_tx_vlan_reset_result *res = parsed_result;
3118
3119         tx_vlan_reset(res->port_id);
3120 }
3121
3122 cmdline_parse_token_string_t cmd_tx_vlan_reset_tx_vlan =
3123         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
3124                                  tx_vlan, "tx_vlan");
3125 cmdline_parse_token_string_t cmd_tx_vlan_reset_reset =
3126         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
3127                                  reset, "reset");
3128 cmdline_parse_token_num_t cmd_tx_vlan_reset_portid =
3129         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_reset_result,
3130                               port_id, UINT8);
3131
3132 cmdline_parse_inst_t cmd_tx_vlan_reset = {
3133         .f = cmd_tx_vlan_reset_parsed,
3134         .data = NULL,
3135         .help_str = "disable hardware insertion of a VLAN header in packets "
3136         "sent on a port",
3137         .tokens = {
3138                 (void *)&cmd_tx_vlan_reset_tx_vlan,
3139                 (void *)&cmd_tx_vlan_reset_reset,
3140                 (void *)&cmd_tx_vlan_reset_portid,
3141                 NULL,
3142         },
3143 };
3144
3145
3146 /* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
3147 struct cmd_csum_result {
3148         cmdline_fixed_string_t csum;
3149         cmdline_fixed_string_t mode;
3150         cmdline_fixed_string_t proto;
3151         cmdline_fixed_string_t hwsw;
3152         uint8_t port_id;
3153 };
3154
3155 static void
3156 csum_show(int port_id)
3157 {
3158         struct rte_eth_dev_info dev_info;
3159         uint16_t ol_flags;
3160
3161         ol_flags = ports[port_id].tx_ol_flags;
3162         printf("Parse tunnel is %s\n",
3163                 (ol_flags & TESTPMD_TX_OFFLOAD_PARSE_TUNNEL) ? "on" : "off");
3164         printf("IP checksum offload is %s\n",
3165                 (ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) ? "hw" : "sw");
3166         printf("UDP checksum offload is %s\n",
3167                 (ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) ? "hw" : "sw");
3168         printf("TCP checksum offload is %s\n",
3169                 (ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw");
3170         printf("SCTP checksum offload is %s\n",
3171                 (ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw");
3172         printf("Outer-Ip checksum offload is %s\n",
3173                 (ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) ? "hw" : "sw");
3174
3175         /* display warnings if configuration is not supported by the NIC */
3176         rte_eth_dev_info_get(port_id, &dev_info);
3177         if ((ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) &&
3178                 (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) {
3179                 printf("Warning: hardware IP checksum enabled but not "
3180                         "supported by port %d\n", port_id);
3181         }
3182         if ((ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) &&
3183                 (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) {
3184                 printf("Warning: hardware UDP checksum enabled but not "
3185                         "supported by port %d\n", port_id);
3186         }
3187         if ((ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) &&
3188                 (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) {
3189                 printf("Warning: hardware TCP checksum enabled but not "
3190                         "supported by port %d\n", port_id);
3191         }
3192         if ((ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) &&
3193                 (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) == 0) {
3194                 printf("Warning: hardware SCTP checksum enabled but not "
3195                         "supported by port %d\n", port_id);
3196         }
3197         if ((ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) &&
3198                 (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) == 0) {
3199                 printf("Warning: hardware outer IP checksum enabled but not "
3200                         "supported by port %d\n", port_id);
3201         }
3202 }
3203
3204 static void
3205 cmd_csum_parsed(void *parsed_result,
3206                        __attribute__((unused)) struct cmdline *cl,
3207                        __attribute__((unused)) void *data)
3208 {
3209         struct cmd_csum_result *res = parsed_result;
3210         int hw = 0;
3211         uint16_t mask = 0;
3212
3213         if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
3214                 printf("invalid port %d\n", res->port_id);
3215                 return;
3216         }
3217
3218         if (!strcmp(res->mode, "set")) {
3219
3220                 if (!strcmp(res->hwsw, "hw"))
3221                         hw = 1;
3222
3223                 if (!strcmp(res->proto, "ip")) {
3224                         mask = TESTPMD_TX_OFFLOAD_IP_CKSUM;
3225                 } else if (!strcmp(res->proto, "udp")) {
3226                         mask = TESTPMD_TX_OFFLOAD_UDP_CKSUM;
3227                 } else if (!strcmp(res->proto, "tcp")) {
3228                         mask = TESTPMD_TX_OFFLOAD_TCP_CKSUM;
3229                 } else if (!strcmp(res->proto, "sctp")) {
3230                         mask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM;
3231                 } else if (!strcmp(res->proto, "outer-ip")) {
3232                         mask = TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM;
3233                 }
3234
3235                 if (hw)
3236                         ports[res->port_id].tx_ol_flags |= mask;
3237                 else
3238                         ports[res->port_id].tx_ol_flags &= (~mask);
3239         }
3240         csum_show(res->port_id);
3241 }
3242
3243 cmdline_parse_token_string_t cmd_csum_csum =
3244         TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3245                                 csum, "csum");
3246 cmdline_parse_token_string_t cmd_csum_mode =
3247         TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3248                                 mode, "set");
3249 cmdline_parse_token_string_t cmd_csum_proto =
3250         TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3251                                 proto, "ip#tcp#udp#sctp#outer-ip");
3252 cmdline_parse_token_string_t cmd_csum_hwsw =
3253         TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3254                                 hwsw, "hw#sw");
3255 cmdline_parse_token_num_t cmd_csum_portid =
3256         TOKEN_NUM_INITIALIZER(struct cmd_csum_result,
3257                                 port_id, UINT8);
3258
3259 cmdline_parse_inst_t cmd_csum_set = {
3260         .f = cmd_csum_parsed,
3261         .data = NULL,
3262         .help_str = "enable/disable hardware calculation of L3/L4 checksum when "
3263                 "using csum forward engine: csum set ip|tcp|udp|sctp|outer-ip hw|sw <port>",
3264         .tokens = {
3265                 (void *)&cmd_csum_csum,
3266                 (void *)&cmd_csum_mode,
3267                 (void *)&cmd_csum_proto,
3268                 (void *)&cmd_csum_hwsw,
3269                 (void *)&cmd_csum_portid,
3270                 NULL,
3271         },
3272 };
3273
3274 cmdline_parse_token_string_t cmd_csum_mode_show =
3275         TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3276                                 mode, "show");
3277
3278 cmdline_parse_inst_t cmd_csum_show = {
3279         .f = cmd_csum_parsed,
3280         .data = NULL,
3281         .help_str = "show checksum offload configuration: csum show <port>",
3282         .tokens = {
3283                 (void *)&cmd_csum_csum,
3284                 (void *)&cmd_csum_mode_show,
3285                 (void *)&cmd_csum_portid,
3286                 NULL,
3287         },
3288 };
3289
3290 /* Enable/disable tunnel parsing */
3291 struct cmd_csum_tunnel_result {
3292         cmdline_fixed_string_t csum;
3293         cmdline_fixed_string_t parse;
3294         cmdline_fixed_string_t onoff;
3295         uint8_t port_id;
3296 };
3297
3298 static void
3299 cmd_csum_tunnel_parsed(void *parsed_result,
3300                        __attribute__((unused)) struct cmdline *cl,
3301                        __attribute__((unused)) void *data)
3302 {
3303         struct cmd_csum_tunnel_result *res = parsed_result;
3304
3305         if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3306                 return;
3307
3308         if (!strcmp(res->onoff, "on"))
3309                 ports[res->port_id].tx_ol_flags |=
3310                         TESTPMD_TX_OFFLOAD_PARSE_TUNNEL;
3311         else
3312                 ports[res->port_id].tx_ol_flags &=
3313                         (~TESTPMD_TX_OFFLOAD_PARSE_TUNNEL);
3314
3315         csum_show(res->port_id);
3316 }
3317
3318 cmdline_parse_token_string_t cmd_csum_tunnel_csum =
3319         TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3320                                 csum, "csum");
3321 cmdline_parse_token_string_t cmd_csum_tunnel_parse =
3322         TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3323                                 parse, "parse_tunnel");
3324 cmdline_parse_token_string_t cmd_csum_tunnel_onoff =
3325         TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3326                                 onoff, "on#off");
3327 cmdline_parse_token_num_t cmd_csum_tunnel_portid =
3328         TOKEN_NUM_INITIALIZER(struct cmd_csum_tunnel_result,
3329                                 port_id, UINT8);
3330
3331 cmdline_parse_inst_t cmd_csum_tunnel = {
3332         .f = cmd_csum_tunnel_parsed,
3333         .data = NULL,
3334         .help_str = "enable/disable parsing of tunnels for csum engine: "
3335         "csum parse_tunnel on|off <tx-port>",
3336         .tokens = {
3337                 (void *)&cmd_csum_tunnel_csum,
3338                 (void *)&cmd_csum_tunnel_parse,
3339                 (void *)&cmd_csum_tunnel_onoff,
3340                 (void *)&cmd_csum_tunnel_portid,
3341                 NULL,
3342         },
3343 };
3344
3345 /* *** ENABLE HARDWARE SEGMENTATION IN TX PACKETS *** */
3346 struct cmd_tso_set_result {
3347         cmdline_fixed_string_t tso;
3348         cmdline_fixed_string_t mode;
3349         uint16_t tso_segsz;
3350         uint8_t port_id;
3351 };
3352
3353 static void
3354 cmd_tso_set_parsed(void *parsed_result,
3355                        __attribute__((unused)) struct cmdline *cl,
3356                        __attribute__((unused)) void *data)
3357 {
3358         struct cmd_tso_set_result *res = parsed_result;
3359         struct rte_eth_dev_info dev_info;
3360
3361         if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3362                 return;
3363
3364         if (!strcmp(res->mode, "set"))
3365                 ports[res->port_id].tso_segsz = res->tso_segsz;
3366
3367         if (ports[res->port_id].tso_segsz == 0)
3368                 printf("TSO is disabled\n");
3369         else
3370                 printf("TSO segment size is %d\n",
3371                         ports[res->port_id].tso_segsz);
3372
3373         /* display warnings if configuration is not supported by the NIC */
3374         rte_eth_dev_info_get(res->port_id, &dev_info);
3375         if ((ports[res->port_id].tso_segsz != 0) &&
3376                 (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) {
3377                 printf("Warning: TSO enabled but not "
3378                         "supported by port %d\n", res->port_id);
3379         }
3380 }
3381
3382 cmdline_parse_token_string_t cmd_tso_set_tso =
3383         TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3384                                 tso, "tso");
3385 cmdline_parse_token_string_t cmd_tso_set_mode =
3386         TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3387                                 mode, "set");
3388 cmdline_parse_token_num_t cmd_tso_set_tso_segsz =
3389         TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
3390                                 tso_segsz, UINT16);
3391 cmdline_parse_token_num_t cmd_tso_set_portid =
3392         TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
3393                                 port_id, UINT8);
3394
3395 cmdline_parse_inst_t cmd_tso_set = {
3396         .f = cmd_tso_set_parsed,
3397         .data = NULL,
3398         .help_str = "Set TSO segment size for csum engine (0 to disable): "
3399         "tso set <tso_segsz> <port>",
3400         .tokens = {
3401                 (void *)&cmd_tso_set_tso,
3402                 (void *)&cmd_tso_set_mode,
3403                 (void *)&cmd_tso_set_tso_segsz,
3404                 (void *)&cmd_tso_set_portid,
3405                 NULL,
3406         },
3407 };
3408
3409 cmdline_parse_token_string_t cmd_tso_show_mode =
3410         TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3411                                 mode, "show");
3412
3413
3414 cmdline_parse_inst_t cmd_tso_show = {
3415         .f = cmd_tso_set_parsed,
3416         .data = NULL,
3417         .help_str = "Show TSO segment size for csum engine: "
3418         "tso show <port>",
3419         .tokens = {
3420                 (void *)&cmd_tso_set_tso,
3421                 (void *)&cmd_tso_show_mode,
3422                 (void *)&cmd_tso_set_portid,
3423                 NULL,
3424         },
3425 };
3426
3427 /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
3428 struct cmd_set_flush_rx {
3429         cmdline_fixed_string_t set;
3430         cmdline_fixed_string_t flush_rx;
3431         cmdline_fixed_string_t mode;
3432 };
3433
3434 static void
3435 cmd_set_flush_rx_parsed(void *parsed_result,
3436                 __attribute__((unused)) struct cmdline *cl,
3437                 __attribute__((unused)) void *data)
3438 {
3439         struct cmd_set_flush_rx *res = parsed_result;
3440         no_flush_rx = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
3441 }
3442
3443 cmdline_parse_token_string_t cmd_setflushrx_set =
3444         TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3445                         set, "set");
3446 cmdline_parse_token_string_t cmd_setflushrx_flush_rx =
3447         TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3448                         flush_rx, "flush_rx");
3449 cmdline_parse_token_string_t cmd_setflushrx_mode =
3450         TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3451                         mode, "on#off");
3452
3453
3454 cmdline_parse_inst_t cmd_set_flush_rx = {
3455         .f = cmd_set_flush_rx_parsed,
3456         .help_str = "set flush_rx on|off: enable/disable flush on rx streams",
3457         .data = NULL,
3458         .tokens = {
3459                 (void *)&cmd_setflushrx_set,
3460                 (void *)&cmd_setflushrx_flush_rx,
3461                 (void *)&cmd_setflushrx_mode,
3462                 NULL,
3463         },
3464 };
3465
3466 /* *** ENABLE/DISABLE LINK STATUS CHECK *** */
3467 struct cmd_set_link_check {
3468         cmdline_fixed_string_t set;
3469         cmdline_fixed_string_t link_check;
3470         cmdline_fixed_string_t mode;
3471 };
3472
3473 static void
3474 cmd_set_link_check_parsed(void *parsed_result,
3475                 __attribute__((unused)) struct cmdline *cl,
3476                 __attribute__((unused)) void *data)
3477 {
3478         struct cmd_set_link_check *res = parsed_result;
3479         no_link_check = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
3480 }
3481
3482 cmdline_parse_token_string_t cmd_setlinkcheck_set =
3483         TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3484                         set, "set");
3485 cmdline_parse_token_string_t cmd_setlinkcheck_link_check =
3486         TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3487                         link_check, "link_check");
3488 cmdline_parse_token_string_t cmd_setlinkcheck_mode =
3489         TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3490                         mode, "on#off");
3491
3492
3493 cmdline_parse_inst_t cmd_set_link_check = {
3494         .f = cmd_set_link_check_parsed,
3495         .help_str = "set link_check on|off: enable/disable link status check "
3496                     "when starting/stopping a port",
3497         .data = NULL,
3498         .tokens = {
3499                 (void *)&cmd_setlinkcheck_set,
3500                 (void *)&cmd_setlinkcheck_link_check,
3501                 (void *)&cmd_setlinkcheck_mode,
3502                 NULL,
3503         },
3504 };
3505
3506 #ifdef RTE_NIC_BYPASS
3507 /* *** SET NIC BYPASS MODE *** */
3508 struct cmd_set_bypass_mode_result {
3509         cmdline_fixed_string_t set;
3510         cmdline_fixed_string_t bypass;
3511         cmdline_fixed_string_t mode;
3512         cmdline_fixed_string_t value;
3513         uint8_t port_id;
3514 };
3515
3516 static void
3517 cmd_set_bypass_mode_parsed(void *parsed_result,
3518                 __attribute__((unused)) struct cmdline *cl,
3519                 __attribute__((unused)) void *data)
3520 {
3521         struct cmd_set_bypass_mode_result *res = parsed_result;
3522         portid_t port_id = res->port_id;
3523         uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
3524
3525         if (!bypass_is_supported(port_id))
3526                 return;
3527
3528         if (!strcmp(res->value, "bypass"))
3529                 bypass_mode = RTE_BYPASS_MODE_BYPASS;
3530         else if (!strcmp(res->value, "isolate"))
3531                 bypass_mode = RTE_BYPASS_MODE_ISOLATE;
3532         else
3533                 bypass_mode = RTE_BYPASS_MODE_NORMAL;
3534
3535         /* Set the bypass mode for the relevant port. */
3536         if (0 != rte_eth_dev_bypass_state_set(port_id, &bypass_mode)) {
3537                 printf("\t Failed to set bypass mode for port = %d.\n", port_id);
3538         }
3539 }
3540
3541 cmdline_parse_token_string_t cmd_setbypass_mode_set =
3542         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3543                         set, "set");
3544 cmdline_parse_token_string_t cmd_setbypass_mode_bypass =
3545         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3546                         bypass, "bypass");
3547 cmdline_parse_token_string_t cmd_setbypass_mode_mode =
3548         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3549                         mode, "mode");
3550 cmdline_parse_token_string_t cmd_setbypass_mode_value =
3551         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3552                         value, "normal#bypass#isolate");
3553 cmdline_parse_token_num_t cmd_setbypass_mode_port =
3554         TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_mode_result,
3555                                 port_id, UINT8);
3556
3557 cmdline_parse_inst_t cmd_set_bypass_mode = {
3558         .f = cmd_set_bypass_mode_parsed,
3559         .help_str = "set bypass mode (normal|bypass|isolate) (port_id): "
3560                     "Set the NIC bypass mode for port_id",
3561         .data = NULL,
3562         .tokens = {
3563                 (void *)&cmd_setbypass_mode_set,
3564                 (void *)&cmd_setbypass_mode_bypass,
3565                 (void *)&cmd_setbypass_mode_mode,
3566                 (void *)&cmd_setbypass_mode_value,
3567                 (void *)&cmd_setbypass_mode_port,
3568                 NULL,
3569         },
3570 };
3571
3572 /* *** SET NIC BYPASS EVENT *** */
3573 struct cmd_set_bypass_event_result {
3574         cmdline_fixed_string_t set;
3575         cmdline_fixed_string_t bypass;
3576         cmdline_fixed_string_t event;
3577         cmdline_fixed_string_t event_value;
3578         cmdline_fixed_string_t mode;
3579         cmdline_fixed_string_t mode_value;
3580         uint8_t port_id;
3581 };
3582
3583 static void
3584 cmd_set_bypass_event_parsed(void *parsed_result,
3585                 __attribute__((unused)) struct cmdline *cl,
3586                 __attribute__((unused)) void *data)
3587 {
3588         int32_t rc;
3589         struct cmd_set_bypass_event_result *res = parsed_result;
3590         portid_t port_id = res->port_id;
3591         uint32_t bypass_event = RTE_BYPASS_EVENT_NONE;
3592         uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
3593
3594         if (!bypass_is_supported(port_id))
3595                 return;
3596
3597         if (!strcmp(res->event_value, "timeout"))
3598                 bypass_event = RTE_BYPASS_EVENT_TIMEOUT;
3599         else if (!strcmp(res->event_value, "os_on"))
3600                 bypass_event = RTE_BYPASS_EVENT_OS_ON;
3601         else if (!strcmp(res->event_value, "os_off"))
3602                 bypass_event = RTE_BYPASS_EVENT_OS_OFF;
3603         else if (!strcmp(res->event_value, "power_on"))
3604                 bypass_event = RTE_BYPASS_EVENT_POWER_ON;
3605         else if (!strcmp(res->event_value, "power_off"))
3606                 bypass_event = RTE_BYPASS_EVENT_POWER_OFF;
3607         else
3608                 bypass_event = RTE_BYPASS_EVENT_NONE;
3609
3610         if (!strcmp(res->mode_value, "bypass"))
3611                 bypass_mode = RTE_BYPASS_MODE_BYPASS;
3612         else if (!strcmp(res->mode_value, "isolate"))
3613                 bypass_mode = RTE_BYPASS_MODE_ISOLATE;
3614         else
3615                 bypass_mode = RTE_BYPASS_MODE_NORMAL;
3616
3617         /* Set the watchdog timeout. */
3618         if (bypass_event == RTE_BYPASS_EVENT_TIMEOUT) {
3619
3620                 rc = -EINVAL;
3621                 if (!RTE_BYPASS_TMT_VALID(bypass_timeout) ||
3622                                 (rc = rte_eth_dev_wd_timeout_store(port_id,
3623                                 bypass_timeout)) != 0) {
3624                         printf("Failed to set timeout value %u "
3625                                 "for port %d, errto code: %d.\n",
3626                                 bypass_timeout, port_id, rc);
3627                 }
3628         }
3629
3630         /* Set the bypass event to transition to bypass mode. */
3631         if (0 != rte_eth_dev_bypass_event_store(port_id,
3632                         bypass_event, bypass_mode)) {
3633                 printf("\t Failed to set bypass event for port = %d.\n", port_id);
3634         }
3635
3636 }
3637
3638 cmdline_parse_token_string_t cmd_setbypass_event_set =
3639         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3640                         set, "set");
3641 cmdline_parse_token_string_t cmd_setbypass_event_bypass =
3642         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3643                         bypass, "bypass");
3644 cmdline_parse_token_string_t cmd_setbypass_event_event =
3645         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3646                         event, "event");
3647 cmdline_parse_token_string_t cmd_setbypass_event_event_value =
3648         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3649                         event_value, "none#timeout#os_off#os_on#power_on#power_off");
3650 cmdline_parse_token_string_t cmd_setbypass_event_mode =
3651         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3652                         mode, "mode");
3653 cmdline_parse_token_string_t cmd_setbypass_event_mode_value =
3654         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3655                         mode_value, "normal#bypass#isolate");
3656 cmdline_parse_token_num_t cmd_setbypass_event_port =
3657         TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_event_result,
3658                                 port_id, UINT8);
3659
3660 cmdline_parse_inst_t cmd_set_bypass_event = {
3661         .f = cmd_set_bypass_event_parsed,
3662         .help_str = "set bypass event (timeout|os_on|os_off|power_on|power_off) "
3663                     "mode (normal|bypass|isolate) (port_id): "
3664                     "Set the NIC bypass event mode for port_id",
3665         .data = NULL,
3666         .tokens = {
3667                 (void *)&cmd_setbypass_event_set,
3668                 (void *)&cmd_setbypass_event_bypass,
3669                 (void *)&cmd_setbypass_event_event,
3670                 (void *)&cmd_setbypass_event_event_value,
3671                 (void *)&cmd_setbypass_event_mode,
3672                 (void *)&cmd_setbypass_event_mode_value,
3673                 (void *)&cmd_setbypass_event_port,
3674                 NULL,
3675         },
3676 };
3677
3678
3679 /* *** SET NIC BYPASS TIMEOUT *** */
3680 struct cmd_set_bypass_timeout_result {
3681         cmdline_fixed_string_t set;
3682         cmdline_fixed_string_t bypass;
3683         cmdline_fixed_string_t timeout;
3684         cmdline_fixed_string_t value;
3685 };
3686
3687 static void
3688 cmd_set_bypass_timeout_parsed(void *parsed_result,
3689                 __attribute__((unused)) struct cmdline *cl,
3690                 __attribute__((unused)) void *data)
3691 {
3692         struct cmd_set_bypass_timeout_result *res = parsed_result;
3693
3694         if (!strcmp(res->value, "1.5"))
3695                 bypass_timeout = RTE_BYPASS_TMT_1_5_SEC;
3696         else if (!strcmp(res->value, "2"))
3697                 bypass_timeout = RTE_BYPASS_TMT_2_SEC;
3698         else if (!strcmp(res->value, "3"))
3699                 bypass_timeout = RTE_BYPASS_TMT_3_SEC;
3700         else if (!strcmp(res->value, "4"))
3701                 bypass_timeout = RTE_BYPASS_TMT_4_SEC;
3702         else if (!strcmp(res->value, "8"))
3703                 bypass_timeout = RTE_BYPASS_TMT_8_SEC;
3704         else if (!strcmp(res->value, "16"))
3705                 bypass_timeout = RTE_BYPASS_TMT_16_SEC;
3706         else if (!strcmp(res->value, "32"))
3707                 bypass_timeout = RTE_BYPASS_TMT_32_SEC;
3708         else
3709                 bypass_timeout = RTE_BYPASS_TMT_OFF;
3710 }
3711
3712 cmdline_parse_token_string_t cmd_setbypass_timeout_set =
3713         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
3714                         set, "set");
3715 cmdline_parse_token_string_t cmd_setbypass_timeout_bypass =
3716         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
3717                         bypass, "bypass");
3718 cmdline_parse_token_string_t cmd_setbypass_timeout_timeout =
3719         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
3720                         timeout, "timeout");
3721 cmdline_parse_token_string_t cmd_setbypass_timeout_value =
3722         TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
3723                         value, "0#1.5#2#3#4#8#16#32");
3724
3725 cmdline_parse_inst_t cmd_set_bypass_timeout = {
3726         .f = cmd_set_bypass_timeout_parsed,
3727         .help_str = "set bypass timeout (0|1.5|2|3|4|8|16|32) seconds: "
3728                     "Set the NIC bypass watchdog timeout",
3729         .data = NULL,
3730         .tokens = {
3731                 (void *)&cmd_setbypass_timeout_set,
3732                 (void *)&cmd_setbypass_timeout_bypass,
3733                 (void *)&cmd_setbypass_timeout_timeout,
3734                 (void *)&cmd_setbypass_timeout_value,
3735                 NULL,
3736         },
3737 };
3738
3739 /* *** SHOW NIC BYPASS MODE *** */
3740 struct cmd_show_bypass_config_result {
3741         cmdline_fixed_string_t show;
3742         cmdline_fixed_string_t bypass;
3743         cmdline_fixed_string_t config;
3744         uint8_t port_id;
3745 };
3746
3747 static void
3748 cmd_show_bypass_config_parsed(void *parsed_result,
3749                 __attribute__((unused)) struct cmdline *cl,
3750                 __attribute__((unused)) void *data)
3751 {
3752         struct cmd_show_bypass_config_result *res = parsed_result;
3753         uint32_t event_mode;
3754         uint32_t bypass_mode;
3755         portid_t port_id = res->port_id;
3756         uint32_t timeout = bypass_timeout;
3757         int i;
3758
3759         static const char * const timeouts[RTE_BYPASS_TMT_NUM] =
3760                 {"off", "1.5", "2", "3", "4", "8", "16", "32"};
3761         static const char * const modes[RTE_BYPASS_MODE_NUM] =
3762                 {"UNKNOWN", "normal", "bypass", "isolate"};
3763         static const char * const events[RTE_BYPASS_EVENT_NUM] = {
3764                 "NONE",
3765                 "OS/board on",
3766                 "power supply on",
3767                 "OS/board off",
3768                 "power supply off",
3769                 "timeout"};
3770         int num_events = (sizeof events) / (sizeof events[0]);
3771
3772         if (!bypass_is_supported(port_id))
3773                 return;
3774
3775         /* Display the bypass mode.*/
3776         if (0 != rte_eth_dev_bypass_state_show(port_id, &bypass_mode)) {
3777                 printf("\tFailed to get bypass mode for port = %d\n", port_id);
3778                 return;
3779         }
3780         else {
3781                 if (!RTE_BYPASS_MODE_VALID(bypass_mode))
3782                         bypass_mode = RTE_BYPASS_MODE_NONE;
3783
3784                 printf("\tbypass mode    = %s\n",  modes[bypass_mode]);
3785         }
3786
3787         /* Display the bypass timeout.*/
3788         if (!RTE_BYPASS_TMT_VALID(timeout))
3789                 timeout = RTE_BYPASS_TMT_OFF;
3790
3791         printf("\tbypass timeout = %s\n", timeouts[timeout]);
3792
3793         /* Display the bypass events and associated modes. */
3794         for (i = RTE_BYPASS_EVENT_START; i < num_events; i++) {
3795
3796                 if (0 != rte_eth_dev_bypass_event_show(port_id, i, &event_mode)) {
3797                         printf("\tFailed to get bypass mode for event = %s\n",
3798                                 events[i]);
3799                 } else {
3800                         if (!RTE_BYPASS_MODE_VALID(event_mode))
3801                                 event_mode = RTE_BYPASS_MODE_NONE;
3802
3803                         printf("\tbypass event: %-16s = %s\n", events[i],
3804                                 modes[event_mode]);
3805                 }
3806         }
3807 }
3808
3809 cmdline_parse_token_string_t cmd_showbypass_config_show =
3810         TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
3811                         show, "show");
3812 cmdline_parse_token_string_t cmd_showbypass_config_bypass =
3813         TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
3814                         bypass, "bypass");
3815 cmdline_parse_token_string_t cmd_showbypass_config_config =
3816         TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
3817                         config, "config");
3818 cmdline_parse_token_num_t cmd_showbypass_config_port =
3819         TOKEN_NUM_INITIALIZER(struct cmd_show_bypass_config_result,
3820                                 port_id, UINT8);
3821
3822 cmdline_parse_inst_t cmd_show_bypass_config = {
3823         .f = cmd_show_bypass_config_parsed,
3824         .help_str = "show bypass config (port_id): "
3825                     "Show the NIC bypass config for port_id",
3826         .data = NULL,
3827         .tokens = {
3828                 (void *)&cmd_showbypass_config_show,
3829                 (void *)&cmd_showbypass_config_bypass,
3830                 (void *)&cmd_showbypass_config_config,
3831                 (void *)&cmd_showbypass_config_port,
3832                 NULL,
3833         },
3834 };
3835 #endif
3836
3837 #ifdef RTE_LIBRTE_PMD_BOND
3838 /* *** SET BONDING MODE *** */
3839 struct cmd_set_bonding_mode_result {
3840         cmdline_fixed_string_t set;
3841         cmdline_fixed_string_t bonding;
3842         cmdline_fixed_string_t mode;
3843         uint8_t value;
3844         uint8_t port_id;
3845 };
3846
3847 static void cmd_set_bonding_mode_parsed(void *parsed_result,
3848                 __attribute__((unused))  struct cmdline *cl,
3849                 __attribute__((unused)) void *data)
3850 {
3851         struct cmd_set_bonding_mode_result *res = parsed_result;
3852         portid_t port_id = res->port_id;
3853
3854         /* Set the bonding mode for the relevant port. */
3855         if (0 != rte_eth_bond_mode_set(port_id, res->value))
3856                 printf("\t Failed to set bonding mode for port = %d.\n", port_id);
3857 }
3858
3859 cmdline_parse_token_string_t cmd_setbonding_mode_set =
3860 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
3861                 set, "set");
3862 cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
3863 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
3864                 bonding, "bonding");
3865 cmdline_parse_token_string_t cmd_setbonding_mode_mode =
3866 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
3867                 mode, "mode");
3868 cmdline_parse_token_num_t cmd_setbonding_mode_value =
3869 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
3870                 value, UINT8);
3871 cmdline_parse_token_num_t cmd_setbonding_mode_port =
3872 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
3873                 port_id, UINT8);
3874
3875 cmdline_parse_inst_t cmd_set_bonding_mode = {
3876                 .f = cmd_set_bonding_mode_parsed,
3877                 .help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
3878                 .data = NULL,
3879                 .tokens = {
3880                                 (void *) &cmd_setbonding_mode_set,
3881                                 (void *) &cmd_setbonding_mode_bonding,
3882                                 (void *) &cmd_setbonding_mode_mode,
3883                                 (void *) &cmd_setbonding_mode_value,
3884                                 (void *) &cmd_setbonding_mode_port,
3885                                 NULL
3886                 }
3887 };
3888
3889 /* *** SET BALANCE XMIT POLICY *** */
3890 struct cmd_set_bonding_balance_xmit_policy_result {
3891         cmdline_fixed_string_t set;
3892         cmdline_fixed_string_t bonding;
3893         cmdline_fixed_string_t balance_xmit_policy;
3894         uint8_t port_id;
3895         cmdline_fixed_string_t policy;
3896 };
3897
3898 static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
3899                 __attribute__((unused))  struct cmdline *cl,
3900                 __attribute__((unused)) void *data)
3901 {
3902         struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
3903         portid_t port_id = res->port_id;
3904         uint8_t policy;
3905
3906         if (!strcmp(res->policy, "l2")) {
3907                 policy = BALANCE_XMIT_POLICY_LAYER2;
3908         } else if (!strcmp(res->policy, "l23")) {
3909                 policy = BALANCE_XMIT_POLICY_LAYER23;
3910         } else if (!strcmp(res->policy, "l34")) {
3911                 policy = BALANCE_XMIT_POLICY_LAYER34;
3912         } else {
3913                 printf("\t Invalid xmit policy selection");
3914                 return;
3915         }
3916
3917         /* Set the bonding mode for the relevant port. */
3918         if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
3919                 printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
3920                                 port_id);
3921         }
3922 }
3923
3924 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
3925 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
3926                 set, "set");
3927 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
3928 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
3929                 bonding, "bonding");
3930 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
3931 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
3932                 balance_xmit_policy, "balance_xmit_policy");
3933 cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
3934 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
3935                 port_id, UINT8);
3936 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
3937 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
3938                 policy, "l2#l23#l34");
3939
3940 cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
3941                 .f = cmd_set_bonding_balance_xmit_policy_parsed,
3942                 .help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
3943                 .data = NULL,
3944                 .tokens = {
3945                                 (void *)&cmd_setbonding_balance_xmit_policy_set,
3946                                 (void *)&cmd_setbonding_balance_xmit_policy_bonding,
3947                                 (void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
3948                                 (void *)&cmd_setbonding_balance_xmit_policy_port,
3949                                 (void *)&cmd_setbonding_balance_xmit_policy_policy,
3950                                 NULL
3951                 }
3952 };
3953
3954 /* *** SHOW NIC BONDING CONFIGURATION *** */
3955 struct cmd_show_bonding_config_result {
3956         cmdline_fixed_string_t show;
3957         cmdline_fixed_string_t bonding;
3958         cmdline_fixed_string_t config;
3959         uint8_t port_id;
3960 };
3961
3962 static void cmd_show_bonding_config_parsed(void *parsed_result,
3963                 __attribute__((unused))  struct cmdline *cl,
3964                 __attribute__((unused)) void *data)
3965 {
3966         struct cmd_show_bonding_config_result *res = parsed_result;
3967         int bonding_mode;
3968         uint8_t slaves[RTE_MAX_ETHPORTS];
3969         int num_slaves, num_active_slaves;
3970         int primary_id;
3971         int i;
3972         portid_t port_id = res->port_id;
3973
3974         /* Display the bonding mode.*/
3975         bonding_mode = rte_eth_bond_mode_get(port_id);
3976         if (bonding_mode < 0) {
3977                 printf("\tFailed to get bonding mode for port = %d\n", port_id);
3978                 return;
3979         } else
3980                 printf("\tBonding mode: %d\n", bonding_mode);
3981
3982         if (bonding_mode == BONDING_MODE_BALANCE) {
3983                 int balance_xmit_policy;
3984
3985                 balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
3986                 if (balance_xmit_policy < 0) {
3987                         printf("\tFailed to get balance xmit policy for port = %d\n",
3988                                         port_id);
3989                         return;
3990                 } else {
3991                         printf("\tBalance Xmit Policy: ");
3992
3993                         switch (balance_xmit_policy) {
3994                         case BALANCE_XMIT_POLICY_LAYER2:
3995                                 printf("BALANCE_XMIT_POLICY_LAYER2");
3996                                 break;
3997                         case BALANCE_XMIT_POLICY_LAYER23:
3998                                 printf("BALANCE_XMIT_POLICY_LAYER23");
3999                                 break;
4000                         case BALANCE_XMIT_POLICY_LAYER34:
4001                                 printf("BALANCE_XMIT_POLICY_LAYER34");
4002                                 break;
4003                         }
4004                         printf("\n");
4005                 }
4006         }
4007
4008         num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
4009
4010         if (num_slaves < 0) {
4011                 printf("\tFailed to get slave list for port = %d\n", port_id);
4012                 return;
4013         }
4014         if (num_slaves > 0) {
4015                 printf("\tSlaves (%d): [", num_slaves);
4016                 for (i = 0; i < num_slaves - 1; i++)
4017                         printf("%d ", slaves[i]);
4018
4019                 printf("%d]\n", slaves[num_slaves - 1]);
4020         } else {
4021                 printf("\tSlaves: []\n");
4022
4023         }
4024
4025         num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
4026                         RTE_MAX_ETHPORTS);
4027
4028         if (num_active_slaves < 0) {
4029                 printf("\tFailed to get active slave list for port = %d\n", port_id);
4030                 return;
4031         }
4032         if (num_active_slaves > 0) {
4033                 printf("\tActive Slaves (%d): [", num_active_slaves);
4034                 for (i = 0; i < num_active_slaves - 1; i++)
4035                         printf("%d ", slaves[i]);
4036
4037                 printf("%d]\n", slaves[num_active_slaves - 1]);
4038
4039         } else {
4040                 printf("\tActive Slaves: []\n");
4041
4042         }
4043
4044         primary_id = rte_eth_bond_primary_get(port_id);
4045         if (primary_id < 0) {
4046                 printf("\tFailed to get primary slave for port = %d\n", port_id);
4047                 return;
4048         } else
4049                 printf("\tPrimary: [%d]\n", primary_id);
4050
4051 }
4052
4053 cmdline_parse_token_string_t cmd_showbonding_config_show =
4054 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4055                 show, "show");
4056 cmdline_parse_token_string_t cmd_showbonding_config_bonding =
4057 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4058                 bonding, "bonding");
4059 cmdline_parse_token_string_t cmd_showbonding_config_config =
4060 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4061                 config, "config");
4062 cmdline_parse_token_num_t cmd_showbonding_config_port =
4063 TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
4064                 port_id, UINT8);
4065
4066 cmdline_parse_inst_t cmd_show_bonding_config = {
4067                 .f = cmd_show_bonding_config_parsed,
4068                 .help_str =     "show bonding config (port_id): Show the bonding config for port_id",
4069                 .data = NULL,
4070                 .tokens = {
4071                                 (void *)&cmd_showbonding_config_show,
4072                                 (void *)&cmd_showbonding_config_bonding,
4073                                 (void *)&cmd_showbonding_config_config,
4074                                 (void *)&cmd_showbonding_config_port,
4075                                 NULL
4076                 }
4077 };
4078
4079 /* *** SET BONDING PRIMARY *** */
4080 struct cmd_set_bonding_primary_result {
4081         cmdline_fixed_string_t set;
4082         cmdline_fixed_string_t bonding;
4083         cmdline_fixed_string_t primary;
4084         uint8_t slave_id;
4085         uint8_t port_id;
4086 };
4087
4088 static void cmd_set_bonding_primary_parsed(void *parsed_result,
4089                 __attribute__((unused))  struct cmdline *cl,
4090                 __attribute__((unused)) void *data)
4091 {
4092         struct cmd_set_bonding_primary_result *res = parsed_result;
4093         portid_t master_port_id = res->port_id;
4094         portid_t slave_port_id = res->slave_id;
4095
4096         /* Set the primary slave for a bonded device. */
4097         if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
4098                 printf("\t Failed to set primary slave for port = %d.\n",
4099                                 master_port_id);
4100                 return;
4101         }
4102         init_port_config();
4103 }
4104
4105 cmdline_parse_token_string_t cmd_setbonding_primary_set =
4106 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4107                 set, "set");
4108 cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
4109 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4110                 bonding, "bonding");
4111 cmdline_parse_token_string_t cmd_setbonding_primary_primary =
4112 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4113                 primary, "primary");
4114 cmdline_parse_token_num_t cmd_setbonding_primary_slave =
4115 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
4116                 slave_id, UINT8);
4117 cmdline_parse_token_num_t cmd_setbonding_primary_port =
4118 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
4119                 port_id, UINT8);
4120
4121 cmdline_parse_inst_t cmd_set_bonding_primary = {
4122                 .f = cmd_set_bonding_primary_parsed,
4123                 .help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
4124                 .data = NULL,
4125                 .tokens = {
4126                                 (void *)&cmd_setbonding_primary_set,
4127                                 (void *)&cmd_setbonding_primary_bonding,
4128                                 (void *)&cmd_setbonding_primary_primary,
4129                                 (void *)&cmd_setbonding_primary_slave,
4130                                 (void *)&cmd_setbonding_primary_port,
4131                                 NULL
4132                 }
4133 };
4134
4135 /* *** ADD SLAVE *** */
4136 struct cmd_add_bonding_slave_result {
4137         cmdline_fixed_string_t add;
4138         cmdline_fixed_string_t bonding;
4139         cmdline_fixed_string_t slave;
4140         uint8_t slave_id;
4141         uint8_t port_id;
4142 };
4143
4144 static void cmd_add_bonding_slave_parsed(void *parsed_result,
4145                 __attribute__((unused))  struct cmdline *cl,
4146                 __attribute__((unused)) void *data)
4147 {
4148         struct cmd_add_bonding_slave_result *res = parsed_result;
4149         portid_t master_port_id = res->port_id;
4150         portid_t slave_port_id = res->slave_id;
4151
4152         /* Set the primary slave for a bonded device. */
4153         if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
4154                 printf("\t Failed to add slave %d to master port = %d.\n",
4155                                 slave_port_id, master_port_id);
4156                 return;
4157         }
4158         init_port_config();
4159         set_port_slave_flag(slave_port_id);
4160 }
4161
4162 cmdline_parse_token_string_t cmd_addbonding_slave_add =
4163 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4164                 add, "add");
4165 cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
4166 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4167                 bonding, "bonding");
4168 cmdline_parse_token_string_t cmd_addbonding_slave_slave =
4169 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4170                 slave, "slave");
4171 cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
4172 TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
4173                 slave_id, UINT8);
4174 cmdline_parse_token_num_t cmd_addbonding_slave_port =
4175 TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
4176                 port_id, UINT8);
4177
4178 cmdline_parse_inst_t cmd_add_bonding_slave = {
4179                 .f = cmd_add_bonding_slave_parsed,
4180                 .help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
4181                 .data = NULL,
4182                 .tokens = {
4183                                 (void *)&cmd_addbonding_slave_add,
4184                                 (void *)&cmd_addbonding_slave_bonding,
4185                                 (void *)&cmd_addbonding_slave_slave,
4186                                 (void *)&cmd_addbonding_slave_slaveid,
4187                                 (void *)&cmd_addbonding_slave_port,
4188                                 NULL
4189                 }
4190 };
4191
4192 /* *** REMOVE SLAVE *** */
4193 struct cmd_remove_bonding_slave_result {
4194         cmdline_fixed_string_t remove;
4195         cmdline_fixed_string_t bonding;
4196         cmdline_fixed_string_t slave;
4197         uint8_t slave_id;
4198         uint8_t port_id;
4199 };
4200
4201 static void cmd_remove_bonding_slave_parsed(void *parsed_result,
4202                 __attribute__((unused))  struct cmdline *cl,
4203                 __attribute__((unused)) void *data)
4204 {
4205         struct cmd_remove_bonding_slave_result *res = parsed_result;
4206         portid_t master_port_id = res->port_id;
4207         portid_t slave_port_id = res->slave_id;
4208
4209         /* Set the primary slave for a bonded device. */
4210         if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
4211                 printf("\t Failed to remove slave %d from master port = %d.\n",
4212                                 slave_port_id, master_port_id);
4213                 return;
4214         }
4215         init_port_config();
4216         clear_port_slave_flag(slave_port_id);
4217 }
4218
4219 cmdline_parse_token_string_t cmd_removebonding_slave_remove =
4220                 TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4221                                 remove, "remove");
4222 cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
4223                 TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4224                                 bonding, "bonding");
4225 cmdline_parse_token_string_t cmd_removebonding_slave_slave =
4226                 TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4227                                 slave, "slave");
4228 cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
4229                 TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
4230                                 slave_id, UINT8);
4231 cmdline_parse_token_num_t cmd_removebonding_slave_port =
4232                 TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
4233                                 port_id, UINT8);
4234
4235 cmdline_parse_inst_t cmd_remove_bonding_slave = {
4236                 .f = cmd_remove_bonding_slave_parsed,
4237                 .help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
4238                 .data = NULL,
4239                 .tokens = {
4240                                 (void *)&cmd_removebonding_slave_remove,
4241                                 (void *)&cmd_removebonding_slave_bonding,
4242                                 (void *)&cmd_removebonding_slave_slave,
4243                                 (void *)&cmd_removebonding_slave_slaveid,
4244                                 (void *)&cmd_removebonding_slave_port,
4245                                 NULL
4246                 }
4247 };
4248
4249 /* *** CREATE BONDED DEVICE *** */
4250 struct cmd_create_bonded_device_result {
4251         cmdline_fixed_string_t create;
4252         cmdline_fixed_string_t bonded;
4253         cmdline_fixed_string_t device;
4254         uint8_t mode;
4255         uint8_t socket;
4256 };
4257
4258 static int bond_dev_num = 0;
4259
4260 static void cmd_create_bonded_device_parsed(void *parsed_result,
4261                 __attribute__((unused))  struct cmdline *cl,
4262                 __attribute__((unused)) void *data)
4263 {
4264         struct cmd_create_bonded_device_result *res = parsed_result;
4265         char ethdev_name[RTE_ETH_NAME_MAX_LEN];
4266         int port_id;
4267
4268         if (test_done == 0) {
4269                 printf("Please stop forwarding first\n");
4270                 return;
4271         }
4272
4273         snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "eth_bond_testpmd_%d",
4274                         bond_dev_num++);
4275
4276         /* Create a new bonded device. */
4277         port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
4278         if (port_id < 0) {
4279                 printf("\t Failed to create bonded device.\n");
4280                 return;
4281         } else {
4282                 printf("Created new bonded device %s on (port %d).\n", ethdev_name,
4283                                 port_id);
4284
4285                 /* Update number of ports */
4286                 nb_ports = rte_eth_dev_count();
4287                 reconfig(port_id, res->socket);
4288                 rte_eth_promiscuous_enable(port_id);
4289                 ports[port_id].enabled = 1;
4290         }
4291
4292 }
4293
4294 cmdline_parse_token_string_t cmd_createbonded_device_create =
4295                 TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4296                                 create, "create");
4297 cmdline_parse_token_string_t cmd_createbonded_device_bonded =
4298                 TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4299                                 bonded, "bonded");
4300 cmdline_parse_token_string_t cmd_createbonded_device_device =
4301                 TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4302                                 device, "device");
4303 cmdline_parse_token_num_t cmd_createbonded_device_mode =
4304                 TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
4305                                 mode, UINT8);
4306 cmdline_parse_token_num_t cmd_createbonded_device_socket =
4307                 TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
4308                                 socket, UINT8);
4309
4310 cmdline_parse_inst_t cmd_create_bonded_device = {
4311                 .f = cmd_create_bonded_device_parsed,
4312                 .help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
4313                 .data = NULL,
4314                 .tokens = {
4315                                 (void *)&cmd_createbonded_device_create,
4316                                 (void *)&cmd_createbonded_device_bonded,
4317                                 (void *)&cmd_createbonded_device_device,
4318                                 (void *)&cmd_createbonded_device_mode,
4319                                 (void *)&cmd_createbonded_device_socket,
4320                                 NULL
4321                 }
4322 };
4323
4324 /* *** SET MAC ADDRESS IN BONDED DEVICE *** */
4325 struct cmd_set_bond_mac_addr_result {
4326         cmdline_fixed_string_t set;
4327         cmdline_fixed_string_t bonding;
4328         cmdline_fixed_string_t mac_addr;
4329         uint8_t port_num;
4330         struct ether_addr address;
4331 };
4332
4333 static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
4334                 __attribute__((unused))  struct cmdline *cl,
4335                 __attribute__((unused)) void *data)
4336 {
4337         struct cmd_set_bond_mac_addr_result *res = parsed_result;
4338         int ret;
4339
4340         if (port_id_is_invalid(res->port_num, ENABLED_WARN))
4341                 return;
4342
4343         ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
4344
4345         /* check the return value and print it if is < 0 */
4346         if (ret < 0)
4347                 printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
4348 }
4349
4350 cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
4351                 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
4352 cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
4353                 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
4354                                 "bonding");
4355 cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
4356                 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
4357                                 "mac_addr");
4358 cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
4359                 TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
4360 cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
4361                 TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
4362
4363 cmdline_parse_inst_t cmd_set_bond_mac_addr = {
4364                 .f = cmd_set_bond_mac_addr_parsed,
4365                 .data = (void *) 0,
4366                 .help_str = "set bonding mac_addr (port_id) (address): ",
4367                 .tokens = {
4368                                 (void *)&cmd_set_bond_mac_addr_set,
4369                                 (void *)&cmd_set_bond_mac_addr_bonding,
4370                                 (void *)&cmd_set_bond_mac_addr_mac,
4371                                 (void *)&cmd_set_bond_mac_addr_portnum,
4372                                 (void *)&cmd_set_bond_mac_addr_addr,
4373                                 NULL
4374                 }
4375 };
4376
4377
4378 /* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
4379 struct cmd_set_bond_mon_period_result {
4380         cmdline_fixed_string_t set;
4381         cmdline_fixed_string_t bonding;
4382         cmdline_fixed_string_t mon_period;
4383         uint8_t port_num;
4384         uint32_t period_ms;
4385 };
4386
4387 static void cmd_set_bond_mon_period_parsed(void *parsed_result,
4388                 __attribute__((unused))  struct cmdline *cl,
4389                 __attribute__((unused)) void *data)
4390 {
4391         struct cmd_set_bond_mon_period_result *res = parsed_result;
4392         int ret;
4393
4394         if (res->port_num >= nb_ports) {
4395                 printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
4396                 return;
4397         }
4398
4399         ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
4400
4401         /* check the return value and print it if is < 0 */
4402         if (ret < 0)
4403                 printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
4404 }
4405
4406 cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
4407                 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4408                                 set, "set");
4409 cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
4410                 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4411                                 bonding, "bonding");
4412 cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
4413                 TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4414                                 mon_period,     "mon_period");
4415 cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
4416                 TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
4417                                 port_num, UINT8);
4418 cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
4419                 TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
4420                                 period_ms, UINT32);
4421
4422 cmdline_parse_inst_t cmd_set_bond_mon_period = {
4423                 .f = cmd_set_bond_mon_period_parsed,
4424                 .data = (void *) 0,
4425                 .help_str = "set bonding mon_period (port_id) (period_ms): ",
4426                 .tokens = {
4427                                 (void *)&cmd_set_bond_mon_period_set,
4428                                 (void *)&cmd_set_bond_mon_period_bonding,
4429                                 (void *)&cmd_set_bond_mon_period_mon_period,
4430                                 (void *)&cmd_set_bond_mon_period_portnum,
4431                                 (void *)&cmd_set_bond_mon_period_period_ms,
4432                                 NULL
4433                 }
4434 };
4435
4436 #endif /* RTE_LIBRTE_PMD_BOND */
4437
4438 /* *** SET FORWARDING MODE *** */
4439 struct cmd_set_fwd_mode_result {
4440         cmdline_fixed_string_t set;
4441         cmdline_fixed_string_t fwd;
4442         cmdline_fixed_string_t mode;
4443 };
4444
4445 static void cmd_set_fwd_mode_parsed(void *parsed_result,
4446                                     __attribute__((unused)) struct cmdline *cl,
4447                                     __attribute__((unused)) void *data)
4448 {
4449         struct cmd_set_fwd_mode_result *res = parsed_result;
4450
4451         set_pkt_forwarding_mode(res->mode);
4452 }
4453
4454 cmdline_parse_token_string_t cmd_setfwd_set =
4455         TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
4456 cmdline_parse_token_string_t cmd_setfwd_fwd =
4457         TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
4458 cmdline_parse_token_string_t cmd_setfwd_mode =
4459         TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
4460                 "" /* defined at init */);
4461
4462 cmdline_parse_inst_t cmd_set_fwd_mode = {
4463         .f = cmd_set_fwd_mode_parsed,
4464         .data = NULL,
4465         .help_str = NULL, /* defined at init */
4466         .tokens = {
4467                 (void *)&cmd_setfwd_set,
4468                 (void *)&cmd_setfwd_fwd,
4469                 (void *)&cmd_setfwd_mode,
4470                 NULL,
4471         },
4472 };
4473
4474 static void cmd_set_fwd_mode_init(void)
4475 {
4476         char *modes, *c;
4477         static char token[128];
4478         static char help[256];
4479         cmdline_parse_token_string_t *token_struct;
4480
4481         modes = list_pkt_forwarding_modes();
4482         snprintf(help, sizeof help, "set fwd %s - "
4483                 "set packet forwarding mode", modes);
4484         cmd_set_fwd_mode.help_str = help;
4485
4486         /* string token separator is # */
4487         for (c = token; *modes != '\0'; modes++)
4488                 if (*modes == '|')
4489                         *c++ = '#';
4490                 else
4491                         *c++ = *modes;
4492         token_struct = (cmdline_parse_token_string_t*)cmd_set_fwd_mode.tokens[2];
4493         token_struct->string_data.str = token;
4494 }
4495
4496 /* *** SET BURST TX DELAY TIME RETRY NUMBER *** */
4497 struct cmd_set_burst_tx_retry_result {
4498         cmdline_fixed_string_t set;
4499         cmdline_fixed_string_t burst;
4500         cmdline_fixed_string_t tx;
4501         cmdline_fixed_string_t delay;
4502         uint32_t time;
4503         cmdline_fixed_string_t retry;
4504         uint32_t retry_num;
4505 };
4506
4507 static void cmd_set_burst_tx_retry_parsed(void *parsed_result,
4508                                         __attribute__((unused)) struct cmdline *cl,
4509                                         __attribute__((unused)) void *data)
4510 {
4511         struct cmd_set_burst_tx_retry_result *res = parsed_result;
4512
4513         if (!strcmp(res->set, "set") && !strcmp(res->burst, "burst")
4514                 && !strcmp(res->tx, "tx")) {
4515                 if (!strcmp(res->delay, "delay"))
4516                         burst_tx_delay_time = res->time;
4517                 if (!strcmp(res->retry, "retry"))
4518                         burst_tx_retry_num = res->retry_num;
4519         }
4520
4521 }
4522
4523 cmdline_parse_token_string_t cmd_set_burst_tx_retry_set =
4524         TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, set, "set");
4525 cmdline_parse_token_string_t cmd_set_burst_tx_retry_burst =
4526         TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, burst,
4527                                  "burst");
4528 cmdline_parse_token_string_t cmd_set_burst_tx_retry_tx =
4529         TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, tx, "tx");
4530 cmdline_parse_token_string_t cmd_set_burst_tx_retry_delay =
4531         TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, delay, "delay");
4532 cmdline_parse_token_num_t cmd_set_burst_tx_retry_time =
4533         TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, time, UINT32);
4534 cmdline_parse_token_string_t cmd_set_burst_tx_retry_retry =
4535         TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry, "retry");
4536 cmdline_parse_token_num_t cmd_set_burst_tx_retry_retry_num =
4537         TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry_num, UINT32);
4538
4539 cmdline_parse_inst_t cmd_set_burst_tx_retry = {
4540         .f = cmd_set_burst_tx_retry_parsed,
4541         .help_str = "set burst tx delay (time_by_useconds) retry (retry_num)",
4542         .tokens = {
4543                 (void *)&cmd_set_burst_tx_retry_set,
4544                 (void *)&cmd_set_burst_tx_retry_burst,
4545                 (void *)&cmd_set_burst_tx_retry_tx,
4546                 (void *)&cmd_set_burst_tx_retry_delay,
4547                 (void *)&cmd_set_burst_tx_retry_time,
4548                 (void *)&cmd_set_burst_tx_retry_retry,
4549                 (void *)&cmd_set_burst_tx_retry_retry_num,
4550                 NULL,
4551         },
4552 };
4553
4554 /* *** SET PROMISC MODE *** */
4555 struct cmd_set_promisc_mode_result {
4556         cmdline_fixed_string_t set;
4557         cmdline_fixed_string_t promisc;
4558         cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
4559         uint8_t port_num;                /* valid if "allports" argument == 0 */
4560         cmdline_fixed_string_t mode;
4561 };
4562
4563 static void cmd_set_promisc_mode_parsed(void *parsed_result,
4564                                         __attribute__((unused)) struct cmdline *cl,
4565                                         void *allports)
4566 {
4567         struct cmd_set_promisc_mode_result *res = parsed_result;
4568         int enable;
4569         portid_t i;
4570
4571         if (!strcmp(res->mode, "on"))
4572                 enable = 1;
4573         else
4574                 enable = 0;
4575
4576         /* all ports */
4577         if (allports) {
4578                 FOREACH_PORT(i, ports) {
4579                         if (enable)
4580                                 rte_eth_promiscuous_enable(i);
4581                         else
4582                                 rte_eth_promiscuous_disable(i);
4583                 }
4584         }
4585         else {
4586                 if (enable)
4587                         rte_eth_promiscuous_enable(res->port_num);
4588                 else
4589                         rte_eth_promiscuous_disable(res->port_num);
4590         }
4591 }
4592
4593 cmdline_parse_token_string_t cmd_setpromisc_set =
4594         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, set, "set");
4595 cmdline_parse_token_string_t cmd_setpromisc_promisc =
4596         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, promisc,
4597                                  "promisc");
4598 cmdline_parse_token_string_t cmd_setpromisc_portall =
4599         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, port_all,
4600                                  "all");
4601 cmdline_parse_token_num_t cmd_setpromisc_portnum =
4602         TOKEN_NUM_INITIALIZER(struct cmd_set_promisc_mode_result, port_num,
4603                               UINT8);
4604 cmdline_parse_token_string_t cmd_setpromisc_mode =
4605         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, mode,
4606                                  "on#off");
4607
4608 cmdline_parse_inst_t cmd_set_promisc_mode_all = {
4609         .f = cmd_set_promisc_mode_parsed,
4610         .data = (void *)1,
4611         .help_str = "set promisc all on|off: set promisc mode for all ports",
4612         .tokens = {
4613                 (void *)&cmd_setpromisc_set,
4614                 (void *)&cmd_setpromisc_promisc,
4615                 (void *)&cmd_setpromisc_portall,
4616                 (void *)&cmd_setpromisc_mode,
4617                 NULL,
4618         },
4619 };
4620
4621 cmdline_parse_inst_t cmd_set_promisc_mode_one = {
4622         .f = cmd_set_promisc_mode_parsed,
4623         .data = (void *)0,
4624         .help_str = "set promisc X on|off: set promisc mode on port X",
4625         .tokens = {
4626                 (void *)&cmd_setpromisc_set,
4627                 (void *)&cmd_setpromisc_promisc,
4628                 (void *)&cmd_setpromisc_portnum,
4629                 (void *)&cmd_setpromisc_mode,
4630                 NULL,
4631         },
4632 };
4633
4634 /* *** SET ALLMULTI MODE *** */
4635 struct cmd_set_allmulti_mode_result {
4636         cmdline_fixed_string_t set;
4637         cmdline_fixed_string_t allmulti;
4638         cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
4639         uint8_t port_num;                /* valid if "allports" argument == 0 */
4640         cmdline_fixed_string_t mode;
4641 };
4642
4643 static void cmd_set_allmulti_mode_parsed(void *parsed_result,
4644                                         __attribute__((unused)) struct cmdline *cl,
4645                                         void *allports)
4646 {
4647         struct cmd_set_allmulti_mode_result *res = parsed_result;
4648         int enable;
4649         portid_t i;
4650
4651         if (!strcmp(res->mode, "on"))
4652                 enable = 1;
4653         else
4654                 enable = 0;
4655
4656         /* all ports */
4657         if (allports) {
4658                 FOREACH_PORT(i, ports) {
4659                         if (enable)
4660                                 rte_eth_allmulticast_enable(i);
4661                         else
4662                                 rte_eth_allmulticast_disable(i);
4663                 }
4664         }
4665         else {
4666                 if (enable)
4667                         rte_eth_allmulticast_enable(res->port_num);
4668                 else
4669                         rte_eth_allmulticast_disable(res->port_num);
4670         }
4671 }
4672
4673 cmdline_parse_token_string_t cmd_setallmulti_set =
4674         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, set, "set");
4675 cmdline_parse_token_string_t cmd_setallmulti_allmulti =
4676         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, allmulti,
4677                                  "allmulti");
4678 cmdline_parse_token_string_t cmd_setallmulti_portall =
4679         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, port_all,
4680                                  "all");
4681 cmdline_parse_token_num_t cmd_setallmulti_portnum =
4682         TOKEN_NUM_INITIALIZER(struct cmd_set_allmulti_mode_result, port_num,
4683                               UINT8);
4684 cmdline_parse_token_string_t cmd_setallmulti_mode =
4685         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, mode,
4686                                  "on#off");
4687
4688 cmdline_parse_inst_t cmd_set_allmulti_mode_all = {
4689         .f = cmd_set_allmulti_mode_parsed,
4690         .data = (void *)1,
4691         .help_str = "set allmulti all on|off: set allmulti mode for all ports",
4692         .tokens = {
4693                 (void *)&cmd_setallmulti_set,
4694                 (void *)&cmd_setallmulti_allmulti,
4695                 (void *)&cmd_setallmulti_portall,
4696                 (void *)&cmd_setallmulti_mode,
4697                 NULL,
4698         },
4699 };
4700
4701 cmdline_parse_inst_t cmd_set_allmulti_mode_one = {
4702         .f = cmd_set_allmulti_mode_parsed,
4703         .data = (void *)0,
4704         .help_str = "set allmulti X on|off: set allmulti mode on port X",
4705         .tokens = {
4706                 (void *)&cmd_setallmulti_set,
4707                 (void *)&cmd_setallmulti_allmulti,
4708                 (void *)&cmd_setallmulti_portnum,
4709                 (void *)&cmd_setallmulti_mode,
4710                 NULL,
4711         },
4712 };
4713
4714 /* *** SETUP ETHERNET LINK FLOW CONTROL *** */
4715 struct cmd_link_flow_ctrl_set_result {
4716         cmdline_fixed_string_t set;
4717         cmdline_fixed_string_t flow_ctrl;
4718         cmdline_fixed_string_t rx;
4719         cmdline_fixed_string_t rx_lfc_mode;
4720         cmdline_fixed_string_t tx;
4721         cmdline_fixed_string_t tx_lfc_mode;
4722         cmdline_fixed_string_t mac_ctrl_frame_fwd;
4723         cmdline_fixed_string_t mac_ctrl_frame_fwd_mode;
4724         cmdline_fixed_string_t autoneg_str;
4725         cmdline_fixed_string_t autoneg;
4726         cmdline_fixed_string_t hw_str;
4727         uint32_t high_water;
4728         cmdline_fixed_string_t lw_str;
4729         uint32_t low_water;
4730         cmdline_fixed_string_t pt_str;
4731         uint16_t pause_time;
4732         cmdline_fixed_string_t xon_str;
4733         uint16_t send_xon;
4734         uint8_t  port_id;
4735 };
4736
4737 cmdline_parse_token_string_t cmd_lfc_set_set =
4738         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4739                                 set, "set");
4740 cmdline_parse_token_string_t cmd_lfc_set_flow_ctrl =
4741         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4742                                 flow_ctrl, "flow_ctrl");
4743 cmdline_parse_token_string_t cmd_lfc_set_rx =
4744         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4745                                 rx, "rx");
4746 cmdline_parse_token_string_t cmd_lfc_set_rx_mode =
4747         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4748                                 rx_lfc_mode, "on#off");
4749 cmdline_parse_token_string_t cmd_lfc_set_tx =
4750         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4751                                 tx, "tx");
4752 cmdline_parse_token_string_t cmd_lfc_set_tx_mode =
4753         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4754                                 tx_lfc_mode, "on#off");
4755 cmdline_parse_token_string_t cmd_lfc_set_high_water_str =
4756         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4757                                 hw_str, "high_water");
4758 cmdline_parse_token_num_t cmd_lfc_set_high_water =
4759         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4760                                 high_water, UINT32);
4761 cmdline_parse_token_string_t cmd_lfc_set_low_water_str =
4762         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4763                                 lw_str, "low_water");
4764 cmdline_parse_token_num_t cmd_lfc_set_low_water =
4765         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4766                                 low_water, UINT32);
4767 cmdline_parse_token_string_t cmd_lfc_set_pause_time_str =
4768         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4769                                 pt_str, "pause_time");
4770 cmdline_parse_token_num_t cmd_lfc_set_pause_time =
4771         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4772                                 pause_time, UINT16);
4773 cmdline_parse_token_string_t cmd_lfc_set_send_xon_str =
4774         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4775                                 xon_str, "send_xon");
4776 cmdline_parse_token_num_t cmd_lfc_set_send_xon =
4777         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4778                                 send_xon, UINT16);
4779 cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd_mode =
4780         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4781                                 mac_ctrl_frame_fwd, "mac_ctrl_frame_fwd");
4782 cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd =
4783         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4784                                 mac_ctrl_frame_fwd_mode, "on#off");
4785 cmdline_parse_token_string_t cmd_lfc_set_autoneg_str =
4786         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4787                                 autoneg_str, "autoneg");
4788 cmdline_parse_token_string_t cmd_lfc_set_autoneg =
4789         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4790                                 autoneg, "on#off");
4791 cmdline_parse_token_num_t cmd_lfc_set_portid =
4792         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
4793                                 port_id, UINT8);
4794
4795 /* forward declaration */
4796 static void
4797 cmd_link_flow_ctrl_set_parsed(void *parsed_result, struct cmdline *cl,
4798                               void *data);
4799
4800 cmdline_parse_inst_t cmd_link_flow_control_set = {
4801         .f = cmd_link_flow_ctrl_set_parsed,
4802         .data = NULL,
4803         .help_str = "Configure the Ethernet flow control: set flow_ctrl rx on|off \
4804 tx on|off high_water low_water pause_time send_xon mac_ctrl_frame_fwd on|off \
4805 autoneg on|off port_id",
4806         .tokens = {
4807                 (void *)&cmd_lfc_set_set,
4808                 (void *)&cmd_lfc_set_flow_ctrl,
4809                 (void *)&cmd_lfc_set_rx,
4810                 (void *)&cmd_lfc_set_rx_mode,
4811                 (void *)&cmd_lfc_set_tx,
4812                 (void *)&cmd_lfc_set_tx_mode,
4813                 (void *)&cmd_lfc_set_high_water,
4814                 (void *)&cmd_lfc_set_low_water,
4815                 (void *)&cmd_lfc_set_pause_time,
4816                 (void *)&cmd_lfc_set_send_xon,
4817                 (void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
4818                 (void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
4819                 (void *)&cmd_lfc_set_autoneg_str,
4820                 (void *)&cmd_lfc_set_autoneg,
4821                 (void *)&cmd_lfc_set_portid,
4822                 NULL,
4823         },
4824 };
4825
4826 cmdline_parse_inst_t cmd_link_flow_control_set_rx = {
4827         .f = cmd_link_flow_ctrl_set_parsed,
4828         .data = (void *)&cmd_link_flow_control_set_rx,
4829         .help_str = "Change rx flow control parameter: set flow_ctrl "
4830                     "rx on|off port_id",
4831         .tokens = {
4832                 (void *)&cmd_lfc_set_set,
4833                 (void *)&cmd_lfc_set_flow_ctrl,
4834                 (void *)&cmd_lfc_set_rx,
4835                 (void *)&cmd_lfc_set_rx_mode,
4836                 (void *)&cmd_lfc_set_portid,
4837                 NULL,
4838         },
4839 };
4840
4841 cmdline_parse_inst_t cmd_link_flow_control_set_tx = {
4842         .f = cmd_link_flow_ctrl_set_parsed,
4843         .data = (void *)&cmd_link_flow_control_set_tx,
4844         .help_str = "Change tx flow control parameter: set flow_ctrl "
4845                     "tx on|off port_id",
4846         .tokens = {
4847                 (void *)&cmd_lfc_set_set,
4848                 (void *)&cmd_lfc_set_flow_ctrl,
4849                 (void *)&cmd_lfc_set_tx,
4850                 (void *)&cmd_lfc_set_tx_mode,
4851                 (void *)&cmd_lfc_set_portid,
4852                 NULL,
4853         },
4854 };
4855
4856 cmdline_parse_inst_t cmd_link_flow_control_set_hw = {
4857         .f = cmd_link_flow_ctrl_set_parsed,
4858         .data = (void *)&cmd_link_flow_control_set_hw,
4859         .help_str = "Change high water flow control parameter: set flow_ctrl "
4860                     "high_water value port_id",
4861         .tokens = {
4862                 (void *)&cmd_lfc_set_set,
4863                 (void *)&cmd_lfc_set_flow_ctrl,
4864                 (void *)&cmd_lfc_set_high_water_str,
4865                 (void *)&cmd_lfc_set_high_water,
4866                 (void *)&cmd_lfc_set_portid,
4867                 NULL,
4868         },
4869 };
4870
4871 cmdline_parse_inst_t cmd_link_flow_control_set_lw = {
4872         .f = cmd_link_flow_ctrl_set_parsed,
4873         .data = (void *)&cmd_link_flow_control_set_lw,
4874         .help_str = "Change low water flow control parameter: set flow_ctrl "
4875                     "low_water value port_id",
4876         .tokens = {
4877                 (void *)&cmd_lfc_set_set,
4878                 (void *)&cmd_lfc_set_flow_ctrl,
4879                 (void *)&cmd_lfc_set_low_water_str,
4880                 (void *)&cmd_lfc_set_low_water,
4881                 (void *)&cmd_lfc_set_portid,
4882                 NULL,
4883         },
4884 };
4885
4886 cmdline_parse_inst_t cmd_link_flow_control_set_pt = {
4887         .f = cmd_link_flow_ctrl_set_parsed,
4888         .data = (void *)&cmd_link_flow_control_set_pt,
4889         .help_str = "Change pause time flow control parameter: set flow_ctrl "
4890                     "pause_time value port_id",
4891         .tokens = {
4892                 (void *)&cmd_lfc_set_set,
4893                 (void *)&cmd_lfc_set_flow_ctrl,
4894                 (void *)&cmd_lfc_set_pause_time_str,
4895                 (void *)&cmd_lfc_set_pause_time,
4896                 (void *)&cmd_lfc_set_portid,
4897                 NULL,
4898         },
4899 };
4900
4901 cmdline_parse_inst_t cmd_link_flow_control_set_xon = {
4902         .f = cmd_link_flow_ctrl_set_parsed,
4903         .data = (void *)&cmd_link_flow_control_set_xon,
4904         .help_str = "Change send_xon flow control parameter: set flow_ctrl "
4905                     "send_xon value port_id",
4906         .tokens = {
4907                 (void *)&cmd_lfc_set_set,
4908                 (void *)&cmd_lfc_set_flow_ctrl,
4909                 (void *)&cmd_lfc_set_send_xon_str,
4910                 (void *)&cmd_lfc_set_send_xon,
4911                 (void *)&cmd_lfc_set_portid,
4912                 NULL,
4913         },
4914 };
4915
4916 cmdline_parse_inst_t cmd_link_flow_control_set_macfwd = {
4917         .f = cmd_link_flow_ctrl_set_parsed,
4918         .data = (void *)&cmd_link_flow_control_set_macfwd,
4919         .help_str = "Change mac ctrl fwd flow control parameter: set flow_ctrl "
4920                     "mac_ctrl_frame_fwd on|off port_id",
4921         .tokens = {
4922                 (void *)&cmd_lfc_set_set,
4923                 (void *)&cmd_lfc_set_flow_ctrl,
4924                 (void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
4925                 (void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
4926                 (void *)&cmd_lfc_set_portid,
4927                 NULL,
4928         },
4929 };
4930
4931 cmdline_parse_inst_t cmd_link_flow_control_set_autoneg = {
4932         .f = cmd_link_flow_ctrl_set_parsed,
4933         .data = (void *)&cmd_link_flow_control_set_autoneg,
4934         .help_str = "Change autoneg flow control parameter: set flow_ctrl "
4935                     "autoneg on|off port_id",
4936         .tokens = {
4937                 (void *)&cmd_lfc_set_set,
4938                 (void *)&cmd_lfc_set_flow_ctrl,
4939                 (void *)&cmd_lfc_set_autoneg_str,
4940                 (void *)&cmd_lfc_set_autoneg,
4941                 (void *)&cmd_lfc_set_portid,
4942                 NULL,
4943         },
4944 };
4945
4946 static void
4947 cmd_link_flow_ctrl_set_parsed(void *parsed_result,
4948                               __attribute__((unused)) struct cmdline *cl,
4949                               void *data)
4950 {
4951         struct cmd_link_flow_ctrl_set_result *res = parsed_result;
4952         cmdline_parse_inst_t *cmd = data;
4953         struct rte_eth_fc_conf fc_conf;
4954         int rx_fc_en = 0;
4955         int tx_fc_en = 0;
4956         int ret;
4957
4958         /*
4959          * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
4960          * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
4961          * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
4962          * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
4963          */
4964         static enum rte_eth_fc_mode rx_tx_onoff_2_lfc_mode[2][2] = {
4965                         {RTE_FC_NONE, RTE_FC_TX_PAUSE}, {RTE_FC_RX_PAUSE, RTE_FC_FULL}
4966         };
4967
4968         /* Partial command line, retrieve current configuration */
4969         if (cmd) {
4970                 ret = rte_eth_dev_flow_ctrl_get(res->port_id, &fc_conf);
4971                 if (ret != 0) {
4972                         printf("cannot get current flow ctrl parameters, return"
4973                                "code = %d\n", ret);
4974                         return;
4975                 }
4976
4977                 if ((fc_conf.mode == RTE_FC_RX_PAUSE) ||
4978                     (fc_conf.mode == RTE_FC_FULL))
4979                         rx_fc_en = 1;
4980                 if ((fc_conf.mode == RTE_FC_TX_PAUSE) ||
4981                     (fc_conf.mode == RTE_FC_FULL))
4982                         tx_fc_en = 1;
4983         }
4984
4985         if (!cmd || cmd == &cmd_link_flow_control_set_rx)
4986                 rx_fc_en = (!strcmp(res->rx_lfc_mode, "on")) ? 1 : 0;
4987
4988         if (!cmd || cmd == &cmd_link_flow_control_set_tx)
4989                 tx_fc_en = (!strcmp(res->tx_lfc_mode, "on")) ? 1 : 0;
4990
4991         fc_conf.mode = rx_tx_onoff_2_lfc_mode[rx_fc_en][tx_fc_en];
4992
4993         if (!cmd || cmd == &cmd_link_flow_control_set_hw)
4994                 fc_conf.high_water = res->high_water;
4995
4996         if (!cmd || cmd == &cmd_link_flow_control_set_lw)
4997                 fc_conf.low_water = res->low_water;
4998
4999         if (!cmd || cmd == &cmd_link_flow_control_set_pt)
5000                 fc_conf.pause_time = res->pause_time;
5001
5002         if (!cmd || cmd == &cmd_link_flow_control_set_xon)
5003                 fc_conf.send_xon = res->send_xon;
5004
5005         if (!cmd || cmd == &cmd_link_flow_control_set_macfwd) {
5006                 if (!strcmp(res->mac_ctrl_frame_fwd_mode, "on"))
5007                         fc_conf.mac_ctrl_frame_fwd = 1;
5008                 else
5009                         fc_conf.mac_ctrl_frame_fwd = 0;
5010         }
5011
5012         if (!cmd || cmd == &cmd_link_flow_control_set_autoneg)
5013                 fc_conf.autoneg = (!strcmp(res->autoneg, "on")) ? 1 : 0;
5014
5015         ret = rte_eth_dev_flow_ctrl_set(res->port_id, &fc_conf);
5016         if (ret != 0)
5017                 printf("bad flow contrl parameter, return code = %d \n", ret);
5018 }
5019
5020 /* *** SETUP ETHERNET PIRORITY FLOW CONTROL *** */
5021 struct cmd_priority_flow_ctrl_set_result {
5022         cmdline_fixed_string_t set;
5023         cmdline_fixed_string_t pfc_ctrl;
5024         cmdline_fixed_string_t rx;
5025         cmdline_fixed_string_t rx_pfc_mode;
5026         cmdline_fixed_string_t tx;
5027         cmdline_fixed_string_t tx_pfc_mode;
5028         uint32_t high_water;
5029         uint32_t low_water;
5030         uint16_t pause_time;
5031         uint8_t  priority;
5032         uint8_t  port_id;
5033 };
5034
5035 static void
5036 cmd_priority_flow_ctrl_set_parsed(void *parsed_result,
5037                        __attribute__((unused)) struct cmdline *cl,
5038                        __attribute__((unused)) void *data)
5039 {
5040         struct cmd_priority_flow_ctrl_set_result *res = parsed_result;
5041         struct rte_eth_pfc_conf pfc_conf;
5042         int rx_fc_enable, tx_fc_enable;
5043         int ret;
5044
5045         /*
5046          * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
5047          * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
5048          * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
5049          * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
5050          */
5051         static enum rte_eth_fc_mode rx_tx_onoff_2_pfc_mode[2][2] = {
5052                         {RTE_FC_NONE, RTE_FC_RX_PAUSE}, {RTE_FC_TX_PAUSE, RTE_FC_FULL}
5053         };
5054
5055         rx_fc_enable = (!strncmp(res->rx_pfc_mode, "on",2)) ? 1 : 0;
5056         tx_fc_enable = (!strncmp(res->tx_pfc_mode, "on",2)) ? 1 : 0;
5057         pfc_conf.fc.mode       = rx_tx_onoff_2_pfc_mode[rx_fc_enable][tx_fc_enable];
5058         pfc_conf.fc.high_water = res->high_water;
5059         pfc_conf.fc.low_water  = res->low_water;
5060         pfc_conf.fc.pause_time = res->pause_time;
5061         pfc_conf.priority      = res->priority;
5062
5063         ret = rte_eth_dev_priority_flow_ctrl_set(res->port_id, &pfc_conf);
5064         if (ret != 0)
5065                 printf("bad priority flow contrl parameter, return code = %d \n", ret);
5066 }
5067
5068 cmdline_parse_token_string_t cmd_pfc_set_set =
5069         TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5070                                 set, "set");
5071 cmdline_parse_token_string_t cmd_pfc_set_flow_ctrl =
5072         TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5073                                 pfc_ctrl, "pfc_ctrl");
5074 cmdline_parse_token_string_t cmd_pfc_set_rx =
5075         TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5076                                 rx, "rx");
5077 cmdline_parse_token_string_t cmd_pfc_set_rx_mode =
5078         TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5079                                 rx_pfc_mode, "on#off");
5080 cmdline_parse_token_string_t cmd_pfc_set_tx =
5081         TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5082                                 tx, "tx");
5083 cmdline_parse_token_string_t cmd_pfc_set_tx_mode =
5084         TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5085                                 tx_pfc_mode, "on#off");
5086 cmdline_parse_token_num_t cmd_pfc_set_high_water =
5087         TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5088                                 high_water, UINT32);
5089 cmdline_parse_token_num_t cmd_pfc_set_low_water =
5090         TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5091                                 low_water, UINT32);
5092 cmdline_parse_token_num_t cmd_pfc_set_pause_time =
5093         TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5094                                 pause_time, UINT16);
5095 cmdline_parse_token_num_t cmd_pfc_set_priority =
5096         TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5097                                 priority, UINT8);
5098 cmdline_parse_token_num_t cmd_pfc_set_portid =
5099         TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5100                                 port_id, UINT8);
5101
5102 cmdline_parse_inst_t cmd_priority_flow_control_set = {
5103         .f = cmd_priority_flow_ctrl_set_parsed,
5104         .data = NULL,
5105         .help_str = "Configure the Ethernet priority flow control: set pfc_ctrl rx on|off\n\
5106                         tx on|off high_water low_water pause_time priority port_id",
5107         .tokens = {
5108                 (void *)&cmd_pfc_set_set,
5109                 (void *)&cmd_pfc_set_flow_ctrl,
5110                 (void *)&cmd_pfc_set_rx,
5111                 (void *)&cmd_pfc_set_rx_mode,
5112                 (void *)&cmd_pfc_set_tx,
5113                 (void *)&cmd_pfc_set_tx_mode,
5114                 (void *)&cmd_pfc_set_high_water,
5115                 (void *)&cmd_pfc_set_low_water,
5116                 (void *)&cmd_pfc_set_pause_time,
5117                 (void *)&cmd_pfc_set_priority,
5118                 (void *)&cmd_pfc_set_portid,
5119                 NULL,
5120         },
5121 };
5122
5123 /* *** RESET CONFIGURATION *** */
5124 struct cmd_reset_result {
5125         cmdline_fixed_string_t reset;
5126         cmdline_fixed_string_t def;
5127 };
5128
5129 static void cmd_reset_parsed(__attribute__((unused)) void *parsed_result,
5130                              struct cmdline *cl,
5131                              __attribute__((unused)) void *data)
5132 {
5133         cmdline_printf(cl, "Reset to default forwarding configuration...\n");
5134         set_def_fwd_config();
5135 }
5136
5137 cmdline_parse_token_string_t cmd_reset_set =
5138         TOKEN_STRING_INITIALIZER(struct cmd_reset_result, reset, "set");
5139 cmdline_parse_token_string_t cmd_reset_def =
5140         TOKEN_STRING_INITIALIZER(struct cmd_reset_result, def,
5141                                  "default");
5142
5143 cmdline_parse_inst_t cmd_reset = {
5144         .f = cmd_reset_parsed,
5145         .data = NULL,
5146         .help_str = "set default: reset default forwarding configuration",
5147         .tokens = {
5148                 (void *)&cmd_reset_set,
5149                 (void *)&cmd_reset_def,
5150                 NULL,
5151         },
5152 };
5153
5154 /* *** START FORWARDING *** */
5155 struct cmd_start_result {
5156         cmdline_fixed_string_t start;
5157 };
5158
5159 cmdline_parse_token_string_t cmd_start_start =
5160         TOKEN_STRING_INITIALIZER(struct cmd_start_result, start, "start");
5161
5162 static void cmd_start_parsed(__attribute__((unused)) void *parsed_result,
5163                              __attribute__((unused)) struct cmdline *cl,
5164                              __attribute__((unused)) void *data)
5165 {
5166         start_packet_forwarding(0);
5167 }
5168
5169 cmdline_parse_inst_t cmd_start = {
5170         .f = cmd_start_parsed,
5171         .data = NULL,
5172         .help_str = "start packet forwarding",
5173         .tokens = {
5174                 (void *)&cmd_start_start,
5175                 NULL,
5176         },
5177 };
5178
5179 /* *** START FORWARDING WITH ONE TX BURST FIRST *** */
5180 struct cmd_start_tx_first_result {
5181         cmdline_fixed_string_t start;
5182         cmdline_fixed_string_t tx_first;
5183 };
5184
5185 static void
5186 cmd_start_tx_first_parsed(__attribute__((unused)) void *parsed_result,
5187                           __attribute__((unused)) struct cmdline *cl,
5188                           __attribute__((unused)) void *data)
5189 {
5190         start_packet_forwarding(1);
5191 }
5192
5193 cmdline_parse_token_string_t cmd_start_tx_first_start =
5194         TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result, start,
5195                                  "start");
5196 cmdline_parse_token_string_t cmd_start_tx_first_tx_first =
5197         TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result,
5198                                  tx_first, "tx_first");
5199
5200 cmdline_parse_inst_t cmd_start_tx_first = {
5201         .f = cmd_start_tx_first_parsed,
5202         .data = NULL,
5203         .help_str = "start packet forwarding, after sending 1 burst of packets",
5204         .tokens = {
5205                 (void *)&cmd_start_tx_first_start,
5206                 (void *)&cmd_start_tx_first_tx_first,
5207                 NULL,
5208         },
5209 };
5210
5211 /* *** SET LINK UP *** */
5212 struct cmd_set_link_up_result {
5213         cmdline_fixed_string_t set;
5214         cmdline_fixed_string_t link_up;
5215         cmdline_fixed_string_t port;
5216         uint8_t port_id;
5217 };
5218
5219 cmdline_parse_token_string_t cmd_set_link_up_set =
5220         TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, set, "set");
5221 cmdline_parse_token_string_t cmd_set_link_up_link_up =
5222         TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, link_up,
5223                                 "link-up");
5224 cmdline_parse_token_string_t cmd_set_link_up_port =
5225         TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, port, "port");
5226 cmdline_parse_token_num_t cmd_set_link_up_port_id =
5227         TOKEN_NUM_INITIALIZER(struct cmd_set_link_up_result, port_id, UINT8);
5228
5229 static void cmd_set_link_up_parsed(__attribute__((unused)) void *parsed_result,
5230                              __attribute__((unused)) struct cmdline *cl,
5231                              __attribute__((unused)) void *data)
5232 {
5233         struct cmd_set_link_up_result *res = parsed_result;
5234         dev_set_link_up(res->port_id);
5235 }
5236
5237 cmdline_parse_inst_t cmd_set_link_up = {
5238         .f = cmd_set_link_up_parsed,
5239         .data = NULL,
5240         .help_str = "set link-up port (port id)",
5241         .tokens = {
5242                 (void *)&cmd_set_link_up_set,
5243                 (void *)&cmd_set_link_up_link_up,
5244                 (void *)&cmd_set_link_up_port,
5245                 (void *)&cmd_set_link_up_port_id,
5246                 NULL,
5247         },
5248 };
5249
5250 /* *** SET LINK DOWN *** */
5251 struct cmd_set_link_down_result {
5252         cmdline_fixed_string_t set;
5253         cmdline_fixed_string_t link_down;
5254         cmdline_fixed_string_t port;
5255         uint8_t port_id;
5256 };
5257
5258 cmdline_parse_token_string_t cmd_set_link_down_set =
5259         TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, set, "set");
5260 cmdline_parse_token_string_t cmd_set_link_down_link_down =
5261         TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, link_down,
5262                                 "link-down");
5263 cmdline_parse_token_string_t cmd_set_link_down_port =
5264         TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, port, "port");
5265 cmdline_parse_token_num_t cmd_set_link_down_port_id =
5266         TOKEN_NUM_INITIALIZER(struct cmd_set_link_down_result, port_id, UINT8);
5267
5268 static void cmd_set_link_down_parsed(
5269                                 __attribute__((unused)) void *parsed_result,
5270                                 __attribute__((unused)) struct cmdline *cl,
5271                                 __attribute__((unused)) void *data)
5272 {
5273         struct cmd_set_link_down_result *res = parsed_result;
5274         dev_set_link_down(res->port_id);
5275 }
5276
5277 cmdline_parse_inst_t cmd_set_link_down = {
5278         .f = cmd_set_link_down_parsed,
5279         .data = NULL,
5280         .help_str = "set link-down port (port id)",
5281         .tokens = {
5282                 (void *)&cmd_set_link_down_set,
5283                 (void *)&cmd_set_link_down_link_down,
5284                 (void *)&cmd_set_link_down_port,
5285                 (void *)&cmd_set_link_down_port_id,
5286                 NULL,
5287         },
5288 };
5289
5290 /* *** SHOW CFG *** */
5291 struct cmd_showcfg_result {
5292         cmdline_fixed_string_t show;
5293         cmdline_fixed_string_t cfg;
5294         cmdline_fixed_string_t what;
5295 };
5296
5297 static void cmd_showcfg_parsed(void *parsed_result,
5298                                __attribute__((unused)) struct cmdline *cl,
5299                                __attribute__((unused)) void *data)
5300 {
5301         struct cmd_showcfg_result *res = parsed_result;
5302         if (!strcmp(res->what, "rxtx"))
5303                 rxtx_config_display();
5304         else if (!strcmp(res->what, "cores"))
5305                 fwd_lcores_config_display();
5306         else if (!strcmp(res->what, "fwd"))
5307                 fwd_config_display();
5308         else if (!strcmp(res->what, "txpkts"))
5309                 show_tx_pkt_segments();
5310 }
5311
5312 cmdline_parse_token_string_t cmd_showcfg_show =
5313         TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, show, "show");
5314 cmdline_parse_token_string_t cmd_showcfg_port =
5315         TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
5316 cmdline_parse_token_string_t cmd_showcfg_what =
5317         TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
5318                                  "rxtx#cores#fwd#txpkts");
5319
5320 cmdline_parse_inst_t cmd_showcfg = {
5321         .f = cmd_showcfg_parsed,
5322         .data = NULL,
5323         .help_str = "show config rxtx|cores|fwd|txpkts",
5324         .tokens = {
5325                 (void *)&cmd_showcfg_show,
5326                 (void *)&cmd_showcfg_port,
5327                 (void *)&cmd_showcfg_what,
5328                 NULL,
5329         },
5330 };
5331
5332 /* *** SHOW ALL PORT INFO *** */
5333 struct cmd_showportall_result {
5334         cmdline_fixed_string_t show;
5335         cmdline_fixed_string_t port;
5336         cmdline_fixed_string_t what;
5337         cmdline_fixed_string_t all;
5338 };
5339
5340 static void cmd_showportall_parsed(void *parsed_result,
5341                                 __attribute__((unused)) struct cmdline *cl,
5342                                 __attribute__((unused)) void *data)
5343 {
5344         portid_t i;
5345
5346         struct cmd_showportall_result *res = parsed_result;
5347         if (!strcmp(res->show, "clear")) {
5348                 if (!strcmp(res->what, "stats"))
5349                         FOREACH_PORT(i, ports)
5350                                 nic_stats_clear(i);
5351                 else if (!strcmp(res->what, "xstats"))
5352                         FOREACH_PORT(i, ports)
5353                                 nic_xstats_clear(i);
5354         } else if (!strcmp(res->what, "info"))
5355                 FOREACH_PORT(i, ports)
5356                         port_infos_display(i);
5357         else if (!strcmp(res->what, "stats"))
5358                 FOREACH_PORT(i, ports)
5359                         nic_stats_display(i);
5360         else if (!strcmp(res->what, "xstats"))
5361                 FOREACH_PORT(i, ports)
5362                         nic_xstats_display(i);
5363         else if (!strcmp(res->what, "fdir"))
5364                 FOREACH_PORT(i, ports)
5365                         fdir_get_infos(i);
5366         else if (!strcmp(res->what, "stat_qmap"))
5367                 FOREACH_PORT(i, ports)
5368                         nic_stats_mapping_display(i);
5369         else if (!strcmp(res->what, "dcb_tc"))
5370                 FOREACH_PORT(i, ports)
5371                         port_dcb_info_display(i);
5372 }
5373
5374 cmdline_parse_token_string_t cmd_showportall_show =
5375         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, show,
5376                                  "show#clear");
5377 cmdline_parse_token_string_t cmd_showportall_port =
5378         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
5379 cmdline_parse_token_string_t cmd_showportall_what =
5380         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
5381                                  "info#stats#xstats#fdir#stat_qmap#dcb_tc");
5382 cmdline_parse_token_string_t cmd_showportall_all =
5383         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
5384 cmdline_parse_inst_t cmd_showportall = {
5385         .f = cmd_showportall_parsed,
5386         .data = NULL,
5387         .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all",
5388         .tokens = {
5389                 (void *)&cmd_showportall_show,
5390                 (void *)&cmd_showportall_port,
5391                 (void *)&cmd_showportall_what,
5392                 (void *)&cmd_showportall_all,
5393                 NULL,
5394         },
5395 };
5396
5397 /* *** SHOW PORT INFO *** */
5398 struct cmd_showport_result {
5399         cmdline_fixed_string_t show;
5400         cmdline_fixed_string_t port;
5401         cmdline_fixed_string_t what;
5402         uint8_t portnum;
5403 };
5404
5405 static void cmd_showport_parsed(void *parsed_result,
5406                                 __attribute__((unused)) struct cmdline *cl,
5407                                 __attribute__((unused)) void *data)
5408 {
5409         struct cmd_showport_result *res = parsed_result;
5410         if (!strcmp(res->show, "clear")) {
5411                 if (!strcmp(res->what, "stats"))
5412                         nic_stats_clear(res->portnum);
5413                 else if (!strcmp(res->what, "xstats"))
5414                         nic_xstats_clear(res->portnum);
5415         } else if (!strcmp(res->what, "info"))
5416                 port_infos_display(res->portnum);
5417         else if (!strcmp(res->what, "stats"))
5418                 nic_stats_display(res->portnum);
5419         else if (!strcmp(res->what, "xstats"))
5420                 nic_xstats_display(res->portnum);
5421         else if (!strcmp(res->what, "fdir"))
5422                  fdir_get_infos(res->portnum);
5423         else if (!strcmp(res->what, "stat_qmap"))
5424                 nic_stats_mapping_display(res->portnum);
5425         else if (!strcmp(res->what, "dcb_tc"))
5426                 port_dcb_info_display(res->portnum);
5427 }
5428
5429 cmdline_parse_token_string_t cmd_showport_show =
5430         TOKEN_STRING_INITIALIZER(struct cmd_showport_result, show,
5431                                  "show#clear");
5432 cmdline_parse_token_string_t cmd_showport_port =
5433         TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
5434 cmdline_parse_token_string_t cmd_showport_what =
5435         TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
5436                                  "info#stats#xstats#fdir#stat_qmap#dcb_tc");
5437 cmdline_parse_token_num_t cmd_showport_portnum =
5438         TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, UINT8);
5439
5440 cmdline_parse_inst_t cmd_showport = {
5441         .f = cmd_showport_parsed,
5442         .data = NULL,
5443         .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc X (X = port number)",
5444         .tokens = {
5445                 (void *)&cmd_showport_show,
5446                 (void *)&cmd_showport_port,
5447                 (void *)&cmd_showport_what,
5448                 (void *)&cmd_showport_portnum,
5449                 NULL,
5450         },
5451 };
5452
5453 /* *** SHOW QUEUE INFO *** */
5454 struct cmd_showqueue_result {
5455         cmdline_fixed_string_t show;
5456         cmdline_fixed_string_t type;
5457         cmdline_fixed_string_t what;
5458         uint8_t portnum;
5459         uint16_t queuenum;
5460 };
5461
5462 static void
5463 cmd_showqueue_parsed(void *parsed_result,
5464         __attribute__((unused)) struct cmdline *cl,
5465         __attribute__((unused)) void *data)
5466 {
5467         struct cmd_showqueue_result *res = parsed_result;
5468
5469         if (!strcmp(res->type, "rxq"))
5470                 rx_queue_infos_display(res->portnum, res->queuenum);
5471         else if (!strcmp(res->type, "txq"))
5472                 tx_queue_infos_display(res->portnum, res->queuenum);
5473 }
5474
5475 cmdline_parse_token_string_t cmd_showqueue_show =
5476         TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, show, "show");
5477 cmdline_parse_token_string_t cmd_showqueue_type =
5478         TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, type, "rxq#txq");
5479 cmdline_parse_token_string_t cmd_showqueue_what =
5480         TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, what, "info");
5481 cmdline_parse_token_num_t cmd_showqueue_portnum =
5482         TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, portnum, UINT8);
5483 cmdline_parse_token_num_t cmd_showqueue_queuenum =
5484         TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, queuenum, UINT16);
5485
5486 cmdline_parse_inst_t cmd_showqueue = {
5487         .f = cmd_showqueue_parsed,
5488         .data = NULL,
5489         .help_str = "show rxq|txq info <port number> <queue_number>",
5490         .tokens = {
5491                 (void *)&cmd_showqueue_show,
5492                 (void *)&cmd_showqueue_type,
5493                 (void *)&cmd_showqueue_what,
5494                 (void *)&cmd_showqueue_portnum,
5495                 (void *)&cmd_showqueue_queuenum,
5496                 NULL,
5497         },
5498 };
5499
5500 /* *** READ PORT REGISTER *** */
5501 struct cmd_read_reg_result {
5502         cmdline_fixed_string_t read;
5503         cmdline_fixed_string_t reg;
5504         uint8_t port_id;
5505         uint32_t reg_off;
5506 };
5507
5508 static void
5509 cmd_read_reg_parsed(void *parsed_result,
5510                     __attribute__((unused)) struct cmdline *cl,
5511                     __attribute__((unused)) void *data)
5512 {
5513         struct cmd_read_reg_result *res = parsed_result;
5514         port_reg_display(res->port_id, res->reg_off);
5515 }
5516
5517 cmdline_parse_token_string_t cmd_read_reg_read =
5518         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, read, "read");
5519 cmdline_parse_token_string_t cmd_read_reg_reg =
5520         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, reg, "reg");
5521 cmdline_parse_token_num_t cmd_read_reg_port_id =
5522         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, port_id, UINT8);
5523 cmdline_parse_token_num_t cmd_read_reg_reg_off =
5524         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, reg_off, UINT32);
5525
5526 cmdline_parse_inst_t cmd_read_reg = {
5527         .f = cmd_read_reg_parsed,
5528         .data = NULL,
5529         .help_str = "read reg port_id reg_off",
5530         .tokens = {
5531                 (void *)&cmd_read_reg_read,
5532                 (void *)&cmd_read_reg_reg,
5533                 (void *)&cmd_read_reg_port_id,
5534                 (void *)&cmd_read_reg_reg_off,
5535                 NULL,
5536         },
5537 };
5538
5539 /* *** READ PORT REGISTER BIT FIELD *** */
5540 struct cmd_read_reg_bit_field_result {
5541         cmdline_fixed_string_t read;
5542         cmdline_fixed_string_t regfield;
5543         uint8_t port_id;
5544         uint32_t reg_off;
5545         uint8_t bit1_pos;
5546         uint8_t bit2_pos;
5547 };
5548
5549 static void
5550 cmd_read_reg_bit_field_parsed(void *parsed_result,
5551                               __attribute__((unused)) struct cmdline *cl,
5552                               __attribute__((unused)) void *data)
5553 {
5554         struct cmd_read_reg_bit_field_result *res = parsed_result;
5555         port_reg_bit_field_display(res->port_id, res->reg_off,
5556                                    res->bit1_pos, res->bit2_pos);
5557 }
5558
5559 cmdline_parse_token_string_t cmd_read_reg_bit_field_read =
5560         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result, read,
5561                                  "read");
5562 cmdline_parse_token_string_t cmd_read_reg_bit_field_regfield =
5563         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result,
5564                                  regfield, "regfield");
5565 cmdline_parse_token_num_t cmd_read_reg_bit_field_port_id =
5566         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, port_id,
5567                               UINT8);
5568 cmdline_parse_token_num_t cmd_read_reg_bit_field_reg_off =
5569         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, reg_off,
5570                               UINT32);
5571 cmdline_parse_token_num_t cmd_read_reg_bit_field_bit1_pos =
5572         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit1_pos,
5573                               UINT8);
5574 cmdline_parse_token_num_t cmd_read_reg_bit_field_bit2_pos =
5575         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit2_pos,
5576                               UINT8);
5577
5578 cmdline_parse_inst_t cmd_read_reg_bit_field = {
5579         .f = cmd_read_reg_bit_field_parsed,
5580         .data = NULL,
5581         .help_str = "read regfield port_id reg_off bit_x bit_y "
5582         "(read register bit field between bit_x and bit_y included)",
5583         .tokens = {
5584                 (void *)&cmd_read_reg_bit_field_read,
5585                 (void *)&cmd_read_reg_bit_field_regfield,
5586                 (void *)&cmd_read_reg_bit_field_port_id,
5587                 (void *)&cmd_read_reg_bit_field_reg_off,
5588                 (void *)&cmd_read_reg_bit_field_bit1_pos,
5589                 (void *)&cmd_read_reg_bit_field_bit2_pos,
5590                 NULL,
5591         },
5592 };
5593
5594 /* *** READ PORT REGISTER BIT *** */
5595 struct cmd_read_reg_bit_result {
5596         cmdline_fixed_string_t read;
5597         cmdline_fixed_string_t regbit;
5598         uint8_t port_id;
5599         uint32_t reg_off;
5600         uint8_t bit_pos;
5601 };
5602
5603 static void
5604 cmd_read_reg_bit_parsed(void *parsed_result,
5605                         __attribute__((unused)) struct cmdline *cl,
5606                         __attribute__((unused)) void *data)
5607 {
5608         struct cmd_read_reg_bit_result *res = parsed_result;
5609         port_reg_bit_display(res->port_id, res->reg_off, res->bit_pos);
5610 }
5611
5612 cmdline_parse_token_string_t cmd_read_reg_bit_read =
5613         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result, read, "read");
5614 cmdline_parse_token_string_t cmd_read_reg_bit_regbit =
5615         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result,
5616                                  regbit, "regbit");
5617 cmdline_parse_token_num_t cmd_read_reg_bit_port_id =
5618         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, port_id, UINT8);
5619 cmdline_parse_token_num_t cmd_read_reg_bit_reg_off =
5620         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, reg_off, UINT32);
5621 cmdline_parse_token_num_t cmd_read_reg_bit_bit_pos =
5622         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, bit_pos, UINT8);
5623
5624 cmdline_parse_inst_t cmd_read_reg_bit = {
5625         .f = cmd_read_reg_bit_parsed,
5626         .data = NULL,
5627         .help_str = "read regbit port_id reg_off bit_x (0 <= bit_x <= 31)",
5628         .tokens = {
5629                 (void *)&cmd_read_reg_bit_read,
5630                 (void *)&cmd_read_reg_bit_regbit,
5631                 (void *)&cmd_read_reg_bit_port_id,
5632                 (void *)&cmd_read_reg_bit_reg_off,
5633                 (void *)&cmd_read_reg_bit_bit_pos,
5634                 NULL,
5635         },
5636 };
5637
5638 /* *** WRITE PORT REGISTER *** */
5639 struct cmd_write_reg_result {
5640         cmdline_fixed_string_t write;
5641         cmdline_fixed_string_t reg;
5642         uint8_t port_id;
5643         uint32_t reg_off;
5644         uint32_t value;
5645 };
5646
5647 static void
5648 cmd_write_reg_parsed(void *parsed_result,
5649                      __attribute__((unused)) struct cmdline *cl,
5650                      __attribute__((unused)) void *data)
5651 {
5652         struct cmd_write_reg_result *res = parsed_result;
5653         port_reg_set(res->port_id, res->reg_off, res->value);
5654 }
5655
5656 cmdline_parse_token_string_t cmd_write_reg_write =
5657         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, write, "write");
5658 cmdline_parse_token_string_t cmd_write_reg_reg =
5659         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, reg, "reg");
5660 cmdline_parse_token_num_t cmd_write_reg_port_id =
5661         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, port_id, UINT8);
5662 cmdline_parse_token_num_t cmd_write_reg_reg_off =
5663         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, reg_off, UINT32);
5664 cmdline_parse_token_num_t cmd_write_reg_value =
5665         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, value, UINT32);
5666
5667 cmdline_parse_inst_t cmd_write_reg = {
5668         .f = cmd_write_reg_parsed,
5669         .data = NULL,
5670         .help_str = "write reg port_id reg_off reg_value",
5671         .tokens = {
5672                 (void *)&cmd_write_reg_write,
5673                 (void *)&cmd_write_reg_reg,
5674                 (void *)&cmd_write_reg_port_id,
5675                 (void *)&cmd_write_reg_reg_off,
5676                 (void *)&cmd_write_reg_value,
5677                 NULL,
5678         },
5679 };
5680
5681 /* *** WRITE PORT REGISTER BIT FIELD *** */
5682 struct cmd_write_reg_bit_field_result {
5683         cmdline_fixed_string_t write;
5684         cmdline_fixed_string_t regfield;
5685         uint8_t port_id;
5686         uint32_t reg_off;
5687         uint8_t bit1_pos;
5688         uint8_t bit2_pos;
5689         uint32_t value;
5690 };
5691
5692 static void
5693 cmd_write_reg_bit_field_parsed(void *parsed_result,
5694                                __attribute__((unused)) struct cmdline *cl,
5695                                __attribute__((unused)) void *data)
5696 {
5697         struct cmd_write_reg_bit_field_result *res = parsed_result;
5698         port_reg_bit_field_set(res->port_id, res->reg_off,
5699                           res->bit1_pos, res->bit2_pos, res->value);
5700 }
5701
5702 cmdline_parse_token_string_t cmd_write_reg_bit_field_write =
5703         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result, write,
5704                                  "write");
5705 cmdline_parse_token_string_t cmd_write_reg_bit_field_regfield =
5706         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result,
5707                                  regfield, "regfield");
5708 cmdline_parse_token_num_t cmd_write_reg_bit_field_port_id =
5709         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, port_id,
5710                               UINT8);
5711 cmdline_parse_token_num_t cmd_write_reg_bit_field_reg_off =
5712         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, reg_off,
5713                               UINT32);
5714 cmdline_parse_token_num_t cmd_write_reg_bit_field_bit1_pos =
5715         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit1_pos,
5716                               UINT8);
5717 cmdline_parse_token_num_t cmd_write_reg_bit_field_bit2_pos =
5718         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit2_pos,
5719                               UINT8);
5720 cmdline_parse_token_num_t cmd_write_reg_bit_field_value =
5721         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, value,
5722                               UINT32);
5723
5724 cmdline_parse_inst_t cmd_write_reg_bit_field = {
5725         .f = cmd_write_reg_bit_field_parsed,
5726         .data = NULL,
5727         .help_str = "write regfield port_id reg_off bit_x bit_y reg_value"
5728         "(set register bit field between bit_x and bit_y included)",
5729         .tokens = {
5730                 (void *)&cmd_write_reg_bit_field_write,
5731                 (void *)&cmd_write_reg_bit_field_regfield,
5732                 (void *)&cmd_write_reg_bit_field_port_id,
5733                 (void *)&cmd_write_reg_bit_field_reg_off,
5734                 (void *)&cmd_write_reg_bit_field_bit1_pos,
5735                 (void *)&cmd_write_reg_bit_field_bit2_pos,
5736                 (void *)&cmd_write_reg_bit_field_value,
5737                 NULL,
5738         },
5739 };
5740
5741 /* *** WRITE PORT REGISTER BIT *** */
5742 struct cmd_write_reg_bit_result {
5743         cmdline_fixed_string_t write;
5744         cmdline_fixed_string_t regbit;
5745         uint8_t port_id;
5746         uint32_t reg_off;
5747         uint8_t bit_pos;
5748         uint8_t value;
5749 };
5750
5751 static void
5752 cmd_write_reg_bit_parsed(void *parsed_result,
5753                          __attribute__((unused)) struct cmdline *cl,
5754                          __attribute__((unused)) void *data)
5755 {
5756         struct cmd_write_reg_bit_result *res = parsed_result;
5757         port_reg_bit_set(res->port_id, res->reg_off, res->bit_pos, res->value);
5758 }
5759
5760 cmdline_parse_token_string_t cmd_write_reg_bit_write =
5761         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result, write,
5762                                  "write");
5763 cmdline_parse_token_string_t cmd_write_reg_bit_regbit =
5764         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result,
5765                                  regbit, "regbit");
5766 cmdline_parse_token_num_t cmd_write_reg_bit_port_id =
5767         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, port_id, UINT8);
5768 cmdline_parse_token_num_t cmd_write_reg_bit_reg_off =
5769         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, reg_off, UINT32);
5770 cmdline_parse_token_num_t cmd_write_reg_bit_bit_pos =
5771         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, bit_pos, UINT8);
5772 cmdline_parse_token_num_t cmd_write_reg_bit_value =
5773         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, value, UINT8);
5774
5775 cmdline_parse_inst_t cmd_write_reg_bit = {
5776         .f = cmd_write_reg_bit_parsed,
5777         .data = NULL,
5778         .help_str = "write regbit port_id reg_off bit_x 0/1 (0 <= bit_x <= 31)",
5779         .tokens = {
5780                 (void *)&cmd_write_reg_bit_write,
5781                 (void *)&cmd_write_reg_bit_regbit,
5782                 (void *)&cmd_write_reg_bit_port_id,
5783                 (void *)&cmd_write_reg_bit_reg_off,
5784                 (void *)&cmd_write_reg_bit_bit_pos,
5785                 (void *)&cmd_write_reg_bit_value,
5786                 NULL,
5787         },
5788 };
5789
5790 /* *** READ A RING DESCRIPTOR OF A PORT RX/TX QUEUE *** */
5791 struct cmd_read_rxd_txd_result {
5792         cmdline_fixed_string_t read;
5793         cmdline_fixed_string_t rxd_txd;
5794         uint8_t port_id;
5795         uint16_t queue_id;
5796         uint16_t desc_id;
5797 };
5798
5799 static void
5800 cmd_read_rxd_txd_parsed(void *parsed_result,
5801                         __attribute__((unused)) struct cmdline *cl,
5802                         __attribute__((unused)) void *data)
5803 {
5804         struct cmd_read_rxd_txd_result *res = parsed_result;
5805
5806         if (!strcmp(res->rxd_txd, "rxd"))
5807                 rx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
5808         else if (!strcmp(res->rxd_txd, "txd"))
5809                 tx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
5810 }
5811
5812 cmdline_parse_token_string_t cmd_read_rxd_txd_read =
5813         TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, read, "read");
5814 cmdline_parse_token_string_t cmd_read_rxd_txd_rxd_txd =
5815         TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, rxd_txd,
5816                                  "rxd#txd");
5817 cmdline_parse_token_num_t cmd_read_rxd_txd_port_id =
5818         TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, port_id, UINT8);
5819 cmdline_parse_token_num_t cmd_read_rxd_txd_queue_id =
5820         TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, queue_id, UINT16);
5821 cmdline_parse_token_num_t cmd_read_rxd_txd_desc_id =
5822         TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, desc_id, UINT16);
5823
5824 cmdline_parse_inst_t cmd_read_rxd_txd = {
5825         .f = cmd_read_rxd_txd_parsed,
5826         .data = NULL,
5827         .help_str = "read rxd|txd port_id queue_id rxd_id",
5828         .tokens = {
5829                 (void *)&cmd_read_rxd_txd_read,
5830                 (void *)&cmd_read_rxd_txd_rxd_txd,
5831                 (void *)&cmd_read_rxd_txd_port_id,
5832                 (void *)&cmd_read_rxd_txd_queue_id,
5833                 (void *)&cmd_read_rxd_txd_desc_id,
5834                 NULL,
5835         },
5836 };
5837
5838 /* *** QUIT *** */
5839 struct cmd_quit_result {
5840         cmdline_fixed_string_t quit;
5841 };
5842
5843 static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
5844                             struct cmdline *cl,
5845                             __attribute__((unused)) void *data)
5846 {
5847         pmd_test_exit();
5848         cmdline_quit(cl);
5849 }
5850
5851 cmdline_parse_token_string_t cmd_quit_quit =
5852         TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
5853
5854 cmdline_parse_inst_t cmd_quit = {
5855         .f = cmd_quit_parsed,
5856         .data = NULL,
5857         .help_str = "exit application",
5858         .tokens = {
5859                 (void *)&cmd_quit_quit,
5860                 NULL,
5861         },
5862 };
5863
5864 /* *** ADD/REMOVE MAC ADDRESS FROM A PORT *** */
5865 struct cmd_mac_addr_result {
5866         cmdline_fixed_string_t mac_addr_cmd;
5867         cmdline_fixed_string_t what;
5868         uint8_t port_num;
5869         struct ether_addr address;
5870 };
5871
5872 static void cmd_mac_addr_parsed(void *parsed_result,
5873                 __attribute__((unused)) struct cmdline *cl,
5874                 __attribute__((unused)) void *data)
5875 {
5876         struct cmd_mac_addr_result *res = parsed_result;
5877         int ret;
5878
5879         if (strcmp(res->what, "add") == 0)
5880                 ret = rte_eth_dev_mac_addr_add(res->port_num, &res->address, 0);
5881         else
5882                 ret = rte_eth_dev_mac_addr_remove(res->port_num, &res->address);
5883
5884         /* check the return value and print it if is < 0 */
5885         if(ret < 0)
5886                 printf("mac_addr_cmd error: (%s)\n", strerror(-ret));
5887
5888 }
5889
5890 cmdline_parse_token_string_t cmd_mac_addr_cmd =
5891         TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, mac_addr_cmd,
5892                                 "mac_addr");
5893 cmdline_parse_token_string_t cmd_mac_addr_what =
5894         TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, what,
5895                                 "add#remove");
5896 cmdline_parse_token_num_t cmd_mac_addr_portnum =
5897                 TOKEN_NUM_INITIALIZER(struct cmd_mac_addr_result, port_num, UINT8);
5898 cmdline_parse_token_etheraddr_t cmd_mac_addr_addr =
5899                 TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
5900
5901 cmdline_parse_inst_t cmd_mac_addr = {
5902         .f = cmd_mac_addr_parsed,
5903         .data = (void *)0,
5904         .help_str = "mac_addr add|remove X <address>: "
5905                         "add/remove MAC address on port X",
5906         .tokens = {
5907                 (void *)&cmd_mac_addr_cmd,
5908                 (void *)&cmd_mac_addr_what,
5909                 (void *)&cmd_mac_addr_portnum,
5910                 (void *)&cmd_mac_addr_addr,
5911                 NULL,
5912         },
5913 };
5914
5915
5916 /* *** CONFIGURE QUEUE STATS COUNTER MAPPINGS *** */
5917 struct cmd_set_qmap_result {
5918         cmdline_fixed_string_t set;
5919         cmdline_fixed_string_t qmap;
5920         cmdline_fixed_string_t what;
5921         uint8_t port_id;
5922         uint16_t queue_id;
5923         uint8_t map_value;
5924 };
5925
5926 static void
5927 cmd_set_qmap_parsed(void *parsed_result,
5928                        __attribute__((unused)) struct cmdline *cl,
5929                        __attribute__((unused)) void *data)
5930 {
5931         struct cmd_set_qmap_result *res = parsed_result;
5932         int is_rx = (strcmp(res->what, "tx") == 0) ? 0 : 1;
5933
5934         set_qmap(res->port_id, (uint8_t)is_rx, res->queue_id, res->map_value);
5935 }
5936
5937 cmdline_parse_token_string_t cmd_setqmap_set =
5938         TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
5939                                  set, "set");
5940 cmdline_parse_token_string_t cmd_setqmap_qmap =
5941         TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
5942                                  qmap, "stat_qmap");
5943 cmdline_parse_token_string_t cmd_setqmap_what =
5944         TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
5945                                  what, "tx#rx");
5946 cmdline_parse_token_num_t cmd_setqmap_portid =
5947         TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
5948                               port_id, UINT8);
5949 cmdline_parse_token_num_t cmd_setqmap_queueid =
5950         TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
5951                               queue_id, UINT16);
5952 cmdline_parse_token_num_t cmd_setqmap_mapvalue =
5953         TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
5954                               map_value, UINT8);
5955
5956 cmdline_parse_inst_t cmd_set_qmap = {
5957         .f = cmd_set_qmap_parsed,
5958         .data = NULL,
5959         .help_str = "Set statistics mapping value on tx|rx queue_id of port_id",
5960         .tokens = {
5961                 (void *)&cmd_setqmap_set,
5962                 (void *)&cmd_setqmap_qmap,
5963                 (void *)&cmd_setqmap_what,
5964                 (void *)&cmd_setqmap_portid,
5965                 (void *)&cmd_setqmap_queueid,
5966                 (void *)&cmd_setqmap_mapvalue,
5967                 NULL,
5968         },
5969 };
5970
5971 /* *** CONFIGURE UNICAST HASH TABLE *** */
5972 struct cmd_set_uc_hash_table {
5973         cmdline_fixed_string_t set;
5974         cmdline_fixed_string_t port;
5975         uint8_t port_id;
5976         cmdline_fixed_string_t what;
5977         struct ether_addr address;
5978         cmdline_fixed_string_t mode;
5979 };
5980
5981 static void
5982 cmd_set_uc_hash_parsed(void *parsed_result,
5983                        __attribute__((unused)) struct cmdline *cl,
5984                        __attribute__((unused)) void *data)
5985 {
5986         int ret=0;
5987         struct cmd_set_uc_hash_table *res = parsed_result;
5988
5989         int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
5990
5991         if (strcmp(res->what, "uta") == 0)
5992                 ret = rte_eth_dev_uc_hash_table_set(res->port_id,
5993                                                 &res->address,(uint8_t)is_on);
5994         if (ret < 0)
5995                 printf("bad unicast hash table parameter, return code = %d \n", ret);
5996
5997 }
5998
5999 cmdline_parse_token_string_t cmd_set_uc_hash_set =
6000         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6001                                  set, "set");
6002 cmdline_parse_token_string_t cmd_set_uc_hash_port =
6003         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6004                                  port, "port");
6005 cmdline_parse_token_num_t cmd_set_uc_hash_portid =
6006         TOKEN_NUM_INITIALIZER(struct cmd_set_uc_hash_table,
6007                               port_id, UINT8);
6008 cmdline_parse_token_string_t cmd_set_uc_hash_what =
6009         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6010                                  what, "uta");
6011 cmdline_parse_token_etheraddr_t cmd_set_uc_hash_mac =
6012         TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_uc_hash_table,
6013                                 address);
6014 cmdline_parse_token_string_t cmd_set_uc_hash_mode =
6015         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6016                                  mode, "on#off");
6017
6018 cmdline_parse_inst_t cmd_set_uc_hash_filter = {
6019         .f = cmd_set_uc_hash_parsed,
6020         .data = NULL,
6021         .help_str = "set port X uta Y on|off(X = port number,Y = MAC address)",
6022         .tokens = {
6023                 (void *)&cmd_set_uc_hash_set,
6024                 (void *)&cmd_set_uc_hash_port,
6025                 (void *)&cmd_set_uc_hash_portid,
6026                 (void *)&cmd_set_uc_hash_what,
6027                 (void *)&cmd_set_uc_hash_mac,
6028                 (void *)&cmd_set_uc_hash_mode,
6029                 NULL,
6030         },
6031 };
6032
6033 struct cmd_set_uc_all_hash_table {
6034         cmdline_fixed_string_t set;
6035         cmdline_fixed_string_t port;
6036         uint8_t port_id;
6037         cmdline_fixed_string_t what;
6038         cmdline_fixed_string_t value;
6039         cmdline_fixed_string_t mode;
6040 };
6041
6042 static void
6043 cmd_set_uc_all_hash_parsed(void *parsed_result,
6044                        __attribute__((unused)) struct cmdline *cl,
6045                        __attribute__((unused)) void *data)
6046 {
6047         int ret=0;
6048         struct cmd_set_uc_all_hash_table *res = parsed_result;
6049
6050         int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
6051
6052         if ((strcmp(res->what, "uta") == 0) &&
6053                 (strcmp(res->value, "all") == 0))
6054                 ret = rte_eth_dev_uc_all_hash_table_set(res->port_id,(uint8_t) is_on);
6055         if (ret < 0)
6056                 printf("bad unicast hash table parameter,"
6057                         "return code = %d \n", ret);
6058 }
6059
6060 cmdline_parse_token_string_t cmd_set_uc_all_hash_set =
6061         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6062                                  set, "set");
6063 cmdline_parse_token_string_t cmd_set_uc_all_hash_port =
6064         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6065                                  port, "port");
6066 cmdline_parse_token_num_t cmd_set_uc_all_hash_portid =
6067         TOKEN_NUM_INITIALIZER(struct cmd_set_uc_all_hash_table,
6068                               port_id, UINT8);
6069 cmdline_parse_token_string_t cmd_set_uc_all_hash_what =
6070         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6071                                  what, "uta");
6072 cmdline_parse_token_string_t cmd_set_uc_all_hash_value =
6073         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6074                                 value,"all");
6075 cmdline_parse_token_string_t cmd_set_uc_all_hash_mode =
6076         TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6077                                  mode, "on#off");
6078
6079 cmdline_parse_inst_t cmd_set_uc_all_hash_filter = {
6080         .f = cmd_set_uc_all_hash_parsed,
6081         .data = NULL,
6082         .help_str = "set port X uta all on|off (X = port number)",
6083         .tokens = {
6084                 (void *)&cmd_set_uc_all_hash_set,
6085                 (void *)&cmd_set_uc_all_hash_port,
6086                 (void *)&cmd_set_uc_all_hash_portid,
6087                 (void *)&cmd_set_uc_all_hash_what,
6088                 (void *)&cmd_set_uc_all_hash_value,
6089                 (void *)&cmd_set_uc_all_hash_mode,
6090                 NULL,
6091         },
6092 };
6093
6094 /* *** CONFIGURE MACVLAN FILTER FOR VF(s) *** */
6095 struct cmd_set_vf_macvlan_filter {
6096         cmdline_fixed_string_t set;
6097         cmdline_fixed_string_t port;
6098         uint8_t port_id;
6099         cmdline_fixed_string_t vf;
6100         uint8_t vf_id;
6101         struct ether_addr address;
6102         cmdline_fixed_string_t filter_type;
6103         cmdline_fixed_string_t mode;
6104 };
6105
6106 static void
6107 cmd_set_vf_macvlan_parsed(void *parsed_result,
6108                        __attribute__((unused)) struct cmdline *cl,
6109                        __attribute__((unused)) void *data)
6110 {
6111         int is_on, ret = 0;
6112         struct cmd_set_vf_macvlan_filter *res = parsed_result;
6113         struct rte_eth_mac_filter filter;
6114
6115         memset(&filter, 0, sizeof(struct rte_eth_mac_filter));
6116
6117         (void)rte_memcpy(&filter.mac_addr, &res->address, ETHER_ADDR_LEN);
6118
6119         /* set VF MAC filter */
6120         filter.is_vf = 1;
6121
6122         /* set VF ID */
6123         filter.dst_id = res->vf_id;
6124
6125         if (!strcmp(res->filter_type, "exact-mac"))
6126                 filter.filter_type = RTE_MAC_PERFECT_MATCH;
6127         else if (!strcmp(res->filter_type, "exact-mac-vlan"))
6128                 filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
6129         else if (!strcmp(res->filter_type, "hashmac"))
6130                 filter.filter_type = RTE_MAC_HASH_MATCH;
6131         else if (!strcmp(res->filter_type, "hashmac-vlan"))
6132                 filter.filter_type = RTE_MACVLAN_HASH_MATCH;
6133
6134         is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
6135
6136         if (is_on)
6137                 ret = rte_eth_dev_filter_ctrl(res->port_id,
6138                                         RTE_ETH_FILTER_MACVLAN,
6139                                         RTE_ETH_FILTER_ADD,
6140                                          &filter);
6141         else
6142                 ret = rte_eth_dev_filter_ctrl(res->port_id,
6143                                         RTE_ETH_FILTER_MACVLAN,
6144                                         RTE_ETH_FILTER_DELETE,
6145                                         &filter);
6146
6147         if (ret < 0)
6148                 printf("bad set MAC hash parameter, return code = %d\n", ret);
6149
6150 }
6151
6152 cmdline_parse_token_string_t cmd_set_vf_macvlan_set =
6153         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6154                                  set, "set");
6155 cmdline_parse_token_string_t cmd_set_vf_macvlan_port =
6156         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6157                                  port, "port");
6158 cmdline_parse_token_num_t cmd_set_vf_macvlan_portid =
6159         TOKEN_NUM_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6160                               port_id, UINT8);
6161 cmdline_parse_token_string_t cmd_set_vf_macvlan_vf =
6162         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6163                                  vf, "vf");
6164 cmdline_parse_token_num_t cmd_set_vf_macvlan_vf_id =
6165         TOKEN_NUM_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6166                                 vf_id, UINT8);
6167 cmdline_parse_token_etheraddr_t cmd_set_vf_macvlan_mac =
6168         TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6169                                 address);
6170 cmdline_parse_token_string_t cmd_set_vf_macvlan_filter_type =
6171         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6172                                 filter_type, "exact-mac#exact-mac-vlan"
6173                                 "#hashmac#hashmac-vlan");
6174 cmdline_parse_token_string_t cmd_set_vf_macvlan_mode =
6175         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6176                                  mode, "on#off");
6177
6178 cmdline_parse_inst_t cmd_set_vf_macvlan_filter = {
6179         .f = cmd_set_vf_macvlan_parsed,
6180         .data = NULL,
6181         .help_str = "set port (portid) vf (vfid) (mac-addr) "
6182                         "(exact-mac|exact-mac-vlan|hashmac|hashmac-vlan) "
6183                         "on|off\n"
6184                         "exact match rule:exact match of MAC or MAC and VLAN; "
6185                         "hash match rule: hash match of MAC and exact match "
6186                         "of VLAN",
6187         .tokens = {
6188                 (void *)&cmd_set_vf_macvlan_set,
6189                 (void *)&cmd_set_vf_macvlan_port,
6190                 (void *)&cmd_set_vf_macvlan_portid,
6191                 (void *)&cmd_set_vf_macvlan_vf,
6192                 (void *)&cmd_set_vf_macvlan_vf_id,
6193                 (void *)&cmd_set_vf_macvlan_mac,
6194                 (void *)&cmd_set_vf_macvlan_filter_type,
6195                 (void *)&cmd_set_vf_macvlan_mode,
6196                 NULL,
6197         },
6198 };
6199
6200 /* *** CONFIGURE VF TRAFFIC CONTROL *** */
6201 struct cmd_set_vf_traffic {
6202         cmdline_fixed_string_t set;
6203         cmdline_fixed_string_t port;
6204         uint8_t port_id;
6205         cmdline_fixed_string_t vf;
6206         uint8_t vf_id;
6207         cmdline_fixed_string_t what;
6208         cmdline_fixed_string_t mode;
6209 };
6210
6211 static void
6212 cmd_set_vf_traffic_parsed(void *parsed_result,
6213                        __attribute__((unused)) struct cmdline *cl,
6214                        __attribute__((unused)) void *data)
6215 {
6216         struct cmd_set_vf_traffic *res = parsed_result;
6217         int is_rx = (strcmp(res->what, "rx") == 0) ? 1 : 0;
6218         int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
6219
6220         set_vf_traffic(res->port_id, (uint8_t)is_rx, res->vf_id,(uint8_t) is_on);
6221 }
6222
6223 cmdline_parse_token_string_t cmd_setvf_traffic_set =
6224         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6225                                  set, "set");
6226 cmdline_parse_token_string_t cmd_setvf_traffic_port =
6227         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6228                                  port, "port");
6229 cmdline_parse_token_num_t cmd_setvf_traffic_portid =
6230         TOKEN_NUM_INITIALIZER(struct cmd_set_vf_traffic,
6231                               port_id, UINT8);
6232 cmdline_parse_token_string_t cmd_setvf_traffic_vf =
6233         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6234                                  vf, "vf");
6235 cmdline_parse_token_num_t cmd_setvf_traffic_vfid =
6236         TOKEN_NUM_INITIALIZER(struct cmd_set_vf_traffic,
6237                               vf_id, UINT8);
6238 cmdline_parse_token_string_t cmd_setvf_traffic_what =
6239         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6240                                  what, "tx#rx");
6241 cmdline_parse_token_string_t cmd_setvf_traffic_mode =
6242         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6243                                  mode, "on#off");
6244
6245 cmdline_parse_inst_t cmd_set_vf_traffic = {
6246         .f = cmd_set_vf_traffic_parsed,
6247         .data = NULL,
6248         .help_str = "set port X vf Y rx|tx on|off"
6249                         "(X = port number,Y = vf id)",
6250         .tokens = {
6251                 (void *)&cmd_setvf_traffic_set,
6252                 (void *)&cmd_setvf_traffic_port,
6253                 (void *)&cmd_setvf_traffic_portid,
6254                 (void *)&cmd_setvf_traffic_vf,
6255                 (void *)&cmd_setvf_traffic_vfid,
6256                 (void *)&cmd_setvf_traffic_what,
6257                 (void *)&cmd_setvf_traffic_mode,
6258                 NULL,
6259         },
6260 };
6261
6262 /* *** CONFIGURE VF RECEIVE MODE *** */
6263 struct cmd_set_vf_rxmode {
6264         cmdline_fixed_string_t set;
6265         cmdline_fixed_string_t port;
6266         uint8_t port_id;
6267         cmdline_fixed_string_t vf;
6268         uint8_t vf_id;
6269         cmdline_fixed_string_t what;
6270         cmdline_fixed_string_t mode;
6271         cmdline_fixed_string_t on;
6272 };
6273
6274 static void
6275 cmd_set_vf_rxmode_parsed(void *parsed_result,
6276                        __attribute__((unused)) struct cmdline *cl,
6277                        __attribute__((unused)) void *data)
6278 {
6279         int ret;
6280         uint16_t rx_mode = 0;
6281         struct cmd_set_vf_rxmode *res = parsed_result;
6282
6283         int is_on = (strcmp(res->on, "on") == 0) ? 1 : 0;
6284         if (!strcmp(res->what,"rxmode")) {
6285                 if (!strcmp(res->mode, "AUPE"))
6286                         rx_mode |= ETH_VMDQ_ACCEPT_UNTAG;
6287                 else if (!strcmp(res->mode, "ROPE"))
6288                         rx_mode |= ETH_VMDQ_ACCEPT_HASH_UC;
6289                 else if (!strcmp(res->mode, "BAM"))
6290                         rx_mode |= ETH_VMDQ_ACCEPT_BROADCAST;
6291                 else if (!strncmp(res->mode, "MPE",3))
6292                         rx_mode |= ETH_VMDQ_ACCEPT_MULTICAST;
6293         }
6294
6295         ret = rte_eth_dev_set_vf_rxmode(res->port_id,res->vf_id,rx_mode,(uint8_t)is_on);
6296         if (ret < 0)
6297                 printf("bad VF receive mode parameter, return code = %d \n",
6298                 ret);
6299 }
6300
6301 cmdline_parse_token_string_t cmd_set_vf_rxmode_set =
6302         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6303                                  set, "set");
6304 cmdline_parse_token_string_t cmd_set_vf_rxmode_port =
6305         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6306                                  port, "port");
6307 cmdline_parse_token_num_t cmd_set_vf_rxmode_portid =
6308         TOKEN_NUM_INITIALIZER(struct cmd_set_vf_rxmode,
6309                               port_id, UINT8);
6310 cmdline_parse_token_string_t cmd_set_vf_rxmode_vf =
6311         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6312                                  vf, "vf");
6313 cmdline_parse_token_num_t cmd_set_vf_rxmode_vfid =
6314         TOKEN_NUM_INITIALIZER(struct cmd_set_vf_rxmode,
6315                               vf_id, UINT8);
6316 cmdline_parse_token_string_t cmd_set_vf_rxmode_what =
6317         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6318                                  what, "rxmode");
6319 cmdline_parse_token_string_t cmd_set_vf_rxmode_mode =
6320         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6321                                  mode, "AUPE#ROPE#BAM#MPE");
6322 cmdline_parse_token_string_t cmd_set_vf_rxmode_on =
6323         TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6324                                  on, "on#off");
6325
6326 cmdline_parse_inst_t cmd_set_vf_rxmode = {
6327         .f = cmd_set_vf_rxmode_parsed,
6328         .data = NULL,
6329         .help_str = "set port X vf Y rxmode AUPE|ROPE|BAM|MPE on|off",
6330         .tokens = {
6331                 (void *)&cmd_set_vf_rxmode_set,
6332                 (void *)&cmd_set_vf_rxmode_port,
6333                 (void *)&cmd_set_vf_rxmode_portid,
6334                 (void *)&cmd_set_vf_rxmode_vf,
6335                 (void *)&cmd_set_vf_rxmode_vfid,
6336                 (void *)&cmd_set_vf_rxmode_what,
6337                 (void *)&cmd_set_vf_rxmode_mode,
6338                 (void *)&cmd_set_vf_rxmode_on,
6339                 NULL,
6340         },
6341 };
6342
6343 /* *** ADD MAC ADDRESS FILTER FOR A VF OF A PORT *** */
6344 struct cmd_vf_mac_addr_result {
6345         cmdline_fixed_string_t mac_addr_cmd;
6346         cmdline_fixed_string_t what;
6347         cmdline_fixed_string_t port;
6348         uint8_t port_num;
6349         cmdline_fixed_string_t vf;
6350         uint8_t vf_num;
6351         struct ether_addr address;
6352 };
6353
6354 static void cmd_vf_mac_addr_parsed(void *parsed_result,
6355                 __attribute__((unused)) struct cmdline *cl,
6356                 __attribute__((unused)) void *data)
6357 {
6358         struct cmd_vf_mac_addr_result *res = parsed_result;
6359         int ret = 0;
6360
6361         if (strcmp(res->what, "add") == 0)
6362                 ret = rte_eth_dev_mac_addr_add(res->port_num,
6363                                         &res->address, res->vf_num);
6364         if(ret < 0)
6365                 printf("vf_mac_addr_cmd error: (%s)\n", strerror(-ret));
6366
6367 }
6368
6369 cmdline_parse_token_string_t cmd_vf_mac_addr_cmd =
6370         TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6371                                 mac_addr_cmd,"mac_addr");
6372 cmdline_parse_token_string_t cmd_vf_mac_addr_what =
6373         TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6374                                 what,"add");
6375 cmdline_parse_token_string_t cmd_vf_mac_addr_port =
6376         TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6377                                 port,"port");
6378 cmdline_parse_token_num_t cmd_vf_mac_addr_portnum =
6379         TOKEN_NUM_INITIALIZER(struct cmd_vf_mac_addr_result,
6380                                 port_num, UINT8);
6381 cmdline_parse_token_string_t cmd_vf_mac_addr_vf =
6382         TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6383                                 vf,"vf");
6384 cmdline_parse_token_num_t cmd_vf_mac_addr_vfnum =
6385         TOKEN_NUM_INITIALIZER(struct cmd_vf_mac_addr_result,
6386                                 vf_num, UINT8);
6387 cmdline_parse_token_etheraddr_t cmd_vf_mac_addr_addr =
6388         TOKEN_ETHERADDR_INITIALIZER(struct cmd_vf_mac_addr_result,
6389                                 address);
6390
6391 cmdline_parse_inst_t cmd_vf_mac_addr_filter = {
6392         .f = cmd_vf_mac_addr_parsed,
6393         .data = (void *)0,
6394         .help_str = "mac_addr add port X vf Y ethaddr:(X = port number,"
6395         "Y = VF number)add MAC address filtering for a VF on port X",
6396         .tokens = {
6397                 (void *)&cmd_vf_mac_addr_cmd,
6398                 (void *)&cmd_vf_mac_addr_what,
6399                 (void *)&cmd_vf_mac_addr_port,
6400                 (void *)&cmd_vf_mac_addr_portnum,
6401                 (void *)&cmd_vf_mac_addr_vf,
6402                 (void *)&cmd_vf_mac_addr_vfnum,
6403                 (void *)&cmd_vf_mac_addr_addr,
6404                 NULL,
6405         },
6406 };
6407
6408 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
6409 struct cmd_vf_rx_vlan_filter {
6410         cmdline_fixed_string_t rx_vlan;
6411         cmdline_fixed_string_t what;
6412         uint16_t vlan_id;
6413         cmdline_fixed_string_t port;
6414         uint8_t port_id;
6415         cmdline_fixed_string_t vf;
6416         uint64_t vf_mask;
6417 };
6418
6419 static void
6420 cmd_vf_rx_vlan_filter_parsed(void *parsed_result,
6421                           __attribute__((unused)) struct cmdline *cl,
6422                           __attribute__((unused)) void *data)
6423 {
6424         struct cmd_vf_rx_vlan_filter *res = parsed_result;
6425
6426         if (!strcmp(res->what, "add"))
6427                 set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 1);
6428         else
6429                 set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 0);
6430 }
6431
6432 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_rx_vlan =
6433         TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6434                                  rx_vlan, "rx_vlan");
6435 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_what =
6436         TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6437                                  what, "add#rm");
6438 cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_vlanid =
6439         TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6440                               vlan_id, UINT16);
6441 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_port =
6442         TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6443                                  port, "port");
6444 cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_portid =
6445         TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6446                               port_id, UINT8);
6447 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_vf =
6448         TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6449                                  vf, "vf");
6450 cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_vf_mask =
6451         TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6452                               vf_mask, UINT64);
6453
6454 cmdline_parse_inst_t cmd_vf_rxvlan_filter = {
6455         .f = cmd_vf_rx_vlan_filter_parsed,
6456         .data = NULL,
6457         .help_str = "rx_vlan add|rm X port Y vf Z (X = VLAN ID,"
6458                 "Y = port number,Z = hexadecimal VF mask)",
6459         .tokens = {
6460                 (void *)&cmd_vf_rx_vlan_filter_rx_vlan,
6461                 (void *)&cmd_vf_rx_vlan_filter_what,
6462                 (void *)&cmd_vf_rx_vlan_filter_vlanid,
6463                 (void *)&cmd_vf_rx_vlan_filter_port,
6464                 (void *)&cmd_vf_rx_vlan_filter_portid,
6465                 (void *)&cmd_vf_rx_vlan_filter_vf,
6466                 (void *)&cmd_vf_rx_vlan_filter_vf_mask,
6467                 NULL,
6468         },
6469 };
6470
6471 /* *** SET RATE LIMIT FOR A QUEUE OF A PORT *** */
6472 struct cmd_queue_rate_limit_result {
6473         cmdline_fixed_string_t set;
6474         cmdline_fixed_string_t port;
6475         uint8_t port_num;
6476         cmdline_fixed_string_t queue;
6477         uint8_t queue_num;
6478         cmdline_fixed_string_t rate;
6479         uint16_t rate_num;
6480 };
6481
6482 static void cmd_queue_rate_limit_parsed(void *parsed_result,
6483                 __attribute__((unused)) struct cmdline *cl,
6484                 __attribute__((unused)) void *data)
6485 {
6486         struct cmd_queue_rate_limit_result *res = parsed_result;
6487         int ret = 0;
6488
6489         if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0)
6490                 && (strcmp(res->queue, "queue") == 0)
6491                 && (strcmp(res->rate, "rate") == 0))
6492                 ret = set_queue_rate_limit(res->port_num, res->queue_num,
6493                                         res->rate_num);
6494         if (ret < 0)
6495                 printf("queue_rate_limit_cmd error: (%s)\n", strerror(-ret));
6496
6497 }
6498
6499 cmdline_parse_token_string_t cmd_queue_rate_limit_set =
6500         TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6501                                 set, "set");
6502 cmdline_parse_token_string_t cmd_queue_rate_limit_port =
6503         TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6504                                 port, "port");
6505 cmdline_parse_token_num_t cmd_queue_rate_limit_portnum =
6506         TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
6507                                 port_num, UINT8);
6508 cmdline_parse_token_string_t cmd_queue_rate_limit_queue =
6509         TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6510                                 queue, "queue");
6511 cmdline_parse_token_num_t cmd_queue_rate_limit_queuenum =
6512         TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
6513                                 queue_num, UINT8);
6514 cmdline_parse_token_string_t cmd_queue_rate_limit_rate =
6515         TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6516                                 rate, "rate");
6517 cmdline_parse_token_num_t cmd_queue_rate_limit_ratenum =
6518         TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
6519                                 rate_num, UINT16);
6520
6521 cmdline_parse_inst_t cmd_queue_rate_limit = {
6522         .f = cmd_queue_rate_limit_parsed,
6523         .data = (void *)0,
6524         .help_str = "set port X queue Y rate Z:(X = port number,"
6525         "Y = queue number,Z = rate number)set rate limit for a queue on port X",
6526         .tokens = {
6527                 (void *)&cmd_queue_rate_limit_set,
6528                 (void *)&cmd_queue_rate_limit_port,
6529                 (void *)&cmd_queue_rate_limit_portnum,
6530                 (void *)&cmd_queue_rate_limit_queue,
6531                 (void *)&cmd_queue_rate_limit_queuenum,
6532                 (void *)&cmd_queue_rate_limit_rate,
6533                 (void *)&cmd_queue_rate_limit_ratenum,
6534                 NULL,
6535         },
6536 };
6537
6538 /* *** SET RATE LIMIT FOR A VF OF A PORT *** */
6539 struct cmd_vf_rate_limit_result {
6540         cmdline_fixed_string_t set;
6541         cmdline_fixed_string_t port;
6542         uint8_t port_num;
6543         cmdline_fixed_string_t vf;
6544         uint8_t vf_num;
6545         cmdline_fixed_string_t rate;
6546         uint16_t rate_num;
6547         cmdline_fixed_string_t q_msk;
6548         uint64_t q_msk_val;
6549 };
6550
6551 static void cmd_vf_rate_limit_parsed(void *parsed_result,
6552                 __attribute__((unused)) struct cmdline *cl,
6553                 __attribute__((unused)) void *data)
6554 {
6555         struct cmd_vf_rate_limit_result *res = parsed_result;
6556         int ret = 0;
6557
6558         if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0)
6559                 && (strcmp(res->vf, "vf") == 0)
6560                 && (strcmp(res->rate, "rate") == 0)
6561                 && (strcmp(res->q_msk, "queue_mask") == 0))
6562                 ret = set_vf_rate_limit(res->port_num, res->vf_num,
6563                                         res->rate_num, res->q_msk_val);
6564         if (ret < 0)
6565                 printf("vf_rate_limit_cmd error: (%s)\n", strerror(-ret));
6566
6567 }
6568
6569 cmdline_parse_token_string_t cmd_vf_rate_limit_set =
6570         TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6571                                 set, "set");
6572 cmdline_parse_token_string_t cmd_vf_rate_limit_port =
6573         TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6574                                 port, "port");
6575 cmdline_parse_token_num_t cmd_vf_rate_limit_portnum =
6576         TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
6577                                 port_num, UINT8);
6578 cmdline_parse_token_string_t cmd_vf_rate_limit_vf =
6579         TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6580                                 vf, "vf");
6581 cmdline_parse_token_num_t cmd_vf_rate_limit_vfnum =
6582         TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
6583                                 vf_num, UINT8);
6584 cmdline_parse_token_string_t cmd_vf_rate_limit_rate =
6585         TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6586                                 rate, "rate");
6587 cmdline_parse_token_num_t cmd_vf_rate_limit_ratenum =
6588         TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
6589                                 rate_num, UINT16);
6590 cmdline_parse_token_string_t cmd_vf_rate_limit_q_msk =
6591         TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6592                                 q_msk, "queue_mask");
6593 cmdline_parse_token_num_t cmd_vf_rate_limit_q_msk_val =
6594         TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
6595                                 q_msk_val, UINT64);
6596
6597 cmdline_parse_inst_t cmd_vf_rate_limit = {
6598         .f = cmd_vf_rate_limit_parsed,
6599         .data = (void *)0,
6600         .help_str = "set port X vf Y rate Z queue_mask V:(X = port number,"
6601         "Y = VF number,Z = rate number, V = queue mask value)set rate limit "
6602         "for queues of VF on port X",
6603         .tokens = {
6604                 (void *)&cmd_vf_rate_limit_set,
6605                 (void *)&cmd_vf_rate_limit_port,
6606                 (void *)&cmd_vf_rate_limit_portnum,
6607                 (void *)&cmd_vf_rate_limit_vf,
6608                 (void *)&cmd_vf_rate_limit_vfnum,
6609                 (void *)&cmd_vf_rate_limit_rate,
6610                 (void *)&cmd_vf_rate_limit_ratenum,
6611                 (void *)&cmd_vf_rate_limit_q_msk,
6612                 (void *)&cmd_vf_rate_limit_q_msk_val,
6613                 NULL,
6614         },
6615 };
6616
6617 /* *** ADD TUNNEL FILTER OF A PORT *** */
6618 struct cmd_tunnel_filter_result {
6619         cmdline_fixed_string_t cmd;
6620         cmdline_fixed_string_t what;
6621         uint8_t port_id;
6622         struct ether_addr outer_mac;
6623         struct ether_addr inner_mac;
6624         cmdline_ipaddr_t ip_value;
6625         uint16_t inner_vlan;
6626         cmdline_fixed_string_t tunnel_type;
6627         cmdline_fixed_string_t filter_type;
6628         uint32_t tenant_id;
6629         uint16_t queue_num;
6630 };
6631
6632 static void
6633 cmd_tunnel_filter_parsed(void *parsed_result,
6634                           __attribute__((unused)) struct cmdline *cl,
6635                           __attribute__((unused)) void *data)
6636 {
6637         struct cmd_tunnel_filter_result *res = parsed_result;
6638         struct rte_eth_tunnel_filter_conf tunnel_filter_conf;
6639         int ret = 0;
6640
6641         tunnel_filter_conf.outer_mac = &res->outer_mac;
6642         tunnel_filter_conf.inner_mac = &res->inner_mac;
6643         tunnel_filter_conf.inner_vlan = res->inner_vlan;
6644
6645         if (res->ip_value.family == AF_INET) {
6646                 tunnel_filter_conf.ip_addr.ipv4_addr =
6647                         res->ip_value.addr.ipv4.s_addr;
6648                 tunnel_filter_conf.ip_type = RTE_TUNNEL_IPTYPE_IPV4;
6649         } else {
6650                 memcpy(&(tunnel_filter_conf.ip_addr.ipv6_addr),
6651                         &(res->ip_value.addr.ipv6),
6652                         sizeof(struct in6_addr));
6653                 tunnel_filter_conf.ip_type = RTE_TUNNEL_IPTYPE_IPV6;
6654         }
6655
6656         if (!strcmp(res->filter_type, "imac-ivlan"))
6657                 tunnel_filter_conf.filter_type = RTE_TUNNEL_FILTER_IMAC_IVLAN;
6658         else if (!strcmp(res->filter_type, "imac-ivlan-tenid"))
6659                 tunnel_filter_conf.filter_type =
6660                         RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID;
6661         else if (!strcmp(res->filter_type, "imac-tenid"))
6662                 tunnel_filter_conf.filter_type = RTE_TUNNEL_FILTER_IMAC_TENID;
6663         else if (!strcmp(res->filter_type, "imac"))
6664                 tunnel_filter_conf.filter_type = ETH_TUNNEL_FILTER_IMAC;
6665         else if (!strcmp(res->filter_type, "omac-imac-tenid"))
6666                 tunnel_filter_conf.filter_type =
6667                         RTE_TUNNEL_FILTER_OMAC_TENID_IMAC;
6668         else {
6669                 printf("The filter type is not supported");
6670                 return;
6671         }
6672
6673         if (!strcmp(res->tunnel_type, "vxlan"))
6674                 tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_VXLAN;
6675         else if (!strcmp(res->tunnel_type, "nvgre"))
6676                 tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_NVGRE;
6677         else {
6678                 printf("The tunnel type %s not supported.\n", res->tunnel_type);
6679                 return;
6680         }
6681
6682         tunnel_filter_conf.tenant_id = res->tenant_id;
6683         tunnel_filter_conf.queue_id = res->queue_num;
6684         if (!strcmp(res->what, "add"))
6685                 ret = rte_eth_dev_filter_ctrl(res->port_id,
6686                                         RTE_ETH_FILTER_TUNNEL,
6687                                         RTE_ETH_FILTER_ADD,
6688                                         &tunnel_filter_conf);
6689         else
6690                 ret = rte_eth_dev_filter_ctrl(res->port_id,
6691                                         RTE_ETH_FILTER_TUNNEL,
6692                                         RTE_ETH_FILTER_DELETE,
6693                                         &tunnel_filter_conf);
6694         if (ret < 0)
6695                 printf("cmd_tunnel_filter_parsed error: (%s)\n",
6696                                 strerror(-ret));
6697
6698 }
6699 cmdline_parse_token_string_t cmd_tunnel_filter_cmd =
6700         TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
6701         cmd, "tunnel_filter");
6702 cmdline_parse_token_string_t cmd_tunnel_filter_what =
6703         TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
6704         what, "add#rm");
6705 cmdline_parse_token_num_t cmd_tunnel_filter_port_id =
6706         TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
6707         port_id, UINT8);
6708 cmdline_parse_token_etheraddr_t cmd_tunnel_filter_outer_mac =
6709         TOKEN_ETHERADDR_INITIALIZER(struct cmd_tunnel_filter_result,
6710         outer_mac);
6711 cmdline_parse_token_etheraddr_t cmd_tunnel_filter_inner_mac =
6712         TOKEN_ETHERADDR_INITIALIZER(struct cmd_tunnel_filter_result,
6713         inner_mac);
6714 cmdline_parse_token_num_t cmd_tunnel_filter_innner_vlan =
6715         TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
6716         inner_vlan, UINT16);
6717 cmdline_parse_token_ipaddr_t cmd_tunnel_filter_ip_value =
6718         TOKEN_IPADDR_INITIALIZER(struct cmd_tunnel_filter_result,
6719         ip_value);
6720 cmdline_parse_token_string_t cmd_tunnel_filter_tunnel_type =
6721         TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
6722         tunnel_type, "vxlan#nvgre");
6723
6724 cmdline_parse_token_string_t cmd_tunnel_filter_filter_type =
6725         TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
6726         filter_type, "imac-ivlan#imac-ivlan-tenid#imac-tenid#"
6727                 "imac#omac-imac-tenid");
6728 cmdline_parse_token_num_t cmd_tunnel_filter_tenant_id =
6729         TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
6730         tenant_id, UINT32);
6731 cmdline_parse_token_num_t cmd_tunnel_filter_queue_num =
6732         TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
6733         queue_num, UINT16);
6734
6735 cmdline_parse_inst_t cmd_tunnel_filter = {
6736         .f = cmd_tunnel_filter_parsed,
6737         .data = (void *)0,
6738         .help_str = "add/rm tunnel filter of a port: "
6739                         "tunnel_filter add port_id outer_mac inner_mac ip "
6740                         "inner_vlan tunnel_type(vxlan|nvgre) filter_type "
6741                         "(imac-ivlan|imac-ivlan-tenid|imac-tenid|"
6742                         "imac|omac-imac-tenid) "
6743                         "tenant_id queue_num",
6744         .tokens = {
6745                 (void *)&cmd_tunnel_filter_cmd,
6746                 (void *)&cmd_tunnel_filter_what,
6747                 (void *)&cmd_tunnel_filter_port_id,
6748                 (void *)&cmd_tunnel_filter_outer_mac,
6749                 (void *)&cmd_tunnel_filter_inner_mac,
6750                 (void *)&cmd_tunnel_filter_ip_value,
6751                 (void *)&cmd_tunnel_filter_innner_vlan,
6752                 (void *)&cmd_tunnel_filter_tunnel_type,
6753                 (void *)&cmd_tunnel_filter_filter_type,
6754                 (void *)&cmd_tunnel_filter_tenant_id,
6755                 (void *)&cmd_tunnel_filter_queue_num,
6756                 NULL,
6757         },
6758 };
6759
6760 /* *** CONFIGURE TUNNEL UDP PORT *** */
6761 struct cmd_tunnel_udp_config {
6762         cmdline_fixed_string_t cmd;
6763         cmdline_fixed_string_t what;
6764         uint16_t udp_port;
6765         uint8_t port_id;
6766 };
6767
6768 static void
6769 cmd_tunnel_udp_config_parsed(void *parsed_result,
6770                           __attribute__((unused)) struct cmdline *cl,
6771                           __attribute__((unused)) void *data)
6772 {
6773         struct cmd_tunnel_udp_config *res = parsed_result;
6774         struct rte_eth_udp_tunnel tunnel_udp;
6775         int ret;
6776
6777         tunnel_udp.udp_port = res->udp_port;
6778
6779         if (!strcmp(res->cmd, "rx_vxlan_port"))
6780                 tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN;
6781
6782         if (!strcmp(res->what, "add"))
6783                 ret = rte_eth_dev_udp_tunnel_add(res->port_id, &tunnel_udp);
6784         else
6785                 ret = rte_eth_dev_udp_tunnel_delete(res->port_id, &tunnel_udp);
6786
6787         if (ret < 0)
6788                 printf("udp tunneling add error: (%s)\n", strerror(-ret));
6789 }
6790
6791 cmdline_parse_token_string_t cmd_tunnel_udp_config_cmd =
6792         TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
6793                                 cmd, "rx_vxlan_port");
6794 cmdline_parse_token_string_t cmd_tunnel_udp_config_what =
6795         TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
6796                                 what, "add#rm");
6797 cmdline_parse_token_num_t cmd_tunnel_udp_config_udp_port =
6798         TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
6799                                 udp_port, UINT16);
6800 cmdline_parse_token_num_t cmd_tunnel_udp_config_port_id =
6801         TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
6802                                 port_id, UINT8);
6803
6804 cmdline_parse_inst_t cmd_tunnel_udp_config = {
6805         .f = cmd_tunnel_udp_config_parsed,
6806         .data = (void *)0,
6807         .help_str = "add/rm an tunneling UDP port filter: "
6808                         "rx_vxlan_port add udp_port port_id",
6809         .tokens = {
6810                 (void *)&cmd_tunnel_udp_config_cmd,
6811                 (void *)&cmd_tunnel_udp_config_what,
6812                 (void *)&cmd_tunnel_udp_config_udp_port,
6813                 (void *)&cmd_tunnel_udp_config_port_id,
6814                 NULL,
6815         },
6816 };
6817
6818 /* *** GLOBAL CONFIG *** */
6819 struct cmd_global_config_result {
6820         cmdline_fixed_string_t cmd;
6821         uint8_t port_id;
6822         cmdline_fixed_string_t cfg_type;
6823         uint8_t len;
6824 };
6825
6826 static void
6827 cmd_global_config_parsed(void *parsed_result,
6828                          __attribute__((unused)) struct cmdline *cl,
6829                          __attribute__((unused)) void *data)
6830 {
6831         struct cmd_global_config_result *res = parsed_result;
6832         struct rte_eth_global_cfg conf;
6833         int ret;
6834
6835         memset(&conf, 0, sizeof(conf));
6836         conf.cfg_type = RTE_ETH_GLOBAL_CFG_TYPE_GRE_KEY_LEN;
6837         conf.cfg.gre_key_len = res->len;
6838         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_NONE,
6839                                       RTE_ETH_FILTER_SET, &conf);
6840         if (ret != 0)
6841                 printf("Global config error\n");
6842 }
6843
6844 cmdline_parse_token_string_t cmd_global_config_cmd =
6845         TOKEN_STRING_INITIALIZER(struct cmd_global_config_result, cmd,
6846                 "global_config");
6847 cmdline_parse_token_num_t cmd_global_config_port_id =
6848         TOKEN_NUM_INITIALIZER(struct cmd_global_config_result, port_id, UINT8);
6849 cmdline_parse_token_string_t cmd_global_config_type =
6850         TOKEN_STRING_INITIALIZER(struct cmd_global_config_result,
6851                 cfg_type, "gre-key-len");
6852 cmdline_parse_token_num_t cmd_global_config_gre_key_len =
6853         TOKEN_NUM_INITIALIZER(struct cmd_global_config_result,
6854                 len, UINT8);
6855
6856 cmdline_parse_inst_t cmd_global_config = {
6857         .f = cmd_global_config_parsed,
6858         .data = (void *)NULL,
6859         .help_str = "global_config <port_id> gre-key-len <number>",
6860         .tokens = {
6861                 (void *)&cmd_global_config_cmd,
6862                 (void *)&cmd_global_config_port_id,
6863                 (void *)&cmd_global_config_type,
6864                 (void *)&cmd_global_config_gre_key_len,
6865                 NULL,
6866         },
6867 };
6868
6869 /* *** CONFIGURE VM MIRROR VLAN/POOL RULE *** */
6870 struct cmd_set_mirror_mask_result {
6871         cmdline_fixed_string_t set;
6872         cmdline_fixed_string_t port;
6873         uint8_t port_id;
6874         cmdline_fixed_string_t mirror;
6875         uint8_t rule_id;
6876         cmdline_fixed_string_t what;
6877         cmdline_fixed_string_t value;
6878         cmdline_fixed_string_t dstpool;
6879         uint8_t dstpool_id;
6880         cmdline_fixed_string_t on;
6881 };
6882
6883 cmdline_parse_token_string_t cmd_mirror_mask_set =
6884         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
6885                                 set, "set");
6886 cmdline_parse_token_string_t cmd_mirror_mask_port =
6887         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
6888                                 port, "port");
6889 cmdline_parse_token_num_t cmd_mirror_mask_portid =
6890         TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_mask_result,
6891                                 port_id, UINT8);
6892 cmdline_parse_token_string_t cmd_mirror_mask_mirror =
6893         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
6894                                 mirror, "mirror-rule");
6895 cmdline_parse_token_num_t cmd_mirror_mask_ruleid =
6896         TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_mask_result,
6897                                 rule_id, UINT8);
6898 cmdline_parse_token_string_t cmd_mirror_mask_what =
6899         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
6900                                 what, "pool-mirror-up#pool-mirror-down"
6901                                       "#vlan-mirror");
6902 cmdline_parse_token_string_t cmd_mirror_mask_value =
6903         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
6904                                 value, NULL);
6905 cmdline_parse_token_string_t cmd_mirror_mask_dstpool =
6906         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
6907                                 dstpool, "dst-pool");
6908 cmdline_parse_token_num_t cmd_mirror_mask_poolid =
6909         TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_mask_result,
6910                                 dstpool_id, UINT8);
6911 cmdline_parse_token_string_t cmd_mirror_mask_on =
6912         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
6913                                 on, "on#off");
6914
6915 static void
6916 cmd_set_mirror_mask_parsed(void *parsed_result,
6917                        __attribute__((unused)) struct cmdline *cl,
6918                        __attribute__((unused)) void *data)
6919 {
6920         int ret,nb_item,i;
6921         struct cmd_set_mirror_mask_result *res = parsed_result;
6922         struct rte_eth_mirror_conf mr_conf;
6923
6924         memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
6925
6926         unsigned int vlan_list[ETH_MIRROR_MAX_VLANS];
6927
6928         mr_conf.dst_pool = res->dstpool_id;
6929
6930         if (!strcmp(res->what, "pool-mirror-up")) {
6931                 mr_conf.pool_mask = strtoull(res->value, NULL, 16);
6932                 mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_UP;
6933         } else if (!strcmp(res->what, "pool-mirror-down")) {
6934                 mr_conf.pool_mask = strtoull(res->value, NULL, 16);
6935                 mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_DOWN;
6936         } else if (!strcmp(res->what, "vlan-mirror")) {
6937                 mr_conf.rule_type = ETH_MIRROR_VLAN;
6938                 nb_item = parse_item_list(res->value, "vlan",
6939                                 ETH_MIRROR_MAX_VLANS, vlan_list, 1);
6940                 if (nb_item <= 0)
6941                         return;
6942
6943                 for (i = 0; i < nb_item; i++) {
6944                         if (vlan_list[i] > ETHER_MAX_VLAN_ID) {
6945                                 printf("Invalid vlan_id: must be < 4096\n");
6946                                 return;
6947                         }
6948
6949                         mr_conf.vlan.vlan_id[i] = (uint16_t)vlan_list[i];
6950                         mr_conf.vlan.vlan_mask |= 1ULL << i;
6951                 }
6952         }
6953
6954         if (!strcmp(res->on, "on"))
6955                 ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
6956                                                 res->rule_id, 1);
6957         else
6958                 ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
6959                                                 res->rule_id, 0);
6960         if (ret < 0)
6961                 printf("mirror rule add error: (%s)\n", strerror(-ret));
6962 }
6963
6964 cmdline_parse_inst_t cmd_set_mirror_mask = {
6965                 .f = cmd_set_mirror_mask_parsed,
6966                 .data = NULL,
6967                 .help_str = "set port X mirror-rule Y pool-mirror-up|pool-mirror-down|vlan-mirror"
6968                             " pool_mask|vlan_id[,vlan_id]* dst-pool Z on|off",
6969                 .tokens = {
6970                         (void *)&cmd_mirror_mask_set,
6971                         (void *)&cmd_mirror_mask_port,
6972                         (void *)&cmd_mirror_mask_portid,
6973                         (void *)&cmd_mirror_mask_mirror,
6974                         (void *)&cmd_mirror_mask_ruleid,
6975                         (void *)&cmd_mirror_mask_what,
6976                         (void *)&cmd_mirror_mask_value,
6977                         (void *)&cmd_mirror_mask_dstpool,
6978                         (void *)&cmd_mirror_mask_poolid,
6979                         (void *)&cmd_mirror_mask_on,
6980                         NULL,
6981                 },
6982 };
6983
6984 /* *** CONFIGURE VM MIRROR UDLINK/DOWNLINK RULE *** */
6985 struct cmd_set_mirror_link_result {
6986         cmdline_fixed_string_t set;
6987         cmdline_fixed_string_t port;
6988         uint8_t port_id;
6989         cmdline_fixed_string_t mirror;
6990         uint8_t rule_id;
6991         cmdline_fixed_string_t what;
6992         cmdline_fixed_string_t dstpool;
6993         uint8_t dstpool_id;
6994         cmdline_fixed_string_t on;
6995 };
6996
6997 cmdline_parse_token_string_t cmd_mirror_link_set =
6998         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
6999                                  set, "set");
7000 cmdline_parse_token_string_t cmd_mirror_link_port =
7001         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7002                                 port, "port");
7003 cmdline_parse_token_num_t cmd_mirror_link_portid =
7004         TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_link_result,
7005                                 port_id, UINT8);
7006 cmdline_parse_token_string_t cmd_mirror_link_mirror =
7007         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7008                                 mirror, "mirror-rule");
7009 cmdline_parse_token_num_t cmd_mirror_link_ruleid =
7010         TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_link_result,
7011                             rule_id, UINT8);
7012 cmdline_parse_token_string_t cmd_mirror_link_what =
7013         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7014                                 what, "uplink-mirror#downlink-mirror");
7015 cmdline_parse_token_string_t cmd_mirror_link_dstpool =
7016         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7017                                 dstpool, "dst-pool");
7018 cmdline_parse_token_num_t cmd_mirror_link_poolid =
7019         TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_link_result,
7020                                 dstpool_id, UINT8);
7021 cmdline_parse_token_string_t cmd_mirror_link_on =
7022         TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7023                                 on, "on#off");
7024
7025 static void
7026 cmd_set_mirror_link_parsed(void *parsed_result,
7027                        __attribute__((unused)) struct cmdline *cl,
7028                        __attribute__((unused)) void *data)
7029 {
7030         int ret;
7031         struct cmd_set_mirror_link_result *res = parsed_result;
7032         struct rte_eth_mirror_conf mr_conf;
7033
7034         memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
7035         if (!strcmp(res->what, "uplink-mirror"))
7036                 mr_conf.rule_type = ETH_MIRROR_UPLINK_PORT;
7037         else
7038                 mr_conf.rule_type = ETH_MIRROR_DOWNLINK_PORT;
7039
7040         mr_conf.dst_pool = res->dstpool_id;
7041
7042         if (!strcmp(res->on, "on"))
7043                 ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
7044                                                 res->rule_id, 1);
7045         else
7046                 ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
7047                                                 res->rule_id, 0);
7048
7049         /* check the return value and print it if is < 0 */
7050         if (ret < 0)
7051                 printf("mirror rule add error: (%s)\n", strerror(-ret));
7052
7053 }
7054
7055 cmdline_parse_inst_t cmd_set_mirror_link = {
7056                 .f = cmd_set_mirror_link_parsed,
7057                 .data = NULL,
7058                 .help_str = "set port X mirror-rule Y uplink-mirror|"
7059                         "downlink-mirror dst-pool Z on|off",
7060                 .tokens = {
7061                         (void *)&cmd_mirror_link_set,
7062                         (void *)&cmd_mirror_link_port,
7063                         (void *)&cmd_mirror_link_portid,
7064                         (void *)&cmd_mirror_link_mirror,
7065                         (void *)&cmd_mirror_link_ruleid,
7066                         (void *)&cmd_mirror_link_what,
7067                         (void *)&cmd_mirror_link_dstpool,
7068                         (void *)&cmd_mirror_link_poolid,
7069                         (void *)&cmd_mirror_link_on,
7070                         NULL,
7071                 },
7072 };
7073
7074 /* *** RESET VM MIRROR RULE *** */
7075 struct cmd_rm_mirror_rule_result {
7076         cmdline_fixed_string_t reset;
7077         cmdline_fixed_string_t port;
7078         uint8_t port_id;
7079         cmdline_fixed_string_t mirror;
7080         uint8_t rule_id;
7081 };
7082
7083 cmdline_parse_token_string_t cmd_rm_mirror_rule_reset =
7084         TOKEN_STRING_INITIALIZER(struct cmd_rm_mirror_rule_result,
7085                                  reset, "reset");
7086 cmdline_parse_token_string_t cmd_rm_mirror_rule_port =
7087         TOKEN_STRING_INITIALIZER(struct cmd_rm_mirror_rule_result,
7088                                 port, "port");
7089 cmdline_parse_token_num_t cmd_rm_mirror_rule_portid =
7090         TOKEN_NUM_INITIALIZER(struct cmd_rm_mirror_rule_result,
7091                                 port_id, UINT8);
7092 cmdline_parse_token_string_t cmd_rm_mirror_rule_mirror =
7093         TOKEN_STRING_INITIALIZER(struct cmd_rm_mirror_rule_result,
7094                                 mirror, "mirror-rule");
7095 cmdline_parse_token_num_t cmd_rm_mirror_rule_ruleid =
7096         TOKEN_NUM_INITIALIZER(struct cmd_rm_mirror_rule_result,
7097                                 rule_id, UINT8);
7098
7099 static void
7100 cmd_reset_mirror_rule_parsed(void *parsed_result,
7101                        __attribute__((unused)) struct cmdline *cl,
7102                        __attribute__((unused)) void *data)
7103 {
7104         int ret;
7105         struct cmd_set_mirror_link_result *res = parsed_result;
7106         /* check rule_id */
7107         ret = rte_eth_mirror_rule_reset(res->port_id,res->rule_id);
7108         if(ret < 0)
7109                 printf("mirror rule remove error: (%s)\n", strerror(-ret));
7110 }
7111
7112 cmdline_parse_inst_t cmd_reset_mirror_rule = {
7113                 .f = cmd_reset_mirror_rule_parsed,
7114                 .data = NULL,
7115                 .help_str = "reset port X mirror-rule Y",
7116                 .tokens = {
7117                         (void *)&cmd_rm_mirror_rule_reset,
7118                         (void *)&cmd_rm_mirror_rule_port,
7119                         (void *)&cmd_rm_mirror_rule_portid,
7120                         (void *)&cmd_rm_mirror_rule_mirror,
7121                         (void *)&cmd_rm_mirror_rule_ruleid,
7122                         NULL,
7123                 },
7124 };
7125
7126 /* ******************************************************************************** */
7127
7128 struct cmd_dump_result {
7129         cmdline_fixed_string_t dump;
7130 };
7131
7132 static void
7133 dump_struct_sizes(void)
7134 {
7135 #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
7136         DUMP_SIZE(struct rte_mbuf);
7137         DUMP_SIZE(struct rte_mempool);
7138         DUMP_SIZE(struct rte_ring);
7139 #undef DUMP_SIZE
7140 }
7141
7142 static void cmd_dump_parsed(void *parsed_result,
7143                             __attribute__((unused)) struct cmdline *cl,
7144                             __attribute__((unused)) void *data)
7145 {
7146         struct cmd_dump_result *res = parsed_result;
7147
7148         if (!strcmp(res->dump, "dump_physmem"))
7149                 rte_dump_physmem_layout(stdout);
7150         else if (!strcmp(res->dump, "dump_memzone"))
7151                 rte_memzone_dump(stdout);
7152         else if (!strcmp(res->dump, "dump_log_history"))
7153                 rte_log_dump_history(stdout);
7154         else if (!strcmp(res->dump, "dump_struct_sizes"))
7155                 dump_struct_sizes();
7156         else if (!strcmp(res->dump, "dump_ring"))
7157                 rte_ring_list_dump(stdout);
7158         else if (!strcmp(res->dump, "dump_mempool"))
7159                 rte_mempool_list_dump(stdout);
7160         else if (!strcmp(res->dump, "dump_devargs"))
7161                 rte_eal_devargs_dump(stdout);
7162 }
7163
7164 cmdline_parse_token_string_t cmd_dump_dump =
7165         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
7166                 "dump_physmem#"
7167                 "dump_memzone#"
7168                 "dump_log_history#"
7169                 "dump_struct_sizes#"
7170                 "dump_ring#"
7171                 "dump_mempool#"
7172                 "dump_devargs");
7173
7174 cmdline_parse_inst_t cmd_dump = {
7175         .f = cmd_dump_parsed,  /* function to call */
7176         .data = NULL,      /* 2nd arg of func */
7177         .help_str = "dump status",
7178         .tokens = {        /* token list, NULL terminated */
7179                 (void *)&cmd_dump_dump,
7180                 NULL,
7181         },
7182 };
7183
7184 /* ******************************************************************************** */
7185
7186 struct cmd_dump_one_result {
7187         cmdline_fixed_string_t dump;
7188         cmdline_fixed_string_t name;
7189 };
7190
7191 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
7192                                 __attribute__((unused)) void *data)
7193 {
7194         struct cmd_dump_one_result *res = parsed_result;
7195
7196         if (!strcmp(res->dump, "dump_ring")) {
7197                 struct rte_ring *r;
7198                 r = rte_ring_lookup(res->name);
7199                 if (r == NULL) {
7200                         cmdline_printf(cl, "Cannot find ring\n");
7201                         return;
7202                 }
7203                 rte_ring_dump(stdout, r);
7204         } else if (!strcmp(res->dump, "dump_mempool")) {
7205                 struct rte_mempool *mp;
7206                 mp = rte_mempool_lookup(res->name);
7207                 if (mp == NULL) {
7208                         cmdline_printf(cl, "Cannot find mempool\n");
7209                         return;
7210                 }
7211                 rte_mempool_dump(stdout, mp);
7212         }
7213 }
7214
7215 cmdline_parse_token_string_t cmd_dump_one_dump =
7216         TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
7217                                  "dump_ring#dump_mempool");
7218
7219 cmdline_parse_token_string_t cmd_dump_one_name =
7220         TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
7221
7222 cmdline_parse_inst_t cmd_dump_one = {
7223         .f = cmd_dump_one_parsed,  /* function to call */
7224         .data = NULL,      /* 2nd arg of func */
7225         .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
7226         .tokens = {        /* token list, NULL terminated */
7227                 (void *)&cmd_dump_one_dump,
7228                 (void *)&cmd_dump_one_name,
7229                 NULL,
7230         },
7231 };
7232
7233 /* *** Add/Del syn filter *** */
7234 struct cmd_syn_filter_result {
7235         cmdline_fixed_string_t filter;
7236         uint8_t port_id;
7237         cmdline_fixed_string_t ops;
7238         cmdline_fixed_string_t priority;
7239         cmdline_fixed_string_t high;
7240         cmdline_fixed_string_t queue;
7241         uint16_t queue_id;
7242 };
7243
7244 static void
7245 cmd_syn_filter_parsed(void *parsed_result,
7246                         __attribute__((unused)) struct cmdline *cl,
7247                         __attribute__((unused)) void *data)
7248 {
7249         struct cmd_syn_filter_result *res = parsed_result;
7250         struct rte_eth_syn_filter syn_filter;
7251         int ret = 0;
7252
7253         ret = rte_eth_dev_filter_supported(res->port_id,
7254                                         RTE_ETH_FILTER_SYN);
7255         if (ret < 0) {
7256                 printf("syn filter is not supported on port %u.\n",
7257                                 res->port_id);
7258                 return;
7259         }
7260
7261         memset(&syn_filter, 0, sizeof(syn_filter));
7262
7263         if (!strcmp(res->ops, "add")) {
7264                 if (!strcmp(res->high, "high"))
7265                         syn_filter.hig_pri = 1;
7266                 else
7267                         syn_filter.hig_pri = 0;
7268
7269                 syn_filter.queue = res->queue_id;
7270                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7271                                                 RTE_ETH_FILTER_SYN,
7272                                                 RTE_ETH_FILTER_ADD,
7273                                                 &syn_filter);
7274         } else
7275                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7276                                                 RTE_ETH_FILTER_SYN,
7277                                                 RTE_ETH_FILTER_DELETE,
7278                                                 &syn_filter);
7279
7280         if (ret < 0)
7281                 printf("syn filter programming error: (%s)\n",
7282                                 strerror(-ret));
7283 }
7284
7285 cmdline_parse_token_string_t cmd_syn_filter_filter =
7286         TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7287         filter, "syn_filter");
7288 cmdline_parse_token_num_t cmd_syn_filter_port_id =
7289         TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result,
7290         port_id, UINT8);
7291 cmdline_parse_token_string_t cmd_syn_filter_ops =
7292         TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7293         ops, "add#del");
7294 cmdline_parse_token_string_t cmd_syn_filter_priority =
7295         TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7296                                 priority, "priority");
7297 cmdline_parse_token_string_t cmd_syn_filter_high =
7298         TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7299                                 high, "high#low");
7300 cmdline_parse_token_string_t cmd_syn_filter_queue =
7301         TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7302                                 queue, "queue");
7303 cmdline_parse_token_num_t cmd_syn_filter_queue_id =
7304         TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result,
7305                                 queue_id, UINT16);
7306
7307 cmdline_parse_inst_t cmd_syn_filter = {
7308         .f = cmd_syn_filter_parsed,
7309         .data = NULL,
7310         .help_str = "add/delete syn filter",
7311         .tokens = {
7312                 (void *)&cmd_syn_filter_filter,
7313                 (void *)&cmd_syn_filter_port_id,
7314                 (void *)&cmd_syn_filter_ops,
7315                 (void *)&cmd_syn_filter_priority,
7316                 (void *)&cmd_syn_filter_high,
7317                 (void *)&cmd_syn_filter_queue,
7318                 (void *)&cmd_syn_filter_queue_id,
7319                 NULL,
7320         },
7321 };
7322
7323 /* *** ADD/REMOVE A 2tuple FILTER *** */
7324 struct cmd_2tuple_filter_result {
7325         cmdline_fixed_string_t filter;
7326         uint8_t  port_id;
7327         cmdline_fixed_string_t ops;
7328         cmdline_fixed_string_t dst_port;
7329         uint16_t dst_port_value;
7330         cmdline_fixed_string_t protocol;
7331         uint8_t protocol_value;
7332         cmdline_fixed_string_t mask;
7333         uint8_t  mask_value;
7334         cmdline_fixed_string_t tcp_flags;
7335         uint8_t tcp_flags_value;
7336         cmdline_fixed_string_t priority;
7337         uint8_t  priority_value;
7338         cmdline_fixed_string_t queue;
7339         uint16_t  queue_id;
7340 };
7341
7342 static void
7343 cmd_2tuple_filter_parsed(void *parsed_result,
7344                         __attribute__((unused)) struct cmdline *cl,
7345                         __attribute__((unused)) void *data)
7346 {
7347         struct rte_eth_ntuple_filter filter;
7348         struct cmd_2tuple_filter_result *res = parsed_result;
7349         int ret = 0;
7350
7351         ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
7352         if (ret < 0) {
7353                 printf("ntuple filter is not supported on port %u.\n",
7354                         res->port_id);
7355                 return;
7356         }
7357
7358         memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
7359
7360         filter.flags = RTE_2TUPLE_FLAGS;
7361         filter.dst_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
7362         filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
7363         filter.proto = res->protocol_value;
7364         filter.priority = res->priority_value;
7365         if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
7366                 printf("nonzero tcp_flags is only meaningful"
7367                         " when protocol is TCP.\n");
7368                 return;
7369         }
7370         if (res->tcp_flags_value > TCP_FLAG_ALL) {
7371                 printf("invalid TCP flags.\n");
7372                 return;
7373         }
7374
7375         if (res->tcp_flags_value != 0) {
7376                 filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
7377                 filter.tcp_flags = res->tcp_flags_value;
7378         }
7379
7380         /* need convert to big endian. */
7381         filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
7382         filter.queue = res->queue_id;
7383
7384         if (!strcmp(res->ops, "add"))
7385                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7386                                 RTE_ETH_FILTER_NTUPLE,
7387                                 RTE_ETH_FILTER_ADD,
7388                                 &filter);
7389         else
7390                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7391                                 RTE_ETH_FILTER_NTUPLE,
7392                                 RTE_ETH_FILTER_DELETE,
7393                                 &filter);
7394         if (ret < 0)
7395                 printf("2tuple filter programming error: (%s)\n",
7396                         strerror(-ret));
7397
7398 }
7399
7400 cmdline_parse_token_string_t cmd_2tuple_filter_filter =
7401         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7402                                  filter, "2tuple_filter");
7403 cmdline_parse_token_num_t cmd_2tuple_filter_port_id =
7404         TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7405                                 port_id, UINT8);
7406 cmdline_parse_token_string_t cmd_2tuple_filter_ops =
7407         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7408                                  ops, "add#del");
7409 cmdline_parse_token_string_t cmd_2tuple_filter_dst_port =
7410         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7411                                 dst_port, "dst_port");
7412 cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_value =
7413         TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7414                                 dst_port_value, UINT16);
7415 cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
7416         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7417                                 protocol, "protocol");
7418 cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
7419         TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7420                                 protocol_value, UINT8);
7421 cmdline_parse_token_string_t cmd_2tuple_filter_mask =
7422         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7423                                 mask, "mask");
7424 cmdline_parse_token_num_t cmd_2tuple_filter_mask_value =
7425         TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7426                                 mask_value, INT8);
7427 cmdline_parse_token_string_t cmd_2tuple_filter_tcp_flags =
7428         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7429                                 tcp_flags, "tcp_flags");
7430 cmdline_parse_token_num_t cmd_2tuple_filter_tcp_flags_value =
7431         TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7432                                 tcp_flags_value, UINT8);
7433 cmdline_parse_token_string_t cmd_2tuple_filter_priority =
7434         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7435                                 priority, "priority");
7436 cmdline_parse_token_num_t cmd_2tuple_filter_priority_value =
7437         TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7438                                 priority_value, UINT8);
7439 cmdline_parse_token_string_t cmd_2tuple_filter_queue =
7440         TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7441                                 queue, "queue");
7442 cmdline_parse_token_num_t cmd_2tuple_filter_queue_id =
7443         TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7444                                 queue_id, UINT16);
7445
7446 cmdline_parse_inst_t cmd_2tuple_filter = {
7447         .f = cmd_2tuple_filter_parsed,
7448         .data = NULL,
7449         .help_str = "add a 2tuple filter",
7450         .tokens = {
7451                 (void *)&cmd_2tuple_filter_filter,
7452                 (void *)&cmd_2tuple_filter_port_id,
7453                 (void *)&cmd_2tuple_filter_ops,
7454                 (void *)&cmd_2tuple_filter_dst_port,
7455                 (void *)&cmd_2tuple_filter_dst_port_value,
7456                 (void *)&cmd_2tuple_filter_protocol,
7457                 (void *)&cmd_2tuple_filter_protocol_value,
7458                 (void *)&cmd_2tuple_filter_mask,
7459                 (void *)&cmd_2tuple_filter_mask_value,
7460                 (void *)&cmd_2tuple_filter_tcp_flags,
7461                 (void *)&cmd_2tuple_filter_tcp_flags_value,
7462                 (void *)&cmd_2tuple_filter_priority,
7463                 (void *)&cmd_2tuple_filter_priority_value,
7464                 (void *)&cmd_2tuple_filter_queue,
7465                 (void *)&cmd_2tuple_filter_queue_id,
7466                 NULL,
7467         },
7468 };
7469
7470 /* *** ADD/REMOVE A 5tuple FILTER *** */
7471 struct cmd_5tuple_filter_result {
7472         cmdline_fixed_string_t filter;
7473         uint8_t  port_id;
7474         cmdline_fixed_string_t ops;
7475         cmdline_fixed_string_t dst_ip;
7476         cmdline_ipaddr_t dst_ip_value;
7477         cmdline_fixed_string_t src_ip;
7478         cmdline_ipaddr_t src_ip_value;
7479         cmdline_fixed_string_t dst_port;
7480         uint16_t dst_port_value;
7481         cmdline_fixed_string_t src_port;
7482         uint16_t src_port_value;
7483         cmdline_fixed_string_t protocol;
7484         uint8_t protocol_value;
7485         cmdline_fixed_string_t mask;
7486         uint8_t  mask_value;
7487         cmdline_fixed_string_t tcp_flags;
7488         uint8_t tcp_flags_value;
7489         cmdline_fixed_string_t priority;
7490         uint8_t  priority_value;
7491         cmdline_fixed_string_t queue;
7492         uint16_t  queue_id;
7493 };
7494
7495 static void
7496 cmd_5tuple_filter_parsed(void *parsed_result,
7497                         __attribute__((unused)) struct cmdline *cl,
7498                         __attribute__((unused)) void *data)
7499 {
7500         struct rte_eth_ntuple_filter filter;
7501         struct cmd_5tuple_filter_result *res = parsed_result;
7502         int ret = 0;
7503
7504         ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
7505         if (ret < 0) {
7506                 printf("ntuple filter is not supported on port %u.\n",
7507                         res->port_id);
7508                 return;
7509         }
7510
7511         memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
7512
7513         filter.flags = RTE_5TUPLE_FLAGS;
7514         filter.dst_ip_mask = (res->mask_value & 0x10) ? UINT32_MAX : 0;
7515         filter.src_ip_mask = (res->mask_value & 0x08) ? UINT32_MAX : 0;
7516         filter.dst_port_mask = (res->mask_value & 0x04) ? UINT16_MAX : 0;
7517         filter.src_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
7518         filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
7519         filter.proto = res->protocol_value;
7520         filter.priority = res->priority_value;
7521         if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
7522                 printf("nonzero tcp_flags is only meaningful"
7523                         " when protocol is TCP.\n");
7524                 return;
7525         }
7526         if (res->tcp_flags_value > TCP_FLAG_ALL) {
7527                 printf("invalid TCP flags.\n");
7528                 return;
7529         }
7530
7531         if (res->tcp_flags_value != 0) {
7532                 filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
7533                 filter.tcp_flags = res->tcp_flags_value;
7534         }
7535
7536         if (res->dst_ip_value.family == AF_INET)
7537                 /* no need to convert, already big endian. */
7538                 filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
7539         else {
7540                 if (filter.dst_ip_mask == 0) {
7541                         printf("can not support ipv6 involved compare.\n");
7542                         return;
7543                 }
7544                 filter.dst_ip = 0;
7545         }
7546
7547         if (res->src_ip_value.family == AF_INET)
7548                 /* no need to convert, already big endian. */
7549                 filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
7550         else {
7551                 if (filter.src_ip_mask == 0) {
7552                         printf("can not support ipv6 involved compare.\n");
7553                         return;
7554                 }
7555                 filter.src_ip = 0;
7556         }
7557         /* need convert to big endian. */
7558         filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
7559         filter.src_port = rte_cpu_to_be_16(res->src_port_value);
7560         filter.queue = res->queue_id;
7561
7562         if (!strcmp(res->ops, "add"))
7563                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7564                                 RTE_ETH_FILTER_NTUPLE,
7565                                 RTE_ETH_FILTER_ADD,
7566                                 &filter);
7567         else
7568                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7569                                 RTE_ETH_FILTER_NTUPLE,
7570                                 RTE_ETH_FILTER_DELETE,
7571                                 &filter);
7572         if (ret < 0)
7573                 printf("5tuple filter programming error: (%s)\n",
7574                         strerror(-ret));
7575 }
7576
7577 cmdline_parse_token_string_t cmd_5tuple_filter_filter =
7578         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7579                                  filter, "5tuple_filter");
7580 cmdline_parse_token_num_t cmd_5tuple_filter_port_id =
7581         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7582                                 port_id, UINT8);
7583 cmdline_parse_token_string_t cmd_5tuple_filter_ops =
7584         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7585                                  ops, "add#del");
7586 cmdline_parse_token_string_t cmd_5tuple_filter_dst_ip =
7587         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7588                                 dst_ip, "dst_ip");
7589 cmdline_parse_token_ipaddr_t cmd_5tuple_filter_dst_ip_value =
7590         TOKEN_IPADDR_INITIALIZER(struct cmd_5tuple_filter_result,
7591                                 dst_ip_value);
7592 cmdline_parse_token_string_t cmd_5tuple_filter_src_ip =
7593         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7594                                 src_ip, "src_ip");
7595 cmdline_parse_token_ipaddr_t cmd_5tuple_filter_src_ip_value =
7596         TOKEN_IPADDR_INITIALIZER(struct cmd_5tuple_filter_result,
7597                                 src_ip_value);
7598 cmdline_parse_token_string_t cmd_5tuple_filter_dst_port =
7599         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7600                                 dst_port, "dst_port");
7601 cmdline_parse_token_num_t cmd_5tuple_filter_dst_port_value =
7602         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7603                                 dst_port_value, UINT16);
7604 cmdline_parse_token_string_t cmd_5tuple_filter_src_port =
7605         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7606                                 src_port, "src_port");
7607 cmdline_parse_token_num_t cmd_5tuple_filter_src_port_value =
7608         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7609                                 src_port_value, UINT16);
7610 cmdline_parse_token_string_t cmd_5tuple_filter_protocol =
7611         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7612                                 protocol, "protocol");
7613 cmdline_parse_token_num_t cmd_5tuple_filter_protocol_value =
7614         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7615                                 protocol_value, UINT8);
7616 cmdline_parse_token_string_t cmd_5tuple_filter_mask =
7617         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7618                                 mask, "mask");
7619 cmdline_parse_token_num_t cmd_5tuple_filter_mask_value =
7620         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7621                                 mask_value, INT8);
7622 cmdline_parse_token_string_t cmd_5tuple_filter_tcp_flags =
7623         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7624                                 tcp_flags, "tcp_flags");
7625 cmdline_parse_token_num_t cmd_5tuple_filter_tcp_flags_value =
7626         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7627                                 tcp_flags_value, UINT8);
7628 cmdline_parse_token_string_t cmd_5tuple_filter_priority =
7629         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7630                                 priority, "priority");
7631 cmdline_parse_token_num_t cmd_5tuple_filter_priority_value =
7632         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7633                                 priority_value, UINT8);
7634 cmdline_parse_token_string_t cmd_5tuple_filter_queue =
7635         TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
7636                                 queue, "queue");
7637 cmdline_parse_token_num_t cmd_5tuple_filter_queue_id =
7638         TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
7639                                 queue_id, UINT16);
7640
7641 cmdline_parse_inst_t cmd_5tuple_filter = {
7642         .f = cmd_5tuple_filter_parsed,
7643         .data = NULL,
7644         .help_str = "add/del a 5tuple filter",
7645         .tokens = {
7646                 (void *)&cmd_5tuple_filter_filter,
7647                 (void *)&cmd_5tuple_filter_port_id,
7648                 (void *)&cmd_5tuple_filter_ops,
7649                 (void *)&cmd_5tuple_filter_dst_ip,
7650                 (void *)&cmd_5tuple_filter_dst_ip_value,
7651                 (void *)&cmd_5tuple_filter_src_ip,
7652                 (void *)&cmd_5tuple_filter_src_ip_value,
7653                 (void *)&cmd_5tuple_filter_dst_port,
7654                 (void *)&cmd_5tuple_filter_dst_port_value,
7655                 (void *)&cmd_5tuple_filter_src_port,
7656                 (void *)&cmd_5tuple_filter_src_port_value,
7657                 (void *)&cmd_5tuple_filter_protocol,
7658                 (void *)&cmd_5tuple_filter_protocol_value,
7659                 (void *)&cmd_5tuple_filter_mask,
7660                 (void *)&cmd_5tuple_filter_mask_value,
7661                 (void *)&cmd_5tuple_filter_tcp_flags,
7662                 (void *)&cmd_5tuple_filter_tcp_flags_value,
7663                 (void *)&cmd_5tuple_filter_priority,
7664                 (void *)&cmd_5tuple_filter_priority_value,
7665                 (void *)&cmd_5tuple_filter_queue,
7666                 (void *)&cmd_5tuple_filter_queue_id,
7667                 NULL,
7668         },
7669 };
7670
7671 /* *** ADD/REMOVE A flex FILTER *** */
7672 struct cmd_flex_filter_result {
7673         cmdline_fixed_string_t filter;
7674         cmdline_fixed_string_t ops;
7675         uint8_t port_id;
7676         cmdline_fixed_string_t len;
7677         uint8_t len_value;
7678         cmdline_fixed_string_t bytes;
7679         cmdline_fixed_string_t bytes_value;
7680         cmdline_fixed_string_t mask;
7681         cmdline_fixed_string_t mask_value;
7682         cmdline_fixed_string_t priority;
7683         uint8_t priority_value;
7684         cmdline_fixed_string_t queue;
7685         uint16_t queue_id;
7686 };
7687
7688 static int xdigit2val(unsigned char c)
7689 {
7690         int val;
7691         if (isdigit(c))
7692                 val = c - '0';
7693         else if (isupper(c))
7694                 val = c - 'A' + 10;
7695         else
7696                 val = c - 'a' + 10;
7697         return val;
7698 }
7699
7700 static void
7701 cmd_flex_filter_parsed(void *parsed_result,
7702                           __attribute__((unused)) struct cmdline *cl,
7703                           __attribute__((unused)) void *data)
7704 {
7705         int ret = 0;
7706         struct rte_eth_flex_filter filter;
7707         struct cmd_flex_filter_result *res = parsed_result;
7708         char *bytes_ptr, *mask_ptr;
7709         uint16_t len, i, j = 0;
7710         char c;
7711         int val;
7712         uint8_t byte = 0;
7713
7714         if (res->len_value > RTE_FLEX_FILTER_MAXLEN) {
7715                 printf("the len exceed the max length 128\n");
7716                 return;
7717         }
7718         memset(&filter, 0, sizeof(struct rte_eth_flex_filter));
7719         filter.len = res->len_value;
7720         filter.priority = res->priority_value;
7721         filter.queue = res->queue_id;
7722         bytes_ptr = res->bytes_value;
7723         mask_ptr = res->mask_value;
7724
7725          /* translate bytes string to array. */
7726         if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
7727                 (bytes_ptr[1] == 'X')))
7728                 bytes_ptr += 2;
7729         len = strnlen(bytes_ptr, res->len_value * 2);
7730         if (len == 0 || (len % 8 != 0)) {
7731                 printf("please check len and bytes input\n");
7732                 return;
7733         }
7734         for (i = 0; i < len; i++) {
7735                 c = bytes_ptr[i];
7736                 if (isxdigit(c) == 0) {
7737                         /* invalid characters. */
7738                         printf("invalid input\n");
7739                         return;
7740                 }
7741                 val = xdigit2val(c);
7742                 if (i % 2) {
7743                         byte |= val;
7744                         filter.bytes[j] = byte;
7745                         printf("bytes[%d]:%02x ", j, filter.bytes[j]);
7746                         j++;
7747                         byte = 0;
7748                 } else
7749                         byte |= val << 4;
7750         }
7751         printf("\n");
7752          /* translate mask string to uint8_t array. */
7753         if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
7754                 (mask_ptr[1] == 'X')))
7755                 mask_ptr += 2;
7756         len = strnlen(mask_ptr, (res->len_value + 3) / 4);
7757         if (len == 0) {
7758                 printf("invalid input\n");
7759                 return;
7760         }
7761         j = 0;
7762         byte = 0;
7763         for (i = 0; i < len; i++) {
7764                 c = mask_ptr[i];
7765                 if (isxdigit(c) == 0) {
7766                         /* invalid characters. */
7767                         printf("invalid input\n");
7768                         return;
7769                 }
7770                 val = xdigit2val(c);
7771                 if (i % 2) {
7772                         byte |= val;
7773                         filter.mask[j] = byte;
7774                         printf("mask[%d]:%02x ", j, filter.mask[j]);
7775                         j++;
7776                         byte = 0;
7777                 } else
7778                         byte |= val << 4;
7779         }
7780         printf("\n");
7781
7782         if (!strcmp(res->ops, "add"))
7783                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7784                                 RTE_ETH_FILTER_FLEXIBLE,
7785                                 RTE_ETH_FILTER_ADD,
7786                                 &filter);
7787         else
7788                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7789                                 RTE_ETH_FILTER_FLEXIBLE,
7790                                 RTE_ETH_FILTER_DELETE,
7791                                 &filter);
7792
7793         if (ret < 0)
7794                 printf("flex filter setting error: (%s)\n", strerror(-ret));
7795 }
7796
7797 cmdline_parse_token_string_t cmd_flex_filter_filter =
7798         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7799                                 filter, "flex_filter");
7800 cmdline_parse_token_num_t cmd_flex_filter_port_id =
7801         TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
7802                                 port_id, UINT8);
7803 cmdline_parse_token_string_t cmd_flex_filter_ops =
7804         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7805                                 ops, "add#del");
7806 cmdline_parse_token_string_t cmd_flex_filter_len =
7807         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7808                                 len, "len");
7809 cmdline_parse_token_num_t cmd_flex_filter_len_value =
7810         TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
7811                                 len_value, UINT8);
7812 cmdline_parse_token_string_t cmd_flex_filter_bytes =
7813         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7814                                 bytes, "bytes");
7815 cmdline_parse_token_string_t cmd_flex_filter_bytes_value =
7816         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7817                                 bytes_value, NULL);
7818 cmdline_parse_token_string_t cmd_flex_filter_mask =
7819         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7820                                 mask, "mask");
7821 cmdline_parse_token_string_t cmd_flex_filter_mask_value =
7822         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7823                                 mask_value, NULL);
7824 cmdline_parse_token_string_t cmd_flex_filter_priority =
7825         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7826                                 priority, "priority");
7827 cmdline_parse_token_num_t cmd_flex_filter_priority_value =
7828         TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
7829                                 priority_value, UINT8);
7830 cmdline_parse_token_string_t cmd_flex_filter_queue =
7831         TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
7832                                 queue, "queue");
7833 cmdline_parse_token_num_t cmd_flex_filter_queue_id =
7834         TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
7835                                 queue_id, UINT16);
7836 cmdline_parse_inst_t cmd_flex_filter = {
7837         .f = cmd_flex_filter_parsed,
7838         .data = NULL,
7839         .help_str = "add/del a flex filter",
7840         .tokens = {
7841                 (void *)&cmd_flex_filter_filter,
7842                 (void *)&cmd_flex_filter_port_id,
7843                 (void *)&cmd_flex_filter_ops,
7844                 (void *)&cmd_flex_filter_len,
7845                 (void *)&cmd_flex_filter_len_value,
7846                 (void *)&cmd_flex_filter_bytes,
7847                 (void *)&cmd_flex_filter_bytes_value,
7848                 (void *)&cmd_flex_filter_mask,
7849                 (void *)&cmd_flex_filter_mask_value,
7850                 (void *)&cmd_flex_filter_priority,
7851                 (void *)&cmd_flex_filter_priority_value,
7852                 (void *)&cmd_flex_filter_queue,
7853                 (void *)&cmd_flex_filter_queue_id,
7854                 NULL,
7855         },
7856 };
7857
7858 /* *** Filters Control *** */
7859
7860 /* *** deal with ethertype filter *** */
7861 struct cmd_ethertype_filter_result {
7862         cmdline_fixed_string_t filter;
7863         uint8_t port_id;
7864         cmdline_fixed_string_t ops;
7865         cmdline_fixed_string_t mac;
7866         struct ether_addr mac_addr;
7867         cmdline_fixed_string_t ethertype;
7868         uint16_t ethertype_value;
7869         cmdline_fixed_string_t drop;
7870         cmdline_fixed_string_t queue;
7871         uint16_t  queue_id;
7872 };
7873
7874 cmdline_parse_token_string_t cmd_ethertype_filter_filter =
7875         TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
7876                                  filter, "ethertype_filter");
7877 cmdline_parse_token_num_t cmd_ethertype_filter_port_id =
7878         TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
7879                               port_id, UINT8);
7880 cmdline_parse_token_string_t cmd_ethertype_filter_ops =
7881         TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
7882                                  ops, "add#del");
7883 cmdline_parse_token_string_t cmd_ethertype_filter_mac =
7884         TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
7885                                  mac, "mac_addr#mac_ignr");
7886 cmdline_parse_token_etheraddr_t cmd_ethertype_filter_mac_addr =
7887         TOKEN_ETHERADDR_INITIALIZER(struct cmd_ethertype_filter_result,
7888                                      mac_addr);
7889 cmdline_parse_token_string_t cmd_ethertype_filter_ethertype =
7890         TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
7891                                  ethertype, "ethertype");
7892 cmdline_parse_token_num_t cmd_ethertype_filter_ethertype_value =
7893         TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
7894                               ethertype_value, UINT16);
7895 cmdline_parse_token_string_t cmd_ethertype_filter_drop =
7896         TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
7897                                  drop, "drop#fwd");
7898 cmdline_parse_token_string_t cmd_ethertype_filter_queue =
7899         TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
7900                                  queue, "queue");
7901 cmdline_parse_token_num_t cmd_ethertype_filter_queue_id =
7902         TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
7903                               queue_id, UINT16);
7904
7905 static void
7906 cmd_ethertype_filter_parsed(void *parsed_result,
7907                           __attribute__((unused)) struct cmdline *cl,
7908                           __attribute__((unused)) void *data)
7909 {
7910         struct cmd_ethertype_filter_result *res = parsed_result;
7911         struct rte_eth_ethertype_filter filter;
7912         int ret = 0;
7913
7914         ret = rte_eth_dev_filter_supported(res->port_id,
7915                         RTE_ETH_FILTER_ETHERTYPE);
7916         if (ret < 0) {
7917                 printf("ethertype filter is not supported on port %u.\n",
7918                         res->port_id);
7919                 return;
7920         }
7921
7922         memset(&filter, 0, sizeof(filter));
7923         if (!strcmp(res->mac, "mac_addr")) {
7924                 filter.flags |= RTE_ETHTYPE_FLAGS_MAC;
7925                 (void)rte_memcpy(&filter.mac_addr, &res->mac_addr,
7926                         sizeof(struct ether_addr));
7927         }
7928         if (!strcmp(res->drop, "drop"))
7929                 filter.flags |= RTE_ETHTYPE_FLAGS_DROP;
7930         filter.ether_type = res->ethertype_value;
7931         filter.queue = res->queue_id;
7932
7933         if (!strcmp(res->ops, "add"))
7934                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7935                                 RTE_ETH_FILTER_ETHERTYPE,
7936                                 RTE_ETH_FILTER_ADD,
7937                                 &filter);
7938         else
7939                 ret = rte_eth_dev_filter_ctrl(res->port_id,
7940                                 RTE_ETH_FILTER_ETHERTYPE,
7941                                 RTE_ETH_FILTER_DELETE,
7942                                 &filter);
7943         if (ret < 0)
7944                 printf("ethertype filter programming error: (%s)\n",
7945                         strerror(-ret));
7946 }
7947
7948 cmdline_parse_inst_t cmd_ethertype_filter = {
7949         .f = cmd_ethertype_filter_parsed,
7950         .data = NULL,
7951         .help_str = "add or delete an ethertype filter entry",
7952         .tokens = {
7953                 (void *)&cmd_ethertype_filter_filter,
7954                 (void *)&cmd_ethertype_filter_port_id,
7955                 (void *)&cmd_ethertype_filter_ops,
7956                 (void *)&cmd_ethertype_filter_mac,
7957                 (void *)&cmd_ethertype_filter_mac_addr,
7958                 (void *)&cmd_ethertype_filter_ethertype,
7959                 (void *)&cmd_ethertype_filter_ethertype_value,
7960                 (void *)&cmd_ethertype_filter_drop,
7961                 (void *)&cmd_ethertype_filter_queue,
7962                 (void *)&cmd_ethertype_filter_queue_id,
7963                 NULL,
7964         },
7965 };
7966
7967 /* *** deal with flow director filter *** */
7968 struct cmd_flow_director_result {
7969         cmdline_fixed_string_t flow_director_filter;
7970         uint8_t port_id;
7971         cmdline_fixed_string_t mode;
7972         cmdline_fixed_string_t mode_value;
7973         cmdline_fixed_string_t ops;
7974         cmdline_fixed_string_t flow;
7975         cmdline_fixed_string_t flow_type;
7976         cmdline_fixed_string_t ether;
7977         uint16_t ether_type;
7978         cmdline_fixed_string_t src;
7979         cmdline_ipaddr_t ip_src;
7980         uint16_t port_src;
7981         cmdline_fixed_string_t dst;
7982         cmdline_ipaddr_t ip_dst;
7983         uint16_t port_dst;
7984         cmdline_fixed_string_t verify_tag;
7985         uint32_t verify_tag_value;
7986         cmdline_fixed_string_t vlan;
7987         uint16_t vlan_value;
7988         cmdline_fixed_string_t flexbytes;
7989         cmdline_fixed_string_t flexbytes_value;
7990         cmdline_fixed_string_t pf_vf;
7991         cmdline_fixed_string_t drop;
7992         cmdline_fixed_string_t queue;
7993         uint16_t  queue_id;
7994         cmdline_fixed_string_t fd_id;
7995         uint32_t  fd_id_value;
7996         cmdline_fixed_string_t mac;
7997         struct ether_addr mac_addr;
7998         cmdline_fixed_string_t tunnel;
7999         cmdline_fixed_string_t tunnel_type;
8000         cmdline_fixed_string_t tunnel_id;
8001         uint32_t tunnel_id_value;
8002 };
8003
8004 static inline int
8005 parse_flexbytes(const char *q_arg, uint8_t *flexbytes, uint16_t max_num)
8006 {
8007         char s[256];
8008         const char *p, *p0 = q_arg;
8009         char *end;
8010         unsigned long int_fld;
8011         char *str_fld[max_num];
8012         int i;
8013         unsigned size;
8014         int ret = -1;
8015
8016         p = strchr(p0, '(');
8017         if (p == NULL)
8018                 return -1;
8019         ++p;
8020         p0 = strchr(p, ')');
8021         if (p0 == NULL)
8022                 return -1;
8023
8024         size = p0 - p;
8025         if (size >= sizeof(s))
8026                 return -1;
8027
8028         snprintf(s, sizeof(s), "%.*s", size, p);
8029         ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
8030         if (ret < 0 || ret > max_num)
8031                 return -1;
8032         for (i = 0; i < ret; i++) {
8033                 errno = 0;
8034                 int_fld = strtoul(str_fld[i], &end, 0);
8035                 if (errno != 0 || *end != '\0' || int_fld > UINT8_MAX)
8036                         return -1;
8037                 flexbytes[i] = (uint8_t)int_fld;
8038         }
8039         return ret;
8040 }
8041
8042 static uint16_t
8043 str2flowtype(char *string)
8044 {
8045         uint8_t i = 0;
8046         static const struct {
8047                 char str[32];
8048                 uint16_t type;
8049         } flowtype_str[] = {
8050                 {"raw", RTE_ETH_FLOW_RAW},
8051                 {"ipv4", RTE_ETH_FLOW_IPV4},
8052                 {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
8053                 {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
8054                 {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
8055                 {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
8056                 {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
8057                 {"ipv6", RTE_ETH_FLOW_IPV6},
8058                 {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
8059                 {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
8060                 {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
8061                 {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
8062                 {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
8063                 {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
8064         };
8065
8066         for (i = 0; i < RTE_DIM(flowtype_str); i++) {
8067                 if (!strcmp(flowtype_str[i].str, string))
8068                         return flowtype_str[i].type;
8069         }
8070         return RTE_ETH_FLOW_UNKNOWN;
8071 }
8072
8073 static enum rte_eth_fdir_tunnel_type
8074 str2fdir_tunneltype(char *string)
8075 {
8076         uint8_t i = 0;
8077
8078         static const struct {
8079                 char str[32];
8080                 enum rte_eth_fdir_tunnel_type type;
8081         } tunneltype_str[] = {
8082                 {"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE},
8083                 {"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN},
8084         };
8085
8086         for (i = 0; i < RTE_DIM(tunneltype_str); i++) {
8087                 if (!strcmp(tunneltype_str[i].str, string))
8088                         return tunneltype_str[i].type;
8089         }
8090         return RTE_FDIR_TUNNEL_TYPE_UNKNOWN;
8091 }
8092
8093 #define IPV4_ADDR_TO_UINT(ip_addr, ip) \
8094 do { \
8095         if ((ip_addr).family == AF_INET) \
8096                 (ip) = (ip_addr).addr.ipv4.s_addr; \
8097         else { \
8098                 printf("invalid parameter.\n"); \
8099                 return; \
8100         } \
8101 } while (0)
8102
8103 #define IPV6_ADDR_TO_ARRAY(ip_addr, ip) \
8104 do { \
8105         if ((ip_addr).family == AF_INET6) \
8106                 (void)rte_memcpy(&(ip), \
8107                                  &((ip_addr).addr.ipv6), \
8108                                  sizeof(struct in6_addr)); \
8109         else { \
8110                 printf("invalid parameter.\n"); \
8111                 return; \
8112         } \
8113 } while (0)
8114
8115 static void
8116 cmd_flow_director_filter_parsed(void *parsed_result,
8117                           __attribute__((unused)) struct cmdline *cl,
8118                           __attribute__((unused)) void *data)
8119 {
8120         struct cmd_flow_director_result *res = parsed_result;
8121         struct rte_eth_fdir_filter entry;
8122         uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
8123         char *end;
8124         unsigned long vf_id;
8125         int ret = 0;
8126
8127         ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
8128         if (ret < 0) {
8129                 printf("flow director is not supported on port %u.\n",
8130                         res->port_id);
8131                 return;
8132         }
8133         memset(flexbytes, 0, sizeof(flexbytes));
8134         memset(&entry, 0, sizeof(struct rte_eth_fdir_filter));
8135
8136         if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
8137                 if (strcmp(res->mode_value, "MAC-VLAN")) {
8138                         printf("Please set mode to MAC-VLAN.\n");
8139                         return;
8140                 }
8141         } else if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
8142                 if (strcmp(res->mode_value, "Tunnel")) {
8143                         printf("Please set mode to Tunnel.\n");
8144                         return;
8145                 }
8146         } else {
8147                 if (strcmp(res->mode_value, "IP")) {
8148                         printf("Please set mode to IP.\n");
8149                         return;
8150                 }
8151                 entry.input.flow_type = str2flowtype(res->flow_type);
8152         }
8153
8154         ret = parse_flexbytes(res->flexbytes_value,
8155                                         flexbytes,
8156                                         RTE_ETH_FDIR_MAX_FLEXLEN);
8157         if (ret < 0) {
8158                 printf("error: Cannot parse flexbytes input.\n");
8159                 return;
8160         }
8161
8162         switch (entry.input.flow_type) {
8163         case RTE_ETH_FLOW_FRAG_IPV4:
8164         case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
8165         case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
8166         case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
8167                 IPV4_ADDR_TO_UINT(res->ip_dst,
8168                         entry.input.flow.ip4_flow.dst_ip);
8169                 IPV4_ADDR_TO_UINT(res->ip_src,
8170                         entry.input.flow.ip4_flow.src_ip);
8171                 /* need convert to big endian. */
8172                 entry.input.flow.udp4_flow.dst_port =
8173                                 rte_cpu_to_be_16(res->port_dst);
8174                 entry.input.flow.udp4_flow.src_port =
8175                                 rte_cpu_to_be_16(res->port_src);
8176                 break;
8177         case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
8178                 IPV4_ADDR_TO_UINT(res->ip_dst,
8179                         entry.input.flow.sctp4_flow.ip.dst_ip);
8180                 IPV4_ADDR_TO_UINT(res->ip_src,
8181                         entry.input.flow.sctp4_flow.ip.src_ip);
8182                 /* need convert to big endian. */
8183                 entry.input.flow.sctp4_flow.dst_port =
8184                                 rte_cpu_to_be_16(res->port_dst);
8185                 entry.input.flow.sctp4_flow.src_port =
8186                                 rte_cpu_to_be_16(res->port_src);
8187                 entry.input.flow.sctp4_flow.verify_tag =
8188                                 rte_cpu_to_be_32(res->verify_tag_value);
8189                 break;
8190         case RTE_ETH_FLOW_FRAG_IPV6:
8191         case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
8192         case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
8193         case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
8194                 IPV6_ADDR_TO_ARRAY(res->ip_dst,
8195                         entry.input.flow.ipv6_flow.dst_ip);
8196                 IPV6_ADDR_TO_ARRAY(res->ip_src,
8197                         entry.input.flow.ipv6_flow.src_ip);
8198                 /* need convert to big endian. */
8199                 entry.input.flow.udp6_flow.dst_port =
8200                                 rte_cpu_to_be_16(res->port_dst);
8201                 entry.input.flow.udp6_flow.src_port =
8202                                 rte_cpu_to_be_16(res->port_src);
8203                 break;
8204         case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
8205                 IPV6_ADDR_TO_ARRAY(res->ip_dst,
8206                         entry.input.flow.sctp6_flow.ip.dst_ip);
8207                 IPV6_ADDR_TO_ARRAY(res->ip_src,
8208                         entry.input.flow.sctp6_flow.ip.src_ip);
8209                 /* need convert to big endian. */
8210                 entry.input.flow.sctp6_flow.dst_port =
8211                                 rte_cpu_to_be_16(res->port_dst);
8212                 entry.input.flow.sctp6_flow.src_port =
8213                                 rte_cpu_to_be_16(res->port_src);
8214                 entry.input.flow.sctp6_flow.verify_tag =
8215                                 rte_cpu_to_be_32(res->verify_tag_value);
8216                 break;
8217         case RTE_ETH_FLOW_L2_PAYLOAD:
8218                 entry.input.flow.l2_flow.ether_type =
8219                         rte_cpu_to_be_16(res->ether_type);
8220                 break;
8221         default:
8222                 break;
8223         }
8224
8225         if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN)
8226                 (void)rte_memcpy(&entry.input.flow.mac_vlan_flow.mac_addr,
8227                                  &res->mac_addr,
8228                                  sizeof(struct ether_addr));
8229
8230         if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
8231                 (void)rte_memcpy(&entry.input.flow.tunnel_flow.mac_addr,
8232                                  &res->mac_addr,
8233                                  sizeof(struct ether_addr));
8234                 entry.input.flow.tunnel_flow.tunnel_type =
8235                         str2fdir_tunneltype(res->tunnel_type);
8236                 entry.input.flow.tunnel_flow.tunnel_id =
8237                         rte_cpu_to_be_32(res->tunnel_id_value);
8238         }
8239
8240         (void)rte_memcpy(entry.input.flow_ext.flexbytes,
8241                    flexbytes,
8242                    RTE_ETH_FDIR_MAX_FLEXLEN);
8243
8244         entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
8245
8246         entry.action.flex_off = 0;  /*use 0 by default */
8247         if (!strcmp(res->drop, "drop"))
8248                 entry.action.behavior = RTE_ETH_FDIR_REJECT;
8249         else
8250                 entry.action.behavior = RTE_ETH_FDIR_ACCEPT;
8251
8252         if (!strcmp(res->pf_vf, "pf"))
8253                 entry.input.flow_ext.is_vf = 0;
8254         else if (!strncmp(res->pf_vf, "vf", 2)) {
8255                 struct rte_eth_dev_info dev_info;
8256
8257                 memset(&dev_info, 0, sizeof(dev_info));
8258                 rte_eth_dev_info_get(res->port_id, &dev_info);
8259                 errno = 0;
8260                 vf_id = strtoul(res->pf_vf + 2, &end, 10);
8261                 if (errno != 0 || *end != '\0' || vf_id >= dev_info.max_vfs) {
8262                         printf("invalid parameter %s.\n", res->pf_vf);
8263                         return;
8264                 }
8265                 entry.input.flow_ext.is_vf = 1;
8266                 entry.input.flow_ext.dst_id = (uint16_t)vf_id;
8267         } else {
8268                 printf("invalid parameter %s.\n", res->pf_vf);
8269                 return;
8270         }
8271
8272         /* set to report FD ID by default */
8273         entry.action.report_status = RTE_ETH_FDIR_REPORT_ID;
8274         entry.action.rx_queue = res->queue_id;
8275         entry.soft_id = res->fd_id_value;
8276         if (!strcmp(res->ops, "add"))
8277                 ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8278                                              RTE_ETH_FILTER_ADD, &entry);
8279         else if (!strcmp(res->ops, "del"))
8280                 ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8281                                              RTE_ETH_FILTER_DELETE, &entry);
8282         else
8283                 ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8284                                              RTE_ETH_FILTER_UPDATE, &entry);
8285         if (ret < 0)
8286                 printf("flow director programming error: (%s)\n",
8287                         strerror(-ret));
8288 }
8289
8290 cmdline_parse_token_string_t cmd_flow_director_filter =
8291         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8292                                  flow_director_filter, "flow_director_filter");
8293 cmdline_parse_token_num_t cmd_flow_director_port_id =
8294         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8295                               port_id, UINT8);
8296 cmdline_parse_token_string_t cmd_flow_director_ops =
8297         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8298                                  ops, "add#del#update");
8299 cmdline_parse_token_string_t cmd_flow_director_flow =
8300         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8301                                  flow, "flow");
8302 cmdline_parse_token_string_t cmd_flow_director_flow_type =
8303         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8304                 flow_type, "ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
8305                 "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload");
8306 cmdline_parse_token_string_t cmd_flow_director_ether =
8307         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8308                                  ether, "ether");
8309 cmdline_parse_token_num_t cmd_flow_director_ether_type =
8310         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8311                               ether_type, UINT16);
8312 cmdline_parse_token_string_t cmd_flow_director_src =
8313         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8314                                  src, "src");
8315 cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src =
8316         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
8317                                  ip_src);
8318 cmdline_parse_token_num_t cmd_flow_director_port_src =
8319         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8320                               port_src, UINT16);
8321 cmdline_parse_token_string_t cmd_flow_director_dst =
8322         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8323                                  dst, "dst");
8324 cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst =
8325         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
8326                                  ip_dst);
8327 cmdline_parse_token_num_t cmd_flow_director_port_dst =
8328         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8329                               port_dst, UINT16);
8330 cmdline_parse_token_string_t cmd_flow_director_verify_tag =
8331         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8332                                   verify_tag, "verify_tag");
8333 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
8334         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8335                               verify_tag_value, UINT32);
8336 cmdline_parse_token_string_t cmd_flow_director_vlan =
8337         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8338                                  vlan, "vlan");
8339 cmdline_parse_token_num_t cmd_flow_director_vlan_value =
8340         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8341                               vlan_value, UINT16);
8342 cmdline_parse_token_string_t cmd_flow_director_flexbytes =
8343         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8344                                  flexbytes, "flexbytes");
8345 cmdline_parse_token_string_t cmd_flow_director_flexbytes_value =
8346         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8347                               flexbytes_value, NULL);
8348 cmdline_parse_token_string_t cmd_flow_director_drop =
8349         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8350                                  drop, "drop#fwd");
8351 cmdline_parse_token_string_t cmd_flow_director_pf_vf =
8352         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8353                               pf_vf, NULL);
8354 cmdline_parse_token_string_t cmd_flow_director_queue =
8355         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8356                                  queue, "queue");
8357 cmdline_parse_token_num_t cmd_flow_director_queue_id =
8358         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8359                               queue_id, UINT16);
8360 cmdline_parse_token_string_t cmd_flow_director_fd_id =
8361         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8362                                  fd_id, "fd_id");
8363 cmdline_parse_token_num_t cmd_flow_director_fd_id_value =
8364         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8365                               fd_id_value, UINT32);
8366
8367 cmdline_parse_token_string_t cmd_flow_director_mode =
8368         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8369                                  mode, "mode");
8370 cmdline_parse_token_string_t cmd_flow_director_mode_ip =
8371         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8372                                  mode_value, "IP");
8373 cmdline_parse_token_string_t cmd_flow_director_mode_mac_vlan =
8374         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8375                                  mode_value, "MAC-VLAN");
8376 cmdline_parse_token_string_t cmd_flow_director_mode_tunnel =
8377         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8378                                  mode_value, "Tunnel");
8379 cmdline_parse_token_string_t cmd_flow_director_mac =
8380         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8381                                  mac, "mac");
8382 cmdline_parse_token_etheraddr_t cmd_flow_director_mac_addr =
8383         TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result,
8384                                     mac_addr);
8385 cmdline_parse_token_string_t cmd_flow_director_tunnel =
8386         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8387                                  tunnel, "tunnel");
8388 cmdline_parse_token_string_t cmd_flow_director_tunnel_type =
8389         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8390                                  tunnel_type, "NVGRE#VxLAN");
8391 cmdline_parse_token_string_t cmd_flow_director_tunnel_id =
8392         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8393                                  tunnel_id, "tunnel-id");
8394 cmdline_parse_token_num_t cmd_flow_director_tunnel_id_value =
8395         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8396                               tunnel_id_value, UINT32);
8397
8398 cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
8399         .f = cmd_flow_director_filter_parsed,
8400         .data = NULL,
8401         .help_str = "add or delete an ip flow director entry on NIC",
8402         .tokens = {
8403                 (void *)&cmd_flow_director_filter,
8404                 (void *)&cmd_flow_director_port_id,
8405                 (void *)&cmd_flow_director_mode,
8406                 (void *)&cmd_flow_director_mode_ip,
8407                 (void *)&cmd_flow_director_ops,
8408                 (void *)&cmd_flow_director_flow,
8409                 (void *)&cmd_flow_director_flow_type,
8410                 (void *)&cmd_flow_director_src,
8411                 (void *)&cmd_flow_director_ip_src,
8412                 (void *)&cmd_flow_director_dst,
8413                 (void *)&cmd_flow_director_ip_dst,
8414                 (void *)&cmd_flow_director_vlan,
8415                 (void *)&cmd_flow_director_vlan_value,
8416                 (void *)&cmd_flow_director_flexbytes,
8417                 (void *)&cmd_flow_director_flexbytes_value,
8418                 (void *)&cmd_flow_director_drop,
8419                 (void *)&cmd_flow_director_pf_vf,
8420                 (void *)&cmd_flow_director_queue,
8421                 (void *)&cmd_flow_director_queue_id,
8422                 (void *)&cmd_flow_director_fd_id,
8423                 (void *)&cmd_flow_director_fd_id_value,
8424                 NULL,
8425         },
8426 };
8427
8428 cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
8429         .f = cmd_flow_director_filter_parsed,
8430         .data = NULL,
8431         .help_str = "add or delete an udp/tcp flow director entry on NIC",
8432         .tokens = {
8433                 (void *)&cmd_flow_director_filter,
8434                 (void *)&cmd_flow_director_port_id,
8435                 (void *)&cmd_flow_director_mode,
8436                 (void *)&cmd_flow_director_mode_ip,
8437                 (void *)&cmd_flow_director_ops,
8438                 (void *)&cmd_flow_director_flow,
8439                 (void *)&cmd_flow_director_flow_type,
8440                 (void *)&cmd_flow_director_src,
8441                 (void *)&cmd_flow_director_ip_src,
8442                 (void *)&cmd_flow_director_port_src,
8443                 (void *)&cmd_flow_director_dst,
8444                 (void *)&cmd_flow_director_ip_dst,
8445                 (void *)&cmd_flow_director_port_dst,
8446                 (void *)&cmd_flow_director_vlan,
8447                 (void *)&cmd_flow_director_vlan_value,
8448                 (void *)&cmd_flow_director_flexbytes,
8449                 (void *)&cmd_flow_director_flexbytes_value,
8450                 (void *)&cmd_flow_director_drop,
8451                 (void *)&cmd_flow_director_pf_vf,
8452                 (void *)&cmd_flow_director_queue,
8453                 (void *)&cmd_flow_director_queue_id,
8454                 (void *)&cmd_flow_director_fd_id,
8455                 (void *)&cmd_flow_director_fd_id_value,
8456                 NULL,
8457         },
8458 };
8459
8460 cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
8461         .f = cmd_flow_director_filter_parsed,
8462         .data = NULL,
8463         .help_str = "add or delete a sctp flow director entry on NIC",
8464         .tokens = {
8465                 (void *)&cmd_flow_director_filter,
8466                 (void *)&cmd_flow_director_port_id,
8467                 (void *)&cmd_flow_director_mode,
8468                 (void *)&cmd_flow_director_mode_ip,
8469                 (void *)&cmd_flow_director_ops,
8470                 (void *)&cmd_flow_director_flow,
8471                 (void *)&cmd_flow_director_flow_type,
8472                 (void *)&cmd_flow_director_src,
8473                 (void *)&cmd_flow_director_ip_src,
8474                 (void *)&cmd_flow_director_port_dst,
8475                 (void *)&cmd_flow_director_dst,
8476                 (void *)&cmd_flow_director_ip_dst,
8477                 (void *)&cmd_flow_director_port_dst,
8478                 (void *)&cmd_flow_director_verify_tag,
8479                 (void *)&cmd_flow_director_verify_tag_value,
8480                 (void *)&cmd_flow_director_vlan,
8481                 (void *)&cmd_flow_director_vlan_value,
8482                 (void *)&cmd_flow_director_flexbytes,
8483                 (void *)&cmd_flow_director_flexbytes_value,
8484                 (void *)&cmd_flow_director_drop,
8485                 (void *)&cmd_flow_director_pf_vf,
8486                 (void *)&cmd_flow_director_queue,
8487                 (void *)&cmd_flow_director_queue_id,
8488                 (void *)&cmd_flow_director_fd_id,
8489                 (void *)&cmd_flow_director_fd_id_value,
8490                 NULL,
8491         },
8492 };
8493
8494 cmdline_parse_inst_t cmd_add_del_l2_flow_director = {
8495         .f = cmd_flow_director_filter_parsed,
8496         .data = NULL,
8497         .help_str = "add or delete a L2 flow director entry on NIC",
8498         .tokens = {
8499                 (void *)&cmd_flow_director_filter,
8500                 (void *)&cmd_flow_director_port_id,
8501                 (void *)&cmd_flow_director_mode,
8502                 (void *)&cmd_flow_director_mode_ip,
8503                 (void *)&cmd_flow_director_ops,
8504                 (void *)&cmd_flow_director_flow,
8505                 (void *)&cmd_flow_director_flow_type,
8506                 (void *)&cmd_flow_director_ether,
8507                 (void *)&cmd_flow_director_ether_type,
8508                 (void *)&cmd_flow_director_flexbytes,
8509                 (void *)&cmd_flow_director_flexbytes_value,
8510                 (void *)&cmd_flow_director_drop,
8511                 (void *)&cmd_flow_director_pf_vf,
8512                 (void *)&cmd_flow_director_queue,
8513                 (void *)&cmd_flow_director_queue_id,
8514                 (void *)&cmd_flow_director_fd_id,
8515                 (void *)&cmd_flow_director_fd_id_value,
8516                 NULL,
8517         },
8518 };
8519
8520 cmdline_parse_inst_t cmd_add_del_mac_vlan_flow_director = {
8521         .f = cmd_flow_director_filter_parsed,
8522         .data = NULL,
8523         .help_str = "add or delete a MAC VLAN flow director entry on NIC",
8524         .tokens = {
8525                 (void *)&cmd_flow_director_filter,
8526                 (void *)&cmd_flow_director_port_id,
8527                 (void *)&cmd_flow_director_mode,
8528                 (void *)&cmd_flow_director_mode_mac_vlan,
8529                 (void *)&cmd_flow_director_ops,
8530                 (void *)&cmd_flow_director_mac,
8531                 (void *)&cmd_flow_director_mac_addr,
8532                 (void *)&cmd_flow_director_vlan,
8533                 (void *)&cmd_flow_director_vlan_value,
8534                 (void *)&cmd_flow_director_flexbytes,
8535                 (void *)&cmd_flow_director_flexbytes_value,
8536                 (void *)&cmd_flow_director_drop,
8537                 (void *)&cmd_flow_director_queue,
8538                 (void *)&cmd_flow_director_queue_id,
8539                 (void *)&cmd_flow_director_fd_id,
8540                 (void *)&cmd_flow_director_fd_id_value,
8541                 NULL,
8542         },
8543 };
8544
8545 cmdline_parse_inst_t cmd_add_del_tunnel_flow_director = {
8546         .f = cmd_flow_director_filter_parsed,
8547         .data = NULL,
8548         .help_str = "add or delete a tunnel flow director entry on NIC",
8549         .tokens = {
8550                 (void *)&cmd_flow_director_filter,
8551                 (void *)&cmd_flow_director_port_id,
8552                 (void *)&cmd_flow_director_mode,
8553                 (void *)&cmd_flow_director_mode_tunnel,
8554                 (void *)&cmd_flow_director_ops,
8555                 (void *)&cmd_flow_director_mac,
8556                 (void *)&cmd_flow_director_mac_addr,
8557                 (void *)&cmd_flow_director_vlan,
8558                 (void *)&cmd_flow_director_vlan_value,
8559                 (void *)&cmd_flow_director_tunnel,
8560                 (void *)&cmd_flow_director_tunnel_type,
8561                 (void *)&cmd_flow_director_tunnel_id,
8562                 (void *)&cmd_flow_director_tunnel_id_value,
8563                 (void *)&cmd_flow_director_flexbytes,
8564                 (void *)&cmd_flow_director_flexbytes_value,
8565                 (void *)&cmd_flow_director_drop,
8566                 (void *)&cmd_flow_director_queue,
8567                 (void *)&cmd_flow_director_queue_id,
8568                 (void *)&cmd_flow_director_fd_id,
8569                 (void *)&cmd_flow_director_fd_id_value,
8570                 NULL,
8571         },
8572 };
8573
8574 struct cmd_flush_flow_director_result {
8575         cmdline_fixed_string_t flush_flow_director;
8576         uint8_t port_id;
8577 };
8578
8579 cmdline_parse_token_string_t cmd_flush_flow_director_flush =
8580         TOKEN_STRING_INITIALIZER(struct cmd_flush_flow_director_result,
8581                                  flush_flow_director, "flush_flow_director");
8582 cmdline_parse_token_num_t cmd_flush_flow_director_port_id =
8583         TOKEN_NUM_INITIALIZER(struct cmd_flush_flow_director_result,
8584                               port_id, UINT8);
8585
8586 static void
8587 cmd_flush_flow_director_parsed(void *parsed_result,
8588                           __attribute__((unused)) struct cmdline *cl,
8589                           __attribute__((unused)) void *data)
8590 {
8591         struct cmd_flow_director_result *res = parsed_result;
8592         int ret = 0;
8593
8594         ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
8595         if (ret < 0) {
8596                 printf("flow director is not supported on port %u.\n",
8597                         res->port_id);
8598                 return;
8599         }
8600
8601         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8602                         RTE_ETH_FILTER_FLUSH, NULL);
8603         if (ret < 0)
8604                 printf("flow director table flushing error: (%s)\n",
8605                         strerror(-ret));
8606 }
8607
8608 cmdline_parse_inst_t cmd_flush_flow_director = {
8609         .f = cmd_flush_flow_director_parsed,
8610         .data = NULL,
8611         .help_str = "flush all flow director entries of a device on NIC",
8612         .tokens = {
8613                 (void *)&cmd_flush_flow_director_flush,
8614                 (void *)&cmd_flush_flow_director_port_id,
8615                 NULL,
8616         },
8617 };
8618
8619 /* *** deal with flow director mask *** */
8620 struct cmd_flow_director_mask_result {
8621         cmdline_fixed_string_t flow_director_mask;
8622         uint8_t port_id;
8623         cmdline_fixed_string_t mode;
8624         cmdline_fixed_string_t mode_value;
8625         cmdline_fixed_string_t vlan;
8626         uint16_t vlan_mask;
8627         cmdline_fixed_string_t src_mask;
8628         cmdline_ipaddr_t ipv4_src;
8629         cmdline_ipaddr_t ipv6_src;
8630         uint16_t port_src;
8631         cmdline_fixed_string_t dst_mask;
8632         cmdline_ipaddr_t ipv4_dst;
8633         cmdline_ipaddr_t ipv6_dst;
8634         uint16_t port_dst;
8635         cmdline_fixed_string_t mac;
8636         uint8_t mac_addr_byte_mask;
8637         cmdline_fixed_string_t tunnel_id;
8638         uint32_t tunnel_id_mask;
8639         cmdline_fixed_string_t tunnel_type;
8640         uint8_t tunnel_type_mask;
8641 };
8642
8643 static void
8644 cmd_flow_director_mask_parsed(void *parsed_result,
8645                           __attribute__((unused)) struct cmdline *cl,
8646                           __attribute__((unused)) void *data)
8647 {
8648         struct cmd_flow_director_mask_result *res = parsed_result;
8649         struct rte_eth_fdir_masks *mask;
8650         struct rte_port *port;
8651
8652         if (res->port_id > nb_ports) {
8653                 printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
8654                 return;
8655         }
8656
8657         port = &ports[res->port_id];
8658         /** Check if the port is not started **/
8659         if (port->port_status != RTE_PORT_STOPPED) {
8660                 printf("Please stop port %d first\n", res->port_id);
8661                 return;
8662         }
8663
8664         mask = &port->dev_conf.fdir_conf.mask;
8665
8666         if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
8667                 if (strcmp(res->mode_value, "MAC-VLAN")) {
8668                         printf("Please set mode to MAC-VLAN.\n");
8669                         return;
8670                 }
8671
8672                 mask->vlan_tci_mask = res->vlan_mask;
8673                 mask->mac_addr_byte_mask = res->mac_addr_byte_mask;
8674         } else if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
8675                 if (strcmp(res->mode_value, "Tunnel")) {
8676                         printf("Please set mode to Tunnel.\n");
8677                         return;
8678                 }
8679
8680                 mask->vlan_tci_mask = res->vlan_mask;
8681                 mask->mac_addr_byte_mask = res->mac_addr_byte_mask;
8682                 mask->tunnel_id_mask = res->tunnel_id_mask;
8683                 mask->tunnel_type_mask = res->tunnel_type_mask;
8684         } else {
8685                 if (strcmp(res->mode_value, "IP")) {
8686                         printf("Please set mode to IP.\n");
8687                         return;
8688                 }
8689
8690                 mask->vlan_tci_mask = res->vlan_mask;
8691                 IPV4_ADDR_TO_UINT(res->ipv4_src, mask->ipv4_mask.src_ip);
8692                 IPV4_ADDR_TO_UINT(res->ipv4_dst, mask->ipv4_mask.dst_ip);
8693                 IPV6_ADDR_TO_ARRAY(res->ipv6_src, mask->ipv6_mask.src_ip);
8694                 IPV6_ADDR_TO_ARRAY(res->ipv6_dst, mask->ipv6_mask.dst_ip);
8695                 mask->src_port_mask = res->port_src;
8696                 mask->dst_port_mask = res->port_dst;
8697         }
8698
8699         cmd_reconfig_device_queue(res->port_id, 1, 1);
8700 }
8701
8702 cmdline_parse_token_string_t cmd_flow_director_mask =
8703         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8704                                  flow_director_mask, "flow_director_mask");
8705 cmdline_parse_token_num_t cmd_flow_director_mask_port_id =
8706         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
8707                               port_id, UINT8);
8708 cmdline_parse_token_string_t cmd_flow_director_mask_vlan =
8709         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8710                                  vlan, "vlan");
8711 cmdline_parse_token_num_t cmd_flow_director_mask_vlan_value =
8712         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
8713                               vlan_mask, UINT16);
8714 cmdline_parse_token_string_t cmd_flow_director_mask_src =
8715         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8716                                  src_mask, "src_mask");
8717 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_src =
8718         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
8719                                  ipv4_src);
8720 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_src =
8721         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
8722                                  ipv6_src);
8723 cmdline_parse_token_num_t cmd_flow_director_mask_port_src =
8724         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
8725                               port_src, UINT16);
8726 cmdline_parse_token_string_t cmd_flow_director_mask_dst =
8727         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8728                                  dst_mask, "dst_mask");
8729 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_dst =
8730         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
8731                                  ipv4_dst);
8732 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_dst =
8733         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
8734                                  ipv6_dst);
8735 cmdline_parse_token_num_t cmd_flow_director_mask_port_dst =
8736         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
8737                               port_dst, UINT16);
8738
8739 cmdline_parse_token_string_t cmd_flow_director_mask_mode =
8740         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8741                                  mode, "mode");
8742 cmdline_parse_token_string_t cmd_flow_director_mask_mode_ip =
8743         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8744                                  mode_value, "IP");
8745 cmdline_parse_token_string_t cmd_flow_director_mask_mode_mac_vlan =
8746         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8747                                  mode_value, "MAC-VLAN");
8748 cmdline_parse_token_string_t cmd_flow_director_mask_mode_tunnel =
8749         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8750                                  mode_value, "Tunnel");
8751 cmdline_parse_token_string_t cmd_flow_director_mask_mac =
8752         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8753                                  mac, "mac");
8754 cmdline_parse_token_num_t cmd_flow_director_mask_mac_value =
8755         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
8756                               mac_addr_byte_mask, UINT8);
8757 cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_type =
8758         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8759                                  tunnel_type, "tunnel-type");
8760 cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_type_value =
8761         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
8762                               tunnel_type_mask, UINT8);
8763 cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_id =
8764         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
8765                                  tunnel_id, "tunnel-id");
8766 cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_id_value =
8767         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
8768                               tunnel_id_mask, UINT32);
8769
8770 cmdline_parse_inst_t cmd_set_flow_director_ip_mask = {
8771         .f = cmd_flow_director_mask_parsed,
8772         .data = NULL,
8773         .help_str = "set IP mode flow director's mask on NIC",
8774         .tokens = {
8775                 (void *)&cmd_flow_director_mask,
8776                 (void *)&cmd_flow_director_mask_port_id,
8777                 (void *)&cmd_flow_director_mask_mode,
8778                 (void *)&cmd_flow_director_mask_mode_ip,
8779                 (void *)&cmd_flow_director_mask_vlan,
8780                 (void *)&cmd_flow_director_mask_vlan_value,
8781                 (void *)&cmd_flow_director_mask_src,
8782                 (void *)&cmd_flow_director_mask_ipv4_src,
8783                 (void *)&cmd_flow_director_mask_ipv6_src,
8784                 (void *)&cmd_flow_director_mask_port_src,
8785                 (void *)&cmd_flow_director_mask_dst,
8786                 (void *)&cmd_flow_director_mask_ipv4_dst,
8787                 (void *)&cmd_flow_director_mask_ipv6_dst,
8788                 (void *)&cmd_flow_director_mask_port_dst,
8789                 NULL,
8790         },
8791 };
8792
8793 cmdline_parse_inst_t cmd_set_flow_director_mac_vlan_mask = {
8794         .f = cmd_flow_director_mask_parsed,
8795         .data = NULL,
8796         .help_str = "set MAC VLAN mode flow director's mask on NIC",
8797         .tokens = {
8798                 (void *)&cmd_flow_director_mask,
8799                 (void *)&cmd_flow_director_mask_port_id,
8800                 (void *)&cmd_flow_director_mask_mode,
8801                 (void *)&cmd_flow_director_mask_mode_mac_vlan,
8802                 (void *)&cmd_flow_director_mask_vlan,
8803                 (void *)&cmd_flow_director_mask_vlan_value,
8804                 (void *)&cmd_flow_director_mask_mac,
8805                 (void *)&cmd_flow_director_mask_mac_value,
8806                 NULL,
8807         },
8808 };
8809
8810 cmdline_parse_inst_t cmd_set_flow_director_tunnel_mask = {
8811         .f = cmd_flow_director_mask_parsed,
8812         .data = NULL,
8813         .help_str = "set tunnel mode flow director's mask on NIC",
8814         .tokens = {
8815                 (void *)&cmd_flow_director_mask,
8816                 (void *)&cmd_flow_director_mask_port_id,
8817                 (void *)&cmd_flow_director_mask_mode,
8818                 (void *)&cmd_flow_director_mask_mode_tunnel,
8819                 (void *)&cmd_flow_director_mask_vlan,
8820                 (void *)&cmd_flow_director_mask_vlan_value,
8821                 (void *)&cmd_flow_director_mask_mac,
8822                 (void *)&cmd_flow_director_mask_mac_value,
8823                 (void *)&cmd_flow_director_mask_tunnel_type,
8824                 (void *)&cmd_flow_director_mask_tunnel_type_value,
8825                 (void *)&cmd_flow_director_mask_tunnel_id,
8826                 (void *)&cmd_flow_director_mask_tunnel_id_value,
8827                 NULL,
8828         },
8829 };
8830
8831 /* *** deal with flow director mask on flexible payload *** */
8832 struct cmd_flow_director_flex_mask_result {
8833         cmdline_fixed_string_t flow_director_flexmask;
8834         uint8_t port_id;
8835         cmdline_fixed_string_t flow;
8836         cmdline_fixed_string_t flow_type;
8837         cmdline_fixed_string_t mask;
8838 };
8839
8840 static void
8841 cmd_flow_director_flex_mask_parsed(void *parsed_result,
8842                           __attribute__((unused)) struct cmdline *cl,
8843                           __attribute__((unused)) void *data)
8844 {
8845         struct cmd_flow_director_flex_mask_result *res = parsed_result;
8846         struct rte_eth_fdir_info fdir_info;
8847         struct rte_eth_fdir_flex_mask flex_mask;
8848         struct rte_port *port;
8849         uint32_t flow_type_mask;
8850         uint16_t i;
8851         int ret;
8852
8853         if (res->port_id > nb_ports) {
8854                 printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
8855                 return;
8856         }
8857
8858         port = &ports[res->port_id];
8859         /** Check if the port is not started **/
8860         if (port->port_status != RTE_PORT_STOPPED) {
8861                 printf("Please stop port %d first\n", res->port_id);
8862                 return;
8863         }
8864
8865         memset(&flex_mask, 0, sizeof(struct rte_eth_fdir_flex_mask));
8866         ret = parse_flexbytes(res->mask,
8867                         flex_mask.mask,
8868                         RTE_ETH_FDIR_MAX_FLEXLEN);
8869         if (ret < 0) {
8870                 printf("error: Cannot parse mask input.\n");
8871                 return;
8872         }
8873
8874         memset(&fdir_info, 0, sizeof(fdir_info));
8875         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8876                                 RTE_ETH_FILTER_INFO, &fdir_info);
8877         if (ret < 0) {
8878                 printf("Cannot get FDir filter info\n");
8879                 return;
8880         }
8881
8882         if (!strcmp(res->flow_type, "none")) {
8883                 /* means don't specify the flow type */
8884                 flex_mask.flow_type = RTE_ETH_FLOW_UNKNOWN;
8885                 for (i = 0; i < RTE_ETH_FLOW_MAX; i++)
8886                         memset(&port->dev_conf.fdir_conf.flex_conf.flex_mask[i],
8887                                0, sizeof(struct rte_eth_fdir_flex_mask));
8888                 port->dev_conf.fdir_conf.flex_conf.nb_flexmasks = 1;
8889                 (void)rte_memcpy(&port->dev_conf.fdir_conf.flex_conf.flex_mask[0],
8890                                  &flex_mask,
8891                                  sizeof(struct rte_eth_fdir_flex_mask));
8892                 cmd_reconfig_device_queue(res->port_id, 1, 1);
8893                 return;
8894         }
8895         flow_type_mask = fdir_info.flow_types_mask[0];
8896         if (!strcmp(res->flow_type, "all")) {
8897                 if (!flow_type_mask) {
8898                         printf("No flow type supported\n");
8899                         return;
8900                 }
8901                 for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) {
8902                         if (flow_type_mask & (1 << i)) {
8903                                 flex_mask.flow_type = i;
8904                                 fdir_set_flex_mask(res->port_id, &flex_mask);
8905                         }
8906                 }
8907                 cmd_reconfig_device_queue(res->port_id, 1, 1);
8908                 return;
8909         }
8910         flex_mask.flow_type = str2flowtype(res->flow_type);
8911         if (!(flow_type_mask & (1 << flex_mask.flow_type))) {
8912                 printf("Flow type %s not supported on port %d\n",
8913                                 res->flow_type, res->port_id);
8914                 return;
8915         }
8916         fdir_set_flex_mask(res->port_id, &flex_mask);
8917         cmd_reconfig_device_queue(res->port_id, 1, 1);
8918 }
8919
8920 cmdline_parse_token_string_t cmd_flow_director_flexmask =
8921         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
8922                                  flow_director_flexmask,
8923                                  "flow_director_flex_mask");
8924 cmdline_parse_token_num_t cmd_flow_director_flexmask_port_id =
8925         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flex_mask_result,
8926                               port_id, UINT8);
8927 cmdline_parse_token_string_t cmd_flow_director_flexmask_flow =
8928         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
8929                                  flow, "flow");
8930 cmdline_parse_token_string_t cmd_flow_director_flexmask_flow_type =
8931         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
8932                 flow_type, "none#ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
8933                 "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload#all");
8934 cmdline_parse_token_string_t cmd_flow_director_flexmask_mask =
8935         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
8936                                  mask, NULL);
8937
8938 cmdline_parse_inst_t cmd_set_flow_director_flex_mask = {
8939         .f = cmd_flow_director_flex_mask_parsed,
8940         .data = NULL,
8941         .help_str = "set flow director's flex mask on NIC",
8942         .tokens = {
8943                 (void *)&cmd_flow_director_flexmask,
8944                 (void *)&cmd_flow_director_flexmask_port_id,
8945                 (void *)&cmd_flow_director_flexmask_flow,
8946                 (void *)&cmd_flow_director_flexmask_flow_type,
8947                 (void *)&cmd_flow_director_flexmask_mask,
8948                 NULL,
8949         },
8950 };
8951
8952 /* *** deal with flow director flexible payload configuration *** */
8953 struct cmd_flow_director_flexpayload_result {
8954         cmdline_fixed_string_t flow_director_flexpayload;
8955         uint8_t port_id;
8956         cmdline_fixed_string_t payload_layer;
8957         cmdline_fixed_string_t payload_cfg;
8958 };
8959
8960 static inline int
8961 parse_offsets(const char *q_arg, uint16_t *offsets, uint16_t max_num)
8962 {
8963         char s[256];
8964         const char *p, *p0 = q_arg;
8965         char *end;
8966         unsigned long int_fld;
8967         char *str_fld[max_num];
8968         int i;
8969         unsigned size;
8970         int ret = -1;
8971
8972         p = strchr(p0, '(');
8973         if (p == NULL)
8974                 return -1;
8975         ++p;
8976         p0 = strchr(p, ')');
8977         if (p0 == NULL)
8978                 return -1;
8979
8980         size = p0 - p;
8981         if (size >= sizeof(s))
8982                 return -1;
8983
8984         snprintf(s, sizeof(s), "%.*s", size, p);
8985         ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
8986         if (ret < 0 || ret > max_num)
8987                 return -1;
8988         for (i = 0; i < ret; i++) {
8989                 errno = 0;
8990                 int_fld = strtoul(str_fld[i], &end, 0);
8991                 if (errno != 0 || *end != '\0' || int_fld > UINT16_MAX)
8992                         return -1;
8993                 offsets[i] = (uint16_t)int_fld;
8994         }
8995         return ret;
8996 }
8997
8998 static void
8999 cmd_flow_director_flxpld_parsed(void *parsed_result,
9000                           __attribute__((unused)) struct cmdline *cl,
9001                           __attribute__((unused)) void *data)
9002 {
9003         struct cmd_flow_director_flexpayload_result *res = parsed_result;
9004         struct rte_eth_flex_payload_cfg flex_cfg;
9005         struct rte_port *port;
9006         int ret = 0;
9007
9008         if (res->port_id > nb_ports) {
9009                 printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
9010                 return;
9011         }
9012
9013         port = &ports[res->port_id];
9014         /** Check if the port is not started **/
9015         if (port->port_status != RTE_PORT_STOPPED) {
9016                 printf("Please stop port %d first\n", res->port_id);
9017                 return;
9018         }
9019
9020         memset(&flex_cfg, 0, sizeof(struct rte_eth_flex_payload_cfg));
9021
9022         if (!strcmp(res->payload_layer, "raw"))
9023                 flex_cfg.type = RTE_ETH_RAW_PAYLOAD;
9024         else if (!strcmp(res->payload_layer, "l2"))
9025                 flex_cfg.type = RTE_ETH_L2_PAYLOAD;
9026         else if (!strcmp(res->payload_layer, "l3"))
9027                 flex_cfg.type = RTE_ETH_L3_PAYLOAD;
9028         else if (!strcmp(res->payload_layer, "l4"))
9029                 flex_cfg.type = RTE_ETH_L4_PAYLOAD;
9030
9031         ret = parse_offsets(res->payload_cfg, flex_cfg.src_offset,
9032                             RTE_ETH_FDIR_MAX_FLEXLEN);
9033         if (ret < 0) {
9034                 printf("error: Cannot parse flex payload input.\n");
9035                 return;
9036         }
9037
9038         fdir_set_flex_payload(res->port_id, &flex_cfg);
9039         cmd_reconfig_device_queue(res->port_id, 1, 1);
9040 }
9041
9042 cmdline_parse_token_string_t cmd_flow_director_flexpayload =
9043         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9044                                  flow_director_flexpayload,
9045                                  "flow_director_flex_payload");
9046 cmdline_parse_token_num_t cmd_flow_director_flexpayload_port_id =
9047         TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9048                               port_id, UINT8);
9049 cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_layer =
9050         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9051                                  payload_layer, "raw#l2#l3#l4");
9052 cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_cfg =
9053         TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9054                                  payload_cfg, NULL);
9055
9056 cmdline_parse_inst_t cmd_set_flow_director_flex_payload = {
9057         .f = cmd_flow_director_flxpld_parsed,
9058         .data = NULL,
9059         .help_str = "set flow director's flex payload on NIC",
9060         .tokens = {
9061                 (void *)&cmd_flow_director_flexpayload,
9062                 (void *)&cmd_flow_director_flexpayload_port_id,
9063                 (void *)&cmd_flow_director_flexpayload_payload_layer,
9064                 (void *)&cmd_flow_director_flexpayload_payload_cfg,
9065                 NULL,
9066         },
9067 };
9068
9069 /* *** Classification Filters Control *** */
9070 /* *** Get symmetric hash enable per port *** */
9071 struct cmd_get_sym_hash_ena_per_port_result {
9072         cmdline_fixed_string_t get_sym_hash_ena_per_port;
9073         uint8_t port_id;
9074 };
9075
9076 static void
9077 cmd_get_sym_hash_per_port_parsed(void *parsed_result,
9078                                  __rte_unused struct cmdline *cl,
9079                                  __rte_unused void *data)
9080 {
9081         struct cmd_get_sym_hash_ena_per_port_result *res = parsed_result;
9082         struct rte_eth_hash_filter_info info;
9083         int ret;
9084
9085         if (rte_eth_dev_filter_supported(res->port_id,
9086                                 RTE_ETH_FILTER_HASH) < 0) {
9087                 printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
9088                                                         res->port_id);
9089                 return;
9090         }
9091
9092         memset(&info, 0, sizeof(info));
9093         info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
9094         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9095                                                 RTE_ETH_FILTER_GET, &info);
9096
9097         if (ret < 0) {
9098                 printf("Cannot get symmetric hash enable per port "
9099                                         "on port %u\n", res->port_id);
9100                 return;
9101         }
9102
9103         printf("Symmetric hash is %s on port %u\n", info.info.enable ?
9104                                 "enabled" : "disabled", res->port_id);
9105 }
9106
9107 cmdline_parse_token_string_t cmd_get_sym_hash_ena_per_port_all =
9108         TOKEN_STRING_INITIALIZER(struct cmd_get_sym_hash_ena_per_port_result,
9109                 get_sym_hash_ena_per_port, "get_sym_hash_ena_per_port");
9110 cmdline_parse_token_num_t cmd_get_sym_hash_ena_per_port_port_id =
9111         TOKEN_NUM_INITIALIZER(struct cmd_get_sym_hash_ena_per_port_result,
9112                 port_id, UINT8);
9113
9114 cmdline_parse_inst_t cmd_get_sym_hash_ena_per_port = {
9115         .f = cmd_get_sym_hash_per_port_parsed,
9116         .data = NULL,
9117         .help_str = "get_sym_hash_ena_per_port port_id",
9118         .tokens = {
9119                 (void *)&cmd_get_sym_hash_ena_per_port_all,
9120                 (void *)&cmd_get_sym_hash_ena_per_port_port_id,
9121                 NULL,
9122         },
9123 };
9124
9125 /* *** Set symmetric hash enable per port *** */
9126 struct cmd_set_sym_hash_ena_per_port_result {
9127         cmdline_fixed_string_t set_sym_hash_ena_per_port;
9128         cmdline_fixed_string_t enable;
9129         uint8_t port_id;
9130 };
9131
9132 static void
9133 cmd_set_sym_hash_per_port_parsed(void *parsed_result,
9134                                  __rte_unused struct cmdline *cl,
9135                                  __rte_unused void *data)
9136 {
9137         struct cmd_set_sym_hash_ena_per_port_result *res = parsed_result;
9138         struct rte_eth_hash_filter_info info;
9139         int ret;
9140
9141         if (rte_eth_dev_filter_supported(res->port_id,
9142                                 RTE_ETH_FILTER_HASH) < 0) {
9143                 printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
9144                                                         res->port_id);
9145                 return;
9146         }
9147
9148         memset(&info, 0, sizeof(info));
9149         info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
9150         if (!strcmp(res->enable, "enable"))
9151                 info.info.enable = 1;
9152         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9153                                         RTE_ETH_FILTER_SET, &info);
9154         if (ret < 0) {
9155                 printf("Cannot set symmetric hash enable per port on "
9156                                         "port %u\n", res->port_id);
9157                 return;
9158         }
9159         printf("Symmetric hash has been set to %s on port %u\n",
9160                                         res->enable, res->port_id);
9161 }
9162
9163 cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_all =
9164         TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
9165                 set_sym_hash_ena_per_port, "set_sym_hash_ena_per_port");
9166 cmdline_parse_token_num_t cmd_set_sym_hash_ena_per_port_port_id =
9167         TOKEN_NUM_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
9168                 port_id, UINT8);
9169 cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_enable =
9170         TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
9171                 enable, "enable#disable");
9172
9173 cmdline_parse_inst_t cmd_set_sym_hash_ena_per_port = {
9174         .f = cmd_set_sym_hash_per_port_parsed,
9175         .data = NULL,
9176         .help_str = "set_sym_hash_ena_per_port port_id enable|disable",
9177         .tokens = {
9178                 (void *)&cmd_set_sym_hash_ena_per_port_all,
9179                 (void *)&cmd_set_sym_hash_ena_per_port_port_id,
9180                 (void *)&cmd_set_sym_hash_ena_per_port_enable,
9181                 NULL,
9182         },
9183 };
9184
9185 /* Get global config of hash function */
9186 struct cmd_get_hash_global_config_result {
9187         cmdline_fixed_string_t get_hash_global_config;
9188         uint8_t port_id;
9189 };
9190
9191 static char *
9192 flowtype_to_str(uint16_t ftype)
9193 {
9194         uint16_t i;
9195         static struct {
9196                 char str[16];
9197                 uint16_t ftype;
9198         } ftype_table[] = {
9199                 {"ipv4", RTE_ETH_FLOW_IPV4},
9200                 {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
9201                 {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
9202                 {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
9203                 {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
9204                 {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
9205                 {"ipv6", RTE_ETH_FLOW_IPV6},
9206                 {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
9207                 {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
9208                 {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
9209                 {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
9210                 {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
9211                 {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
9212         };
9213
9214         for (i = 0; i < RTE_DIM(ftype_table); i++) {
9215                 if (ftype_table[i].ftype == ftype)
9216                         return ftype_table[i].str;
9217         }
9218
9219         return NULL;
9220 }
9221
9222 static void
9223 cmd_get_hash_global_config_parsed(void *parsed_result,
9224                                   __rte_unused struct cmdline *cl,
9225                                   __rte_unused void *data)
9226 {
9227         struct cmd_get_hash_global_config_result *res = parsed_result;
9228         struct rte_eth_hash_filter_info info;
9229         uint32_t idx, offset;
9230         uint16_t i;
9231         char *str;
9232         int ret;
9233
9234         if (rte_eth_dev_filter_supported(res->port_id,
9235                         RTE_ETH_FILTER_HASH) < 0) {
9236                 printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
9237                                                         res->port_id);
9238                 return;
9239         }
9240
9241         memset(&info, 0, sizeof(info));
9242         info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
9243         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9244                                         RTE_ETH_FILTER_GET, &info);
9245         if (ret < 0) {
9246                 printf("Cannot get hash global configurations by port %d\n",
9247                                                         res->port_id);
9248                 return;
9249         }
9250
9251         switch (info.info.global_conf.hash_func) {
9252         case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
9253                 printf("Hash function is Toeplitz\n");
9254                 break;
9255         case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
9256                 printf("Hash function is Simple XOR\n");
9257                 break;
9258         default:
9259                 printf("Unknown hash function\n");
9260                 break;
9261         }
9262
9263         for (i = 0; i < RTE_ETH_FLOW_MAX; i++) {
9264                 idx = i / UINT32_BIT;
9265                 offset = i % UINT32_BIT;
9266                 if (!(info.info.global_conf.valid_bit_mask[idx] &
9267                                                 (1UL << offset)))
9268                         continue;
9269                 str = flowtype_to_str(i);
9270                 if (!str)
9271                         continue;
9272                 printf("Symmetric hash is %s globally for flow type %s "
9273                                                         "by port %d\n",
9274                         ((info.info.global_conf.sym_hash_enable_mask[idx] &
9275                         (1UL << offset)) ? "enabled" : "disabled"), str,
9276                                                         res->port_id);
9277         }
9278 }
9279
9280 cmdline_parse_token_string_t cmd_get_hash_global_config_all =
9281         TOKEN_STRING_INITIALIZER(struct cmd_get_hash_global_config_result,
9282                 get_hash_global_config, "get_hash_global_config");
9283 cmdline_parse_token_num_t cmd_get_hash_global_config_port_id =
9284         TOKEN_NUM_INITIALIZER(struct cmd_get_hash_global_config_result,
9285                 port_id, UINT8);
9286
9287 cmdline_parse_inst_t cmd_get_hash_global_config = {
9288         .f = cmd_get_hash_global_config_parsed,
9289         .data = NULL,
9290         .help_str = "get_hash_global_config port_id",
9291         .tokens = {
9292                 (void *)&cmd_get_hash_global_config_all,
9293                 (void *)&cmd_get_hash_global_config_port_id,
9294                 NULL,
9295         },
9296 };
9297
9298 /* Set global config of hash function */
9299 struct cmd_set_hash_global_config_result {
9300         cmdline_fixed_string_t set_hash_global_config;
9301         uint8_t port_id;
9302         cmdline_fixed_string_t hash_func;
9303         cmdline_fixed_string_t flow_type;
9304         cmdline_fixed_string_t enable;
9305 };
9306
9307 static void
9308 cmd_set_hash_global_config_parsed(void *parsed_result,
9309                                   __rte_unused struct cmdline *cl,
9310                                   __rte_unused void *data)
9311 {
9312         struct cmd_set_hash_global_config_result *res = parsed_result;
9313         struct rte_eth_hash_filter_info info;
9314         uint32_t ftype, idx, offset;
9315         int ret;
9316
9317         if (rte_eth_dev_filter_supported(res->port_id,
9318                                 RTE_ETH_FILTER_HASH) < 0) {
9319                 printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
9320                                                         res->port_id);
9321                 return;
9322         }
9323         memset(&info, 0, sizeof(info));
9324         info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
9325         if (!strcmp(res->hash_func, "toeplitz"))
9326                 info.info.global_conf.hash_func =
9327                         RTE_ETH_HASH_FUNCTION_TOEPLITZ;
9328         else if (!strcmp(res->hash_func, "simple_xor"))
9329                 info.info.global_conf.hash_func =
9330                         RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
9331         else if (!strcmp(res->hash_func, "default"))
9332                 info.info.global_conf.hash_func =
9333                         RTE_ETH_HASH_FUNCTION_DEFAULT;
9334
9335         ftype = str2flowtype(res->flow_type);
9336         idx = ftype / (CHAR_BIT * sizeof(uint32_t));
9337         offset = ftype % (CHAR_BIT * sizeof(uint32_t));
9338         info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
9339         if (!strcmp(res->enable, "enable"))
9340                 info.info.global_conf.sym_hash_enable_mask[idx] |=
9341                                                 (1UL << offset);
9342         ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9343                                         RTE_ETH_FILTER_SET, &info);
9344         if (ret < 0)
9345                 printf("Cannot set global hash configurations by port %d\n",
9346                                                         res->port_id);
9347         else
9348                 printf("Global hash configurations have been set "
9349                         "succcessfully by port %d\n", res->port_id);
9350 }
9351
9352 cmdline_parse_token_string_t cmd_set_hash_global_config_all =
9353         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9354                 set_hash_global_config, "set_hash_global_config");
9355 cmdline_parse_token_num_t cmd_set_hash_global_config_port_id =
9356         TOKEN_NUM_INITIALIZER(struct cmd_set_hash_global_config_result,
9357                 port_id, UINT8);
9358 cmdline_parse_token_string_t cmd_set_hash_global_config_hash_func =
9359         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9360                 hash_func, "toeplitz#simple_xor#default");
9361 cmdline_parse_token_string_t cmd_set_hash_global_config_flow_type =
9362         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9363                 flow_type,
9364                 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
9365                 "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
9366 cmdline_parse_token_string_t cmd_set_hash_global_config_enable =
9367         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9368                 enable, "enable#disable");
9369
9370 cmdline_parse_inst_t cmd_set_hash_global_config = {
9371         .f = cmd_set_hash_global_config_parsed,
9372         .data = NULL,
9373         .help_str = "set_hash_global_config port_id "
9374                 "toeplitz|simple_xor|default "
9375                 "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
9376                 "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
9377                 "enable|disable",
9378         .tokens = {
9379                 (void *)&cmd_set_hash_global_config_all,
9380                 (void *)&cmd_set_hash_global_config_port_id,
9381                 (void *)&cmd_set_hash_global_config_hash_func,
9382                 (void *)&cmd_set_hash_global_config_flow_type,
9383                 (void *)&cmd_set_hash_global_config_enable,
9384                 NULL,
9385         },
9386 };
9387
9388 /* Set hash input set */
9389 struct cmd_set_hash_input_set_result {
9390         cmdline_fixed_string_t set_hash_input_set;
9391         uint8_t port_id;
9392         cmdline_fixed_string_t flow_type;
9393         cmdline_fixed_string_t inset_field;
9394         cmdline_fixed_string_t select;
9395 };
9396
9397 static enum rte_eth_input_set_field
9398 str2inset(char *string)
9399 {
9400         uint16_t i;
9401
9402         static const struct {
9403                 char str[32];
9404                 enum rte_eth_input_set_field inset;
9405         } inset_table[] = {
9406                 {"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
9407                 {"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
9408                 {"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
9409                 {"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
9410                 {"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
9411                 {"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
9412                 {"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
9413                 {"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
9414                 {"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
9415                 {"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
9416                 {"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
9417                 {"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
9418                 {"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
9419                 {"tcp-dst-port", RTE_ETH_INPUT_SET_L4_TCP_DST_PORT},
9420                 {"sctp-src-port", RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT},
9421                 {"sctp-dst-port", RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT},
9422                 {"sctp-veri-tag", RTE_ETH_INPUT_SET_L4_SCTP_VERIFICATION_TAG},
9423                 {"udp-key", RTE_ETH_INPUT_SET_TUNNEL_L4_UDP_KEY},
9424                 {"gre-key", RTE_ETH_INPUT_SET_TUNNEL_GRE_KEY},
9425                 {"fld-1st", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_1ST_WORD},
9426                 {"fld-2nd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_2ND_WORD},
9427                 {"fld-3rd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_3RD_WORD},
9428                 {"fld-4th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_4TH_WORD},
9429                 {"fld-5th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_5TH_WORD},
9430                 {"fld-6th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_6TH_WORD},
9431                 {"fld-7th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_7TH_WORD},
9432                 {"fld-8th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_8TH_WORD},
9433                 {"none", RTE_ETH_INPUT_SET_NONE},
9434         };
9435
9436         for (i = 0; i < RTE_DIM(inset_table); i++) {
9437                 if (!strcmp(string, inset_table[i].str))
9438                         return inset_table[i].inset;
9439         }
9440
9441         return RTE_ETH_INPUT_SET_UNKNOWN;
9442 }
9443
9444 static void
9445 cmd_set_hash_input_set_parsed(void *parsed_result,
9446                               __rte_unused struct cmdline *cl,
9447                               __rte_unused void *data)
9448 {
9449         struct cmd_set_hash_input_set_result *res = parsed_result;
9450         struct rte_eth_hash_filter_info info;
9451
9452         memset(&info, 0, sizeof(info));
9453         info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
9454         info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
9455         info.info.input_set_conf.field[0] = str2inset(res->inset_field);
9456         info.info.input_set_conf.inset_size = 1;
9457         if (!strcmp(res->select, "select"))
9458                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
9459         else if (!strcmp(res->select, "add"))
9460                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
9461         rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9462                                 RTE_ETH_FILTER_SET, &info);
9463 }
9464
9465 cmdline_parse_token_string_t cmd_set_hash_input_set_cmd =
9466         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9467                 set_hash_input_set, "set_hash_input_set");
9468 cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
9469         TOKEN_NUM_INITIALIZER(struct cmd_set_hash_input_set_result,
9470                 port_id, UINT8);
9471 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
9472         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9473                 flow_type,
9474                 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
9475                 "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
9476 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
9477         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9478                 inset_field,
9479                 "ovlan#ivlan#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
9480                 "ipv4-tos#ipv4-proto#ipv6-tc#ipv6-next-header#udp-src-port#"
9481                 "udp-dst-port#tcp-src-port#tcp-dst-port#sctp-src-port#"
9482                 "sctp-dst-port#sctp-veri-tag#udp-key#gre-key#fld-1st#"
9483                 "fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#fld-7th#"
9484                 "fld-8th#none");
9485 cmdline_parse_token_string_t cmd_set_hash_input_set_select =
9486         TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9487                 select, "select#add");
9488
9489 cmdline_parse_inst_t cmd_set_hash_input_set = {
9490         .f = cmd_set_hash_input_set_parsed,
9491         .data = NULL,
9492         .help_str = "set_hash_input_set <port_id> "
9493         "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
9494         "ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
9495         "ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
9496         "ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
9497         "tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
9498         "gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
9499         "fld-7th|fld-8th|none select|add",
9500         .tokens = {
9501                 (void *)&cmd_set_hash_input_set_cmd,
9502                 (void *)&cmd_set_hash_input_set_port_id,
9503                 (void *)&cmd_set_hash_input_set_flow_type,
9504                 (void *)&cmd_set_hash_input_set_field,
9505                 (void *)&cmd_set_hash_input_set_select,
9506                 NULL,
9507         },
9508 };
9509
9510 /* Set flow director input set */
9511 struct cmd_set_fdir_input_set_result {
9512         cmdline_fixed_string_t set_fdir_input_set;
9513         uint8_t port_id;
9514         cmdline_fixed_string_t flow_type;
9515         cmdline_fixed_string_t inset_field;
9516         cmdline_fixed_string_t select;
9517 };
9518
9519 static void
9520 cmd_set_fdir_input_set_parsed(void *parsed_result,
9521         __rte_unused struct cmdline *cl,
9522         __rte_unused void *data)
9523 {
9524         struct cmd_set_fdir_input_set_result *res = parsed_result;
9525         struct rte_eth_fdir_filter_info info;
9526
9527         memset(&info, 0, sizeof(info));
9528         info.info_type = RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT;
9529         info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
9530         info.info.input_set_conf.field[0] = str2inset(res->inset_field);
9531         info.info.input_set_conf.inset_size = 1;
9532         if (!strcmp(res->select, "select"))
9533                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
9534         else if (!strcmp(res->select, "add"))
9535                 info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
9536         rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
9537                 RTE_ETH_FILTER_SET, &info);
9538 }
9539
9540 cmdline_parse_token_string_t cmd_set_fdir_input_set_cmd =
9541         TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
9542         set_fdir_input_set, "set_fdir_input_set");
9543 cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
9544         TOKEN_NUM_INITIALIZER(struct cmd_set_fdir_input_set_result,
9545         port_id, UINT8);
9546 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
9547         TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
9548         flow_type,
9549         "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
9550         "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
9551 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
9552         TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
9553         inset_field,
9554         "src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
9555         "tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
9556         "sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
9557         "fld-7th#fld-8th#none");
9558 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
9559         TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
9560         select, "select#add");
9561
9562 cmdline_parse_inst_t cmd_set_fdir_input_set = {
9563         .f = cmd_set_fdir_input_set_parsed,
9564         .data = NULL,
9565         .help_str = "set_fdir_input_set <port_id> "
9566         "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
9567         "ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
9568         "src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
9569         "tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
9570         "fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
9571         "fld-7th|fld-8th|none select|add",
9572         .tokens = {
9573                 (void *)&cmd_set_fdir_input_set_cmd,
9574                 (void *)&cmd_set_fdir_input_set_port_id,
9575                 (void *)&cmd_set_fdir_input_set_flow_type,
9576                 (void *)&cmd_set_fdir_input_set_field,
9577                 (void *)&cmd_set_fdir_input_set_select,
9578                 NULL,
9579         },
9580 };
9581
9582 /* *** ADD/REMOVE A MULTICAST MAC ADDRESS TO/FROM A PORT *** */
9583 struct cmd_mcast_addr_result {
9584         cmdline_fixed_string_t mcast_addr_cmd;
9585         cmdline_fixed_string_t what;
9586         uint8_t port_num;
9587         struct ether_addr mc_addr;
9588 };
9589
9590 static void cmd_mcast_addr_parsed(void *parsed_result,
9591                 __attribute__((unused)) struct cmdline *cl,
9592                 __attribute__((unused)) void *data)
9593 {
9594         struct cmd_mcast_addr_result *res = parsed_result;
9595
9596         if (!is_multicast_ether_addr(&res->mc_addr)) {
9597                 printf("Invalid multicast addr %02X:%02X:%02X:%02X:%02X:%02X\n",
9598                        res->mc_addr.addr_bytes[0], res->mc_addr.addr_bytes[1],
9599                        res->mc_addr.addr_bytes[2], res->mc_addr.addr_bytes[3],
9600                        res->mc_addr.addr_bytes[4], res->mc_addr.addr_bytes[5]);
9601                 return;
9602         }
9603         if (strcmp(res->what, "add") == 0)
9604                 mcast_addr_add(res->port_num, &res->mc_addr);
9605         else
9606                 mcast_addr_remove(res->port_num, &res->mc_addr);
9607 }
9608
9609 cmdline_parse_token_string_t cmd_mcast_addr_cmd =
9610         TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result,
9611                                  mcast_addr_cmd, "mcast_addr");
9612 cmdline_parse_token_string_t cmd_mcast_addr_what =
9613         TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, what,
9614                                  "add#remove");
9615 cmdline_parse_token_num_t cmd_mcast_addr_portnum =
9616         TOKEN_NUM_INITIALIZER(struct cmd_mcast_addr_result, port_num, UINT8);
9617 cmdline_parse_token_etheraddr_t cmd_mcast_addr_addr =
9618         TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
9619
9620 cmdline_parse_inst_t cmd_mcast_addr = {
9621         .f = cmd_mcast_addr_parsed,
9622         .data = (void *)0,
9623         .help_str = "mcast_addr add|remove X <mcast_addr>: add/remove multicast MAC address on port X",
9624         .tokens = {
9625                 (void *)&cmd_mcast_addr_cmd,
9626                 (void *)&cmd_mcast_addr_what,
9627                 (void *)&cmd_mcast_addr_portnum,
9628                 (void *)&cmd_mcast_addr_addr,
9629                 NULL,
9630         },
9631 };
9632
9633 /* ******************************************************************************** */
9634
9635 /* list of instructions */
9636 cmdline_parse_ctx_t main_ctx[] = {
9637         (cmdline_parse_inst_t *)&cmd_help_brief,
9638         (cmdline_parse_inst_t *)&cmd_help_long,
9639         (cmdline_parse_inst_t *)&cmd_quit,
9640         (cmdline_parse_inst_t *)&cmd_showport,
9641         (cmdline_parse_inst_t *)&cmd_showqueue,
9642         (cmdline_parse_inst_t *)&cmd_showportall,
9643         (cmdline_parse_inst_t *)&cmd_showcfg,
9644         (cmdline_parse_inst_t *)&cmd_start,
9645         (cmdline_parse_inst_t *)&cmd_start_tx_first,
9646         (cmdline_parse_inst_t *)&cmd_set_link_up,
9647         (cmdline_parse_inst_t *)&cmd_set_link_down,
9648         (cmdline_parse_inst_t *)&cmd_reset,
9649         (cmdline_parse_inst_t *)&cmd_set_numbers,
9650         (cmdline_parse_inst_t *)&cmd_set_txpkts,
9651         (cmdline_parse_inst_t *)&cmd_set_txsplit,
9652         (cmdline_parse_inst_t *)&cmd_set_fwd_list,
9653         (cmdline_parse_inst_t *)&cmd_set_fwd_mask,
9654         (cmdline_parse_inst_t *)&cmd_set_fwd_mode,
9655         (cmdline_parse_inst_t *)&cmd_set_burst_tx_retry,
9656         (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one,
9657         (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all,
9658         (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_one,
9659         (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_all,
9660         (cmdline_parse_inst_t *)&cmd_set_flush_rx,
9661         (cmdline_parse_inst_t *)&cmd_set_link_check,
9662 #ifdef RTE_NIC_BYPASS
9663         (cmdline_parse_inst_t *)&cmd_set_bypass_mode,
9664         (cmdline_parse_inst_t *)&cmd_set_bypass_event,
9665         (cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
9666         (cmdline_parse_inst_t *)&cmd_show_bypass_config,
9667 #endif
9668 #ifdef RTE_LIBRTE_PMD_BOND
9669         (cmdline_parse_inst_t *) &cmd_set_bonding_mode,
9670         (cmdline_parse_inst_t *) &cmd_show_bonding_config,
9671         (cmdline_parse_inst_t *) &cmd_set_bonding_primary,
9672         (cmdline_parse_inst_t *) &cmd_add_bonding_slave,
9673         (cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
9674         (cmdline_parse_inst_t *) &cmd_create_bonded_device,
9675         (cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
9676         (cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
9677         (cmdline_parse_inst_t *) &cmd_set_bond_mon_period,
9678 #endif
9679         (cmdline_parse_inst_t *)&cmd_vlan_offload,
9680         (cmdline_parse_inst_t *)&cmd_vlan_tpid,
9681         (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
9682         (cmdline_parse_inst_t *)&cmd_rx_vlan_filter,
9683         (cmdline_parse_inst_t *)&cmd_tx_vlan_set,
9684         (cmdline_parse_inst_t *)&cmd_tx_vlan_set_qinq,
9685         (cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
9686         (cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid,
9687         (cmdline_parse_inst_t *)&cmd_csum_set,
9688         (cmdline_parse_inst_t *)&cmd_csum_show,
9689         (cmdline_parse_inst_t *)&cmd_csum_tunnel,
9690         (cmdline_parse_inst_t *)&cmd_tso_set,
9691         (cmdline_parse_inst_t *)&cmd_tso_show,
9692         (cmdline_parse_inst_t *)&cmd_link_flow_control_set,
9693         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_rx,
9694         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_tx,
9695         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_hw,
9696         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_lw,
9697         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_pt,
9698         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_xon,
9699         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_macfwd,
9700         (cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
9701         (cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
9702         (cmdline_parse_inst_t *)&cmd_config_dcb,
9703         (cmdline_parse_inst_t *)&cmd_read_reg,
9704         (cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
9705         (cmdline_parse_inst_t *)&cmd_read_reg_bit,
9706         (cmdline_parse_inst_t *)&cmd_write_reg,
9707         (cmdline_parse_inst_t *)&cmd_write_reg_bit_field,
9708         (cmdline_parse_inst_t *)&cmd_write_reg_bit,
9709         (cmdline_parse_inst_t *)&cmd_read_rxd_txd,
9710         (cmdline_parse_inst_t *)&cmd_stop,
9711         (cmdline_parse_inst_t *)&cmd_mac_addr,
9712         (cmdline_parse_inst_t *)&cmd_set_qmap,
9713         (cmdline_parse_inst_t *)&cmd_operate_port,
9714         (cmdline_parse_inst_t *)&cmd_operate_specific_port,
9715         (cmdline_parse_inst_t *)&cmd_operate_attach_port,
9716         (cmdline_parse_inst_t *)&cmd_operate_detach_port,
9717         (cmdline_parse_inst_t *)&cmd_config_speed_all,
9718         (cmdline_parse_inst_t *)&cmd_config_speed_specific,
9719         (cmdline_parse_inst_t *)&cmd_config_rx_tx,
9720         (cmdline_parse_inst_t *)&cmd_config_mtu,
9721         (cmdline_parse_inst_t *)&cmd_config_max_pkt_len,
9722         (cmdline_parse_inst_t *)&cmd_config_rx_mode_flag,
9723         (cmdline_parse_inst_t *)&cmd_config_rss,
9724         (cmdline_parse_inst_t *)&cmd_config_rxtx_queue,
9725         (cmdline_parse_inst_t *)&cmd_config_rss_reta,
9726         (cmdline_parse_inst_t *)&cmd_showport_reta,
9727         (cmdline_parse_inst_t *)&cmd_config_burst,
9728         (cmdline_parse_inst_t *)&cmd_config_thresh,
9729         (cmdline_parse_inst_t *)&cmd_config_threshold,
9730         (cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
9731         (cmdline_parse_inst_t *)&cmd_set_uc_hash_filter,
9732         (cmdline_parse_inst_t *)&cmd_set_uc_all_hash_filter,
9733         (cmdline_parse_inst_t *)&cmd_vf_mac_addr_filter,
9734         (cmdline_parse_inst_t *)&cmd_set_vf_macvlan_filter,
9735         (cmdline_parse_inst_t *)&cmd_set_vf_traffic,
9736         (cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
9737         (cmdline_parse_inst_t *)&cmd_queue_rate_limit,
9738         (cmdline_parse_inst_t *)&cmd_vf_rate_limit,
9739         (cmdline_parse_inst_t *)&cmd_tunnel_filter,
9740         (cmdline_parse_inst_t *)&cmd_tunnel_udp_config,
9741         (cmdline_parse_inst_t *)&cmd_global_config,
9742         (cmdline_parse_inst_t *)&cmd_set_mirror_mask,
9743         (cmdline_parse_inst_t *)&cmd_set_mirror_link,
9744         (cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
9745         (cmdline_parse_inst_t *)&cmd_showport_rss_hash,
9746         (cmdline_parse_inst_t *)&cmd_showport_rss_hash_key,
9747         (cmdline_parse_inst_t *)&cmd_config_rss_hash_key,
9748         (cmdline_parse_inst_t *)&cmd_dump,
9749         (cmdline_parse_inst_t *)&cmd_dump_one,
9750         (cmdline_parse_inst_t *)&cmd_ethertype_filter,
9751         (cmdline_parse_inst_t *)&cmd_syn_filter,
9752         (cmdline_parse_inst_t *)&cmd_2tuple_filter,
9753         (cmdline_parse_inst_t *)&cmd_5tuple_filter,
9754         (cmdline_parse_inst_t *)&cmd_flex_filter,
9755         (cmdline_parse_inst_t *)&cmd_add_del_ip_flow_director,
9756         (cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director,
9757         (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
9758         (cmdline_parse_inst_t *)&cmd_add_del_l2_flow_director,
9759         (cmdline_parse_inst_t *)&cmd_add_del_mac_vlan_flow_director,
9760         (cmdline_parse_inst_t *)&cmd_add_del_tunnel_flow_director,
9761         (cmdline_parse_inst_t *)&cmd_flush_flow_director,
9762         (cmdline_parse_inst_t *)&cmd_set_flow_director_ip_mask,
9763         (cmdline_parse_inst_t *)&cmd_set_flow_director_mac_vlan_mask,
9764         (cmdline_parse_inst_t *)&cmd_set_flow_director_tunnel_mask,
9765         (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask,
9766         (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload,
9767         (cmdline_parse_inst_t *)&cmd_get_sym_hash_ena_per_port,
9768         (cmdline_parse_inst_t *)&cmd_set_sym_hash_ena_per_port,
9769         (cmdline_parse_inst_t *)&cmd_get_hash_global_config,
9770         (cmdline_parse_inst_t *)&cmd_set_hash_global_config,
9771         (cmdline_parse_inst_t *)&cmd_set_hash_input_set,
9772         (cmdline_parse_inst_t *)&cmd_set_fdir_input_set,
9773         (cmdline_parse_inst_t *)&cmd_mcast_addr,
9774         NULL,
9775 };
9776
9777 /* prompt function, called from main on MASTER lcore */
9778 void
9779 prompt(void)
9780 {
9781         struct cmdline *cl;
9782
9783         /* initialize non-constant commands */
9784         cmd_set_fwd_mode_init();
9785
9786         cl = cmdline_stdin_new(main_ctx, "testpmd> ");
9787         if (cl == NULL) {
9788                 return;
9789         }
9790         cmdline_interact(cl);
9791         cmdline_stdin_exit(cl);
9792 }
9793
9794 static void
9795 cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue)
9796 {
9797         if (id == (portid_t)RTE_PORT_ALL) {
9798                 portid_t pid;
9799
9800                 FOREACH_PORT(pid, ports) {
9801                         /* check if need_reconfig has been set to 1 */
9802                         if (ports[pid].need_reconfig == 0)
9803                                 ports[pid].need_reconfig = dev;
9804                         /* check if need_reconfig_queues has been set to 1 */
9805                         if (ports[pid].need_reconfig_queues == 0)
9806                                 ports[pid].need_reconfig_queues = queue;
9807                 }
9808         } else if (!port_id_is_invalid(id, DISABLED_WARN)) {
9809                 /* check if need_reconfig has been set to 1 */
9810                 if (ports[id].need_reconfig == 0)
9811                         ports[id].need_reconfig = dev;
9812                 /* check if need_reconfig_queues has been set to 1 */
9813                 if (ports[id].need_reconfig_queues == 0)
9814                         ports[id].need_reconfig_queues = queue;
9815         }
9816 }
9817
9818 #ifdef RTE_NIC_BYPASS
9819 #include <rte_pci_dev_ids.h>
9820 uint8_t
9821 bypass_is_supported(portid_t port_id)
9822 {
9823         struct rte_port   *port;
9824         struct rte_pci_id *pci_id;
9825
9826         if (port_id_is_invalid(port_id, ENABLED_WARN))
9827                 return 0;
9828
9829         /* Get the device id. */
9830         port    = &ports[port_id];
9831         pci_id = &port->dev_info.pci_dev->id;
9832
9833         /* Check if NIC supports bypass. */
9834         if (pci_id->device_id == IXGBE_DEV_ID_82599_BYPASS) {
9835                 return 1;
9836         }
9837         else {
9838                 printf("\tBypass not supported for port_id = %d.\n", port_id);
9839                 return 0;
9840         }
9841 }
9842 #endif