QMI/Gobi management in the kernel: qmi_wwan or GobiNet?

videotape

Introduction

Gobi chipsets are mobile broadband modems developed by Qualcomm, and they are nowadays used by lots of different manufacturers, including Sierra Wireless, ZTE, Huawei and of course Qualcomm themselves.

These devices will usually expose several interfaces in the USB layer, and each interface will then be published to userspace as different ‘ports’ (not the correct name, but I guess easier to understand). Some of the interfaces wil give access to serial ports (e.g. ttys) in the modem, which will let users execute standard connection procedures using the AT protocol and a PPP session. The main problem with using a PPP session over a serial port is that it makes it very difficult, if not totally impossible, to handle datarates above 3G, like LTE. So, in addition to these serial ports, Gobi modems also provide access to a control port (speaking the QMI protocol) and a network interface (think of it as a standard ethernet interface). The connection procedure then can be executed purely through QMI (e.g. providing APN, authentication…) and then userspace can use a much more convenient network interface for the real data communication.

For a long time, the only way to use such QMI+net pair in the Linux kernel was to use the out-of-tree GobiNet drivers provided by Qualcomm or by other manufacturers, along with user-space tools also developed by them (some of them free/open, some of them proprietary). Luckily, a couple of years ago a new qmi_wwan driver was developed by Bjørn Mork and merged into the upstream kernel. This new driver provided access to both the QMI port and the network interface, but was much simpler than the original GobiNet one. The scope was reduced so much, that most of the work that the GobiNet driver was doing in kernel-space, now it had to be done by userspace applications. There are now at least 3 different user-space implementations allowing to use QMI devices through the qmi_wwan port: ofono, uqmi and of course, libqmi.

The question, though, still remains. What should I use? The upstream qmi_wwan kernel driver and user-space utilities like libqmi? Or rather, the out-of-tree GobiNet driver and user-space utilities provided by manufacturers? I’m probably totally biased, but I’ll try to compare the two approaches by pointing out their main differences.

Note: you may want to read the ‘Introduction to libqmi‘ post I wrote a while ago first.

in-tree vs out-of-tree

The qmi_wwan driver is maintained within the upstream Linux kernel (in-tree). This, alone, is a huge advantage compared to GobiNet. Kernel updates may modify the internal interfaces they expose for the different drivers, and being within the same sources as all the other ones, the qmi_wwan driver will also get those updates without further effort. Whenever you install a kernel, you know you’ll have the qmi_wwan driver applicable to that same kernel version ready, so its use is very straightforward. The qmi_wwan driver also contains support for Gobi-based devices from all vendors, so regardless of whether you have a Sierra Wireless modem or a Huawei one (just to name a few), the driver will be able to make your device work as expected in the kernel.

GobiNet is a whole different story. There is not just one GobiNet: each manufacturer keeps its own. If you’re using a Sierra Wireless device you’ll likely want to use the GobiNet driver maintained by them, so that for example, the specific VID/PID pairs are already included in the driver; or going a bit deeper, so that the driver knows which is supposed to be the QMI/WWAN interface number that should be used (different vendors have different USB interface layouts). In addition to the problem of requiring to look for the GobiNet driver most suitable for your device, having the drivers maintained out-of-tree means that they need to provide a single set of sources for a very long set of kernel versions. The sources, therefore, are full of #ifdefs enabling/disabling different code paths depending on the kernel version targeted, so maintaining it gets to be much more complicated than if they just had it in-tree.

Note: Interestingly, we’ve already seen fixes that were first implemented in qmi_wwan ‘ported’ to GobiNet variants.

Complexity

The qmi_wwan driver is simple; it will just get a USB interface and split it into a QMI-capable /dev/cdc-wdm port (through the cdc-wdm driver) and a wwan network interface. As the kernel only provides basic transport to and from the device, it is left to user-space the need to manage the QMI protocol completely, including service client allocations/releases as well as the whole internal CTL service. Note, though, that this is not a problem; user-space tools like libqmi will do this work nicely.

The GobiNet driver is instead very complex. The driver also exposes a control interface (e.g. /dev/qcqmi) and a network interface, but all the work that is done through the internal CTL service is done at kernel-level. So all client allocations/releases for the different services are actually performed internally, not exposed to user-space. Users will just be able to request client allocations via ioctl() calls, and client releases will be automatically managed within the kernel. In general, it is never advisable to have such a complex driver. As complexity of a driver increases, so does the likelyhood of having errors, and crashes in a driver could affect the whole kernel. Quoting Bjørn, the smaller the device driver is, the more robust the system is.

Note: Some Android devices also support QMI-capable chipsets through GobiNet (everything hidden in the kernel and the RIL). In this case, though, you may see that shared memory can also be used to talk to the QMI device, instead of a /dev/qcqmi port.

Device initialization

One of the first tasks that is done while communicating with the Gobi device is to set it up (e.g. decide which link-layer protocol to use in the network interface) and make sure that the modem is ready to talk QMI. In the case of the GobiNet driver, this is all done in kernel-space; while in the case of qmi_wwan everything can be managed in user-space. The libqmi library allows several actions to be performed during device initialization, including the setting of the link-layer protocol to use. There are, for example, models from Sierra Wireless (like the new MC7305) which expose by default one QMI+network interface (#8) configured to use 802.3 (ethernet headers) and another QMI+network interface (#10) configured to use raw IP (no ethernet headers). With libqmi, we can switch the second one to use 802.3, which is what qmi_wwan expects, thus allowing us to use both QMI+net pairs at the same time.

Multiple processes talking QMI

One of the problems of qmi_wwan is that only one process is capable of using the control port at a given time. The GobiNet driver, instead, allows multiple processes to concurrently access the device, as each process would get assigned different QMI clients with different client IDs directly from the kernel, hence, not interfering with each other. In order to handle this issue, libqmi (since version 1.8) was extended to implement a ‘qmi-proxy’ process which would be the only one accessing the QMI port, but which would allow different process to communicate with the device concurrently (by sharing and synchronizing the CTL service among the connected peers).

User-space libraries

The GobiNet driver is designed to be used along with Qualcomm’s C++ GobiAPI library in user-space. On top of this library, other manufacturers (like Sierra Wireless) provide additional libraries to use specific features of their devices. This GobiAPI library will handle itself all the ioctl() calls required to e.g. allocate new clients, and will also provide a high level API to access the different QMI services and operations in the device.

In the case of the qmi_wwan driver, as already said, there are several implementations which will let you talk QMI with the device. libqmi, which I maintain, is one of them. libqmi provides a GLib-based C library, and therefore it exposes objects and interfaces which provide access to the most used QMI services in any kind of device. The CTL service, the internal one which was managed in the kernel by GobiNet, will be managed internally by libqmi and therefore mostly hidden to the users of the library.

Note: It is not (yet) possible to mix GobiAPI with qmi_wwan and e.g. libqmi with GobiNet. Therefore, it is not (yet) possible to use libqmi or qmicli in e.g. an Android device with a QMI-capable chipset.

User-space command line tools

I am no really aware of any general purpose command line tool developed to be used with the GobiNet driver (well, firmware loader applications, but those are not general purpose). The lack of command line tools may be likely due to the fact that, as QMI clients are released automatically by the GobiNet kernel, it is not easy (if at all possible) to leave a QMI client allocated and re-use it over and over by a command line tool which executes an action and exits.

With qmi_wwan, though, as clients are not automatically released, command line tools are much easier to handle. The libqmi project includes a qmicli tool which is able to execute independent QMI requests in each run of the program, even re-using the same QMI client in each of the runs if needed. This is especially important when launching a connection, as the WDS client which executes the “Start Network” command must be kept registered as long as the connection is open, or otherwise the connection will get dropped.

New firmware loading

The process of loading new firmware into a QMI-based device is not straightforward. It involves several interactions at QMI-level, plus a QDL based download of the firware to the device (kind of what gobi_loader does for Gobi 2K). Sadly, there is not yet a way to perform this operation when using qmi_wwan and its user-space tools. If you’re in the need of updating the firmware of the device, the only choice left is to use the GobiNet driver plus the vendor-provided programs.

[Update December 2016] Since libqmi 1.18.0, firmware update operations may be done with libqmi and qmi_wwan using the new qmi-firmware-update tool.

Support

One of the advantages of the GobiNet driver is that every manufacturer will (should) give direct support for their devices if that kernel driver is used. Actually, there are vendors which will only give support for the hardware if their driver is the one in use. I’m therefore assuming that GobiNet may be a good choice for companies if they want to rely in the vendor-provided support, but likely not for standard users which just happen to have a device of this kind in their systems.

But, even if it is not the official support, you can anyway still get in touch with the libqmi mailing list if you’re experiencing issues with your QMI device; or contact companies or individuals (e.g. me!) which provide commercial support for the qmi_wwan driver and libqmi/qmicli integration needs.

Posted on June 11, 2014, in FreeDesktop Planet, GNOME Planet, GNU Planet, Planets and tagged , , , , . Bookmark the permalink. 27 Comments.

  1. Does this driver also work for the Gobi 2000 device? It is quite a hasle to move the Windows driver files to Linux when I do another install and the original driver is also very buggy. Would be great, if this driver could act as a replacement.

  2. Yes, you can use this driver with Gobi2k, but you will still need the gobi_loader to load the firmware to the device…

  3. So if the firmware is the buggy part (which I suspect, because it connections break sometimes in Windows too), then there is no improvement?

  4. Likely no improvement, no. Have you tried to look for newer firmware? Qualcomm moved to Gobi3k and Gobi4k a lot of time ago, so Gobi2k is likely not well supported any more…

  5. Hello,
    I’ve a quectel LTE EC20-E and I’d like to install the GobiNet driver.
    The linux version is 4.1.7+

    when installing the driver and when I do the modprobe GobiNet
    I’ve this error
    modprobe error could not insert ‘GobiNet’ exec format error

    Could you please help me for that point.

    Thank you in advance

  6. Did you compile the GobiNet driver yourself for the same arch and for the same kernel you’re using?

  7. We use MSM8909 of Qualcomm.
    MSM8909 is android device also support QMI-capable chipsets.
    Does MSM8909 android device can use qmi_wwan with libqmi ?
    Thanks.

  8. aleksander

    No idea, never tried.

  9. I inserted the qmi_wwan kernel module, but the device cdc-wdm is not pop-out in /dev?
    dmesg as below:
    [ 212.578854] usbcore: registered new interface driver cdc_wdm
    [ 212.584865] usbcore: registered new interface driver qmi_wwan
    I want to use qmi_wwan with Sierra MC7455 to do a basic 3G/LTE data connection?
    Any comments are welcome.

  10. What kernel version are you using? Support for the MC7455 is only available since 4.5.

  11. My kernel version is 3.16.0-77(upgrade from ubuntu-14.04.1 to ubuntu-lts-utopic)
    So it is not about the firmware version of MC7455? And I also have MC7430 on hand.
    Does it be supported by my Linux kernel? Where I can get the support list or info?
    Thanks your kindly help.

  12. Your kernel is too old :/ the MC7430 also requires 4.5.

    I maintain an Ubuntu 16.04 PPA that supports the kernel 4.4 with backported support for the MC74xx. I don’t have a PPA for 14.04 yet.

  13. Jim Van Vorst

    Can’t MC74xx be ported to kernel 3.x by just adding entries to qcserial.c? For instance:
    {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9071, 0)}, /* Sierra Wireless Modem Device Management */
    {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9071, 2)}, /* Sierra Wireless Modem NMEA */
    {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9071, 3)}, /* Sierra Wireless Modem Modem */

  14. Well, it depends.

    If you add entries to qcserial like those you’ll get TTYs that you may use to do AT+PPP. If you’re fine with the limited speed that the PPP session gives you (no LTE datarates) then it’s ok. If you do want full LTE speeds, you want to use the QMI+WWAN pair, and for that you need not only new entries added in qmi_wwan.c, but also the “raw-ip” support backported from kernel 4.5, as that is required for the EM74xx/MC74xx modules.

  15. Blasonario Cremonese

    Good morning,

    I’m new in Linux world using Fedora 27 on a Thinkpad x220. I have a Sierra Qualcomm Gobi 3000 in my machine… and I tried many times to install the tar.gz files from CodeAurora without any success… Now I’m trying to use qmi_wwan but I don’t manage to get that Gobi3000 work…

    Is there a solution? I’m not an expert user in Linux.

  16. Hi aleksander! Nice article!

    We have already installed the last QMI Linux Drivers (GobiNet) from Sierra Wireless. Now, we just want to test the modem, but since cli doesn’t work with GobiNet, we are wondering how…Is it mandatory to install the SDK (or something) in order to get some working output from the modem?

    We’re using a MC7455 with a 4.4 kernel (no possibility to upgrade), since 4.4 kernel doesn’t support MC7455-libqmi interface, we need GobiNet (and GobiSerial?).

    Thanks!

  17. I assume that if you do want to use GobiNet, you also need the Sierra SDK to test it.
    Although you could always patch your 4.4 kernel to support the “raw-ip” interface that the MC7455 has, or even easier, switch it into MBIM mode and use libmbim/mbimcli.

  18. Thank you for your quick response.

    Yes, we were thinking about the last option before…We’ll rethink it considering your response!

  19. Hi! First of all: Awesome work, thank you!

    I’d like to ask a short question: Is the situation still the same with Gobi 2000, i.e. it requires the gobi_loader in order to load the (proprietary) firmware first?

  20. Yes, that didn’t change

  21. Hi
    we are using Quectel EC25-E module . we ported qmi_wwan driver . In the booting logs its shows [ 212.584865] usbcore: registered new interface driver qmi_wwan , but for that device port (ttyUSB) is not created in /dev folder .
    Is there anything need to do ?

    development platform – yocto
    kernel version -4.9

  22. You also need to add support for the EC25 in the option kernel driver.

  1. Pingback: Links 13/6/2014: Docker Hype, Manjaro 0.8.10 | Techrights

  2. Pingback: WHITE PAPER: Qualcomm Gobi devices in Linux based systems | Lanedo GmbH

  3. Pingback: Dell-branded Sierra Wireless 3G/4G modem not online? | SIGQUIT

  4. Pingback: QMI firmware update with libqmi | SIGQUIT

  5. Pingback: mc7304 – Tips and Thoughts

Leave a comment