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