Date: Thu, 16 May 2019 17:50:53 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r347841 - in stable/11: sys/dev/mlx5 sys/dev/mlx5/mlx5_core usr.sbin/mlx5tool Message-ID: <201905161750.x4GHorvH020200@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905161750.x4GHorvH020200>