2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright (c) 2018 by Chelsio Communications, Inc.
20 #include <sys/types.h>
23 #include <sys/socket.h>
25 #include <sys/varargs.h>
27 #include <sys/byteorder.h>
29 #include <sys/sysmacros.h>
34 #include "t4fw_interface.h"
37 * Firmware Device Log Dumping
40 static const char * const devlog_level_strings
[] = {
41 [FW_DEVLOG_LEVEL_EMERG
] = "EMERG",
42 [FW_DEVLOG_LEVEL_CRIT
] = "CRIT",
43 [FW_DEVLOG_LEVEL_ERR
] = "ERR",
44 [FW_DEVLOG_LEVEL_NOTICE
] = "NOTICE",
45 [FW_DEVLOG_LEVEL_INFO
] = "INFO",
46 [FW_DEVLOG_LEVEL_DEBUG
] = "DEBUG"
49 static const char * const devlog_facility_strings
[] = {
50 [FW_DEVLOG_FACILITY_CORE
] = "CORE",
51 [FW_DEVLOG_FACILITY_CF
] = "CF",
52 [FW_DEVLOG_FACILITY_SCHED
] = "SCHED",
53 [FW_DEVLOG_FACILITY_TIMER
] = "TIMER",
54 [FW_DEVLOG_FACILITY_RES
] = "RES",
55 [FW_DEVLOG_FACILITY_HW
] = "HW",
56 [FW_DEVLOG_FACILITY_FLR
] = "FLR",
57 [FW_DEVLOG_FACILITY_DMAQ
] = "DMAQ",
58 [FW_DEVLOG_FACILITY_PHY
] = "PHY",
59 [FW_DEVLOG_FACILITY_MAC
] = "MAC",
60 [FW_DEVLOG_FACILITY_PORT
] = "PORT",
61 [FW_DEVLOG_FACILITY_VI
] = "VI",
62 [FW_DEVLOG_FACILITY_FILTER
] = "FILTER",
63 [FW_DEVLOG_FACILITY_ACL
] = "ACL",
64 [FW_DEVLOG_FACILITY_TM
] = "TM",
65 [FW_DEVLOG_FACILITY_QFC
] = "QFC",
66 [FW_DEVLOG_FACILITY_DCB
] = "DCB",
67 [FW_DEVLOG_FACILITY_ETH
] = "ETH",
68 [FW_DEVLOG_FACILITY_OFLD
] = "OFLD",
69 [FW_DEVLOG_FACILITY_RI
] = "RI",
70 [FW_DEVLOG_FACILITY_ISCSI
] = "ISCSI",
71 [FW_DEVLOG_FACILITY_FCOE
] = "FCOE",
72 [FW_DEVLOG_FACILITY_FOISCSI
] = "FOISCSI",
73 [FW_DEVLOG_FACILITY_FOFCOE
] = "FOFCOE",
74 [FW_DEVLOG_FACILITY_CHNET
] = "CHNET",
77 static const char *progname
;
79 static void usage(FILE *fp
)
81 fprintf(fp
, "Usage: %s <path to t4nex#> [operation]\n", progname
);
83 "\tdevlog show device log\n"
84 "\tloadfw <FW image> Flash the FW image\n");
85 exit(fp
== stderr
? 1 : 0);
89 err(int code
, const char *fmt
, ...)
95 fprintf(stderr
, "error: ");
96 vfprintf(stderr
, fmt
, ap
);
97 fprintf(stderr
, ": %s\n", strerror(e
));
103 doit(const char *iff_name
, unsigned long cmd
, void *data
)
108 if ((fd
= open(iff_name
, O_RDWR
)) < 0)
111 rc
= (ioctl(fd
, cmd
, data
) < 0) ? errno
: rc
;
117 get_devlog(int argc
, char *argv
[], int start_arg
, const char *iff_name
)
119 struct t4_devlog
*devlog
;
120 struct fw_devlog_e
*entry
, *buf
;
121 int rc
= 0, first
= 0, nentries
, i
, j
, len
;
122 uint64_t ftstamp
= UINT64_MAX
;
124 devlog
= malloc(T4_DEVLOG_SIZE
+ sizeof (struct t4_devlog
));
126 err(1, "%s: can't allocate devlog buffer", __func__
);
128 devlog
->len
= T4_DEVLOG_SIZE
;
130 rc
= doit(iff_name
, T4_IOCTL_DEVLOG
, devlog
);
133 * Default buffer size is not sufficient to hold device log.
134 * Driver has updated the devlog.len to indicate the expected
135 * size. Free the currently allocated devlog.data, allocate
136 * again with right size and retry.
141 if ((devlog
= malloc(len
+ sizeof (struct t4_devlog
))) == NULL
)
142 err(1, "%s: can't reallocate devlog buffer", __func__
);
144 rc
= doit(iff_name
, T4_IOCTL_DEVLOG
, devlog
);
148 err(1, "%s: can't get device log", __func__
);
151 /* There are nentries number of entries in the buffer */
152 nentries
= (devlog
->len
/ sizeof (struct fw_devlog_e
));
154 buf
= (struct fw_devlog_e
*)devlog
->data
;
156 /* Find the first entry */
157 for (i
= 0; i
< nentries
; i
++) {
160 if (entry
->timestamp
== 0)
163 entry
->timestamp
= BE_64(entry
->timestamp
);
164 entry
->seqno
= BE_32(entry
->seqno
);
165 for (j
= 0; j
< 8; j
++)
166 entry
->params
[j
] = BE_32(entry
->params
[j
]);
168 if (entry
->timestamp
< ftstamp
) {
169 ftstamp
= entry
->timestamp
;
174 printf("%10s %15s %8s %8s %s\n", "Seq#", "Tstamp", "Level",
175 "Facility", "Message");
182 if (entry
->timestamp
== 0)
185 printf("%10d %15llu %8s %8s ", entry
->seqno
,
187 (entry
->level
< ARRAY_SIZE(devlog_level_strings
) ?
188 devlog_level_strings
[entry
->level
] : "UNKNOWN"),
189 (entry
->facility
< ARRAY_SIZE(devlog_facility_strings
) ?
190 devlog_facility_strings
[entry
->facility
] : "UNKNOWN"));
192 printf((const char *)entry
->fmt
, entry
->params
[0],
193 entry
->params
[1], entry
->params
[2], entry
->params
[3],
194 entry
->params
[4], entry
->params
[5], entry
->params
[6],
200 } while (i
!= first
);
206 load_fw(int argc
, char *argv
[], int start_arg
, const char *iff_name
)
208 const char *fname
= argv
[start_arg
];
215 err(1, "incorrect number of arguments.");
217 fd
= open(fname
, O_RDONLY
);
219 err(1, "%s: opening %s failed", __func__
, fname
);
220 if (fstat(fd
, &sb
) < 0) {
222 err(1, "%s: fstat %s failed", __func__
, fname
);
224 len
= (size_t)sb
.st_size
;
226 fw
= malloc(sizeof (struct t4_ldfw
) + len
);
229 err(1, "%s: %s allocate %ld bytes failed",
230 __func__
, fname
, sizeof (struct t4_ldfw
) + len
);
233 if (read(fd
, fw
->data
, len
) < len
) {
236 err(1, "%s: %s read failed", __func__
, fname
);
243 if (doit(iff_name
, T4_IOCTL_LOAD_FW
, fw
)) {
245 err(1, "%s: IOCTL failed", __func__
);
247 printf("FW flash success, reload driver/reboot to take "
255 run_cmd(int argc
, char *argv
[], const char *iff_name
)
257 if (strcmp(argv
[2], "devlog") == 0)
258 get_devlog(argc
, argv
, 3, iff_name
);
259 else if (strcmp(argv
[2], "loadfw") == 0)
260 load_fw(argc
, argv
, 3, iff_name
);
266 main(int argc
, char *argv
[])
268 const char *iff_name
;
273 if (strcmp(argv
[1], "-h") == 0 ||
274 strcmp(argv
[1], "--help") == 0) {
278 if (strcmp(argv
[1], "-v") == 0 ||
279 strcmp(argv
[1], "--version") == 0) {
280 printf("cxgbetool version %s\n", DRV_VERSION
);
290 run_cmd(argc
, argv
, iff_name
);