Commit 2cf1e703 authored by Ioana Ciornei's avatar Ioana Ciornei Committed by Greg Kroah-Hartman

bus: fsl-mc: add fsl-mc userspace support

Adding userspace support for the MC (Management Complex) means exporting
an ioctl capable device file representing the root resource container.

This new functionality in the fsl-mc bus driver intends to provide
userspace applications an interface to interact with the MC firmware.

Commands that are composed in userspace are sent to the MC firmware
through the FSL_MC_SEND_MC_COMMAND ioctl.  By default the implicit MC
I/O portal is used for this operation, but if the implicit one is busy,
a dynamic portal is allocated and then freed upon execution.

The command received through the ioctl interface is checked against a
known whitelist of accepted MC commands. Commands that attempt a change
in hardware configuration will need CAP_NET_ADMIN, while commands used
in debugging do not need it.
Acked-by: default avatarLaurentiu Tudor <laurentiu.tudor@nxp.com>
Signed-off-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Link: https://lore.kernel.org/r/20210114170752.2927915-4-ciorneiioana@gmail.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 46707989
......@@ -180,6 +180,7 @@ Code Seq# Include File Comments
'R' 00-1F linux/random.h conflict!
'R' 01 linux/rfkill.h conflict!
'R' C0-DF net/bluetooth/rfcomm.h
'R' E0 uapi/linux/fsl_mc.h
'S' all linux/cdrom.h conflict!
'S' 80-81 scsi/scsi_ioctl.h conflict!
'S' 82-FF scsi/scsi.h conflict!
......
......@@ -14,3 +14,10 @@ config FSL_MC_BUS
architecture. The fsl-mc bus driver handles discovery of
DPAA2 objects (which are represented as Linux devices) and
binding objects to drivers.
config FSL_MC_UAPI_SUPPORT
bool "Management Complex (MC) userspace support"
depends on FSL_MC_BUS
help
Provides userspace support for interrogating, creating, destroying or
configuring DPAA2 objects exported by the Management Complex.
......@@ -16,3 +16,6 @@ mc-bus-driver-objs := fsl-mc-bus.o \
fsl-mc-allocator.o \
fsl-mc-msi.o \
dpmcp.o
# MC userspace support
obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o
......@@ -603,6 +603,7 @@ int dprc_setup(struct fsl_mc_device *mc_dev)
struct irq_domain *mc_msi_domain;
bool mc_io_created = false;
bool msi_domain_set = false;
bool uapi_created = false;
u16 major_ver, minor_ver;
size_t region_size;
int error;
......@@ -635,6 +636,11 @@ int dprc_setup(struct fsl_mc_device *mc_dev)
return error;
mc_io_created = true;
} else {
error = fsl_mc_uapi_create_device_file(mc_bus);
if (error < 0)
return -EPROBE_DEFER;
uapi_created = true;
}
mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev);
......@@ -692,6 +698,9 @@ int dprc_setup(struct fsl_mc_device *mc_dev)
mc_dev->mc_io = NULL;
}
if (uapi_created)
fsl_mc_uapi_remove_device_file(mc_bus);
return error;
}
EXPORT_SYMBOL_GPL(dprc_setup);
......@@ -763,6 +772,7 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
int dprc_cleanup(struct fsl_mc_device *mc_dev)
{
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
int error;
/* this function should be called only for DPRCs, it
......@@ -793,6 +803,8 @@ int dprc_cleanup(struct fsl_mc_device *mc_dev)
if (!fsl_mc_is_root_dprc(&mc_dev->dev)) {
fsl_destroy_mc_io(mc_dev->mc_io);
mc_dev->mc_io = NULL;
} else {
fsl_mc_uapi_remove_device_file(mc_bus);
}
return 0;
......
......@@ -10,6 +10,8 @@
#include <linux/fsl/mc.h>
#include <linux/mutex.h>
#include <linux/ioctl.h>
#include <linux/miscdevice.h>
/*
* Data Path Management Complex (DPMNG) General API
......@@ -542,6 +544,22 @@ struct fsl_mc_resource_pool {
struct fsl_mc_bus *mc_bus;
};
/**
* struct fsl_mc_uapi - information associated with a device file
* @misc: struct miscdevice linked to the root dprc
* @device: newly created device in /dev
* @mutex: mutex lock to serialize the open/release operations
* @local_instance_in_use: local MC I/O instance in use or not
* @static_mc_io: pointer to the static MC I/O object
*/
struct fsl_mc_uapi {
struct miscdevice misc;
struct device *device;
struct mutex mutex; /* serialize open/release operations */
u32 local_instance_in_use;
struct fsl_mc_io *static_mc_io;
};
/**
* struct fsl_mc_bus - logical bus that corresponds to a physical DPRC
* @mc_dev: fsl-mc device for the bus device itself.
......@@ -551,6 +569,7 @@ struct fsl_mc_resource_pool {
* @irq_resources: Pointer to array of IRQ objects for the IRQ pool
* @scan_mutex: Serializes bus scanning
* @dprc_attr: DPRC attributes
* @uapi_misc: struct that abstracts the interaction with userspace
*/
struct fsl_mc_bus {
struct fsl_mc_device mc_dev;
......@@ -558,6 +577,7 @@ struct fsl_mc_bus {
struct fsl_mc_device_irq *irq_resources;
struct mutex scan_mutex; /* serializes bus scanning */
struct dprc_attributes dprc_attr;
struct fsl_mc_uapi uapi_misc;
};
#define to_fsl_mc_bus(_mc_dev) \
......@@ -614,4 +634,23 @@ struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc,
u16 mc_cmd_hdr_read_cmdid(struct fsl_mc_command *cmd);
#ifdef CONFIG_FSL_MC_UAPI_SUPPORT
int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus);
void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus);
#else
static inline int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus)
{
return 0;
}
static inline void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus)
{
}
#endif
#endif /* _FSL_MC_PRIVATE_H_ */
This diff is collapsed.
......@@ -16,10 +16,19 @@
* struct fsl_mc_command - Management Complex (MC) command structure
* @header: MC command header
* @params: MC command parameters
*
* Used by FSL_MC_SEND_MC_COMMAND
*/
struct fsl_mc_command {
__le64 header;
__le64 params[MC_CMD_NUM_OF_PARAMS];
};
#define FSL_MC_SEND_CMD_IOCTL_TYPE 'R'
#define FSL_MC_SEND_CMD_IOCTL_SEQ 0xE0
#define FSL_MC_SEND_MC_COMMAND \
_IOWR(FSL_MC_SEND_CMD_IOCTL_TYPE, FSL_MC_SEND_CMD_IOCTL_SEQ, \
struct fsl_mc_command)
#endif /* _UAPI_FSL_MC_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment