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