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