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