2 * Copyright (c) 2018, Mellanox Technologies, Ltd. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
29 #include <sys/param.h>
30 #include <sys/ioctl.h>
31 #include <dev/mlx5/mlx5io.h>
42 /* stolen from pciconf.c: parsesel() */
44 parse_pci_addr(const char *addrstr, struct mlx5_fwdump_addr *addr)
47 unsigned long selarr[4];
50 if (addrstr == NULL) {
51 warnx("no pci address specified");
54 if (strncmp(addrstr, "pci", 3) == 0) {
57 while (isdigit(*addrstr) && i < 4) {
58 selarr[i++] = strtoul(addrstr, &eppos, 10);
63 if (i > 0 && *addrstr == '\0') {
64 addr->func = (i > 2) ? selarr[--i] : 0;
65 addr->slot = (i > 0) ? selarr[--i] : 0;
66 addr->bus = (i > 0) ? selarr[--i] : 0;
67 addr->domain = (i > 0) ? selarr[--i] : 0;
71 warnx("invalid pci address %s", addrstr);
76 mlx5tool_save_dump(int ctldev, const struct mlx5_fwdump_addr *addr,
79 struct mlx5_fwdump_get fdg;
80 struct mlx5_fwdump_reg *rege;
88 dump = fopen(dumpname, "w");
90 warn("open %s", dumpname);
94 memset(&fdg, 0, sizeof(fdg));
96 error = ioctl(ctldev, MLX5_FWDUMP_GET, &fdg);
98 warn("MLX5_FWDUMP_GET dumpsize");
101 rege = calloc(fdg.reg_filled, sizeof(*rege));
107 fdg.reg_cnt = fdg.reg_filled;
108 error = ioctl(ctldev, MLX5_FWDUMP_GET, &fdg);
111 warnx("no dump recorded");
113 warn("MLX5_FWDUMP_GET dump fetch");
116 for (cnt = 0; cnt < fdg.reg_cnt; cnt++, rege++)
117 fprintf(dump, "0x%08x\t0x%08x\n", rege->addr, rege->val);
126 mlx5tool_dump_reset(int ctldev, const struct mlx5_fwdump_addr *addr)
129 if (ioctl(ctldev, MLX5_FWDUMP_RESET, addr) == -1) {
130 warn("MLX5_FWDUMP_RESET");
137 mlx5tool_dump_force(int ctldev, const struct mlx5_fwdump_addr *addr)
140 if (ioctl(ctldev, MLX5_FWDUMP_FORCE, addr) == -1) {
141 warn("MLX5_FWDUMP_FORCE");
152 "Usage: mlx5tool -d pci<d:b:s:f> [-w -o dump.file | -r | -e]\n");
153 fprintf(stderr, "\t-w - write firmware dump to the specified file\n");
154 fprintf(stderr, "\t-r - reset dump\n");
155 fprintf(stderr, "\t-e - force dump\n");
167 main(int argc, char *argv[])
169 struct mlx5_fwdump_addr addr;
173 enum mlx5_action act;
178 while ((c = getopt(argc, argv, "d:eho:rw")) != -1) {
184 act = ACTION_DUMP_GET;
187 act= ACTION_DUMP_FORCE;
193 act = ACTION_DUMP_RESET;
200 if (act == ACTION_NONE || (dumpname != NULL && act != ACTION_DUMP_GET))
202 if (parse_pci_addr(addrstr, &addr) != 0)
205 ctldev = open(MLX5_DEV_PATH, O_RDWR);
207 err(1, "open "MLX5_DEV_PATH);
209 case ACTION_DUMP_GET:
210 res = mlx5tool_save_dump(ctldev, &addr, dumpname);
212 case ACTION_DUMP_RESET:
213 res = mlx5tool_dump_reset(ctldev, &addr);
215 case ACTION_DUMP_FORCE:
216 res = mlx5tool_dump_force(ctldev, &addr);