0001 .. SPDX-License-Identifier: GPL-2.0
0002
0003 ==============================================
0004 Intel(R) Management Engine (ME) Client bus API
0005 ==============================================
0006
0007
0008 Rationale
0009 =========
0010
0011 The MEI character device is useful for dedicated applications to send and receive
0012 data to the many FW appliance found in Intel's ME from the user space.
0013 However, for some of the ME functionalities it makes sense to leverage existing software
0014 stack and expose them through existing kernel subsystems.
0015
0016 In order to plug seamlessly into the kernel device driver model we add kernel virtual
0017 bus abstraction on top of the MEI driver. This allows implementing Linux kernel drivers
0018 for the various MEI features as a stand alone entities found in their respective subsystem.
0019 Existing device drivers can even potentially be re-used by adding an MEI CL bus layer to
0020 the existing code.
0021
0022
0023 MEI CL bus API
0024 ==============
0025
0026 A driver implementation for an MEI Client is very similar to any other existing bus
0027 based device drivers. The driver registers itself as an MEI CL bus driver through
0028 the ``struct mei_cl_driver`` structure defined in :file:`include/linux/mei_cl_bus.c`
0029
0030 .. code-block:: C
0031
0032 struct mei_cl_driver {
0033 struct device_driver driver;
0034 const char *name;
0035
0036 const struct mei_cl_device_id *id_table;
0037
0038 int (*probe)(struct mei_cl_device *dev, const struct mei_cl_id *id);
0039 int (*remove)(struct mei_cl_device *dev);
0040 };
0041
0042
0043
0044 The mei_cl_device_id structure defined in :file:`include/linux/mod_devicetable.h` allows a
0045 driver to bind itself against a device name.
0046
0047 .. code-block:: C
0048
0049 struct mei_cl_device_id {
0050 char name[MEI_CL_NAME_SIZE];
0051 uuid_le uuid;
0052 __u8 version;
0053 kernel_ulong_t driver_info;
0054 };
0055
0056 To actually register a driver on the ME Client bus one must call the :c:func:`mei_cl_add_driver`
0057 API. This is typically called at module initialization time.
0058
0059 Once the driver is registered and bound to the device, a driver will typically
0060 try to do some I/O on this bus and this should be done through the :c:func:`mei_cl_send`
0061 and :c:func:`mei_cl_recv` functions. More detailed information is in :ref:`api` section.
0062
0063 In order for a driver to be notified about pending traffic or event, the driver
0064 should register a callback via :c:func:`mei_cl_devev_register_rx_cb` and
0065 :c:func:`mei_cldev_register_notify_cb` function respectively.
0066
0067 .. _api:
0068
0069 API:
0070 ----
0071 .. kernel-doc:: drivers/misc/mei/bus.c
0072 :export: drivers/misc/mei/bus.c
0073
0074
0075
0076 Example
0077 =======
0078
0079 As a theoretical example let's pretend the ME comes with a "contact" NFC IP.
0080 The driver init and exit routines for this device would look like:
0081
0082 .. code-block:: C
0083
0084 #define CONTACT_DRIVER_NAME "contact"
0085
0086 static struct mei_cl_device_id contact_mei_cl_tbl[] = {
0087 { CONTACT_DRIVER_NAME, },
0088
0089 /* required last entry */
0090 { }
0091 };
0092 MODULE_DEVICE_TABLE(mei_cl, contact_mei_cl_tbl);
0093
0094 static struct mei_cl_driver contact_driver = {
0095 .id_table = contact_mei_tbl,
0096 .name = CONTACT_DRIVER_NAME,
0097
0098 .probe = contact_probe,
0099 .remove = contact_remove,
0100 };
0101
0102 static int contact_init(void)
0103 {
0104 int r;
0105
0106 r = mei_cl_driver_register(&contact_driver);
0107 if (r) {
0108 pr_err(CONTACT_DRIVER_NAME ": driver registration failed\n");
0109 return r;
0110 }
0111
0112 return 0;
0113 }
0114
0115 static void __exit contact_exit(void)
0116 {
0117 mei_cl_driver_unregister(&contact_driver);
0118 }
0119
0120 module_init(contact_init);
0121 module_exit(contact_exit);
0122
0123 And the driver's simplified probe routine would look like that:
0124
0125 .. code-block:: C
0126
0127 int contact_probe(struct mei_cl_device *dev, struct mei_cl_device_id *id)
0128 {
0129 [...]
0130 mei_cldev_enable(dev);
0131
0132 mei_cldev_register_rx_cb(dev, contact_rx_cb);
0133
0134 return 0;
0135 }
0136
0137 In the probe routine the driver first enable the MEI device and then registers
0138 an rx handler which is as close as it can get to registering a threaded IRQ handler.
0139 The handler implementation will typically call :c:func:`mei_cldev_recv` and then
0140 process received data.
0141
0142 .. code-block:: C
0143
0144 #define MAX_PAYLOAD 128
0145 #define HDR_SIZE 4
0146 static void conntact_rx_cb(struct mei_cl_device *cldev)
0147 {
0148 struct contact *c = mei_cldev_get_drvdata(cldev);
0149 unsigned char payload[MAX_PAYLOAD];
0150 ssize_t payload_sz;
0151
0152 payload_sz = mei_cldev_recv(cldev, payload, MAX_PAYLOAD)
0153 if (reply_size < HDR_SIZE) {
0154 return;
0155 }
0156
0157 c->process_rx(payload);
0158
0159 }
0160
0161 MEI Client Bus Drivers
0162 ======================
0163
0164 .. toctree::
0165 :maxdepth: 2
0166
0167 hdcp
0168 nfc