summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cxgbetool
diff options
context:
space:
mode:
authorVishal Kulkarni <vishal@chelsio.com>2018-04-13 23:33:08 +0000
committerRobert Mustacchi <rm@joyent.com>2018-05-23 23:50:04 +0000
commit5a9113e79c46be778552f0a0fd02087e13e41bff (patch)
treeb917fcc65529b742be84af13ee88c30fd3ade4d2 /usr/src/cmd/cxgbetool
parentaafbdf3fa8f988ec989a8143b47d3158161d2143 (diff)
downloadillumos-joyent-5a9113e79c46be778552f0a0fd02087e13e41bff.tar.gz
9482 Want cxgbetool
Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/cmd/cxgbetool')
-rw-r--r--usr/src/cmd/cxgbetool/Makefile29
-rw-r--r--usr/src/cmd/cxgbetool/cxgbetool.c293
2 files changed, 322 insertions, 0 deletions
diff --git a/usr/src/cmd/cxgbetool/Makefile b/usr/src/cmd/cxgbetool/Makefile
new file mode 100644
index 0000000000..4a39c9e80f
--- /dev/null
+++ b/usr/src/cmd/cxgbetool/Makefile
@@ -0,0 +1,29 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2018 by Chelsio Communications, Inc.
+#
+PROG = cxgbetool
+
+include ../Makefile.cmd
+
+CFLAGS += $(CCVERBOSE) -I$(SRC)/uts/common/io/cxgbe/t4nex -I$(SRC)/uts/common/io/cxgbe/firmware
+
+all: $(PROG)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/cxgbetool/cxgbetool.c b/usr/src/cmd/cxgbetool/cxgbetool.c
new file mode 100644
index 0000000000..d45e843202
--- /dev/null
+++ b/usr/src/cmd/cxgbetool/cxgbetool.c
@@ -0,0 +1,293 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2018 by Chelsio Communications, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <strings.h>
+#include <sys/varargs.h>
+#include <errno.h>
+#include <sys/byteorder.h>
+#include <inttypes.h>
+#include <sys/sysmacros.h>
+
+#include "t4nex.h"
+#include "version.h"
+#include "osdep.h"
+#include "t4fw_interface.h"
+
+/*
+ * Firmware Device Log Dumping
+ */
+
+static const char * const devlog_level_strings[] = {
+ [FW_DEVLOG_LEVEL_EMERG] = "EMERG",
+ [FW_DEVLOG_LEVEL_CRIT] = "CRIT",
+ [FW_DEVLOG_LEVEL_ERR] = "ERR",
+ [FW_DEVLOG_LEVEL_NOTICE] = "NOTICE",
+ [FW_DEVLOG_LEVEL_INFO] = "INFO",
+ [FW_DEVLOG_LEVEL_DEBUG] = "DEBUG"
+};
+
+static const char * const devlog_facility_strings[] = {
+ [FW_DEVLOG_FACILITY_CORE] = "CORE",
+ [FW_DEVLOG_FACILITY_CF] = "CF",
+ [FW_DEVLOG_FACILITY_SCHED] = "SCHED",
+ [FW_DEVLOG_FACILITY_TIMER] = "TIMER",
+ [FW_DEVLOG_FACILITY_RES] = "RES",
+ [FW_DEVLOG_FACILITY_HW] = "HW",
+ [FW_DEVLOG_FACILITY_FLR] = "FLR",
+ [FW_DEVLOG_FACILITY_DMAQ] = "DMAQ",
+ [FW_DEVLOG_FACILITY_PHY] = "PHY",
+ [FW_DEVLOG_FACILITY_MAC] = "MAC",
+ [FW_DEVLOG_FACILITY_PORT] = "PORT",
+ [FW_DEVLOG_FACILITY_VI] = "VI",
+ [FW_DEVLOG_FACILITY_FILTER] = "FILTER",
+ [FW_DEVLOG_FACILITY_ACL] = "ACL",
+ [FW_DEVLOG_FACILITY_TM] = "TM",
+ [FW_DEVLOG_FACILITY_QFC] = "QFC",
+ [FW_DEVLOG_FACILITY_DCB] = "DCB",
+ [FW_DEVLOG_FACILITY_ETH] = "ETH",
+ [FW_DEVLOG_FACILITY_OFLD] = "OFLD",
+ [FW_DEVLOG_FACILITY_RI] = "RI",
+ [FW_DEVLOG_FACILITY_ISCSI] = "ISCSI",
+ [FW_DEVLOG_FACILITY_FCOE] = "FCOE",
+ [FW_DEVLOG_FACILITY_FOISCSI] = "FOISCSI",
+ [FW_DEVLOG_FACILITY_FOFCOE] = "FOFCOE",
+ [FW_DEVLOG_FACILITY_CHNET] = "CHNET",
+};
+
+static const char *progname;
+
+static void usage(FILE *fp)
+{
+ fprintf(fp, "Usage: %s <path to t4nex#> [operation]\n", progname);
+ fprintf(fp,
+ "\tdevlog show device log\n"
+ "\tloadfw <FW image> Flash the FW image\n");
+ exit(fp == stderr ? 1 : 0);
+}
+
+static void
+err(int code, const char *fmt, ...)
+{
+ va_list ap;
+ int e = errno;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "error: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ": %s\n", strerror(e));
+ va_end(ap);
+ exit(code);
+}
+
+static int
+doit(const char *iff_name, unsigned long cmd, void *data)
+{
+ int fd = 0;
+ int rc = 0;
+
+ if ((fd = open(iff_name, O_RDWR)) < 0)
+ return (-1);
+
+ rc = (ioctl(fd, cmd, data) < 0) ? errno : rc;
+ close(fd);
+ return (rc);
+}
+
+static void
+get_devlog(int argc, char *argv[], int start_arg, const char *iff_name)
+{
+ struct t4_devlog *devlog;
+ struct fw_devlog_e *entry, *buf;
+ int rc = 0, first = 0, nentries, i, j, len;
+ uint64_t ftstamp = UINT64_MAX;
+
+ devlog = malloc(T4_DEVLOG_SIZE + sizeof (struct t4_devlog));
+ if (!devlog)
+ err(1, "%s: can't allocate devlog buffer", __func__);
+
+ devlog->len = T4_DEVLOG_SIZE;
+ /* Get device log */
+ rc = doit(iff_name, T4_IOCTL_DEVLOG, devlog);
+ if (rc == ENOBUFS) {
+ /*
+ * Default buffer size is not sufficient to hold device log.
+ * Driver has updated the devlog.len to indicate the expected
+ * size. Free the currently allocated devlog.data, allocate
+ * again with right size and retry.
+ */
+ len = devlog->len;
+ free(devlog);
+
+ if ((devlog = malloc(len + sizeof (struct t4_devlog))) == NULL)
+ err(1, "%s: can't reallocate devlog buffer", __func__);
+
+ rc = doit(iff_name, T4_IOCTL_DEVLOG, devlog);
+ }
+ if (rc) {
+ free(devlog);
+ err(1, "%s: can't get device log", __func__);
+ }
+
+ /* There are nentries number of entries in the buffer */
+ nentries = (devlog->len / sizeof (struct fw_devlog_e));
+
+ buf = (struct fw_devlog_e *)devlog->data;
+
+ /* Find the first entry */
+ for (i = 0; i < nentries; i++) {
+ entry = &buf[i];
+
+ if (entry->timestamp == 0)
+ break;
+
+ entry->timestamp = BE_64(entry->timestamp);
+ entry->seqno = BE_32(entry->seqno);
+ for (j = 0; j < 8; j++)
+ entry->params[j] = BE_32(entry->params[j]);
+
+ if (entry->timestamp < ftstamp) {
+ ftstamp = entry->timestamp;
+ first = i;
+ }
+ }
+
+ printf("%10s %15s %8s %8s %s\n", "Seq#", "Tstamp", "Level",
+ "Facility", "Message");
+
+ i = first;
+
+ do {
+ entry = &buf[i];
+
+ if (entry->timestamp == 0)
+ break;
+
+ printf("%10d %15llu %8s %8s ", entry->seqno,
+ entry->timestamp,
+ (entry->level < ARRAY_SIZE(devlog_level_strings) ?
+ devlog_level_strings[entry->level] : "UNKNOWN"),
+ (entry->facility < ARRAY_SIZE(devlog_facility_strings) ?
+ devlog_facility_strings[entry->facility] : "UNKNOWN"));
+
+ printf((const char *)entry->fmt, entry->params[0],
+ entry->params[1], entry->params[2], entry->params[3],
+ entry->params[4], entry->params[5], entry->params[6],
+ entry->params[7]);
+
+ if (++i == nentries)
+ i = 0;
+
+ } while (i != first);
+
+ free(devlog);
+}
+
+static void
+load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
+{
+ const char *fname = argv[start_arg];
+ struct t4_ldfw *fw;
+ struct stat sb;
+ size_t len;
+ int fd;
+
+ if (argc != 4)
+ err(1, "incorrect number of arguments.");
+
+ fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ err(1, "%s: opening %s failed", __func__, fname);
+ if (fstat(fd, &sb) < 0) {
+ close(fd);
+ err(1, "%s: fstat %s failed", __func__, fname);
+ }
+ len = (size_t)sb.st_size;
+
+ fw = malloc(sizeof (struct t4_ldfw) + len);
+ if (!fw) {
+ close(fd);
+ err(1, "%s: %s allocate %ld bytes failed",
+ __func__, fname, sizeof (struct t4_ldfw) + len);
+ }
+
+ if (read(fd, fw->data, len) < len) {
+ close(fd);
+ free(fw);
+ err(1, "%s: %s read failed", __func__, fname);
+ }
+
+ close(fd);
+
+ fw->len = len;
+
+ if (doit(iff_name, T4_IOCTL_LOAD_FW, fw)) {
+ free(fw);
+ err(1, "%s: IOCTL failed", __func__);
+ } else {
+ printf("FW flash success, reload driver/reboot to take "
+ "effect\n");
+ }
+
+ free(fw);
+}
+
+static void
+run_cmd(int argc, char *argv[], const char *iff_name)
+{
+ if (strcmp(argv[2], "devlog") == 0)
+ get_devlog(argc, argv, 3, iff_name);
+ else if (strcmp(argv[2], "loadfw") == 0)
+ load_fw(argc, argv, 3, iff_name);
+ else
+ usage(stderr);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *iff_name;
+
+ progname = argv[0];
+
+ if (argc == 2) {
+ if (strcmp(argv[1], "-h") == 0 ||
+ strcmp(argv[1], "--help") == 0) {
+ usage(stdout);
+ }
+
+ if (strcmp(argv[1], "-v") == 0 ||
+ strcmp(argv[1], "--version") == 0) {
+ printf("cxgbetool version %s\n", DRV_VERSION);
+ exit(0);
+ }
+ }
+
+ if (argc < 3)
+ usage(stderr);
+
+ iff_name = argv[1];
+
+ run_cmd(argc, argv, iff_name);
+
+ return (0);
+}