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 ...@@ -180,6 +180,7 @@ Code Seq# Include File Comments
'R' 00-1F linux/random.h conflict! 'R' 00-1F linux/random.h conflict!
'R' 01 linux/rfkill.h conflict! 'R' 01 linux/rfkill.h conflict!
'R' C0-DF net/bluetooth/rfcomm.h 'R' C0-DF net/bluetooth/rfcomm.h
'R' E0 uapi/linux/fsl_mc.h
'S' all linux/cdrom.h conflict! 'S' all linux/cdrom.h conflict!
'S' 80-81 scsi/scsi_ioctl.h conflict! 'S' 80-81 scsi/scsi_ioctl.h conflict!
'S' 82-FF scsi/scsi.h conflict! 'S' 82-FF scsi/scsi.h conflict!
......
...@@ -14,3 +14,10 @@ config FSL_MC_BUS ...@@ -14,3 +14,10 @@ config FSL_MC_BUS
architecture. The fsl-mc bus driver handles discovery of architecture. The fsl-mc bus driver handles discovery of
DPAA2 objects (which are represented as Linux devices) and DPAA2 objects (which are represented as Linux devices) and
binding objects to drivers. 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 \ ...@@ -16,3 +16,6 @@ mc-bus-driver-objs := fsl-mc-bus.o \
fsl-mc-allocator.o \ fsl-mc-allocator.o \
fsl-mc-msi.o \ fsl-mc-msi.o \
dpmcp.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) ...@@ -603,6 +603,7 @@ int dprc_setup(struct fsl_mc_device *mc_dev)
struct irq_domain *mc_msi_domain; struct irq_domain *mc_msi_domain;
bool mc_io_created = false; bool mc_io_created = false;
bool msi_domain_set = false; bool msi_domain_set = false;
bool uapi_created = false;
u16 major_ver, minor_ver; u16 major_ver, minor_ver;
size_t region_size; size_t region_size;
int error; int error;
...@@ -635,6 +636,11 @@ int dprc_setup(struct fsl_mc_device *mc_dev) ...@@ -635,6 +636,11 @@ int dprc_setup(struct fsl_mc_device *mc_dev)
return error; return error;
mc_io_created = true; 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); mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev);
...@@ -692,6 +698,9 @@ int dprc_setup(struct fsl_mc_device *mc_dev) ...@@ -692,6 +698,9 @@ int dprc_setup(struct fsl_mc_device *mc_dev)
mc_dev->mc_io = NULL; mc_dev->mc_io = NULL;
} }
if (uapi_created)
fsl_mc_uapi_remove_device_file(mc_bus);
return error; return error;
} }
EXPORT_SYMBOL_GPL(dprc_setup); EXPORT_SYMBOL_GPL(dprc_setup);
...@@ -763,6 +772,7 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev) ...@@ -763,6 +772,7 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
int dprc_cleanup(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; int error;
/* this function should be called only for DPRCs, it /* this function should be called only for DPRCs, it
...@@ -793,6 +803,8 @@ int dprc_cleanup(struct fsl_mc_device *mc_dev) ...@@ -793,6 +803,8 @@ int dprc_cleanup(struct fsl_mc_device *mc_dev)
if (!fsl_mc_is_root_dprc(&mc_dev->dev)) { if (!fsl_mc_is_root_dprc(&mc_dev->dev)) {
fsl_destroy_mc_io(mc_dev->mc_io); fsl_destroy_mc_io(mc_dev->mc_io);
mc_dev->mc_io = NULL; mc_dev->mc_io = NULL;
} else {
fsl_mc_uapi_remove_device_file(mc_bus);
} }
return 0; return 0;
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <linux/fsl/mc.h> #include <linux/fsl/mc.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/ioctl.h>
#include <linux/miscdevice.h>
/* /*
* Data Path Management Complex (DPMNG) General API * Data Path Management Complex (DPMNG) General API
...@@ -542,6 +544,22 @@ struct fsl_mc_resource_pool { ...@@ -542,6 +544,22 @@ struct fsl_mc_resource_pool {
struct fsl_mc_bus *mc_bus; 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 * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC
* @mc_dev: fsl-mc device for the bus device itself. * @mc_dev: fsl-mc device for the bus device itself.
...@@ -551,6 +569,7 @@ struct fsl_mc_resource_pool { ...@@ -551,6 +569,7 @@ struct fsl_mc_resource_pool {
* @irq_resources: Pointer to array of IRQ objects for the IRQ pool * @irq_resources: Pointer to array of IRQ objects for the IRQ pool
* @scan_mutex: Serializes bus scanning * @scan_mutex: Serializes bus scanning
* @dprc_attr: DPRC attributes * @dprc_attr: DPRC attributes
* @uapi_misc: struct that abstracts the interaction with userspace
*/ */
struct fsl_mc_bus { struct fsl_mc_bus {
struct fsl_mc_device mc_dev; struct fsl_mc_device mc_dev;
...@@ -558,6 +577,7 @@ struct fsl_mc_bus { ...@@ -558,6 +577,7 @@ struct fsl_mc_bus {
struct fsl_mc_device_irq *irq_resources; struct fsl_mc_device_irq *irq_resources;
struct mutex scan_mutex; /* serializes bus scanning */ struct mutex scan_mutex; /* serializes bus scanning */
struct dprc_attributes dprc_attr; struct dprc_attributes dprc_attr;
struct fsl_mc_uapi uapi_misc;
}; };
#define to_fsl_mc_bus(_mc_dev) \ #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, ...@@ -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); 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_ */ #endif /* _FSL_MC_PRIVATE_H_ */
This diff is collapsed.
...@@ -16,10 +16,19 @@ ...@@ -16,10 +16,19 @@
* struct fsl_mc_command - Management Complex (MC) command structure * struct fsl_mc_command - Management Complex (MC) command structure
* @header: MC command header * @header: MC command header
* @params: MC command parameters * @params: MC command parameters
*
* Used by FSL_MC_SEND_MC_COMMAND
*/ */
struct fsl_mc_command { struct fsl_mc_command {
__le64 header; __le64 header;
__le64 params[MC_CMD_NUM_OF_PARAMS]; __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_ */ #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