Commit 052493d5 authored by Alex Williamson's avatar Alex Williamson
Browse files

Merge branch 'v5.16/vfio/diana-fsl-reset-v2' into v5.16/vfio/next

parents d9a0cd51 8798a803
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -15,7 +15,8 @@ mc-bus-driver-objs := fsl-mc-bus.o \
		      dprc-driver.o \
		      fsl-mc-allocator.o \
		      fsl-mc-msi.o \
		      dpmcp.o
		      dpmcp.o \
		      obj-api.o

# MC userspace support
obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o
+35 −4
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ struct dpmng_rsp_get_version {

/* DPMCP command IDs */
#define DPMCP_CMDID_CLOSE		DPMCP_CMD(0x800)
#define DPMCP_CMDID_OPEN		DPMCP_CMD(0x80b)
#define DPMCP_CMDID_RESET		DPMCP_CMD(0x005)

struct dpmcp_cmd_open {
@@ -91,7 +90,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io,

/* DPRC command IDs */
#define DPRC_CMDID_CLOSE                        DPRC_CMD(0x800)
#define DPRC_CMDID_OPEN                         DPRC_CMD(0x805)
#define DPRC_CMDID_GET_API_VERSION              DPRC_CMD(0xa05)

#define DPRC_CMDID_GET_ATTR                     DPRC_CMD(0x004)
@@ -453,7 +451,6 @@ int dprc_get_connection(struct fsl_mc_io *mc_io,

/* Command IDs */
#define DPBP_CMDID_CLOSE		DPBP_CMD(0x800)
#define DPBP_CMDID_OPEN			DPBP_CMD(0x804)

#define DPBP_CMDID_ENABLE		DPBP_CMD(0x002)
#define DPBP_CMDID_DISABLE		DPBP_CMD(0x003)
@@ -492,7 +489,6 @@ struct dpbp_rsp_get_attributes {

/* Command IDs */
#define DPCON_CMDID_CLOSE			DPCON_CMD(0x800)
#define DPCON_CMDID_OPEN			DPCON_CMD(0x808)

#define DPCON_CMDID_ENABLE			DPCON_CMD(0x002)
#define DPCON_CMDID_DISABLE			DPCON_CMD(0x003)
@@ -524,6 +520,41 @@ struct dpcon_cmd_set_notification {
	__le64 user_ctx;
};

/*
 * Generic FSL MC API
 */

/* generic command versioning */
#define OBJ_CMD_BASE_VERSION		1
#define OBJ_CMD_ID_OFFSET		4

#define OBJ_CMD(id)	(((id) << OBJ_CMD_ID_OFFSET) | OBJ_CMD_BASE_VERSION)

/* open command codes */
#define DPRTC_CMDID_OPEN		OBJ_CMD(0x810)
#define DPNI_CMDID_OPEN		OBJ_CMD(0x801)
#define DPSW_CMDID_OPEN		OBJ_CMD(0x802)
#define DPIO_CMDID_OPEN		OBJ_CMD(0x803)
#define DPBP_CMDID_OPEN		OBJ_CMD(0x804)
#define DPRC_CMDID_OPEN		OBJ_CMD(0x805)
#define DPDMUX_CMDID_OPEN		OBJ_CMD(0x806)
#define DPCI_CMDID_OPEN		OBJ_CMD(0x807)
#define DPCON_CMDID_OPEN		OBJ_CMD(0x808)
#define DPSECI_CMDID_OPEN		OBJ_CMD(0x809)
#define DPAIOP_CMDID_OPEN		OBJ_CMD(0x80a)
#define DPMCP_CMDID_OPEN		OBJ_CMD(0x80b)
#define DPMAC_CMDID_OPEN		OBJ_CMD(0x80c)
#define DPDCEI_CMDID_OPEN		OBJ_CMD(0x80d)
#define DPDMAI_CMDID_OPEN		OBJ_CMD(0x80e)
#define DPDBG_CMDID_OPEN		OBJ_CMD(0x80f)

/* Generic object command IDs */
#define OBJ_CMDID_CLOSE		OBJ_CMD(0x800)
#define OBJ_CMDID_RESET		OBJ_CMD(0x005)

struct fsl_mc_obj_cmd_open {
	__le32 obj_id;
};

/**
 * struct fsl_mc_resource_pool - Pool of MC resources of a given
+103 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
 * Copyright 2021 NXP
 *
 */
#include <linux/kernel.h>
#include <linux/fsl/mc.h>

#include "fsl-mc-private.h"

static int fsl_mc_get_open_cmd_id(const char *type)
{
	static const struct {
		int cmd_id;
		const char *type;
	} dev_ids[] = {
		{ DPRTC_CMDID_OPEN, "dprtc" },
		{ DPRC_CMDID_OPEN, "dprc" },
		{ DPNI_CMDID_OPEN, "dpni" },
		{ DPIO_CMDID_OPEN, "dpio" },
		{ DPSW_CMDID_OPEN, "dpsw" },
		{ DPBP_CMDID_OPEN, "dpbp" },
		{ DPCON_CMDID_OPEN, "dpcon" },
		{ DPMCP_CMDID_OPEN, "dpmcp" },
		{ DPMAC_CMDID_OPEN, "dpmac" },
		{ DPSECI_CMDID_OPEN, "dpseci" },
		{ DPDMUX_CMDID_OPEN, "dpdmux" },
		{ DPDCEI_CMDID_OPEN, "dpdcei" },
		{ DPAIOP_CMDID_OPEN, "dpaiop" },
		{ DPCI_CMDID_OPEN, "dpci" },
		{ DPDMAI_CMDID_OPEN, "dpdmai" },
		{ DPDBG_CMDID_OPEN, "dpdbg" },
		{ 0, NULL }
	};
	int i;

	for (i = 0; dev_ids[i].type; i++)
		if (!strcmp(dev_ids[i].type, type))
			return dev_ids[i].cmd_id;

	return -1;
}

int fsl_mc_obj_open(struct fsl_mc_io *mc_io,
		    u32 cmd_flags,
		    int obj_id,
		    char *obj_type,
		    u16 *token)
{
	struct fsl_mc_command cmd = { 0 };
	struct fsl_mc_obj_cmd_open *cmd_params;
	int err = 0;
	int cmd_id = fsl_mc_get_open_cmd_id(obj_type);

	if (cmd_id == -1)
		return -ENODEV;

	/* prepare command */
	cmd.header = mc_encode_cmd_header(cmd_id, cmd_flags, 0);
	cmd_params = (struct fsl_mc_obj_cmd_open *)cmd.params;
	cmd_params->obj_id = cpu_to_le32(obj_id);

	/* send command to mc*/
	err = mc_send_command(mc_io, &cmd);
	if (err)
		return err;

	/* retrieve response parameters */
	*token = mc_cmd_hdr_read_token(&cmd);

	return err;
}
EXPORT_SYMBOL_GPL(fsl_mc_obj_open);

int fsl_mc_obj_close(struct fsl_mc_io *mc_io,
		     u32 cmd_flags,
		     u16 token)
{
	struct fsl_mc_command cmd = { 0 };

	/* prepare command */
	cmd.header = mc_encode_cmd_header(OBJ_CMDID_CLOSE, cmd_flags,
					  token);

	/* send command to mc*/
	return mc_send_command(mc_io, &cmd);
}
EXPORT_SYMBOL_GPL(fsl_mc_obj_close);

int fsl_mc_obj_reset(struct fsl_mc_io *mc_io,
		     u32 cmd_flags,
		     u16 token)
{
	struct fsl_mc_command cmd = { 0 };

	/* prepare command */
	cmd.header = mc_encode_cmd_header(OBJ_CMDID_RESET, cmd_flags,
					  token);

	/* send command to mc*/
	return mc_send_command(mc_io, &cmd);
}
EXPORT_SYMBOL_GPL(fsl_mc_obj_reset);
+30 −15
Original line number Diff line number Diff line
@@ -65,6 +65,34 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev)
	kfree(vdev->regions);
}

static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev)
{
	struct fsl_mc_device *mc_dev = vdev->mc_dev;
	int ret = 0;

	if (is_fsl_mc_bus_dprc(vdev->mc_dev)) {
		return dprc_reset_container(mc_dev->mc_io, 0,
					mc_dev->mc_handle,
					mc_dev->obj_desc.id,
					DPRC_RESET_OPTION_NON_RECURSIVE);
	} else {
		u16 token;

		ret = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
				      mc_dev->obj_desc.type,
				      &token);
		if (ret)
			goto out;
		ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token);
		if (ret) {
			fsl_mc_obj_close(mc_dev->mc_io, 0, token);
			goto out;
		}
		ret = fsl_mc_obj_close(mc_dev->mc_io, 0, token);
	}
out:
	return ret;
}

static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev)
{
@@ -78,9 +106,7 @@ static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev)
	vfio_fsl_mc_regions_cleanup(vdev);

	/* reset the device before cleaning up the interrupts */
	ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle,
				   mc_cont->obj_desc.id,
				   DPRC_RESET_OPTION_NON_RECURSIVE);
	ret = vfio_fsl_mc_reset_device(vdev);

	if (WARN_ON(ret))
		dev_warn(&mc_cont->dev,
@@ -203,18 +229,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev,
	}
	case VFIO_DEVICE_RESET:
	{
		int ret;
		struct fsl_mc_device *mc_dev = vdev->mc_dev;

		/* reset is supported only for the DPRC */
		if (!is_fsl_mc_bus_dprc(mc_dev))
			return -ENOTTY;

		ret = dprc_reset_container(mc_dev->mc_io, 0,
					   mc_dev->mc_handle,
					   mc_dev->obj_desc.id,
					   DPRC_RESET_OPTION_NON_RECURSIVE);
		return ret;
		return vfio_fsl_mc_reset_device(vdev);

	}
	default:
+14 −0
Original line number Diff line number Diff line
@@ -620,6 +620,20 @@ int dpcon_reset(struct fsl_mc_io *mc_io,
		u32 cmd_flags,
		u16 token);

int fsl_mc_obj_open(struct fsl_mc_io *mc_io,
		    u32 cmd_flags,
		    int obj_id,
		    char *obj_type,
		    u16 *token);

int fsl_mc_obj_close(struct fsl_mc_io *mc_io,
		     u32 cmd_flags,
		     u16 token);

int fsl_mc_obj_reset(struct fsl_mc_io *mc_io,
		     u32 cmd_flags,
		     u16 token);

/**
 * struct dpcon_attr - Structure representing DPCON attributes
 * @id: DPCON object ID