net/ice: support switch flow for specific L4 type
[dpdk.git] / examples / ethtool / ethtool-app / ethapp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015 Intel Corporation
3  */
4
5 #include <cmdline_parse.h>
6 #include <cmdline_parse_num.h>
7 #include <cmdline_parse_string.h>
8 #include <cmdline_parse_etheraddr.h>
9 #include <cmdline_socket.h>
10 #include <cmdline.h>
11
12 #include "rte_ethtool.h"
13 #include "ethapp.h"
14
15 #define EEPROM_DUMP_CHUNKSIZE 1024
16
17
18 struct pcmd_get_params {
19         cmdline_fixed_string_t cmd;
20 };
21 struct pcmd_int_params {
22         cmdline_fixed_string_t cmd;
23         uint16_t port;
24 };
25 struct pcmd_intstr_params {
26         cmdline_fixed_string_t cmd;
27         uint16_t port;
28         cmdline_fixed_string_t opt;
29 };
30 struct pcmd_intmac_params {
31         cmdline_fixed_string_t cmd;
32         uint16_t port;
33         struct rte_ether_addr mac;
34 };
35 struct pcmd_str_params {
36         cmdline_fixed_string_t cmd;
37         cmdline_fixed_string_t opt;
38 };
39 struct pcmd_vlan_params {
40         cmdline_fixed_string_t cmd;
41         uint16_t port;
42         cmdline_fixed_string_t mode;
43         uint16_t vid;
44 };
45 struct pcmd_intintint_params {
46         cmdline_fixed_string_t cmd;
47         uint16_t port;
48         uint16_t tx;
49         uint16_t rx;
50 };
51
52
53 /* Parameter-less commands */
54 cmdline_parse_token_string_t pcmd_quit_token_cmd =
55         TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "quit");
56 cmdline_parse_token_string_t pcmd_stats_token_cmd =
57         TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "stats");
58 cmdline_parse_token_string_t pcmd_drvinfo_token_cmd =
59         TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "drvinfo");
60 cmdline_parse_token_string_t pcmd_link_token_cmd =
61         TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "link");
62
63 /* Commands taking just port id */
64 cmdline_parse_token_string_t pcmd_open_token_cmd =
65         TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "open");
66 cmdline_parse_token_string_t pcmd_stop_token_cmd =
67         TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "stop");
68 cmdline_parse_token_string_t pcmd_rxmode_token_cmd =
69         TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode");
70 cmdline_parse_token_string_t pcmd_portstats_token_cmd =
71         TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats");
72 cmdline_parse_token_num_t pcmd_int_token_port =
73         TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16);
74
75 /* Commands taking port id and string */
76 cmdline_parse_token_string_t pcmd_eeprom_token_cmd =
77         TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "eeprom");
78 cmdline_parse_token_string_t pcmd_module_eeprom_token_cmd =
79         TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd,
80                                  "module-eeprom");
81 cmdline_parse_token_string_t pcmd_mtu_token_cmd =
82         TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "mtu");
83 cmdline_parse_token_string_t pcmd_regs_token_cmd =
84         TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "regs");
85
86 cmdline_parse_token_num_t pcmd_intstr_token_port =
87         TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
88 cmdline_parse_token_string_t pcmd_intstr_token_opt =
89         TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, opt, NULL);
90
91 /* Commands taking port id and a MAC address string */
92 cmdline_parse_token_string_t pcmd_macaddr_token_cmd =
93         TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "macaddr");
94 cmdline_parse_token_num_t pcmd_intmac_token_port =
95         TOKEN_NUM_INITIALIZER(struct pcmd_intmac_params, port, UINT16);
96 cmdline_parse_token_etheraddr_t pcmd_intmac_token_mac =
97         TOKEN_ETHERADDR_INITIALIZER(struct pcmd_intmac_params, mac);
98
99 /* Command taking just a MAC address */
100 cmdline_parse_token_string_t pcmd_validate_token_cmd =
101         TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "validate");
102
103
104 /* Commands taking port id and two integers */
105 cmdline_parse_token_string_t pcmd_ringparam_token_cmd =
106         TOKEN_STRING_INITIALIZER(struct pcmd_intintint_params, cmd,
107                 "ringparam");
108 cmdline_parse_token_num_t pcmd_intintint_token_port =
109         TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, port, UINT16);
110 cmdline_parse_token_num_t pcmd_intintint_token_tx =
111         TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, tx, UINT16);
112 cmdline_parse_token_num_t pcmd_intintint_token_rx =
113         TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, rx, UINT16);
114
115
116 /* Pause commands */
117 cmdline_parse_token_string_t pcmd_pause_token_cmd =
118         TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "pause");
119 cmdline_parse_token_num_t pcmd_pause_token_port =
120         TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
121 cmdline_parse_token_string_t pcmd_pause_token_opt =
122         TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params,
123                 opt, "all#tx#rx#none");
124
125 /* VLAN commands */
126 cmdline_parse_token_string_t pcmd_vlan_token_cmd =
127         TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, cmd, "vlan");
128 cmdline_parse_token_num_t pcmd_vlan_token_port =
129         TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, port, UINT16);
130 cmdline_parse_token_string_t pcmd_vlan_token_mode =
131         TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, mode, "add#del");
132 cmdline_parse_token_num_t pcmd_vlan_token_vid =
133         TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, vid, UINT16);
134
135
136 static void
137 pcmd_quit_callback(__rte_unused void *ptr_params,
138         struct cmdline *ctx,
139         __rte_unused void *ptr_data)
140 {
141         cmdline_quit(ctx);
142 }
143
144
145 static void
146 pcmd_drvinfo_callback(__rte_unused void *ptr_params,
147         __rte_unused struct cmdline *ctx,
148         __rte_unused void *ptr_data)
149 {
150         struct ethtool_drvinfo info;
151         uint16_t id_port;
152
153         RTE_ETH_FOREACH_DEV(id_port) {
154                 memset(&info, 0, sizeof(info));
155                 if (rte_ethtool_get_drvinfo(id_port, &info)) {
156                         printf("Error getting info for port %i\n", id_port);
157                         return;
158                 }
159                 printf("Port %i driver: %s (ver: %s)\n",
160                         id_port, info.driver, info.version
161                       );
162                 printf("firmware-version: %s\n", info.fw_version);
163                 printf("bus-info: %s\n", info.bus_info);
164         }
165 }
166
167
168 static void
169 pcmd_link_callback(__rte_unused void *ptr_params,
170         __rte_unused struct cmdline *ctx,
171         __rte_unused void *ptr_data)
172 {
173         uint16_t id_port;
174         int stat_port;
175
176         RTE_ETH_FOREACH_DEV(id_port) {
177                 if (!rte_eth_dev_is_valid_port(id_port))
178                         continue;
179                 stat_port = rte_ethtool_get_link(id_port);
180                 switch (stat_port) {
181                 case 0:
182                         printf("Port %i: Down\n", id_port);
183                         break;
184                 case 1:
185                         printf("Port %i: Up\n", id_port);
186                         break;
187                 default:
188                         printf("Port %i: Error getting link status\n",
189                                 id_port
190                                 );
191                         break;
192                 }
193         }
194         printf("\n");
195 }
196
197
198 static void
199 pcmd_regs_callback(void *ptr_params,
200         __rte_unused struct cmdline *ctx,
201         __rte_unused void *ptr_data)
202 {
203         struct pcmd_intstr_params *params = ptr_params;
204         int len_regs;
205         struct ethtool_regs regs;
206         unsigned char *buf_data;
207         FILE *fp_regs;
208
209         if (!rte_eth_dev_is_valid_port(params->port)) {
210                 printf("Error: Invalid port number %i\n", params->port);
211                 return;
212         }
213         len_regs = rte_ethtool_get_regs_len(params->port);
214         if (len_regs > 0) {
215                 printf("Port %i: %i bytes\n", params->port, len_regs);
216                 buf_data = malloc(len_regs);
217                 if (buf_data == NULL) {
218                         printf("Error allocating %i bytes for buffer\n",
219                                 len_regs);
220                         return;
221                 }
222                 if (!rte_ethtool_get_regs(params->port, &regs, buf_data)) {
223                         fp_regs = fopen(params->opt, "wb");
224                         if (fp_regs == NULL) {
225                                 printf("Error opening '%s' for writing\n",
226                                         params->opt);
227                         } else {
228                                 if ((int)fwrite(buf_data,
229                                                 1, len_regs,
230                                                 fp_regs) != len_regs)
231                                         printf("Error writing '%s'\n",
232                                                 params->opt);
233                                 fclose(fp_regs);
234                         }
235                 }
236                 free(buf_data);
237         } else if (len_regs == -ENOTSUP)
238                 printf("Port %i: Operation not supported\n", params->port);
239         else
240                 printf("Port %i: Error getting registers\n", params->port);
241 }
242
243
244 static void
245 pcmd_eeprom_callback(void *ptr_params,
246         __rte_unused struct cmdline *ctx,
247         __rte_unused void *ptr_data)
248 {
249         struct pcmd_intstr_params *params = ptr_params;
250         struct ethtool_eeprom info_eeprom;
251         int len_eeprom;
252         int pos_eeprom;
253         int stat;
254         unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE];
255         FILE *fp_eeprom;
256
257         if (!rte_eth_dev_is_valid_port(params->port)) {
258                 printf("Error: Invalid port number %i\n", params->port);
259                 return;
260         }
261         len_eeprom = rte_ethtool_get_eeprom_len(params->port);
262         if (len_eeprom > 0) {
263                 fp_eeprom = fopen(params->opt, "wb");
264                 if (fp_eeprom == NULL) {
265                         printf("Error opening '%s' for writing\n",
266                                 params->opt);
267                         return;
268                 }
269                 printf("Total EEPROM length: %i bytes\n", len_eeprom);
270                 info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
271                 for (pos_eeprom = 0;
272                                 pos_eeprom < len_eeprom;
273                                 pos_eeprom += EEPROM_DUMP_CHUNKSIZE) {
274                         info_eeprom.offset = pos_eeprom;
275                         if (pos_eeprom + EEPROM_DUMP_CHUNKSIZE > len_eeprom)
276                                 info_eeprom.len = len_eeprom - pos_eeprom;
277                         else
278                                 info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
279                         stat = rte_ethtool_get_eeprom(
280                                 params->port, &info_eeprom, bytes_eeprom
281                                 );
282                         if (stat != 0) {
283                                 printf("EEPROM read error %i\n", stat);
284                                 break;
285                         }
286                         if (fwrite(bytes_eeprom,
287                                         1, info_eeprom.len,
288                                         fp_eeprom) != info_eeprom.len) {
289                                 printf("Error writing '%s'\n", params->opt);
290                                 break;
291                         }
292                 }
293                 fclose(fp_eeprom);
294         } else if (len_eeprom == 0)
295                 printf("Port %i: Device does not have EEPROM\n", params->port);
296         else if (len_eeprom == -ENOTSUP)
297                 printf("Port %i: Operation not supported\n", params->port);
298         else
299                 printf("Port %i: Error getting EEPROM\n", params->port);
300 }
301
302
303 static void
304 pcmd_module_eeprom_callback(void *ptr_params,
305         __rte_unused struct cmdline *ctx,
306         __rte_unused void *ptr_data)
307 {
308         struct pcmd_intstr_params *params = ptr_params;
309         struct ethtool_eeprom info_eeprom;
310         uint32_t module_info[2];
311         int stat;
312         unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE];
313         FILE *fp_eeprom;
314
315         if (!rte_eth_dev_is_valid_port(params->port)) {
316                 printf("Error: Invalid port number %i\n", params->port);
317                 return;
318         }
319
320         stat = rte_ethtool_get_module_info(params->port, module_info);
321         if (stat != 0) {
322                 printf("Module EEPROM information read error %i\n", stat);
323                 return;
324         }
325
326         info_eeprom.len = module_info[1];
327         info_eeprom.offset = 0;
328
329         stat = rte_ethtool_get_module_eeprom(params->port,
330                                              &info_eeprom, bytes_eeprom);
331         if (stat != 0) {
332                 printf("Module EEPROM read error %i\n", stat);
333                 return;
334         }
335
336         fp_eeprom = fopen(params->opt, "wb");
337         if (fp_eeprom == NULL) {
338                 printf("Error opening '%s' for writing\n", params->opt);
339                 return;
340         }
341         printf("Total plugin module EEPROM length: %i bytes\n",
342                info_eeprom.len);
343         if (fwrite(bytes_eeprom, 1, info_eeprom.len,
344                    fp_eeprom) != info_eeprom.len) {
345                 printf("Error writing '%s'\n", params->opt);
346         }
347         fclose(fp_eeprom);
348 }
349
350
351 static void
352 pcmd_pause_callback(void *ptr_params,
353         __rte_unused struct cmdline *ctx,
354         void *ptr_data)
355 {
356         struct pcmd_intstr_params *params = ptr_params;
357         struct ethtool_pauseparam info;
358         int stat;
359
360         if (!rte_eth_dev_is_valid_port(params->port)) {
361                 printf("Error: Invalid port number %i\n", params->port);
362                 return;
363         }
364         if (ptr_data != NULL) {
365                 stat = rte_ethtool_get_pauseparam(params->port, &info);
366         } else {
367                 memset(&info, 0, sizeof(info));
368                 if (strcasecmp("all", params->opt) == 0) {
369                         info.tx_pause = 1;
370                         info.rx_pause = 1;
371                 } else if (strcasecmp("tx", params->opt) == 0) {
372                         info.tx_pause = 1;
373                         info.rx_pause = 0;
374                 } else if (strcasecmp("rx", params->opt) == 0) {
375                         info.tx_pause = 0;
376                         info.rx_pause = 1;
377                 } else {
378                         info.tx_pause = 0;
379                         info.rx_pause = 0;
380                 }
381                 /* Assume auto-negotiation wanted */
382                 info.autoneg = 1;
383                 stat = rte_ethtool_set_pauseparam(params->port, &info);
384         }
385         if (stat == 0) {
386                 if (info.rx_pause && info.tx_pause)
387                         printf("Port %i: Tx & Rx Paused\n", params->port);
388                 else if (info.rx_pause)
389                         printf("Port %i: Rx Paused\n", params->port);
390                 else if (info.tx_pause)
391                         printf("Port %i: Tx Paused\n", params->port);
392                 else
393                         printf("Port %i: Tx & Rx not paused\n", params->port);
394         } else if (stat == -ENOTSUP)
395                 printf("Port %i: Operation not supported\n", params->port);
396         else
397                 printf("Port %i: Error %i\n", params->port, stat);
398 }
399
400
401 static void
402 pcmd_open_callback(__rte_unused void *ptr_params,
403         __rte_unused struct cmdline *ctx,
404         __rte_unused void *ptr_data)
405 {
406         struct pcmd_int_params *params = ptr_params;
407         int stat;
408
409         if (!rte_eth_dev_is_valid_port(params->port)) {
410                 printf("Error: Invalid port number %i\n", params->port);
411                 return;
412         }
413         lock_port(params->port);
414         stat = rte_ethtool_net_open(params->port);
415         mark_port_active(params->port);
416         unlock_port(params->port);
417         if (stat == 0)
418                 return;
419         else if (stat == -ENOTSUP)
420                 printf("Port %i: Operation not supported\n", params->port);
421         else
422                 printf("Port %i: Error opening device\n", params->port);
423 }
424
425 static void
426 pcmd_stop_callback(__rte_unused void *ptr_params,
427         __rte_unused struct cmdline *ctx,
428         __rte_unused void *ptr_data)
429 {
430         struct pcmd_int_params *params = ptr_params;
431         int stat;
432
433         if (!rte_eth_dev_is_valid_port(params->port)) {
434                 printf("Error: Invalid port number %i\n", params->port);
435                 return;
436         }
437         lock_port(params->port);
438         stat = rte_ethtool_net_stop(params->port);
439         mark_port_inactive(params->port);
440         unlock_port(params->port);
441         if (stat == 0)
442                 return;
443         else if (stat == -ENOTSUP)
444                 printf("Port %i: Operation not supported\n", params->port);
445         else
446                 printf("Port %i: Error stopping device\n", params->port);
447 }
448
449
450 static void
451 pcmd_rxmode_callback(void *ptr_params,
452         __rte_unused struct cmdline *ctx,
453         __rte_unused void *ptr_data)
454 {
455         struct pcmd_intstr_params *params = ptr_params;
456         int stat;
457
458         if (!rte_eth_dev_is_valid_port(params->port)) {
459                 printf("Error: Invalid port number %i\n", params->port);
460                 return;
461         }
462         stat = rte_ethtool_net_set_rx_mode(params->port);
463         if (stat == 0)
464                 return;
465         else if (stat == -ENOTSUP)
466                 printf("Port %i: Operation not supported\n", params->port);
467         else
468                 printf("Port %i: Error setting rx mode\n", params->port);
469 }
470
471
472 static void
473 pcmd_macaddr_callback(void *ptr_params,
474         __rte_unused struct cmdline *ctx,
475         void *ptr_data)
476 {
477         struct pcmd_intmac_params *params = ptr_params;
478         struct rte_ether_addr mac_addr;
479         int stat;
480
481         stat = 0;
482         if (!rte_eth_dev_is_valid_port(params->port)) {
483                 printf("Error: Invalid port number %i\n", params->port);
484                 return;
485         }
486         if (ptr_data != NULL) {
487                 lock_port(params->port);
488                 stat = rte_ethtool_net_set_mac_addr(params->port,
489                         &params->mac);
490                 mark_port_newmac(params->port);
491                 unlock_port(params->port);
492                 if (stat == 0) {
493                         printf("MAC address changed\n");
494                         return;
495                 }
496         } else {
497                 stat = rte_ethtool_net_get_mac_addr(params->port, &mac_addr);
498                 if (stat == 0) {
499                         printf(
500                                 "Port %i MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
501                                 params->port,
502                                 mac_addr.addr_bytes[0],
503                                 mac_addr.addr_bytes[1],
504                                 mac_addr.addr_bytes[2],
505                                 mac_addr.addr_bytes[3],
506                                 mac_addr.addr_bytes[4],
507                                 mac_addr.addr_bytes[5]);
508                         return;
509                 }
510         }
511
512         printf("Port %i: Error %s\n", params->port,
513                strerror(-stat));
514 }
515
516 static void
517 pcmd_mtu_callback(void *ptr_params,
518         __rte_unused struct cmdline *ctx,
519         __rte_unused void *ptr_data)
520 {
521         struct pcmd_intstr_params *params = ptr_params;
522         int stat;
523         int new_mtu;
524         char *ptr_parse_end;
525
526         if (!rte_eth_dev_is_valid_port(params->port)) {
527                 printf("Error: Invalid port number %i\n", params->port);
528                 return;
529         }
530         new_mtu = atoi(params->opt);
531         new_mtu = strtoul(params->opt, &ptr_parse_end, 10);
532         if (*ptr_parse_end != '\0' ||
533                         new_mtu < RTE_ETHER_MIN_MTU ||
534                         new_mtu > RTE_ETHER_MAX_JUMBO_FRAME_LEN) {
535                 printf("Port %i: Invalid MTU value\n", params->port);
536                 return;
537         }
538         stat = rte_ethtool_net_change_mtu(params->port, new_mtu);
539         if (stat == 0)
540                 printf("Port %i: MTU set to %i\n", params->port, new_mtu);
541         else if (stat == -ENOTSUP)
542                 printf("Port %i: Operation not supported\n", params->port);
543         else
544                 printf("Port %i: Error setting MTU\n", params->port);
545 }
546
547
548
549 static void pcmd_portstats_callback(__rte_unused void *ptr_params,
550         __rte_unused struct cmdline *ctx,
551         __rte_unused void *ptr_data)
552 {
553         struct pcmd_int_params *params = ptr_params;
554         struct rte_eth_stats stat_info;
555         int stat;
556
557         if (!rte_eth_dev_is_valid_port(params->port)) {
558                 printf("Error: Invalid port number %i\n", params->port);
559                 return;
560         }
561         stat = rte_ethtool_net_get_stats64(params->port, &stat_info);
562         if (stat == 0) {
563                 printf("Port %i stats\n", params->port);
564                 printf("   In: %" PRIu64 " (%" PRIu64 " bytes)\n"
565                         "  Out: %"PRIu64" (%"PRIu64 " bytes)\n"
566                         "  Err: %"PRIu64"\n",
567                         stat_info.ipackets,
568                         stat_info.ibytes,
569                         stat_info.opackets,
570                         stat_info.obytes,
571                         stat_info.ierrors+stat_info.oerrors
572                       );
573         } else if (stat == -ENOTSUP)
574                 printf("Port %i: Operation not supported\n", params->port);
575         else
576                 printf("Port %i: Error fetching statistics\n", params->port);
577 }
578
579 static void pcmd_ringparam_callback(__rte_unused void *ptr_params,
580         __rte_unused struct cmdline *ctx,
581         void *ptr_data)
582 {
583         struct pcmd_intintint_params *params = ptr_params;
584         struct ethtool_ringparam ring_data;
585         struct ethtool_ringparam ring_params;
586         int stat;
587
588         if (!rte_eth_dev_is_valid_port(params->port)) {
589                 printf("Error: Invalid port number %i\n", params->port);
590                 return;
591         }
592         if (ptr_data == NULL) {
593                 stat = rte_ethtool_get_ringparam(params->port, &ring_data);
594                 if (stat == 0) {
595                         printf("Port %i ring parameters\n"
596                                 "  Rx Pending: %i (%i max)\n"
597                                 "  Tx Pending: %i (%i max)\n",
598                                 params->port,
599                                 ring_data.rx_pending,
600                                 ring_data.rx_max_pending,
601                                 ring_data.tx_pending,
602                                 ring_data.tx_max_pending);
603                 }
604         } else {
605                 if (params->tx < 1 || params->rx < 1) {
606                         printf("Error: Invalid parameters\n");
607                         return;
608                 }
609                 memset(&ring_params, 0, sizeof(struct ethtool_ringparam));
610                 ring_params.tx_pending = params->tx;
611                 ring_params.rx_pending = params->rx;
612                 lock_port(params->port);
613                 stat = rte_ethtool_set_ringparam(params->port, &ring_params);
614                 unlock_port(params->port);
615         }
616         if (stat == 0)
617                 return;
618         else if (stat == -ENOTSUP)
619                 printf("Port %i: Operation not supported\n", params->port);
620         else
621                 printf("Port %i: Error fetching statistics\n", params->port);
622 }
623
624 static void pcmd_validate_callback(void *ptr_params,
625         __rte_unused struct cmdline *ctx,
626         __rte_unused void *ptr_data)
627 {
628         struct pcmd_intmac_params *params = ptr_params;
629
630         if (rte_ethtool_net_validate_addr(0, &params->mac))
631                 printf("Address is unicast\n");
632         else
633                 printf("Address is not unicast\n");
634 }
635
636
637 static void pcmd_vlan_callback(__rte_unused void *ptr_params,
638         __rte_unused struct cmdline *ctx,
639         __rte_unused void *ptr_data)
640 {
641         struct pcmd_vlan_params *params = ptr_params;
642         int stat;
643
644         if (!rte_eth_dev_is_valid_port(params->port)) {
645                 printf("Error: Invalid port number %i\n", params->port);
646                 return;
647         }
648         stat = 0;
649
650         if (strcasecmp("add", params->mode) == 0) {
651                 stat = rte_ethtool_net_vlan_rx_add_vid(
652                         params->port, params->vid
653                         );
654                 if (stat == 0)
655                         printf("VLAN vid %i added\n", params->vid);
656
657         } else if (strcasecmp("del", params->mode) == 0) {
658                 stat = rte_ethtool_net_vlan_rx_kill_vid(
659                         params->port, params->vid
660                         );
661                 if (stat == 0)
662                         printf("VLAN vid %i removed\n", params->vid);
663         } else {
664                 /* Should not happen! */
665                 printf("Error: Bad mode %s\n", params->mode);
666         }
667         if (stat == -ENOTSUP)
668                 printf("Port %i: Operation not supported\n", params->port);
669         else if (stat == -ENOSYS)
670                 printf("Port %i: VLAN filtering disabled\n", params->port);
671         else if (stat != 0)
672                 printf("Port %i: Error changing VLAN setup (code %i)\n",
673                         params->port, -stat);
674 }
675
676
677 cmdline_parse_inst_t pcmd_quit = {
678         .f = pcmd_quit_callback,
679         .data = NULL,
680         .help_str = "quit\n     Exit program",
681         .tokens = {(void *)&pcmd_quit_token_cmd, NULL},
682 };
683 cmdline_parse_inst_t pcmd_drvinfo = {
684         .f = pcmd_drvinfo_callback,
685         .data = NULL,
686         .help_str = "drvinfo\n     Print driver info",
687         .tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL},
688 };
689 cmdline_parse_inst_t pcmd_link = {
690         .f = pcmd_link_callback,
691         .data = NULL,
692         .help_str = "link\n     Print port link states",
693         .tokens = {(void *)&pcmd_link_token_cmd, NULL},
694 };
695 cmdline_parse_inst_t pcmd_regs = {
696         .f = pcmd_regs_callback,
697         .data = NULL,
698         .help_str = "regs <port_id> <filename>\n"
699                 "     Dump port register(s) to file",
700         .tokens = {
701                 (void *)&pcmd_regs_token_cmd,
702                 (void *)&pcmd_intstr_token_port,
703                 (void *)&pcmd_intstr_token_opt,
704                 NULL
705         },
706 };
707 cmdline_parse_inst_t pcmd_eeprom = {
708         .f = pcmd_eeprom_callback,
709         .data = NULL,
710         .help_str = "eeprom <port_id> <filename>\n    Dump EEPROM to file",
711         .tokens = {
712                 (void *)&pcmd_eeprom_token_cmd,
713                 (void *)&pcmd_intstr_token_port,
714                 (void *)&pcmd_intstr_token_opt,
715                 NULL
716         },
717 };
718 cmdline_parse_inst_t pcmd_module_eeprom = {
719         .f = pcmd_module_eeprom_callback,
720         .data = NULL,
721         .help_str = "module-eeprom <port_id> <filename>\n"
722                 "     Dump plugin module EEPROM to file",
723         .tokens = {
724                 (void *)&pcmd_module_eeprom_token_cmd,
725                 (void *)&pcmd_intstr_token_port,
726                 (void *)&pcmd_intstr_token_opt,
727                 NULL
728         },
729 };
730 cmdline_parse_inst_t pcmd_pause_noopt = {
731         .f = pcmd_pause_callback,
732         .data = (void *)0x01,
733         .help_str = "pause <port_id>\n     Print port pause state",
734         .tokens = {
735                 (void *)&pcmd_pause_token_cmd,
736                 (void *)&pcmd_pause_token_port,
737                 NULL
738         },
739 };
740 cmdline_parse_inst_t pcmd_pause = {
741         .f = pcmd_pause_callback,
742         .data = NULL,
743         .help_str =
744                 "pause <port_id> <all|tx|rx|none>\n     Pause/unpause port",
745         .tokens = {
746                 (void *)&pcmd_pause_token_cmd,
747                 (void *)&pcmd_pause_token_port,
748                 (void *)&pcmd_pause_token_opt,
749                 NULL
750         },
751 };
752 cmdline_parse_inst_t pcmd_open = {
753         .f = pcmd_open_callback,
754         .data = NULL,
755         .help_str = "open <port_id>\n     Open port",
756         .tokens = {
757                 (void *)&pcmd_open_token_cmd,
758                 (void *)&pcmd_int_token_port,
759                 NULL
760         },
761 };
762 cmdline_parse_inst_t pcmd_stop = {
763         .f = pcmd_stop_callback,
764         .data = NULL,
765         .help_str = "stop <port_id>\n     Stop port",
766         .tokens = {
767                 (void *)&pcmd_stop_token_cmd,
768                 (void *)&pcmd_int_token_port,
769                 NULL
770         },
771 };
772 cmdline_parse_inst_t pcmd_rxmode = {
773         .f = pcmd_rxmode_callback,
774         .data = NULL,
775         .help_str = "rxmode <port_id>\n     Toggle port Rx mode",
776         .tokens = {
777                 (void *)&pcmd_rxmode_token_cmd,
778                 (void *)&pcmd_int_token_port,
779                 NULL
780         },
781 };
782 cmdline_parse_inst_t pcmd_macaddr_get = {
783         .f = pcmd_macaddr_callback,
784         .data = NULL,
785         .help_str = "macaddr <port_id>\n"
786                 "     Get MAC address",
787         .tokens = {
788                 (void *)&pcmd_macaddr_token_cmd,
789                 (void *)&pcmd_intstr_token_port,
790                 NULL
791         },
792 };
793 cmdline_parse_inst_t pcmd_macaddr = {
794         .f = pcmd_macaddr_callback,
795         .data = (void *)0x01,
796         .help_str =
797                 "macaddr <port_id> <mac_addr>\n"
798                 "     Set MAC address",
799         .tokens = {
800                 (void *)&pcmd_macaddr_token_cmd,
801                 (void *)&pcmd_intmac_token_port,
802                 (void *)&pcmd_intmac_token_mac,
803                 NULL
804         },
805 };
806 cmdline_parse_inst_t pcmd_mtu = {
807         .f = pcmd_mtu_callback,
808         .data = NULL,
809         .help_str = "mtu <port_id> <mtu_value>\n"
810                 "     Change MTU",
811         .tokens = {
812                 (void *)&pcmd_mtu_token_cmd,
813                 (void *)&pcmd_intstr_token_port,
814                 (void *)&pcmd_intstr_token_opt,
815                 NULL
816         },
817 };
818 cmdline_parse_inst_t pcmd_portstats = {
819         .f = pcmd_portstats_callback,
820         .data = NULL,
821         .help_str = "portstats <port_id>\n"
822                 "     Print port eth statistics",
823         .tokens = {
824                 (void *)&pcmd_portstats_token_cmd,
825                 (void *)&pcmd_int_token_port,
826                 NULL
827         },
828 };
829 cmdline_parse_inst_t pcmd_ringparam = {
830         .f = pcmd_ringparam_callback,
831         .data = NULL,
832         .help_str = "ringparam <port_id>\n"
833                 "     Print ring parameters",
834         .tokens = {
835                 (void *)&pcmd_ringparam_token_cmd,
836                 (void *)&pcmd_intintint_token_port,
837                 NULL
838         },
839 };
840 cmdline_parse_inst_t pcmd_ringparam_set = {
841         .f = pcmd_ringparam_callback,
842         .data = (void *)1,
843         .help_str = "ringparam <port_id> <tx_param> <rx_param>\n"
844                 "     Set ring parameters",
845         .tokens = {
846                 (void *)&pcmd_ringparam_token_cmd,
847                 (void *)&pcmd_intintint_token_port,
848                 (void *)&pcmd_intintint_token_tx,
849                 (void *)&pcmd_intintint_token_rx,
850                 NULL
851         },
852 };
853 cmdline_parse_inst_t pcmd_validate = {
854         .f = pcmd_validate_callback,
855         .data = NULL,
856         .help_str = "validate <mac_addr>\n"
857                 "     Check that MAC address is valid unicast address",
858         .tokens = {
859                 (void *)&pcmd_validate_token_cmd,
860                 (void *)&pcmd_intmac_token_mac,
861                 NULL
862         },
863 };
864 cmdline_parse_inst_t pcmd_vlan = {
865         .f = pcmd_vlan_callback,
866         .data = NULL,
867         .help_str = "vlan <port_id> <add|del> <vlan_id>\n"
868                 "     Add/remove VLAN id",
869         .tokens = {
870                 (void *)&pcmd_vlan_token_cmd,
871                 (void *)&pcmd_vlan_token_port,
872                 (void *)&pcmd_vlan_token_mode,
873                 (void *)&pcmd_vlan_token_vid,
874                 NULL
875         },
876 };
877
878
879 cmdline_parse_ctx_t list_prompt_commands[] = {
880         (cmdline_parse_inst_t *)&pcmd_drvinfo,
881         (cmdline_parse_inst_t *)&pcmd_eeprom,
882         (cmdline_parse_inst_t *)&pcmd_module_eeprom,
883         (cmdline_parse_inst_t *)&pcmd_link,
884         (cmdline_parse_inst_t *)&pcmd_macaddr_get,
885         (cmdline_parse_inst_t *)&pcmd_macaddr,
886         (cmdline_parse_inst_t *)&pcmd_mtu,
887         (cmdline_parse_inst_t *)&pcmd_open,
888         (cmdline_parse_inst_t *)&pcmd_pause_noopt,
889         (cmdline_parse_inst_t *)&pcmd_pause,
890         (cmdline_parse_inst_t *)&pcmd_portstats,
891         (cmdline_parse_inst_t *)&pcmd_regs,
892         (cmdline_parse_inst_t *)&pcmd_ringparam,
893         (cmdline_parse_inst_t *)&pcmd_ringparam_set,
894         (cmdline_parse_inst_t *)&pcmd_rxmode,
895         (cmdline_parse_inst_t *)&pcmd_stop,
896         (cmdline_parse_inst_t *)&pcmd_validate,
897         (cmdline_parse_inst_t *)&pcmd_vlan,
898         (cmdline_parse_inst_t *)&pcmd_quit,
899         NULL
900 };
901
902
903 void ethapp_main(void)
904 {
905         struct cmdline *ctx_cmdline;
906
907         ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> ");
908         cmdline_interact(ctx_cmdline);
909         cmdline_stdin_exit(ctx_cmdline);
910 }