QMI firmware update with libqmi


One of the key reasons to keep using the out-of-tree Sierra GobiNet drivers and GobiAPI was that upgrading firmware in the WWAN modules was supported out of the box, while we didn’t have any way to do so with qmi_wwan in the upstream kernel and libqmi.

I’m glad to say that this is no longer the case; as we already have a new working solution in the aleksander/qmi-firmware-update branch in the upstream libqmi git repository, which will be released in the next major libqmi release. Check it out!

The new tool is named, no surprise, qmi-firmware-update; and allows upgrading firmware for Qualcomm based Sierra Wireless devices (e.g. MC7700, MC7710, MC7304, MC7354, MC7330, MC7444…). I’ve personally not tested any other device or manufacturer yet, so won’t say we support others just yet.

This work wouldn’t have been possible without Bjørn Mork‘s swi-update program, which already contained most of the bits and pieces for the QDL download session management, we all owe him quite some virtual beers. And thanks also to Zodiac Inflight Innovations for sponsoring this work!

Sierra Wireless SWI9200 series (e.g. MC7700, MC7710…)

The upgrade process for Sierra Wireless SWI9200 devices (already flagged as EOL, but still used in thousands of places) is very straightforward:

  • Device is rebooted in boot & hold mode (what we call QDL download mode) by running AT!BOOTHOLD in the primary AT port.
  • A QDL download session is run to upload the firmware image, which is usually just one single file which contains the base system plus the carrier-specific settings.
  • Once the QDL download session is finished, the device is rebooted in normal mode.

The new qmi-firmware-update tool supports all these steps just by running one single command as follows:

$ sudo qmi-firmware-update \
     --update \
     -d 1199:68a2 \

Sierra Wireless SWI9x15 series (e.g. MC7304, MC7354…)

The upgrade process for Sierra Wireless SWI9x15 devices is a bit more complex, as these devices support and require the QMI DMS Set/Get Firmware Preference commands to initiate the download. The steps would be:

  • Decide which firmware version, config version and carrier strings to use. The firmware version is the version of the system itself, the config version is the version of the carrier-specific image, and the carrier string is the identifier of the network operator.
  • Using QMI DMS Set Firmware Preference, the new desired firmware version, config version and carrier are specified. When the firmware and config version don’t match the ones currently running in the device, it will reboot itself in boot & hold mode and wait for the new downloads.
  • A QDL download session is run to upload each firmware image available. For these kind of devices, two options are given to the users: a pair of .cwe and .nvu images containing the system and carrier images separately, or a consolidated .spk image with both. It’s advised to always use the consolidated .spk image to avoid mismatches between system and config.
  • Once the QDL download sessions are finished, the device is rebooted in normal mode.

Again, the new qmi-firmware-update tool supports all these steps just by running one single command as follows:

$ sudo qmi-firmware-update \
     --update \
     -d 1199:68c0 \

This previous commands will analyze each firmware image provided and will extract the firmware version, config version and carrier so that the user doesn’t need to explicitly provide them (although there are also options to do that if needed).

Sierra Wireless SWI9x30 series (e.g. MC7455, MC7430..)

The upgrade process for Sierra Wireless SWI9x30 devices is equivalent to the one used for SWI9x15. One of the main differences, though, is that SWI9x15 devices seem to only allow one pair of modem+pri images (system+config) installed in the system, while the SWI9x30 allows the user to download multiple images and then select them using the QMI DMS List/Select/Delete Stored Image commands.

The SWI9x30 modules may also run in MBIM mode instead of QMI. In this case, the firmware upgrade process is exactly the same as with the SWI9x15 series, but using QMI over MBIM. The qmi-firmware-update program supports this operation with the –device-open-mbim command line argument:

$ sudo qmi-firmware-update \
    --update \
    -d 1199:9071 \
    --device-open-mbim \
    SWI9X30C_02.20.03.00.cwe \

Notes on device selection

There are multiple ways to select which device is going to be upgraded:

  • vid:pid: If there is a single device to upgrade in the system, it usually is easiest to use the -d option to select it by vid:pid (or even just by vid). This is the way used by default in all previous examples, and really the easiest one if you just have one modem available.
  • bus:dev: If there are multiple devices to upgrade in the same system, a more restrictive device selection can be achieved with the -s option specifying the USB device bus number plus device number, which is unique per physical device.
  • /dev/cdc-wdm: A firmware upgrade operation may also be started by using the –cdc-wdm option (shorter, -w) and specifying a /dev/cdc-wdm device exposed by the module.
  • /dev/ttyUSB: If the device is already in boot & hold mode, a QDL download session may be performed directly on the tty specified by the –qdl-serial (shorter, -q) option.

Notes on firmware images

Sierra Wireless provides firmware images for all their SWI9200, SWI9x15 and SWI9x30 modules in their website. Sometimes they do specify “for Linux” (and you would get .cwe, .nvu or .spk images) and sometimes they just provide .exe Windows OS binaries. For the latter, you can just decompress the .exe file e.g. using 7-Zip and get the firmware images that you would use with qmi-firmware-update, e.g.:

 $ 7z x SWI9200M_3.5-Release13-SWI9200X_03.05.29.03.exe
 $ ls *.{cwe,nvu,spk} 2>/dev/null


qmi-firmware-update now allows upgrading firmware in Sierra Wireless modems using qmi_wwan and libqmi.


Posted on December 9, 2016, in FreeDesktop Planet, GNOME Planet, Planets and tagged , , , , , , , . Bookmark the permalink. 38 Comments.

  1. Could this perhaps be integrated into fwupd?

  2. I’ll take a look at that, yes.

  3. Awesome! I compiled this and ran it on ubuntu, trying to recover my mc7455 out of bootandhold. I tried flashing the firmware, but get the following error:

    error: couldn’t allocate DMS QMI client: CID allocation failed in the CTL client: Transaction timed out

    I am able to “Reset device into QDL download mode.”. Really though, I just want the device to work again. It seems to not respond since it’s stuck in bootandhold from a failed flash using the windows tools by sierra.

  4. Ahh, I see I have to compile with mbim and then use it. Ok, I retried with this, and it’s been sitting there unresponsive for 10 mins. No idea what to do now. Again, in reality I just want to get this card out of bootandhold!

    sudo qmi-firmware-update \
    –update \
    -s 2:14 \
    –device-open-mbim \
    SWI9X30C_02.20.03.00_Generic_002.017_000/SWI9X30C_02.20.03.00.cwe \

  5. Last comment, I’m sorry. Here’s the pastebin of what I’m seeing.


  6. Now I really feel like I’m spamming. Suffice to say, running these commands worked:

    sudo qmi-firmware-update -v -b -s 2:27

    wait for reboot

    sudo qmi-firmware-update -v –update-qdl -s 2:28 –firmware-version –config-version 002.017_000 –carrier Generic SWI9X30C_02.20.03.00.cwe SWI9X30C_02.20.03.00_Generic_002.017_000.nvu

    Thanks for an awesome tool!

  7. Yes, when in boot and hold mode, you just need to run with –update-qdl and ignore all other options like –carrier, –firmware-version or –config-version. See –help and –help-examples.

    Glad it worked for you! 😉

  8. Rachel ShuchunChiu

    I have tested both Sierra 7455 and 7304, both show fininshed successfully
    but how can I verify the firmware image version is the one I updated?

  9. Thanks for testing! You can try to list the available images with –dms-list-stored-images or just check the software revision reported at –dms-get-revision.

  10. Short update; once the program finishes, it will print the information of the firmware version before and after the update, so that the user can see how it was updated.

  11. how to compile libqmi latest version in openwrt, i am getting some dependencies error “configure: error: Cannot build `qmi-firmware-update’ if GUDev >= GUDEV_REQUIRED is not available. Install it, or otherwise configure using –disable-firmware-update to disable building `qmi-firmware-update’. ” please send me Makefile for openwrt

  12. Not yet possible, I still need to update the build system to allow building the updater program without “udev”. Under OpenWRT there’s no udev by default, and therefore even the update operation will be a bit
    different; less automatic, more manual steps.

  13. trying to update my EM7455/Lenovo, fails with CRC checks on any update:

    kom@junocat qmi-firmware-update % sudo ./qmi-firmware-update -w /dev/cdc-wdm1 –update ~/downloads/SWI9X30C_02.23.00.00.cwe ~/downloads/SWI9X30C_02.23.00.00_Generic_002.018_000.nvu
    loading device information before the update…
    setting firmware preference:
    firmware version: ‘’
    config version: ‘002.018_000’
    carrier: ‘GENERIC’
    rebooting in download mode…
    download mode detected
    downloading cwe image: SWI9X30C_02.23.00.00.cwe (64,4 MB)…
    (—*–) 27,9%error: error downloading image: couldn’t write in session: error unframing message: crc check failed: 0x183f != 0xe3d3

  14. Is this with git master? I think that was already fixed.

  15. Oh, this is from aleksander/qmi-firmware-update branch – let me retry it with master!

  16. rebuilt git master – same thing:

    kom@junocat qmi-firmware-update % sudo ./qmi-firmware-update -d 1199 –update ~/downloads/SWI9X30C_02.23.00.00.cwe ~/downloads/SWI9X30C_02.23.00.00_Generic_002.018_000.nvu
    loading device information before the update…
    setting firmware preference:
    firmware version: ‘’
    config version: ‘002.018_000’
    carrier: ‘GENERIC’
    rebooting in download mode…
    download mode detected
    downloading cwe image: SWI9X30C_02.23.00.00.cwe (64,4 MB)…
    (—–*) 24,6%error: error downloading image: couldn’t write in session: Invalid CRC

  17. also happens with different firmwares:

    kom@junocat libqmi % sudo qmi-firmware-update -d 1199 –update ~/downloads/SWI9X30C_02.20.03.22.cwe ~/downloads/SWI9X30C_02.20.03.22_Verizon_002.026_000.nvu
    loading device information before the update…
    setting firmware preference:
    firmware version: ‘’
    config version: ‘002.026_000’
    carrier: ‘VERIZON’
    rebooting in download mode…
    download mode detected
    downloading cwe image: SWI9X30C_02.20.03.22.cwe (64,4 MB)…
    (—*–) 27,9%error: error downloading image: couldn’t write in session: error unframing message: crc check failed: 0x183f != 0xe3d3

  18. Weird, could you run with “-L /tmp/qfu.log” and email me the file generated?

  19. For reference, this issue was related to having ModemManager running at the same time the updater program was running. I’ll update it to avoid this situation again.

  20. Zainulabidin Omar

    I’ve successfull compiling “libqmi 1.18.0” on Ubuntu 12 and qmi-firmware-update was geneerated. My question is via “man qmi-firmware-update” it shown about lot of options such as “s” and “d” unlike via “qmi-firmware-update”. So weird for me why inside “man qmi-firmware-update” it does stated “lt-qmi-firmware-update” whilst this file doesn’t exists.

  21. Make sure you have compiled libqmi WITH udev support, otherwise you won’t have the options like “-s” or “-d”.

    Also, the “lt-qmi-firware-update” is really just “qmi-firmware-update”; the “lt-” prefix is the name of the libtool generated program; I may need to fix how the manpage is generated.

  22. Zainulabidin Omar

    hi thanks a lot whene I manage to configure libqmi 1.18 on ubuntu 12 but couldn’t successfull on ubuntu16 LT where its looking forr gudev >= 147 whilst system gudev already 229. Any thought from your end.

  23. You’re probably missing the gudev-devel package (or some name like that), which is the one that contains the headers.

    For Ubuntu 14.04 and 16.04 I maintain PPAs that include libqmi 1.18.0 already, see e.g.: https://launchpad.net/~aleksander-m/+archive/ubuntu/modemmanager-xenial

  24. Zainulabidin Omar

    Thanks a lot for your valuable inputs. Anyway I manage to configure all other dependency modules for libqmi 1.18.0 on ubuntu 16 lt except for udev 175. I was able to configure successfully. But when initiate “make” then below errors come out:
    Makefile:1850:recipe for target ‘extras/mtd_probe/extras_mtd_probe_mtd_probe-mtd_probe.o’ failed
    make[2]: *** [extrad/mtd_probe/extras_mtd_probe-mtd_probe.o] Error 1
    Makefile:2297: recipe for target ‘all-recursive’ failed
    make[1]: *** [all-recurcive] Error 1
    Makefile:1108: recipe for target ‘all’ failed
    make: *** [all] Error 2

    Any thought from your end how to resolve these errors ?.

  25. Are you trying to compile gudev yourself? why? don’t.

  26. Zainulabidin Omar

    Because when I try to configure libqmi 1.18.0 , it asking for udev module and minimun release is 147. Actualy I’m new to ubuntu. Unlike for ubuntu 13 … I manage to configure libqmi 1.18.0 by running all module dependencies such as udev-175 without errors. Actually weird for me …

  27. Zainulabidin Omar


    Latest info where I manage to configure libqmi 1.18.0 by install gudev-1.0 using below syntaxes:

    sudo apt-get install gudev-1.0


  28. Anyone attempted a cross compile for ARM? About to take that step 🙂

  29. gudev-1.0 is the package that contains the binary library; you also need libgudev-1.0-dev to BUILD against GUdev, which is the package that contains e.g. the library headers.

  30. I’ve cross compiled for ARM quite some times, should work.

  31. Zainulabidin Omar

    Tlanks alek. Actuslly (I believe) all are taken care by system where I’ve done installation only for gudev-1.0. By cross checked against the system seems all libgudev as well as dbg and dev are already updated with latest releases.

  32. Zainulabidin Omar

    Mr alex, I got problem for qmi-firmware-update on ubuntu 14.04. Actually MC7455 already at ‘boot and hold’ where only /dev/ttyUSB0 shown. That syntaxes as below :
    sudo qmi-firmware-update \
    -t /dev/ttyUSB0 \
    –update-qdl \
    SWI9X30C_02.20.03.00.cwe \
    error: error creating device: HDLC trailing control charactet not found

    Any thought from your enand much appreciated.

  33. Could you guys talk to Richard Hughes please to integrate this into fwupdmgr?
    That would be totally awesome!

  34. He already talked to me about doing this actually, I just never got around looking at how much effort it would be.

  35. Hey Aleksander — if you want me to start on a plugin I just need some compatible hardware for testing. If you email the fwupd mailing list we can help you as much as you need!

  1. Pingback: Links 12/12/2016: Linux Kernel 4.9, 6 Months of Nextcloud | Techrights

  2. Pingback: ModemManager in OpenWRT (take #2) | SIGQUIT

  3. Pingback: QMI/Gobi management in the kernel: qmi_wwan or GobiNet? | SIGQUIT

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: