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
pcmd_quit_callback(__rte_unused void * ptr_params,struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_drvinfo_callback(__rte_unused void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_link_callback(__rte_unused void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_regs_callback(void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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, ®s, 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
pcmd_eeprom_callback(void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_module_eeprom_callback(void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_pause_callback(void * ptr_params,__rte_unused struct cmdline * ctx,void * ptr_data)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
pcmd_open_callback(__rte_unused void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_stop_callback(__rte_unused void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_rxmode_callback(void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)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
pcmd_macaddr_callback(void * ptr_params,__rte_unused struct cmdline * ctx,void * ptr_data)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 ¶ms->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: " RTE_ETHER_ADDR_PRT_FMT "\n",
502 params->port, RTE_ETHER_ADDR_BYTES(&mac_addr));
503 return;
504 }
505 }
506
507 printf("Port %i: Error %s\n", params->port,
508 strerror(-stat));
509 }
510
511 static void
pcmd_mtu_callback(void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)512 pcmd_mtu_callback(void *ptr_params,
513 __rte_unused struct cmdline *ctx,
514 __rte_unused void *ptr_data)
515 {
516 struct pcmd_intstr_params *params = ptr_params;
517 int stat;
518 int new_mtu;
519 char *ptr_parse_end;
520
521 if (!rte_eth_dev_is_valid_port(params->port)) {
522 printf("Error: Invalid port number %i\n", params->port);
523 return;
524 }
525 new_mtu = strtoul(params->opt, &ptr_parse_end, 10);
526 if (*ptr_parse_end != '\0' ||
527 new_mtu < RTE_ETHER_MIN_MTU ||
528 new_mtu > RTE_ETHER_MAX_JUMBO_FRAME_LEN) {
529 printf("Port %i: Invalid MTU value\n", params->port);
530 return;
531 }
532 stat = rte_ethtool_net_change_mtu(params->port, new_mtu);
533 if (stat == 0)
534 printf("Port %i: MTU set to %i\n", params->port, new_mtu);
535 else if (stat == -ENOTSUP)
536 printf("Port %i: Operation not supported\n", params->port);
537 else
538 printf("Port %i: Error setting MTU\n", params->port);
539 }
540
541
542
pcmd_portstats_callback(__rte_unused void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)543 static void pcmd_portstats_callback(__rte_unused void *ptr_params,
544 __rte_unused struct cmdline *ctx,
545 __rte_unused void *ptr_data)
546 {
547 struct pcmd_int_params *params = ptr_params;
548 struct rte_eth_stats stat_info;
549 int stat;
550
551 if (!rte_eth_dev_is_valid_port(params->port)) {
552 printf("Error: Invalid port number %i\n", params->port);
553 return;
554 }
555 stat = rte_ethtool_net_get_stats64(params->port, &stat_info);
556 if (stat == 0) {
557 printf("Port %i stats\n", params->port);
558 printf(" In: %" PRIu64 " (%" PRIu64 " bytes)\n"
559 " Out: %"PRIu64" (%"PRIu64 " bytes)\n"
560 " Err: %"PRIu64"\n",
561 stat_info.ipackets,
562 stat_info.ibytes,
563 stat_info.opackets,
564 stat_info.obytes,
565 stat_info.ierrors+stat_info.oerrors
566 );
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
pcmd_ringparam_callback(__rte_unused void * ptr_params,__rte_unused struct cmdline * ctx,void * ptr_data)573 static void pcmd_ringparam_callback(__rte_unused void *ptr_params,
574 __rte_unused struct cmdline *ctx,
575 void *ptr_data)
576 {
577 struct pcmd_intintint_params *params = ptr_params;
578 struct ethtool_ringparam ring_data;
579 struct ethtool_ringparam ring_params;
580 int stat;
581
582 if (!rte_eth_dev_is_valid_port(params->port)) {
583 printf("Error: Invalid port number %i\n", params->port);
584 return;
585 }
586 if (ptr_data == NULL) {
587 stat = rte_ethtool_get_ringparam(params->port, &ring_data);
588 if (stat == 0) {
589 printf("Port %i ring parameters\n"
590 " Rx Pending: %i (%i max)\n"
591 " Tx Pending: %i (%i max)\n",
592 params->port,
593 ring_data.rx_pending,
594 ring_data.rx_max_pending,
595 ring_data.tx_pending,
596 ring_data.tx_max_pending);
597 }
598 } else {
599 if (params->tx < 1 || params->rx < 1) {
600 printf("Error: Invalid parameters\n");
601 return;
602 }
603 memset(&ring_params, 0, sizeof(struct ethtool_ringparam));
604 ring_params.tx_pending = params->tx;
605 ring_params.rx_pending = params->rx;
606 lock_port(params->port);
607 stat = rte_ethtool_set_ringparam(params->port, &ring_params);
608 unlock_port(params->port);
609 }
610 if (stat == 0)
611 return;
612 else if (stat == -ENOTSUP)
613 printf("Port %i: Operation not supported\n", params->port);
614 else
615 printf("Port %i: Error fetching statistics\n", params->port);
616 }
617
pcmd_validate_callback(void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)618 static void pcmd_validate_callback(void *ptr_params,
619 __rte_unused struct cmdline *ctx,
620 __rte_unused void *ptr_data)
621 {
622 struct pcmd_intmac_params *params = ptr_params;
623
624 if (rte_ethtool_net_validate_addr(0, ¶ms->mac))
625 printf("Address is unicast\n");
626 else
627 printf("Address is not unicast\n");
628 }
629
630
pcmd_vlan_callback(__rte_unused void * ptr_params,__rte_unused struct cmdline * ctx,__rte_unused void * ptr_data)631 static void pcmd_vlan_callback(__rte_unused void *ptr_params,
632 __rte_unused struct cmdline *ctx,
633 __rte_unused void *ptr_data)
634 {
635 struct pcmd_vlan_params *params = ptr_params;
636 int stat;
637
638 if (!rte_eth_dev_is_valid_port(params->port)) {
639 printf("Error: Invalid port number %i\n", params->port);
640 return;
641 }
642 stat = 0;
643
644 if (strcasecmp("add", params->mode) == 0) {
645 stat = rte_ethtool_net_vlan_rx_add_vid(
646 params->port, params->vid
647 );
648 if (stat == 0)
649 printf("VLAN vid %i added\n", params->vid);
650
651 } else if (strcasecmp("del", params->mode) == 0) {
652 stat = rte_ethtool_net_vlan_rx_kill_vid(
653 params->port, params->vid
654 );
655 if (stat == 0)
656 printf("VLAN vid %i removed\n", params->vid);
657 } else {
658 /* Should not happen! */
659 printf("Error: Bad mode %s\n", params->mode);
660 }
661 if (stat == -ENOTSUP)
662 printf("Port %i: Operation not supported\n", params->port);
663 else if (stat == -ENOSYS)
664 printf("Port %i: VLAN filtering disabled\n", params->port);
665 else if (stat != 0)
666 printf("Port %i: Error changing VLAN setup (code %i)\n",
667 params->port, -stat);
668 }
669
670
671 cmdline_parse_inst_t pcmd_quit = {
672 .f = pcmd_quit_callback,
673 .data = NULL,
674 .help_str = "quit\n Exit program",
675 .tokens = {(void *)&pcmd_quit_token_cmd, NULL},
676 };
677 cmdline_parse_inst_t pcmd_drvinfo = {
678 .f = pcmd_drvinfo_callback,
679 .data = NULL,
680 .help_str = "drvinfo\n Print driver info",
681 .tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL},
682 };
683 cmdline_parse_inst_t pcmd_link = {
684 .f = pcmd_link_callback,
685 .data = NULL,
686 .help_str = "link\n Print port link states",
687 .tokens = {(void *)&pcmd_link_token_cmd, NULL},
688 };
689 cmdline_parse_inst_t pcmd_regs = {
690 .f = pcmd_regs_callback,
691 .data = NULL,
692 .help_str = "regs <port_id> <filename>\n"
693 " Dump port register(s) to file",
694 .tokens = {
695 (void *)&pcmd_regs_token_cmd,
696 (void *)&pcmd_intstr_token_port,
697 (void *)&pcmd_intstr_token_opt,
698 NULL
699 },
700 };
701 cmdline_parse_inst_t pcmd_eeprom = {
702 .f = pcmd_eeprom_callback,
703 .data = NULL,
704 .help_str = "eeprom <port_id> <filename>\n Dump EEPROM to file",
705 .tokens = {
706 (void *)&pcmd_eeprom_token_cmd,
707 (void *)&pcmd_intstr_token_port,
708 (void *)&pcmd_intstr_token_opt,
709 NULL
710 },
711 };
712 cmdline_parse_inst_t pcmd_module_eeprom = {
713 .f = pcmd_module_eeprom_callback,
714 .data = NULL,
715 .help_str = "module-eeprom <port_id> <filename>\n"
716 " Dump plugin module EEPROM to file",
717 .tokens = {
718 (void *)&pcmd_module_eeprom_token_cmd,
719 (void *)&pcmd_intstr_token_port,
720 (void *)&pcmd_intstr_token_opt,
721 NULL
722 },
723 };
724 cmdline_parse_inst_t pcmd_pause_noopt = {
725 .f = pcmd_pause_callback,
726 .data = (void *)0x01,
727 .help_str = "pause <port_id>\n Print port pause state",
728 .tokens = {
729 (void *)&pcmd_pause_token_cmd,
730 (void *)&pcmd_pause_token_port,
731 NULL
732 },
733 };
734 cmdline_parse_inst_t pcmd_pause = {
735 .f = pcmd_pause_callback,
736 .data = NULL,
737 .help_str =
738 "pause <port_id> <all|tx|rx|none>\n Pause/unpause port",
739 .tokens = {
740 (void *)&pcmd_pause_token_cmd,
741 (void *)&pcmd_pause_token_port,
742 (void *)&pcmd_pause_token_opt,
743 NULL
744 },
745 };
746 cmdline_parse_inst_t pcmd_open = {
747 .f = pcmd_open_callback,
748 .data = NULL,
749 .help_str = "open <port_id>\n Open port",
750 .tokens = {
751 (void *)&pcmd_open_token_cmd,
752 (void *)&pcmd_int_token_port,
753 NULL
754 },
755 };
756 cmdline_parse_inst_t pcmd_stop = {
757 .f = pcmd_stop_callback,
758 .data = NULL,
759 .help_str = "stop <port_id>\n Stop port",
760 .tokens = {
761 (void *)&pcmd_stop_token_cmd,
762 (void *)&pcmd_int_token_port,
763 NULL
764 },
765 };
766 cmdline_parse_inst_t pcmd_rxmode = {
767 .f = pcmd_rxmode_callback,
768 .data = NULL,
769 .help_str = "rxmode <port_id>\n Toggle port Rx mode",
770 .tokens = {
771 (void *)&pcmd_rxmode_token_cmd,
772 (void *)&pcmd_int_token_port,
773 NULL
774 },
775 };
776 cmdline_parse_inst_t pcmd_macaddr_get = {
777 .f = pcmd_macaddr_callback,
778 .data = NULL,
779 .help_str = "macaddr <port_id>\n"
780 " Get MAC address",
781 .tokens = {
782 (void *)&pcmd_macaddr_token_cmd,
783 (void *)&pcmd_intstr_token_port,
784 NULL
785 },
786 };
787 cmdline_parse_inst_t pcmd_macaddr = {
788 .f = pcmd_macaddr_callback,
789 .data = (void *)0x01,
790 .help_str =
791 "macaddr <port_id> <mac_addr>\n"
792 " Set MAC address",
793 .tokens = {
794 (void *)&pcmd_macaddr_token_cmd,
795 (void *)&pcmd_intmac_token_port,
796 (void *)&pcmd_intmac_token_mac,
797 NULL
798 },
799 };
800 cmdline_parse_inst_t pcmd_mtu = {
801 .f = pcmd_mtu_callback,
802 .data = NULL,
803 .help_str = "mtu <port_id> <mtu_value>\n"
804 " Change MTU",
805 .tokens = {
806 (void *)&pcmd_mtu_token_cmd,
807 (void *)&pcmd_intstr_token_port,
808 (void *)&pcmd_intstr_token_opt,
809 NULL
810 },
811 };
812 cmdline_parse_inst_t pcmd_portstats = {
813 .f = pcmd_portstats_callback,
814 .data = NULL,
815 .help_str = "portstats <port_id>\n"
816 " Print port eth statistics",
817 .tokens = {
818 (void *)&pcmd_portstats_token_cmd,
819 (void *)&pcmd_int_token_port,
820 NULL
821 },
822 };
823 cmdline_parse_inst_t pcmd_ringparam = {
824 .f = pcmd_ringparam_callback,
825 .data = NULL,
826 .help_str = "ringparam <port_id>\n"
827 " Print ring parameters",
828 .tokens = {
829 (void *)&pcmd_ringparam_token_cmd,
830 (void *)&pcmd_intintint_token_port,
831 NULL
832 },
833 };
834 cmdline_parse_inst_t pcmd_ringparam_set = {
835 .f = pcmd_ringparam_callback,
836 .data = (void *)1,
837 .help_str = "ringparam <port_id> <tx_param> <rx_param>\n"
838 " Set ring parameters",
839 .tokens = {
840 (void *)&pcmd_ringparam_token_cmd,
841 (void *)&pcmd_intintint_token_port,
842 (void *)&pcmd_intintint_token_tx,
843 (void *)&pcmd_intintint_token_rx,
844 NULL
845 },
846 };
847 cmdline_parse_inst_t pcmd_validate = {
848 .f = pcmd_validate_callback,
849 .data = NULL,
850 .help_str = "validate <mac_addr>\n"
851 " Check that MAC address is valid unicast address",
852 .tokens = {
853 (void *)&pcmd_validate_token_cmd,
854 (void *)&pcmd_intmac_token_mac,
855 NULL
856 },
857 };
858 cmdline_parse_inst_t pcmd_vlan = {
859 .f = pcmd_vlan_callback,
860 .data = NULL,
861 .help_str = "vlan <port_id> <add|del> <vlan_id>\n"
862 " Add/remove VLAN id",
863 .tokens = {
864 (void *)&pcmd_vlan_token_cmd,
865 (void *)&pcmd_vlan_token_port,
866 (void *)&pcmd_vlan_token_mode,
867 (void *)&pcmd_vlan_token_vid,
868 NULL
869 },
870 };
871
872
873 cmdline_parse_ctx_t list_prompt_commands[] = {
874 (cmdline_parse_inst_t *)&pcmd_drvinfo,
875 (cmdline_parse_inst_t *)&pcmd_eeprom,
876 (cmdline_parse_inst_t *)&pcmd_module_eeprom,
877 (cmdline_parse_inst_t *)&pcmd_link,
878 (cmdline_parse_inst_t *)&pcmd_macaddr_get,
879 (cmdline_parse_inst_t *)&pcmd_macaddr,
880 (cmdline_parse_inst_t *)&pcmd_mtu,
881 (cmdline_parse_inst_t *)&pcmd_open,
882 (cmdline_parse_inst_t *)&pcmd_pause_noopt,
883 (cmdline_parse_inst_t *)&pcmd_pause,
884 (cmdline_parse_inst_t *)&pcmd_portstats,
885 (cmdline_parse_inst_t *)&pcmd_regs,
886 (cmdline_parse_inst_t *)&pcmd_ringparam,
887 (cmdline_parse_inst_t *)&pcmd_ringparam_set,
888 (cmdline_parse_inst_t *)&pcmd_rxmode,
889 (cmdline_parse_inst_t *)&pcmd_stop,
890 (cmdline_parse_inst_t *)&pcmd_validate,
891 (cmdline_parse_inst_t *)&pcmd_vlan,
892 (cmdline_parse_inst_t *)&pcmd_quit,
893 NULL
894 };
895
896
ethapp_main(void)897 void ethapp_main(void)
898 {
899 struct cmdline *ctx_cmdline;
900
901 ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> ");
902 cmdline_interact(ctx_cmdline);
903 cmdline_stdin_exit(ctx_cmdline);
904 }
905