Talk:QMI
libqmi
libqmi can be used on downstream kernels with qcom_rmtfs running with env LD_PRELOAD=/usr/lib/preload/libsmdpkt_wrapper.so qmicli -d /dev/smdcntl0 --get-service-version-info
. You can replace the last argument with another different one (for available commands consult --help
).
On mainline this works: qmicli -d /dev/rpmsg0 --get-service-version-info
.
Instead of using /dev/smdcntl0
or /dev/rpmsg0
you can use the /dev/modem
symlink which should exist in both cases.
Without libsmdpkt_wrapper, qmicli hangs on downstream on writing/reading to the smdpkt device, read the comment in libsmdpkt_wrapper/wrapper.c
for more information.
Make sure to use libqmi from git master until the next version is released (as of 2019-10-21).
Example output:
[/dev/smdcntl0] Supported versions: ctl (1.5) wds (1.36) dms (1.14) nas (1.25) qos (1.3) wms (1.10) auth (1.3) at (1.2) voice (2.1) cat2 (2.24) uim (1.36) pbm (1.4) test (1.0) loc (2.0) sar (1.0) ts (1.0) tmd (1.0) wda (1.11) csvt (1.1) coex (1.0) pdc (1.0) rfrpe (1.0) dsd (1.0) ssctl (1.0) unknown [0x30] (1.0)
QMI
QMI is a protocol using fixed structured data.
There are services (e.g. DMS = Device Management Service with ID 0x02). Each service has multiple messages and/or indications which have IDs that identify them (e.g. "Get Manufacturer" with ID "0x21" in "DMS" service).
Messages are requested by the client (e.g. qmicli) and will have a response. Indications are 'unsolicited' messages from the other side, e.g. to notify the client that something has happened.
Each message has a defined input structure and an output structure where some parts can be optional. These are called TLV (Type-length-value). The structures can contain integers, arrays, structs, sequences etc (TODO Difference between sequence and struct?). Each top level parameter has their own ID as well, it seems that 0x00-0x0F are required attributes and optional starting with ID 0x10.
In libqmi, enums (integers with fixed meanings) have a so-called "public-format" attached which is basically a reference to the enum.
There are also other implementations of qmi other than libqmi, such as uqmi from OpenWrt, ofono has its own implementation, qrtr user space also has an implementation(?)
Links
- libqmi: List of QMI services
- libqmi: Service messages of the DMS service
- libqmi: Enums used by the DMS service
smd, smdpkt, rmtfs, rpmsg, rpmsgexport, qrtr, msmipc?
Acronyms:
- smd: Shared Memory Device
- smdpkt: Qualcomm Shared Memory Packet Driver
- qrtr: Qualcomm IPC router
- remoteproc: Remote Processor
- rpmsg: Remote Processor Messaging
- rmtfs: Remote File System
Socket types:
- msmipc = AF_MSM_IPC
- qrtr = AF_QIPCRTR
smd
A fifo based communication channel for sending data between the various subsystems in Qualcomm platforms. The low-level form of mostly everything else here???
smd channels
Communication channels over smd, the names are strings and these are hardcoded in e.g. modem firmware? e.g. DATA5_CNTL
smd edges
Represents a remote subsystem or a remote processor of some sort - see https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/soc/qcom/qcom%2Csmd.txt
smdpkt
Kernel driver on downstream kernels which creates /dev nodes for different SMD Channels and handles the communication.
rpmsg
Framework in the Linux kernel that provides a messaging bus that allows kernel drivers to communicate with remote processors available on the system - see https://github.com/torvalds/linux/blob/master/Documentation/staging/rpmsg.rst
rpmsgexport
User space tool for telling the kernel to create a /dev node for the specified SMD Channel via the RPMSG_CREATE_EPT_IOCTL call.
https://github.com/andersson/rpmsgexport
rmtfs
User space daemon for giving to modem (and other remote processors?) access to persistent storage
https://github.com/andersson/rmtfs
libqipcrtr4msmipc
Library for translating QIPCRTR (QRTR) sockets to MSM_IPC sockets, so software using AF_QIPCRTR sockets can run on downstream kernels (which only support AF_MSM_IPC).
https://github.com/scintill/libqipcrtr4msmipc
libsmdpkt_wrapper
Wrapper to work around a kernel bug on smdpkt devices which makes operations hang. Used in applications that access smd devices.
https://github.com/scintill/libsmdpkt_wrapper
qrtr
Protocol used to communicate with service providing remote processors.
Consists of kernel components and user space component. Kernel components: ? User space components: ?
https://github.com/andersson/qrtr
msmipc
The equivalent of qrtr but on downstream kernels, but it includes a service discovery mechanism that's done by qrtr in user space.
sysmon
sysmon
is a mechanism in Qualcomm devices to notify remote processors when other remote processors goes away. This is required for such things as letting the modem firmware know that the audio path is gone in the case that the adsp abruptly disappears - i.e. when the adsp hits a watchdog bite and doesn't have a chance to close the modem<->audio
communication channels.
Example on mainline kernel
- rmtfs gets started by openrc
- rpmsgexport gets called by the modem-qcom-msm-mainline-common udev rule and tells /dev/rpmsg_ctrl0 (or whichever rpmsg control-node is for the modem) to create /dev/modem with the DATA5_CNTL channel
- ofono uses that dev node to communicate with the modem over QMI.
Note: the SMD Edge IDs are defined in the device tree with the qcom,smd-edge attribute.
Note: some device tree nodes also have qcom,smd-channels defined, when they use channels directly, e.g. wcnss (wifi/bt/fm)
Example on downstream kernel
- Kernel creates /dev/smdcntl0 on boot (which is hardcoded in the kernel to be: SMD Edge "SMD_APPS_MODEM" (0); SMD Channel "DATA5_CNTL", see arch/arm/mach-msm/smd_pkt.c for a list (smd_pkt_dev_name, smd_ch_name, smd_ch_edge is matched index-based))
- /dev/smdcntl0 gets symlinked to /dev/modem by the modem-qcom-msm-downstream-common udev rule
- rmtfs gets started (with libqipcrtr4msmipc LD_PRELOADed) by openrc
- ofono (with libsmdpkt_wrapper LD_PRELOADed) gets started and uses that dev node to communicate with the modem over QMI.
Links
- https://lore.kernel.org/patchwork/cover/817421/#1013135
- https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/Documentation/arm/msm/msm_ipc_router.txt
- https://discuss.96boards.org/t/controlling-the-gps-chip-qualcomm-wgr7640/1670/3
- https://gitlab.com/postmarketOS/pmaports/-/merge_requests/907
- https://osmocom.org/projects/quectel-modems/wiki/Qualcomm_Linux_SMD