| .. SPDX-License-Identifier: GPL-2.0 | |
| ====================================================== | |
| cdc_mbim - Driver for CDC MBIM Mobile Broadband modems | |
| ====================================================== | |
| The cdc_mbim driver supports USB devices conforming to the "Universal | |
| Serial Bus Communications Class Subclass Specification for Mobile | |
| Broadband Interface Model" [1], which is a further development of | |
| "Universal Serial Bus Communications Class Subclass Specifications for | |
| Network Control Model Devices" [2] optimized for Mobile Broadband | |
| devices, aka "3G/LTE modems". | |
| Command Line Parameters | |
| ======================= | |
| The cdc_mbim driver has no parameters of its own. But the probing | |
| behaviour for NCM 1.0 backwards compatible MBIM functions (an | |
| "NCM/MBIM function" as defined in section 3.2 of [1]) is affected | |
| by a cdc_ncm driver parameter: | |
| prefer_mbim | |
| ----------- | |
| :Type: Boolean | |
| :Valid Range: N/Y (0-1) | |
| :Default Value: Y (MBIM is preferred) | |
| This parameter sets the system policy for NCM/MBIM functions. Such | |
| functions will be handled by either the cdc_ncm driver or the cdc_mbim | |
| driver depending on the prefer_mbim setting. Setting prefer_mbim=N | |
| makes the cdc_mbim driver ignore these functions and lets the cdc_ncm | |
| driver handle them instead. | |
| The parameter is writable, and can be changed at any time. A manual | |
| unbind/bind is required to make the change effective for NCM/MBIM | |
| functions bound to the "wrong" driver | |
| Basic usage | |
| =========== | |
| MBIM functions are inactive when unmanaged. The cdc_mbim driver only | |
| provides a userspace interface to the MBIM control channel, and will | |
| not participate in the management of the function. This implies that a | |
| userspace MBIM management application always is required to enable a | |
| MBIM function. | |
| Such userspace applications includes, but are not limited to: | |
| - mbimcli (included with the libmbim [3] library), and | |
| - ModemManager [4] | |
| Establishing a MBIM IP session requires at least these actions by the | |
| management application: | |
| - open the control channel | |
| - configure network connection settings | |
| - connect to network | |
| - configure IP interface | |
| Management application development | |
| ---------------------------------- | |
| The driver <-> userspace interfaces are described below. The MBIM | |
| control channel protocol is described in [1]. | |
| MBIM control channel userspace ABI | |
| ================================== | |
| /dev/cdc-wdmX character device | |
| ------------------------------ | |
| The driver creates a two-way pipe to the MBIM function control channel | |
| using the cdc-wdm driver as a subdriver. The userspace end of the | |
| control channel pipe is a /dev/cdc-wdmX character device. | |
| The cdc_mbim driver does not process or police messages on the control | |
| channel. The channel is fully delegated to the userspace management | |
| application. It is therefore up to this application to ensure that it | |
| complies with all the control channel requirements in [1]. | |
| The cdc-wdmX device is created as a child of the MBIM control | |
| interface USB device. The character device associated with a specific | |
| MBIM function can be looked up using sysfs. For example:: | |
| bjorn@nemi:~$ ls /sys/bus/usb/drivers/cdc_mbim/2-4:2.12/usbmisc | |
| cdc-wdm0 | |
| bjorn@nemi:~$ grep . /sys/bus/usb/drivers/cdc_mbim/2-4:2.12/usbmisc/cdc-wdm0/dev | |
| 180:0 | |
| USB configuration descriptors | |
| ----------------------------- | |
| The wMaxControlMessage field of the CDC MBIM functional descriptor | |
| limits the maximum control message size. The management application is | |
| responsible for negotiating a control message size complying with the | |
| requirements in section 9.3.1 of [1], taking this descriptor field | |
| into consideration. | |
| The userspace application can access the CDC MBIM functional | |
| descriptor of a MBIM function using either of the two USB | |
| configuration descriptor kernel interfaces described in [6] or [7]. | |
| See also the ioctl documentation below. | |
| Fragmentation | |
| ------------- | |
| The userspace application is responsible for all control message | |
| fragmentation and defragmentaion, as described in section 9.5 of [1]. | |
| /dev/cdc-wdmX write() | |
| --------------------- | |
| The MBIM control messages from the management application *must not* | |
| exceed the negotiated control message size. | |
| /dev/cdc-wdmX read() | |
| -------------------- | |
| The management application *must* accept control messages of up the | |
| negotiated control message size. | |
| /dev/cdc-wdmX ioctl() | |
| --------------------- | |
| IOCTL_WDM_MAX_COMMAND: Get Maximum Command Size | |
| This ioctl returns the wMaxControlMessage field of the CDC MBIM | |
| functional descriptor for MBIM devices. This is intended as a | |
| convenience, eliminating the need to parse the USB descriptors from | |
| userspace. | |
| :: | |
| #include <stdio.h> | |
| #include <fcntl.h> | |
| #include <sys/ioctl.h> | |
| #include <linux/types.h> | |
| #include <linux/usb/cdc-wdm.h> | |
| int main() | |
| { | |
| __u16 max; | |
| int fd = open("/dev/cdc-wdm0", O_RDWR); | |
| if (!ioctl(fd, IOCTL_WDM_MAX_COMMAND, &max)) | |
| printf("wMaxControlMessage is %d\n", max); | |
| } | |
| Custom device services | |
| ---------------------- | |
| The MBIM specification allows vendors to freely define additional | |
| services. This is fully supported by the cdc_mbim driver. | |
| Support for new MBIM services, including vendor specified services, is | |
| implemented entirely in userspace, like the rest of the MBIM control | |
| protocol | |
| New services should be registered in the MBIM Registry [5]. | |
| MBIM data channel userspace ABI | |
| =============================== | |
| wwanY network device | |
| -------------------- | |
| The cdc_mbim driver represents the MBIM data channel as a single | |
| network device of the "wwan" type. This network device is initially | |
| mapped to MBIM IP session 0. | |
| Multiplexed IP sessions (IPS) | |
| ----------------------------- | |
| MBIM allows multiplexing up to 256 IP sessions over a single USB data | |
| channel. The cdc_mbim driver models such IP sessions as 802.1q VLAN | |
| subdevices of the master wwanY device, mapping MBIM IP session Z to | |
| VLAN ID Z for all values of Z greater than 0. | |
| The device maximum Z is given in the MBIM_DEVICE_CAPS_INFO structure | |
| described in section 10.5.1 of [1]. | |
| The userspace management application is responsible for adding new | |
| VLAN links prior to establishing MBIM IP sessions where the SessionId | |
| is greater than 0. These links can be added by using the normal VLAN | |
| kernel interfaces, either ioctl or netlink. | |
| For example, adding a link for a MBIM IP session with SessionId 3:: | |
| ip link add link wwan0 name wwan0.3 type vlan id 3 | |
| The driver will automatically map the "wwan0.3" network device to MBIM | |
| IP session 3. | |
| Device Service Streams (DSS) | |
| ---------------------------- | |
| MBIM also allows up to 256 non-IP data streams to be multiplexed over | |
| the same shared USB data channel. The cdc_mbim driver models these | |
| sessions as another set of 802.1q VLAN subdevices of the master wwanY | |
| device, mapping MBIM DSS session A to VLAN ID (256 + A) for all values | |
| of A. | |
| The device maximum A is given in the MBIM_DEVICE_SERVICES_INFO | |
| structure described in section 10.5.29 of [1]. | |
| The DSS VLAN subdevices are used as a practical interface between the | |
| shared MBIM data channel and a MBIM DSS aware userspace application. | |
| It is not intended to be presented as-is to an end user. The | |
| assumption is that a userspace application initiating a DSS session | |
| also takes care of the necessary framing of the DSS data, presenting | |
| the stream to the end user in an appropriate way for the stream type. | |
| The network device ABI requires a dummy ethernet header for every DSS | |
| data frame being transported. The contents of this header is | |
| arbitrary, with the following exceptions: | |
| - TX frames using an IP protocol (0x0800 or 0x86dd) will be dropped | |
| - RX frames will have the protocol field set to ETH_P_802_3 (but will | |
| not be properly formatted 802.3 frames) | |
| - RX frames will have the destination address set to the hardware | |
| address of the master device | |
| The DSS supporting userspace management application is responsible for | |
| adding the dummy ethernet header on TX and stripping it on RX. | |
| This is a simple example using tools commonly available, exporting | |
| DssSessionId 5 as a pty character device pointed to by a /dev/nmea | |
| symlink:: | |
| ip link add link wwan0 name wwan0.dss5 type vlan id 261 | |
| ip link set dev wwan0.dss5 up | |
| socat INTERFACE:wwan0.dss5,type=2 PTY:,echo=0,link=/dev/nmea | |
| This is only an example, most suitable for testing out a DSS | |
| service. Userspace applications supporting specific MBIM DSS services | |
| are expected to use the tools and programming interfaces required by | |
| that service. | |
| Note that adding VLAN links for DSS sessions is entirely optional. A | |
| management application may instead choose to bind a packet socket | |
| directly to the master network device, using the received VLAN tags to | |
| map frames to the correct DSS session and adding 18 byte VLAN ethernet | |
| headers with the appropriate tag on TX. In this case using a socket | |
| filter is recommended, matching only the DSS VLAN subset. This avoid | |
| unnecessary copying of unrelated IP session data to userspace. For | |
| example:: | |
| static struct sock_filter dssfilter[] = { | |
| /* use special negative offsets to get VLAN tag */ | |
| BPF_STMT(BPF_LD|BPF_B|BPF_ABS, SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT), | |
| BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 1, 0, 6), /* true */ | |
| /* verify DSS VLAN range */ | |
| BPF_STMT(BPF_LD|BPF_H|BPF_ABS, SKF_AD_OFF + SKF_AD_VLAN_TAG), | |
| BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 0, 4), /* 256 is first DSS VLAN */ | |
| BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 512, 3, 0), /* 511 is last DSS VLAN */ | |
| /* verify ethertype */ | |
| BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 2 * ETH_ALEN), | |
| BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, ETH_P_802_3, 0, 1), | |
| BPF_STMT(BPF_RET|BPF_K, (u_int)-1), /* accept */ | |
| BPF_STMT(BPF_RET|BPF_K, 0), /* ignore */ | |
| }; | |
| Tagged IP session 0 VLAN | |
| ------------------------ | |
| As described above, MBIM IP session 0 is treated as special by the | |
| driver. It is initially mapped to untagged frames on the wwanY | |
| network device. | |
| This mapping implies a few restrictions on multiplexed IPS and DSS | |
| sessions, which may not always be practical: | |
| - no IPS or DSS session can use a frame size greater than the MTU on | |
| IP session 0 | |
| - no IPS or DSS session can be in the up state unless the network | |
| device representing IP session 0 also is up | |
| These problems can be avoided by optionally making the driver map IP | |
| session 0 to a VLAN subdevice, similar to all other IP sessions. This | |
| behaviour is triggered by adding a VLAN link for the magic VLAN ID | |
| 4094. The driver will then immediately start mapping MBIM IP session | |
| 0 to this VLAN, and will drop untagged frames on the master wwanY | |
| device. | |
| Tip: It might be less confusing to the end user to name this VLAN | |
| subdevice after the MBIM SessionID instead of the VLAN ID. For | |
| example:: | |
| ip link add link wwan0 name wwan0.0 type vlan id 4094 | |
| VLAN mapping | |
| ------------ | |
| Summarizing the cdc_mbim driver mapping described above, we have this | |
| relationship between VLAN tags on the wwanY network device and MBIM | |
| sessions on the shared USB data channel:: | |
| VLAN ID MBIM type MBIM SessionID Notes | |
| --------------------------------------------------------- | |
| untagged IPS 0 a) | |
| 1 - 255 IPS 1 - 255 <VLANID> | |
| 256 - 511 DSS 0 - 255 <VLANID - 256> | |
| 512 - 4093 b) | |
| 4094 IPS 0 c) | |
| a) if no VLAN ID 4094 link exists, else dropped | |
| b) unsupported VLAN range, unconditionally dropped | |
| c) if a VLAN ID 4094 link exists, else dropped | |
| References | |
| ========== | |
| 1) USB Implementers Forum, Inc. - "Universal Serial Bus | |
| Communications Class Subclass Specification for Mobile Broadband | |
| Interface Model", Revision 1.0 (Errata 1), May 1, 2013 | |
| - http://www.usb.org/developers/docs/devclass_docs/ | |
| 2) USB Implementers Forum, Inc. - "Universal Serial Bus | |
| Communications Class Subclass Specifications for Network Control | |
| Model Devices", Revision 1.0 (Errata 1), November 24, 2010 | |
| - http://www.usb.org/developers/docs/devclass_docs/ | |
| 3) libmbim - "a glib-based library for talking to WWAN modems and | |
| devices which speak the Mobile Interface Broadband Model (MBIM) | |
| protocol" | |
| - http://www.freedesktop.org/wiki/Software/libmbim/ | |
| 4) ModemManager - "a DBus-activated daemon which controls mobile | |
| broadband (2G/3G/4G) devices and connections" | |
| - http://www.freedesktop.org/wiki/Software/ModemManager/ | |
| 5) "MBIM (Mobile Broadband Interface Model) Registry" | |
| - http://compliance.usb.org/mbim/ | |
| 6) "/sys/kernel/debug/usb/devices output format" | |
| - Documentation/driver-api/usb/usb.rst | |
| 7) "/sys/bus/usb/devices/.../descriptors" | |
| - Documentation/ABI/stable/sysfs-bus-usb |