mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
Implement firmware reset from userspace in mlx5tool(8).
Submitted by: kib@ MFC after: 3 days Sponsored by: Mellanox Technologies
This commit is contained in:
parent
939c79a213
commit
998c9a2bbc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=347313
|
@ -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
|
||||
|
|
|
@ -225,6 +225,24 @@ mlx5_fwdump_copyout(struct mlx5_dump_data *dd, struct mlx5_fwdump_get *fwg)
|
|||
return (0);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -307,6 +325,17 @@ mlx5_fwdump_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
|||
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;
|
||||
break;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -189,17 +189,29 @@ mlx5tool_fw_update(int ctldev, const struct mlx5_tool_addr *addr,
|
|||
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();
|
||||
|
@ -274,6 +290,9 @@ main(int argc, char *argv[])
|
|||
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;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue