svn commit: r347841 - in stable/11: sys/dev/mlx5 sys/dev/mlx5/mlx5_core usr.sbin/mlx5tool
Hans Petter Selasky
hselasky at FreeBSD.org
Thu May 16 17:50:54 UTC 2019
Author: hselasky
Date: Thu May 16 17:50:52 2019
New Revision: 347841
URL: https://svnweb.freebsd.org/changeset/base/347841
Log:
MFC r347288:
Implement userspace firmware update for ConnectX-4/5/6.
Submitted by: kib@
Sponsored by: Mellanox Technologies
Modified:
stable/11/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c
stable/11/sys/dev/mlx5/mlx5io.h
stable/11/usr.sbin/mlx5tool/mlx5tool.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c Thu May 16 17:50:15 2019 (r347840)
+++ stable/11/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c Thu May 16 17:50:52 2019 (r347841)
@@ -233,6 +233,8 @@ mlx5_fwdump_ioctl(struct cdev *dev, u_long cmd, caddr_
struct mlx5_fwdump_get *fwg;
struct mlx5_tool_addr *devaddr;
struct mlx5_dump_data *dd;
+ struct mlx5_fw_update *fu;
+ struct firmware fake_fw;
int error;
error = 0;
@@ -274,6 +276,36 @@ mlx5_fwdump_ioctl(struct cdev *dev, u_long cmd, caddr_
if (error != 0)
break;
mlx5_fwdump(mdev);
+ break;
+ case MLX5_FW_UPDATE:
+ if ((fflag & FWRITE) == 0) {
+ error = EBADF;
+ break;
+ }
+ fu = (struct mlx5_fw_update *)data;
+ if (fu->img_fw_data_len > 10 * 1024 * 1024) {
+ error = EINVAL;
+ break;
+ }
+ devaddr = &fu->devaddr;
+ error = mlx5_dbsf_to_core(devaddr, &mdev);
+ if (error != 0)
+ break;
+ bzero(&fake_fw, sizeof(fake_fw));
+ fake_fw.name = "umlx_fw_up";
+ fake_fw.datasize = fu->img_fw_data_len;
+ fake_fw.version = 1;
+ fake_fw.data = (void *)kmem_malloc(fu->img_fw_data_len,
+ M_WAITOK);
+ if (fake_fw.data == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ error = copyin(fu->img_fw_data, __DECONST(void *, fake_fw.data),
+ fu->img_fw_data_len);
+ if (error == 0)
+ error = -mlx5_firmware_flash(mdev, &fake_fw);
+ kmem_free((vm_offset_t)fake_fw.data, fu->img_fw_data_len);
break;
default:
error = ENOTTY;
Modified: stable/11/sys/dev/mlx5/mlx5io.h
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5io.h Thu May 16 17:50:15 2019 (r347840)
+++ stable/11/sys/dev/mlx5/mlx5io.h Thu May 16 17:50:52 2019 (r347841)
@@ -49,9 +49,16 @@ struct mlx5_fwdump_get {
size_t reg_filled; /* out */
};
+struct mlx5_fw_update {
+ struct mlx5_tool_addr devaddr;
+ void *img_fw_data;
+ size_t img_fw_data_len;
+};
+
#define MLX5_FWDUMP_GET _IOWR('m', 1, struct mlx5_fwdump_get)
#define MLX5_FWDUMP_RESET _IOW('m', 2, struct mlx5_tool_addr)
#define MLX5_FWDUMP_FORCE _IOW('m', 3, struct mlx5_tool_addr)
+#define MLX5_FW_UPDATE _IOW('m', 4, struct mlx5_fw_update)
#ifndef _KERNEL
#define MLX5_DEV_PATH _PATH_DEV"mlx5ctl"
Modified: stable/11/usr.sbin/mlx5tool/mlx5tool.c
==============================================================================
--- stable/11/usr.sbin/mlx5tool/mlx5tool.c Thu May 16 17:50:15 2019 (r347840)
+++ stable/11/usr.sbin/mlx5tool/mlx5tool.c Thu May 16 17:50:52 2019 (r347841)
@@ -28,6 +28,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
#include <dev/mlx5/mlx5io.h>
#include <ctype.h>
#include <err.h>
@@ -144,15 +146,60 @@ mlx5tool_dump_force(int ctldev, const struct mlx5_tool
return (0);
}
+static int
+mlx5tool_fw_update(int ctldev, const struct mlx5_tool_addr *addr,
+ const char *img_fw_path)
+{
+ struct stat st;
+ struct mlx5_fw_update fwup;
+ int error, fd, res;
+
+ res = 0;
+ fd = open(img_fw_path, O_RDONLY);
+ if (fd == -1) {
+ warn("Unable to open %s", img_fw_path);
+ res = 1;
+ goto close_fd;
+ }
+ error = fstat(fd, &st);
+ if (error != 0) {
+ warn("Unable to stat %s", img_fw_path);
+ res = 1;
+ goto close_fd;
+ }
+ memset(&fwup, 0, sizeof(fwup));
+ memcpy(&fwup.devaddr, addr, sizeof(fwup.devaddr));
+ fwup.img_fw_data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE,
+ fd, 0);
+ if (fwup.img_fw_data == MAP_FAILED) {
+ warn("Unable to mmap %s", img_fw_path);
+ res = 1;
+ goto close_fd;
+ }
+ fwup.img_fw_data_len = st.st_size;
+
+ error = ioctl(ctldev, MLX5_FW_UPDATE, &fwup);
+ if (error == -1) {
+ warn("MLX5_FW_UPDATE");
+ }
+
+ munmap(fwup.img_fw_data, st.st_size);
+close_fd:
+ close(fd);
+ return (res);
+}
+
static void
usage(void)
{
fprintf(stderr,
- "Usage: mlx5tool -d pci<d:b:s:f> [-w -o dump.file | -r | -e]\n");
+ "Usage: mlx5tool -d pci<d:b:s:f> [-w -o dump.file | -r |"
+ " -e | -f fw.mfa2]\n");
fprintf(stderr, "\t-w - write firmware dump to the specified file\n");
fprintf(stderr, "\t-r - reset dump\n");
fprintf(stderr, "\t-e - force dump\n");
+ fprintf(stderr, "\t-f fw.img - flash firmware from fw.img\n");
exit(1);
}
@@ -160,6 +207,7 @@ enum mlx5_action {
ACTION_DUMP_GET,
ACTION_DUMP_RESET,
ACTION_DUMP_FORCE,
+ ACTION_FW_UPDATE,
ACTION_NONE,
};
@@ -169,13 +217,15 @@ main(int argc, char *argv[])
struct mlx5_tool_addr addr;
char *dumpname;
char *addrstr;
+ char *img_fw_path;
int c, ctldev, res;
enum mlx5_action act;
act = ACTION_NONE;
addrstr = NULL;
dumpname = NULL;
- while ((c = getopt(argc, argv, "d:eho:rw")) != -1) {
+ img_fw_path = NULL;
+ while ((c = getopt(argc, argv, "d:ef:ho:rw")) != -1) {
switch (c) {
case 'd':
addrstr = optarg;
@@ -192,12 +242,18 @@ main(int argc, char *argv[])
case 'r':
act = ACTION_DUMP_RESET;
break;
+ case 'f':
+ act = ACTION_FW_UPDATE;
+ img_fw_path = optarg;
+ break;
case 'h':
default:
usage();
}
}
- if (act == ACTION_NONE || (dumpname != NULL && act != ACTION_DUMP_GET))
+ if (act == ACTION_NONE || (dumpname != NULL &&
+ act != ACTION_DUMP_GET) || (img_fw_path != NULL &&
+ act != ACTION_FW_UPDATE))
usage();
if (parse_pci_addr(addrstr, &addr) != 0)
exit(1);
@@ -214,6 +270,9 @@ main(int argc, char *argv[])
break;
case ACTION_DUMP_FORCE:
res = mlx5tool_dump_force(ctldev, &addr);
+ break;
+ case ACTION_FW_UPDATE:
+ res = mlx5tool_fw_update(ctldev, &addr, img_fw_path);
break;
default:
res = 0;
More information about the svn-src-stable-11
mailing list