xref: /freebsd/usr.sbin/mlx5tool/mlx5tool.c (revision 4d65a7c6951cea0333f1a0c1b32c38489cdfa6c5)
1e808190aSHans Petter Selasky /*-
2e808190aSHans Petter Selasky  * Copyright (c) 2018, Mellanox Technologies, Ltd.  All rights reserved.
3e808190aSHans Petter Selasky  *
4e808190aSHans Petter Selasky  * Redistribution and use in source and binary forms, with or without
5e808190aSHans Petter Selasky  * modification, are permitted provided that the following conditions
6e808190aSHans Petter Selasky  * are met:
7e808190aSHans Petter Selasky  * 1. Redistributions of source code must retain the above copyright
8e808190aSHans Petter Selasky  *    notice, this list of conditions and the following disclaimer.
9e808190aSHans Petter Selasky  * 2. Redistributions in binary form must reproduce the above copyright
10e808190aSHans Petter Selasky  *    notice, this list of conditions and the following disclaimer in the
11e808190aSHans Petter Selasky  *    documentation and/or other materials provided with the distribution.
12e808190aSHans Petter Selasky  *
13e808190aSHans Petter Selasky  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14e808190aSHans Petter Selasky  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15e808190aSHans Petter Selasky  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16e808190aSHans Petter Selasky  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17e808190aSHans Petter Selasky  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18e808190aSHans Petter Selasky  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19e808190aSHans Petter Selasky  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20e808190aSHans Petter Selasky  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21e808190aSHans Petter Selasky  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22e808190aSHans Petter Selasky  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23e808190aSHans Petter Selasky  * SUCH DAMAGE.
24e808190aSHans Petter Selasky  */
25e808190aSHans Petter Selasky 
26e808190aSHans Petter Selasky #include <sys/param.h>
27e808190aSHans Petter Selasky #include <sys/ioctl.h>
28ea78f07bSHans Petter Selasky #include <sys/mman.h>
29ea78f07bSHans Petter Selasky #include <sys/stat.h>
30e808190aSHans Petter Selasky #include <dev/mlx5/mlx5io.h>
31e808190aSHans Petter Selasky #include <ctype.h>
32e808190aSHans Petter Selasky #include <err.h>
33e808190aSHans Petter Selasky #include <errno.h>
34e808190aSHans Petter Selasky #include <fcntl.h>
35e808190aSHans Petter Selasky #include <paths.h>
36e808190aSHans Petter Selasky #include <stdio.h>
37e808190aSHans Petter Selasky #include <stdlib.h>
38e808190aSHans Petter Selasky #include <string.h>
39e808190aSHans Petter Selasky #include <unistd.h>
40e808190aSHans Petter Selasky 
41e808190aSHans Petter Selasky /* stolen from pciconf.c: parsesel() */
42e808190aSHans Petter Selasky static int
parse_pci_addr(const char * addrstr,struct mlx5_tool_addr * addr)43b255ca09SHans Petter Selasky parse_pci_addr(const char *addrstr, struct mlx5_tool_addr *addr)
44e808190aSHans Petter Selasky {
45e808190aSHans Petter Selasky 	char *eppos;
46e808190aSHans Petter Selasky 	unsigned long selarr[4];
47e808190aSHans Petter Selasky 	int i;
48e808190aSHans Petter Selasky 
49f3365f07SHans Petter Selasky 	if (addrstr == NULL) {
50f3365f07SHans Petter Selasky 		warnx("no pci address specified");
51f3365f07SHans Petter Selasky 		return (1);
52f3365f07SHans Petter Selasky 	}
53e808190aSHans Petter Selasky 	if (strncmp(addrstr, "pci", 3) == 0) {
54e808190aSHans Petter Selasky 		addrstr += 3;
55e808190aSHans Petter Selasky 		i = 0;
56e808190aSHans Petter Selasky 		while (isdigit(*addrstr) && i < 4) {
57e808190aSHans Petter Selasky 			selarr[i++] = strtoul(addrstr, &eppos, 10);
58e808190aSHans Petter Selasky 			addrstr = eppos;
59e808190aSHans Petter Selasky 			if (*addrstr == ':')
60e808190aSHans Petter Selasky 				addrstr++;
61e808190aSHans Petter Selasky 		}
62e808190aSHans Petter Selasky 		if (i > 0 && *addrstr == '\0') {
63e808190aSHans Petter Selasky 			addr->func = (i > 2) ? selarr[--i] : 0;
64e808190aSHans Petter Selasky 			addr->slot = (i > 0) ? selarr[--i] : 0;
65e808190aSHans Petter Selasky 			addr->bus = (i > 0) ? selarr[--i] : 0;
66e808190aSHans Petter Selasky 			addr->domain = (i > 0) ? selarr[--i] : 0;
67e808190aSHans Petter Selasky 			return (0);
68e808190aSHans Petter Selasky 		}
69e808190aSHans Petter Selasky 	}
70e808190aSHans Petter Selasky 	warnx("invalid pci address %s", addrstr);
71e808190aSHans Petter Selasky 	return (1);
72e808190aSHans Petter Selasky }
73e808190aSHans Petter Selasky 
74e808190aSHans Petter Selasky static int
mlx5tool_save_dump(int ctldev,const struct mlx5_tool_addr * addr,const char * dumpname)75b255ca09SHans Petter Selasky mlx5tool_save_dump(int ctldev, const struct mlx5_tool_addr *addr,
76e808190aSHans Petter Selasky     const char *dumpname)
77e808190aSHans Petter Selasky {
78e808190aSHans Petter Selasky 	struct mlx5_fwdump_get fdg;
79e808190aSHans Petter Selasky 	struct mlx5_fwdump_reg *rege;
80e808190aSHans Petter Selasky 	FILE *dump;
81e808190aSHans Petter Selasky 	size_t cnt;
82e808190aSHans Petter Selasky 	int error, res;
83e808190aSHans Petter Selasky 
84e808190aSHans Petter Selasky 	if (dumpname == NULL)
85e808190aSHans Petter Selasky 		dump = stdout;
86e808190aSHans Petter Selasky 	else
87e808190aSHans Petter Selasky 		dump = fopen(dumpname, "w");
88e808190aSHans Petter Selasky 	if (dump == NULL) {
89e808190aSHans Petter Selasky 		warn("open %s", dumpname);
90e808190aSHans Petter Selasky 		return (1);
91e808190aSHans Petter Selasky 	}
92e808190aSHans Petter Selasky 	res = 1;
93e808190aSHans Petter Selasky 	memset(&fdg, 0, sizeof(fdg));
94e808190aSHans Petter Selasky 	fdg.devaddr = *addr;
95e808190aSHans Petter Selasky 	error = ioctl(ctldev, MLX5_FWDUMP_GET, &fdg);
96e808190aSHans Petter Selasky 	if (error != 0) {
97e808190aSHans Petter Selasky 		warn("MLX5_FWDUMP_GET dumpsize");
98e808190aSHans Petter Selasky 		goto out;
99e808190aSHans Petter Selasky 	}
100e808190aSHans Petter Selasky 	rege = calloc(fdg.reg_filled, sizeof(*rege));
101e808190aSHans Petter Selasky 	if (rege == NULL) {
102e808190aSHans Petter Selasky 		warn("alloc rege");
103e808190aSHans Petter Selasky 		goto out;
104e808190aSHans Petter Selasky 	}
105e808190aSHans Petter Selasky 	fdg.buf = rege;
106e808190aSHans Petter Selasky 	fdg.reg_cnt = fdg.reg_filled;
107e808190aSHans Petter Selasky 	error = ioctl(ctldev, MLX5_FWDUMP_GET, &fdg);
108e808190aSHans Petter Selasky 	if (error != 0) {
109e808190aSHans Petter Selasky 		if (errno == ENOENT)
110e808190aSHans Petter Selasky 			warnx("no dump recorded");
111e808190aSHans Petter Selasky 		else
112e808190aSHans Petter Selasky 			warn("MLX5_FWDUMP_GET dump fetch");
113e808190aSHans Petter Selasky 		goto out;
114e808190aSHans Petter Selasky 	}
115e808190aSHans Petter Selasky 	for (cnt = 0; cnt < fdg.reg_cnt; cnt++, rege++)
116e808190aSHans Petter Selasky 		fprintf(dump, "0x%08x\t0x%08x\n", rege->addr, rege->val);
117e808190aSHans Petter Selasky 	res = 0;
118e808190aSHans Petter Selasky out:
119e808190aSHans Petter Selasky 	if (dump != stdout)
120e808190aSHans Petter Selasky 		fclose(dump);
121e808190aSHans Petter Selasky 	return (res);
122e808190aSHans Petter Selasky }
123e808190aSHans Petter Selasky 
124e808190aSHans Petter Selasky static int
mlx5tool_dump_reset(int ctldev,const struct mlx5_tool_addr * addr)125b255ca09SHans Petter Selasky mlx5tool_dump_reset(int ctldev, const struct mlx5_tool_addr *addr)
126e808190aSHans Petter Selasky {
127e808190aSHans Petter Selasky 
128e808190aSHans Petter Selasky 	if (ioctl(ctldev, MLX5_FWDUMP_RESET, addr) == -1) {
129e808190aSHans Petter Selasky 		warn("MLX5_FWDUMP_RESET");
130e808190aSHans Petter Selasky 		return (1);
131e808190aSHans Petter Selasky 	}
132e808190aSHans Petter Selasky 	return (0);
133e808190aSHans Petter Selasky }
134e808190aSHans Petter Selasky 
135e808190aSHans Petter Selasky static int
mlx5tool_dump_force(int ctldev,const struct mlx5_tool_addr * addr)136b255ca09SHans Petter Selasky mlx5tool_dump_force(int ctldev, const struct mlx5_tool_addr *addr)
137e808190aSHans Petter Selasky {
138e808190aSHans Petter Selasky 
139e808190aSHans Petter Selasky 	if (ioctl(ctldev, MLX5_FWDUMP_FORCE, addr) == -1) {
140e808190aSHans Petter Selasky 		warn("MLX5_FWDUMP_FORCE");
141e808190aSHans Petter Selasky 		return (1);
142e808190aSHans Petter Selasky 	}
143e808190aSHans Petter Selasky 	return (0);
144e808190aSHans Petter Selasky }
145e808190aSHans Petter Selasky 
146ea78f07bSHans Petter Selasky static int
mlx5tool_fw_update(int ctldev,const struct mlx5_tool_addr * addr,const char * img_fw_path)147ea78f07bSHans Petter Selasky mlx5tool_fw_update(int ctldev, const struct mlx5_tool_addr *addr,
148ea78f07bSHans Petter Selasky     const char *img_fw_path)
149ea78f07bSHans Petter Selasky {
150ea78f07bSHans Petter Selasky 	struct stat st;
151ea78f07bSHans Petter Selasky 	struct mlx5_fw_update fwup;
152ea78f07bSHans Petter Selasky 	int error, fd, res;
153ea78f07bSHans Petter Selasky 
154ea78f07bSHans Petter Selasky 	res = 0;
155ea78f07bSHans Petter Selasky 	fd = open(img_fw_path, O_RDONLY);
156ea78f07bSHans Petter Selasky 	if (fd == -1) {
157ea78f07bSHans Petter Selasky 		warn("Unable to open %s", img_fw_path);
158ea78f07bSHans Petter Selasky 		res = 1;
159ea78f07bSHans Petter Selasky 		goto close_fd;
160ea78f07bSHans Petter Selasky 	}
161ea78f07bSHans Petter Selasky 	error = fstat(fd, &st);
162ea78f07bSHans Petter Selasky 	if (error != 0) {
163ea78f07bSHans Petter Selasky 		warn("Unable to stat %s", img_fw_path);
164ea78f07bSHans Petter Selasky 		res = 1;
165ea78f07bSHans Petter Selasky 		goto close_fd;
166ea78f07bSHans Petter Selasky 	}
167ea78f07bSHans Petter Selasky 	memset(&fwup, 0, sizeof(fwup));
168ea78f07bSHans Petter Selasky 	memcpy(&fwup.devaddr, addr, sizeof(fwup.devaddr));
169ea78f07bSHans Petter Selasky 	fwup.img_fw_data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE,
170ea78f07bSHans Petter Selasky 	    fd, 0);
171ea78f07bSHans Petter Selasky 	if (fwup.img_fw_data == MAP_FAILED) {
172ea78f07bSHans Petter Selasky 		warn("Unable to mmap %s", img_fw_path);
173ea78f07bSHans Petter Selasky 		res = 1;
174ea78f07bSHans Petter Selasky 		goto close_fd;
175ea78f07bSHans Petter Selasky 	}
176ea78f07bSHans Petter Selasky 	fwup.img_fw_data_len = st.st_size;
177ea78f07bSHans Petter Selasky 
178ea78f07bSHans Petter Selasky 	error = ioctl(ctldev, MLX5_FW_UPDATE, &fwup);
179ea78f07bSHans Petter Selasky 	if (error == -1) {
180ea78f07bSHans Petter Selasky 		warn("MLX5_FW_UPDATE");
181ea78f07bSHans Petter Selasky 	}
182ea78f07bSHans Petter Selasky 
183ea78f07bSHans Petter Selasky 	munmap(fwup.img_fw_data, st.st_size);
184ea78f07bSHans Petter Selasky close_fd:
185ea78f07bSHans Petter Selasky 	close(fd);
186ea78f07bSHans Petter Selasky 	return (res);
187ea78f07bSHans Petter Selasky }
188ea78f07bSHans Petter Selasky 
189998c9a2bSHans Petter Selasky static int
mlx5tool_fw_reset(int ctldev,const struct mlx5_tool_addr * addr)190998c9a2bSHans Petter Selasky mlx5tool_fw_reset(int ctldev, const struct mlx5_tool_addr *addr)
191998c9a2bSHans Petter Selasky {
192998c9a2bSHans Petter Selasky 
193998c9a2bSHans Petter Selasky 	if (ioctl(ctldev, MLX5_FW_RESET, addr) == -1) {
194998c9a2bSHans Petter Selasky 		warn("MLX5_FW_RESET");
195998c9a2bSHans Petter Selasky 		return (1);
196998c9a2bSHans Petter Selasky 	}
197998c9a2bSHans Petter Selasky 	return (0);
198998c9a2bSHans Petter Selasky }
199998c9a2bSHans Petter Selasky 
200133fc15cSHans Petter Selasky #define	MLX5_EEPROM_HIGH_PAGE_OFFSET		128
201133fc15cSHans Petter Selasky #define	MLX5_EEPROM_PAGE_LENGTH			256
202133fc15cSHans Petter Selasky 
203133fc15cSHans Petter Selasky static void
mlx5tool_eeprom_print(struct mlx5_eeprom_get * eeprom_info)204133fc15cSHans Petter Selasky mlx5tool_eeprom_print(struct mlx5_eeprom_get *eeprom_info)
205133fc15cSHans Petter Selasky {
206*eff4361dSHans Petter Selasky 	int index_in_row, line_length, row;
207*eff4361dSHans Petter Selasky 	size_t byte_to_write;
208133fc15cSHans Petter Selasky 
209133fc15cSHans Petter Selasky 	byte_to_write = 0;
210133fc15cSHans Petter Selasky 	line_length = 16;
211133fc15cSHans Petter Selasky 
212133fc15cSHans Petter Selasky 	printf("\nOffset\t\tValues\n");
213133fc15cSHans Petter Selasky 	printf("------\t\t------");
214133fc15cSHans Petter Selasky 	while (byte_to_write < eeprom_info->eeprom_info_out_len) {
215*eff4361dSHans Petter Selasky 		printf("\n0x%04zX\t\t", byte_to_write);
216133fc15cSHans Petter Selasky 		for (index_in_row = 0; index_in_row < line_length;
217133fc15cSHans Petter Selasky 		    index_in_row++) {
218133fc15cSHans Petter Selasky 			printf("%02X ",
219133fc15cSHans Petter Selasky 			    ((uint8_t *)eeprom_info->eeprom_info_buf)[
220133fc15cSHans Petter Selasky 			    byte_to_write]);
221133fc15cSHans Petter Selasky 			byte_to_write++;
222133fc15cSHans Petter Selasky 		}
223133fc15cSHans Petter Selasky 	}
224133fc15cSHans Petter Selasky 
225133fc15cSHans Petter Selasky 	if (eeprom_info->eeprom_info_page_valid) {
226133fc15cSHans Petter Selasky 		row = MLX5_EEPROM_HIGH_PAGE_OFFSET;
227133fc15cSHans Petter Selasky 		printf("\n\nUpper Page 0x03\n");
228133fc15cSHans Petter Selasky 		printf("\nOffset\t\tValues\n");
229133fc15cSHans Petter Selasky 		printf("------\t\t------");
230133fc15cSHans Petter Selasky 		for (row = MLX5_EEPROM_HIGH_PAGE_OFFSET;
231133fc15cSHans Petter Selasky 		    row < MLX5_EEPROM_PAGE_LENGTH;) {
232133fc15cSHans Petter Selasky 			printf("\n0x%04X\t\t", row);
233133fc15cSHans Petter Selasky 			for (index_in_row = 0;
234133fc15cSHans Petter Selasky 			     index_in_row < line_length;
235133fc15cSHans Petter Selasky 			     index_in_row++) {
236133fc15cSHans Petter Selasky 				printf("%02X ",
237133fc15cSHans Petter Selasky 				    ((uint8_t *)eeprom_info->
238133fc15cSHans Petter Selasky 				    eeprom_info_buf)[byte_to_write]);
239133fc15cSHans Petter Selasky 				byte_to_write++;
240133fc15cSHans Petter Selasky 				row++;
241133fc15cSHans Petter Selasky 			}
242133fc15cSHans Petter Selasky 		}
243133fc15cSHans Petter Selasky 	}
244133fc15cSHans Petter Selasky 	printf("\n");
245133fc15cSHans Petter Selasky }
246133fc15cSHans Petter Selasky 
247133fc15cSHans Petter Selasky static int
mlx5tool_get_eeprom_info(int ctldev,const struct mlx5_tool_addr * addr)248133fc15cSHans Petter Selasky mlx5tool_get_eeprom_info(int ctldev, const struct mlx5_tool_addr *addr)
249133fc15cSHans Petter Selasky {
250133fc15cSHans Petter Selasky 	struct mlx5_eeprom_get eeprom_info;
251133fc15cSHans Petter Selasky 	int error;
252133fc15cSHans Petter Selasky 
253133fc15cSHans Petter Selasky 	memset(&eeprom_info, 0, sizeof(eeprom_info));
254133fc15cSHans Petter Selasky 	eeprom_info.devaddr = *addr;
255133fc15cSHans Petter Selasky 
256133fc15cSHans Petter Selasky 	error = ioctl(ctldev, MLX5_EEPROM_GET, &eeprom_info);
257133fc15cSHans Petter Selasky 	if (error != 0) {
258133fc15cSHans Petter Selasky 		warn("MLX5_EEPROM_GET");
259133fc15cSHans Petter Selasky 		return (error);
260133fc15cSHans Petter Selasky 	}
261133fc15cSHans Petter Selasky 	eeprom_info.eeprom_info_buf =
262133fc15cSHans Petter Selasky 	    malloc(eeprom_info.eeprom_info_out_len + MLX5_EEPROM_PAGE_LENGTH);
263133fc15cSHans Petter Selasky 	if (eeprom_info.eeprom_info_buf == NULL) {
264133fc15cSHans Petter Selasky 		warn("alloc eeprom_info.eeprom_info_buf ");
265133fc15cSHans Petter Selasky 		return (ENOMEM);
266133fc15cSHans Petter Selasky 	}
267133fc15cSHans Petter Selasky 	error = ioctl(ctldev, MLX5_EEPROM_GET, &eeprom_info);
268133fc15cSHans Petter Selasky 	if (error != 0) {
269133fc15cSHans Petter Selasky 		warn("MLX5_EEPROM_GET");
270133fc15cSHans Petter Selasky 		free(eeprom_info.eeprom_info_buf);
271133fc15cSHans Petter Selasky 		return (error);
272133fc15cSHans Petter Selasky 	}
273133fc15cSHans Petter Selasky 
274133fc15cSHans Petter Selasky 	mlx5tool_eeprom_print(&eeprom_info);
275133fc15cSHans Petter Selasky 
276133fc15cSHans Petter Selasky 	free(eeprom_info.eeprom_info_buf);
277133fc15cSHans Petter Selasky 	return (0);
278133fc15cSHans Petter Selasky }
279133fc15cSHans Petter Selasky 
280e808190aSHans Petter Selasky static void
usage(void)281e808190aSHans Petter Selasky usage(void)
282e808190aSHans Petter Selasky {
283e808190aSHans Petter Selasky 
284e808190aSHans Petter Selasky 	fprintf(stderr,
285ea78f07bSHans Petter Selasky 	    "Usage: mlx5tool -d pci<d:b:s:f> [-w -o dump.file | -r |"
286998c9a2bSHans Petter Selasky 	    " -e | -f fw.mfa2 | -z]\n");
287e808190aSHans Petter Selasky 	fprintf(stderr, "\t-w - write firmware dump to the specified file\n");
288e808190aSHans Petter Selasky 	fprintf(stderr, "\t-r - reset dump\n");
289133fc15cSHans Petter Selasky 	fprintf(stderr, "\t-E - get eeprom info\n");
290e808190aSHans Petter Selasky 	fprintf(stderr, "\t-e - force dump\n");
291ea78f07bSHans Petter Selasky 	fprintf(stderr, "\t-f fw.img - flash firmware from fw.img\n");
292998c9a2bSHans Petter Selasky 	fprintf(stderr, "\t-z - initiate firmware reset\n");
293e808190aSHans Petter Selasky 	exit(1);
294e808190aSHans Petter Selasky }
295e808190aSHans Petter Selasky 
296e808190aSHans Petter Selasky enum mlx5_action {
297e808190aSHans Petter Selasky 	ACTION_DUMP_GET,
298e808190aSHans Petter Selasky 	ACTION_DUMP_RESET,
299e808190aSHans Petter Selasky 	ACTION_DUMP_FORCE,
300ea78f07bSHans Petter Selasky 	ACTION_FW_UPDATE,
301998c9a2bSHans Petter Selasky 	ACTION_FW_RESET,
302133fc15cSHans Petter Selasky 	ACTION_GET_EEPROM_INFO,
303e808190aSHans Petter Selasky 	ACTION_NONE,
304e808190aSHans Petter Selasky };
305e808190aSHans Petter Selasky 
306e808190aSHans Petter Selasky int
main(int argc,char * argv[])307e808190aSHans Petter Selasky main(int argc, char *argv[])
308e808190aSHans Petter Selasky {
309b255ca09SHans Petter Selasky 	struct mlx5_tool_addr addr;
310e808190aSHans Petter Selasky 	char *dumpname;
311e808190aSHans Petter Selasky 	char *addrstr;
312ea78f07bSHans Petter Selasky 	char *img_fw_path;
313e808190aSHans Petter Selasky 	int c, ctldev, res;
314e808190aSHans Petter Selasky 	enum mlx5_action act;
315e808190aSHans Petter Selasky 
316e808190aSHans Petter Selasky 	act = ACTION_NONE;
317e808190aSHans Petter Selasky 	addrstr = NULL;
318e808190aSHans Petter Selasky 	dumpname = NULL;
319ea78f07bSHans Petter Selasky 	img_fw_path = NULL;
320133fc15cSHans Petter Selasky 	while ((c = getopt(argc, argv, "d:Eef:ho:rwz")) != -1) {
321e808190aSHans Petter Selasky 		switch (c) {
322e808190aSHans Petter Selasky 		case 'd':
323e808190aSHans Petter Selasky 			addrstr = optarg;
324e808190aSHans Petter Selasky 			break;
325e808190aSHans Petter Selasky 		case 'w':
326b4b75592SHans Petter Selasky 			if (act != ACTION_NONE)
327b4b75592SHans Petter Selasky 				usage();
328e808190aSHans Petter Selasky 			act = ACTION_DUMP_GET;
329e808190aSHans Petter Selasky 			break;
330133fc15cSHans Petter Selasky 		case 'E':
331133fc15cSHans Petter Selasky 			if (act != ACTION_NONE)
332133fc15cSHans Petter Selasky 				usage();
333133fc15cSHans Petter Selasky 			act = ACTION_GET_EEPROM_INFO;
334133fc15cSHans Petter Selasky 			break;
335e808190aSHans Petter Selasky 		case 'e':
336b4b75592SHans Petter Selasky 			if (act != ACTION_NONE)
337b4b75592SHans Petter Selasky 				usage();
338e808190aSHans Petter Selasky 			act = ACTION_DUMP_FORCE;
339e808190aSHans Petter Selasky 			break;
340e808190aSHans Petter Selasky 		case 'o':
341e808190aSHans Petter Selasky 			dumpname = optarg;
342e808190aSHans Petter Selasky 			break;
343e808190aSHans Petter Selasky 		case 'r':
344b4b75592SHans Petter Selasky 			if (act != ACTION_NONE)
345b4b75592SHans Petter Selasky 				usage();
346e808190aSHans Petter Selasky 			act = ACTION_DUMP_RESET;
347e808190aSHans Petter Selasky 			break;
348ea78f07bSHans Petter Selasky 		case 'f':
349b4b75592SHans Petter Selasky 			if (act != ACTION_NONE)
350b4b75592SHans Petter Selasky 				usage();
351ea78f07bSHans Petter Selasky 			act = ACTION_FW_UPDATE;
352ea78f07bSHans Petter Selasky 			img_fw_path = optarg;
353ea78f07bSHans Petter Selasky 			break;
354998c9a2bSHans Petter Selasky 		case 'z':
355b4b75592SHans Petter Selasky 			if (act != ACTION_NONE)
356b4b75592SHans Petter Selasky 				usage();
357998c9a2bSHans Petter Selasky 			act = ACTION_FW_RESET;
358998c9a2bSHans Petter Selasky 			break;
359e808190aSHans Petter Selasky 		case 'h':
360e808190aSHans Petter Selasky 		default:
361e808190aSHans Petter Selasky 			usage();
362e808190aSHans Petter Selasky 		}
363e808190aSHans Petter Selasky 	}
364ea78f07bSHans Petter Selasky 	if (act == ACTION_NONE || (dumpname != NULL &&
365ea78f07bSHans Petter Selasky 	    act != ACTION_DUMP_GET) || (img_fw_path != NULL &&
366ea78f07bSHans Petter Selasky 	    act != ACTION_FW_UPDATE))
367e808190aSHans Petter Selasky 		usage();
368e808190aSHans Petter Selasky 	if (parse_pci_addr(addrstr, &addr) != 0)
369e808190aSHans Petter Selasky 		exit(1);
370e808190aSHans Petter Selasky 
371e808190aSHans Petter Selasky 	ctldev = open(MLX5_DEV_PATH, O_RDWR);
372e808190aSHans Petter Selasky 	if (ctldev == -1)
373e808190aSHans Petter Selasky 		err(1, "open "MLX5_DEV_PATH);
374e808190aSHans Petter Selasky 	switch (act) {
375e808190aSHans Petter Selasky 	case ACTION_DUMP_GET:
376e808190aSHans Petter Selasky 		res = mlx5tool_save_dump(ctldev, &addr, dumpname);
377e808190aSHans Petter Selasky 		break;
378e808190aSHans Petter Selasky 	case ACTION_DUMP_RESET:
379e808190aSHans Petter Selasky 		res = mlx5tool_dump_reset(ctldev, &addr);
380e808190aSHans Petter Selasky 		break;
381e808190aSHans Petter Selasky 	case ACTION_DUMP_FORCE:
382e808190aSHans Petter Selasky 		res = mlx5tool_dump_force(ctldev, &addr);
383e808190aSHans Petter Selasky 		break;
384ea78f07bSHans Petter Selasky 	case ACTION_FW_UPDATE:
385ea78f07bSHans Petter Selasky 		res = mlx5tool_fw_update(ctldev, &addr, img_fw_path);
386ea78f07bSHans Petter Selasky 		break;
387998c9a2bSHans Petter Selasky 	case ACTION_FW_RESET:
388998c9a2bSHans Petter Selasky 		res = mlx5tool_fw_reset(ctldev, &addr);
389998c9a2bSHans Petter Selasky 		break;
390133fc15cSHans Petter Selasky 	case ACTION_GET_EEPROM_INFO:
391133fc15cSHans Petter Selasky 		res = mlx5tool_get_eeprom_info(ctldev, &addr);
392133fc15cSHans Petter Selasky 		break;
393e808190aSHans Petter Selasky 	default:
394e808190aSHans Petter Selasky 		res = 0;
395e808190aSHans Petter Selasky 		break;
396e808190aSHans Petter Selasky 	}
397e808190aSHans Petter Selasky 	close(ctldev);
398e808190aSHans Petter Selasky 	exit(res);
399e808190aSHans Petter Selasky }
400