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