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