^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) .. SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ==============================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Intel(R) Management Engine (ME) Client bus API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) ==============================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) Rationale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) =========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) The MEI character device is useful for dedicated applications to send and receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) data to the many FW appliance found in Intel's ME from the user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) However, for some of the ME functionalities it makes sense to leverage existing software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) stack and expose them through existing kernel subsystems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) In order to plug seamlessly into the kernel device driver model we add kernel virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) bus abstraction on top of the MEI driver. This allows implementing Linux kernel drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) for the various MEI features as a stand alone entities found in their respective subsystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) Existing device drivers can even potentially be re-used by adding an MEI CL bus layer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) the existing code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MEI CL bus API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ==============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) A driver implementation for an MEI Client is very similar to any other existing bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) based device drivers. The driver registers itself as an MEI CL bus driver through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) the ``struct mei_cl_driver`` structure defined in :file:`include/linux/mei_cl_bus.c`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct mei_cl_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct device_driver driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) const struct mei_cl_device_id *id_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int (*probe)(struct mei_cl_device *dev, const struct mei_cl_id *id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int (*remove)(struct mei_cl_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) The mei_cl_device_id structure defined in :file:`include/linux/mod_devicetable.h` allows a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) driver to bind itself against a device name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct mei_cl_device_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) char name[MEI_CL_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) uuid_le uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __u8 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) kernel_ulong_t driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) To actually register a driver on the ME Client bus one must call the :c:func:`mei_cl_add_driver`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) API. This is typically called at module initialization time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) Once the driver is registered and bound to the device, a driver will typically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) try to do some I/O on this bus and this should be done through the :c:func:`mei_cl_send`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) and :c:func:`mei_cl_recv` functions. More detailed information is in :ref:`api` section.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) In order for a driver to be notified about pending traffic or event, the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) should register a callback via :c:func:`mei_cl_devev_register_rx_cb` and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) :c:func:`mei_cldev_register_notify_cb` function respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .. _api:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) API:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .. kernel-doc:: drivers/misc/mei/bus.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) :export: drivers/misc/mei/bus.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) Example
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) =======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) As a theoretical example let's pretend the ME comes with a "contact" NFC IP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) The driver init and exit routines for this device would look like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define CONTACT_DRIVER_NAME "contact"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct mei_cl_device_id contact_mei_cl_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) { CONTACT_DRIVER_NAME, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* required last entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) MODULE_DEVICE_TABLE(mei_cl, contact_mei_cl_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static struct mei_cl_driver contact_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .id_table = contact_mei_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .name = CONTACT_DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .probe = contact_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .remove = contact_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int contact_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) r = mei_cl_driver_register(&contact_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) pr_err(CONTACT_DRIVER_NAME ": driver registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void __exit contact_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mei_cl_driver_unregister(&contact_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) module_init(contact_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) module_exit(contact_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) And the driver's simplified probe routine would look like that:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int contact_probe(struct mei_cl_device *dev, struct mei_cl_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) [...]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mei_cldev_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mei_cldev_register_rx_cb(dev, contact_rx_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) In the probe routine the driver first enable the MEI device and then registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) an rx handler which is as close as it can get to registering a threaded IRQ handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) The handler implementation will typically call :c:func:`mei_cldev_recv` and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) process received data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .. code-block:: C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define MAX_PAYLOAD 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define HDR_SIZE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void conntact_rx_cb(struct mei_cl_device *cldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct contact *c = mei_cldev_get_drvdata(cldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned char payload[MAX_PAYLOAD];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ssize_t payload_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) payload_sz = mei_cldev_recv(cldev, payload, MAX_PAYLOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (reply_size < HDR_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) c->process_rx(payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) MEI Client Bus Drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ======================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .. toctree::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) :maxdepth: 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) hdcp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) nfc