svn commit: r347313 - in head: share/man/man4 sys/dev/mlx5 sys/dev/mlx5/mlx5_core usr.sbin/mlx5tool

Hans Petter Selasky hselasky at FreeBSD.org
Wed May 8 11:05:11 UTC 2019


Author: hselasky
Date: Wed May  8 11:05:09 2019
New Revision: 347313
URL: https://svnweb.freebsd.org/changeset/base/347313

Log:
  Implement firmware reset from userspace in mlx5tool(8).
  
  Submitted by:	kib@
  MFC after:	3 days
  Sponsored by:	Mellanox Technologies

Modified:
  head/share/man/man4/mlx5io.4
  head/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c
  head/sys/dev/mlx5/mlx5io.h
  head/usr.sbin/mlx5tool/mlx5tool.8
  head/usr.sbin/mlx5tool/mlx5tool.c

Modified: head/share/man/man4/mlx5io.4
==============================================================================
--- head/share/man/man4/mlx5io.4	Wed May  8 11:04:40 2019	(r347312)
+++ head/share/man/man4/mlx5io.4	Wed May  8 11:05:09 2019	(r347313)
@@ -142,6 +142,11 @@ Image address in memory is passed in
 the length of the image is specified in
 .Dv img_fw_data_len
 field.
+.It Dv MLX5_FW_RESET
+Requests PCIe link-level reset on the device.
+The address of the device is specified by the
+.Vt struct mlx5_tool_addr
+structure, which should be passed as an argument.
 .El
 .Sh FILES
 The

Modified: head/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c	Wed May  8 11:04:40 2019	(r347312)
+++ head/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c	Wed May  8 11:05:09 2019	(r347313)
@@ -226,6 +226,24 @@ out:
 }
 
 static int
+mlx5_fw_reset(struct mlx5_core_dev *mdev)
+{
+	device_t dev, bus;
+	int error;
+
+	error = -mlx5_set_mfrl_reg(mdev, MLX5_FRL_LEVEL3);
+	if (error == 0) {
+		dev = mdev->pdev->dev.bsddev;
+		mtx_lock(&Giant);
+		bus = device_get_parent(dev);
+		error = BUS_RESET_CHILD(device_get_parent(bus), bus,
+		    DEVF_RESET_DETACH);
+		mtx_unlock(&Giant);
+	}
+	return (error);
+}
+
+static int
 mlx5_fwdump_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
     struct thread *td)
 {
@@ -306,6 +324,17 @@ mlx5_fwdump_ioctl(struct cdev *dev, u_long cmd, caddr_
 		if (error == 0)
 			error = -mlx5_firmware_flash(mdev, &fake_fw);
 		kmem_free((vm_offset_t)fake_fw.data, fu->img_fw_data_len);
+		break;
+	case MLX5_FW_RESET:
+		if ((fflag & FWRITE) == 0) {
+			error = EBADF;
+			break;
+		}
+		devaddr = (struct mlx5_tool_addr *)data;
+		error = mlx5_dbsf_to_core(devaddr, &mdev);
+		if (error != 0)
+			break;
+		error = mlx5_fw_reset(mdev);
 		break;
 	default:
 		error = ENOTTY;

Modified: head/sys/dev/mlx5/mlx5io.h
==============================================================================
--- head/sys/dev/mlx5/mlx5io.h	Wed May  8 11:04:40 2019	(r347312)
+++ head/sys/dev/mlx5/mlx5io.h	Wed May  8 11:05:09 2019	(r347313)
@@ -59,6 +59,7 @@ struct mlx5_fw_update {
 #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)
+#define	MLX5_FW_RESET		_IOW('m', 5, struct mlx5_tool_addr)
 
 #ifndef _KERNEL
 #define	MLX5_DEV_PATH	_PATH_DEV"mlx5ctl"

Modified: head/usr.sbin/mlx5tool/mlx5tool.8
==============================================================================
--- head/usr.sbin/mlx5tool/mlx5tool.8	Wed May  8 11:04:40 2019	(r347312)
+++ head/usr.sbin/mlx5tool/mlx5tool.8	Wed May  8 11:05:09 2019	(r347313)
@@ -45,6 +45,9 @@
 .Nm
 .Fl d Ar domain:bus:slot:func
 .Fl f Ar file.mfa2
+.Nm
+.Fl d Ar domain:bus:slot:func
+.Fl z
 .Sh DESCRIPTION
 The
 .Nm
@@ -91,6 +94,14 @@ Flashes the firmware image
 to the specified adapter.
 Image must be in MFA2 pack format and contain a component suitable
 for the adapter hardware.
+.Pp
+Typically, PCIe link-level reset is required to activate the
+newly flashed image, which can be performed by the system reboot
+or using the
+.Fl z
+option.
+.It Fl z
+Performs PCIe link-level reset on the specified device.
 .El
 .Sh FILES
 The

Modified: head/usr.sbin/mlx5tool/mlx5tool.c
==============================================================================
--- head/usr.sbin/mlx5tool/mlx5tool.c	Wed May  8 11:04:40 2019	(r347312)
+++ head/usr.sbin/mlx5tool/mlx5tool.c	Wed May  8 11:05:09 2019	(r347313)
@@ -189,17 +189,29 @@ close_fd:
 	return (res);
 }
 
+static int
+mlx5tool_fw_reset(int ctldev, const struct mlx5_tool_addr *addr)
+{
+
+	if (ioctl(ctldev, MLX5_FW_RESET, addr) == -1) {
+		warn("MLX5_FW_RESET");
+		return (1);
+	}
+	return (0);
+}
+
 static void
 usage(void)
 {
 
 	fprintf(stderr,
 	    "Usage: mlx5tool -d pci<d:b:s:f> [-w -o dump.file | -r |"
-	    "    -e | -f fw.mfa2]\n");
+	    " -e | -f fw.mfa2 | -z]\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");
+	fprintf(stderr, "\t-z - initiate firmware reset\n");
 	exit(1);
 }
 
@@ -208,6 +220,7 @@ enum mlx5_action {
 	ACTION_DUMP_RESET,
 	ACTION_DUMP_FORCE,
 	ACTION_FW_UPDATE,
+	ACTION_FW_RESET,
 	ACTION_NONE,
 };
 
@@ -225,7 +238,7 @@ main(int argc, char *argv[])
 	addrstr = NULL;
 	dumpname = NULL;
 	img_fw_path = NULL;
-	while ((c = getopt(argc, argv, "d:ef:ho:rw")) != -1) {
+	while ((c = getopt(argc, argv, "d:ef:ho:rwz")) != -1) {
 		switch (c) {
 		case 'd':
 			addrstr = optarg;
@@ -246,6 +259,9 @@ main(int argc, char *argv[])
 			act = ACTION_FW_UPDATE;
 			img_fw_path = optarg;
 			break;
+		case 'z':
+			act = ACTION_FW_RESET;
+			break;
 		case 'h':
 		default:
 			usage();
@@ -273,6 +289,9 @@ main(int argc, char *argv[])
 		break;
 	case ACTION_FW_UPDATE:
 		res = mlx5tool_fw_update(ctldev, &addr, img_fw_path);
+		break;
+	case ACTION_FW_RESET:
+		res = mlx5tool_fw_reset(ctldev, &addr);
 		break;
 	default:
 		res = 0;


More information about the svn-src-head mailing list