konifay

Stumbling blocks - the Quectel EM05-G LTE Modem under Fedora 39

Introduction An attempt to collect all scattered information, yielding a successful connection to a LTE network using the Quectel EM05-G as found in the Lenovo T14s Gen 3 AMD. The below is not a one-size-fits-all solution, but a key-value, problem-solution approach with a defined goal.

Context

At the time of writing:

  • libmbim-utils-1.28.4-2.fc39.x86_64
  • ModemManager-1.20.6-3.fc39.x86_64

Open issues:

  • Suspend Resume
  • SIM Locking

Sources

The Goal

In the end we want a working connection via mobile broadband (3GPP, LTE / 4G).

Mai 14 21:09:06 spacegray ModemManager[18425]: <info>  [modem0] 3GPP registration state changed (idle -> registering)
Mai 14 21:09:06 spacegray ModemManager[18425]: <info>  [modem0] 3GPP registration state changed (registering -> home)
Mai 14 21:09:06 spacegray ModemManager[18425]: <info>  [modem0] state changed (enabled -> registered)
Mai 14 21:09:06 spacegray ModemManager[18425]: <info>  [modem0] simple connect state (7/10): wait to get packet service state attached
Mai 14 21:09:06 spacegray ModemManager[18425]: <info>  [modem0] simple connect state (8/10): bearer
Mai 14 21:09:07 spacegray ModemManager[18425]: <info>  [modem0] simple connect state (9/10): connect
Mai 14 21:09:07 spacegray ModemManager[18425]: <info>  [modem0] state changed (registered -> connecting)
Mai 14 21:09:07 spacegray ModemManager[18425]: <info>  [modem0/bearer0] reloading stats is supported by the device
Mai 14 21:09:07 spacegray ModemManager[18425]: <info>  [modem0] state changed (connecting -> connected)
Mai 14 21:09:07 spacegray ModemManager[18425]: <info>  [modem0] simple connect state (10/10): all done
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4219] device (cdc-wdm0): state change: prepare -> config (reason 'none', sys-iface-state: 'managed')
Mai 14 21:09:07 spacegray audit[2085]: NETFILTER_CFG table=firewalld:11 family=1 entries=25 op=nft_register_rule pid=2085 subj=system_u:system_r:firewalld_t:s0 comm="firewalld"
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4564] device (cdc-wdm0): state change: config -> ip-config (reason 'none', sys-iface-state: 'managed')
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4580] modem-broadband[cdc-wdm0]: IPv4 static configuration:
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4581] modem-broadband[cdc-wdm0]:   address 10.132.224.163/29 brd* 10.132.224.167 lft forever pref forever lifetime 11934-0[0,0] src wwan
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4582] modem-broadband[cdc-wdm0]:   gateway 10.132.224.164
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4582] modem-broadband[cdc-wdm0]:   DNS 62.109.121.17
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4582] modem-broadband[cdc-wdm0]:   DNS 62.109.121.18
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4582] modem-broadband[cdc-wdm0]:   MTU 1500
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4583] modem-broadband[cdc-wdm0]: IPv6 base configuration:
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4583] modem-broadband[cdc-wdm0]:   address 2a02:3033:211:91e4:b951:de93:c1a4:862b/64 lft forever pref forever lifetime 11934-0[0,0] src unknown (slaac disabled)
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4583] modem-broadband[cdc-wdm0]:   gateway 2a02:3033:211:91e4:6d17:ba87:e991:c32e
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4584] modem-broadband[cdc-wdm0]:   DNS 2a02:3018:0:40ff::aaaa
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4584] modem-broadband[cdc-wdm0]:   DNS 2a02:3018:0:40ff::bbbb
...
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.4684] device (cdc-wdm0): state change: ip-config -> ip-check (reason 'none', sys-iface-state: 'managed')
...
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.5187] device (cdc-wdm0): state change: ip-check -> secondaries (reason 'none', sys-iface-state: 'managed')
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.5191] device (cdc-wdm0): state change: secondaries -> activated (reason 'none', sys-iface-state: 'managed')
Mai 14 21:09:07 spacegray NetworkManager[2110]: <info>  [1715713747.5198] device (cdc-wdm0): Activation: successful, device activated.

Which device is in my laptop?

The quectel EM05-G is hooked up the internal USB bus. As such, you can use lsusb to figure out the specific vendor and device IDs.

lsusb | rg Quectel
# Bus 001 Device 003: ID 2c7c:030a Quectel Wireless Solutions Co., Ltd. Quectel EM05-G

Enabling the Frontend

In some forums, the frontend activation is described as FCC lock. I lack knowledge to confirm the relation to the FCC, but it does disable the radio power source.

sudo mbimcli --device-open-proxy --device=/dev/cdc-wdm0 --quectel-set-radio-state=on

Mobile Provider Selection

Since I am in Europe, or Germany specifically, I want to register automatically to any provider available. Depending on your country, I have no idea if this can cause additional costs or not.

sudo mbimcli --device="/dev/cdc-wdm0" -p --register-automatic

Integration with ModemManager

To integrate with ModemManager we need to link /usr/share/ModemManager/fcc-unlock.available.d/2c7c to the full vendor and device ID above.

At this time there are two known PCI identifiers in use, 030a for an "older" iteration and 0313.

sudo ln -s -f "/usr/share/ModemManager/fcc-unlock.available.d/2c7c" "/etc/ModemManager/fcc-unlock.d/2c7c:030a"
sudo ln -s -f "/usr/share/ModemManager/fcc-unlock.available.d/2c7c" "/etc/ModemManager/fcc-unlock.d/2c7c:0313"

The content of the file is as follows:

#!/bin/bash

# SPDX-License-Identifier: CC0-1.0
# 2022 Leah Oswald <mail@leahoswald.de>
#
# Queltec EM05-G FCC unlock mechanism
#

# require program name and at least 2 arguments
[ $# -lt 2 ] && exit 1

# first argument is DBus path, not needed here
shift

# second and next arguments are control port names
for PORT in "$@"; do
  # match port name
  echo "$PORT" | grep -q cdc-wdm && {
    CDC_WDM_PORT=$PORT
    break
  }
done

# fail if no cdc-wdm port exposed
[ -n "$CDC_WDM_PORT" ] || exit 2

# run mbimcli operation
mbimcli --device-open-proxy --device="/dev/$CDC_WDM_PORT" --quectel-set-radio-state=on
exit $?

This should be picked up automatically.

SIM Locking

When the SIM locks itself again, it's a bit of a pain to figure that out. There is no popup that asks you to re-enter.

Adding a line second to last to the lockup script to enter the PIN automatically, is the best approach.

Note that disabling the PIN on the sim via mbimcli is NOT what you want!

GUI

The ModemManager integration leaves much to be desired. Besides the occassional SIM unlock - you need the PUK1 for that (!) and it fails on the CLI - I tend to use the commandline to gain a reasonable amount of feedback if the panel doesn't respond quick enough. Rule of thumb: If you get connecitivty issues, the PIN is the first goto place.

Suspend Resume

Occassionally the device disappears after resuming from suspend to RAM.

Check journalctl --since="5min ago", I saw a missing directory once and creating that fixed it.

Mai 15 13:57:46 spacegray NetworkManager[2110]: <info>  [1715774266.1051] device (ttyUSB0): state change: prepare -> config (reason 'none', sys-iface-state: 'managed')
Mai 15 13:57:46 spacegray NetworkManager[2110]: <info>  [1715774266.1053] modem["ttyUSB0"]: using modem-specified IP timeout: 20 seconds
Mai 15 13:57:46 spacegray NetworkManager[2110]: <info>  [1715774266.1053] ppp-manager: starting PPP connection
Mai 15 13:57:46 spacegray NetworkManager[2110]: <info>  [1715774266.1081] ppp-manager: pppd started with pid 81512
Mai 15 13:57:46 spacegray pppd[81512]: Plugin /usr/lib64/pppd/2.5.0/nm-pppd-plugin.so loaded.
Mai 15 13:57:46 spacegray NetworkManager[81512]: Plugin /usr/lib64/pppd/2.5.0/nm-pppd-plugin.so loaded.
Mai 15 13:57:46 spacegray pppd[81512]: nm-ppp-plugin: initializing
Mai 15 13:57:46 spacegray pppd[81512]: pppd 2.5.0 started by root, uid 0
Mai 15 13:57:46 spacegray pppd[81512]: nm-ppp-plugin: status 2 / phase 'serial connection'
Mai 15 13:57:46 spacegray pppd[81512]: Can't create lock file /run/pppd/lock/LCK..ttyUSB0: No such file or directory
Mai 15 13:57:46 spacegray NetworkManager[81512]: Can't create lock file /run/pppd/lock/LCK..ttyUSB0: No such file or directory
Mai 15 13:57:46 spacegray pppd[81512]: nm-ppp-plugin: status 0 / phase 'dead'
Mai 15 13:57:46 spacegray pppd[81512]: nm-ppp-plugin: cleaning up
Mai 15 13:57:46 spacegray pppd[81512]: Exit.

which is fixed by

sudo mkdir -p /run/pppd/lock

Useful status queries

journalctl -xn -f
sudo mbimcli --device="/dev/cdc-wdm0" -p --query-ip-configuration
sudo mbimcli --device="/dev/cdc-wdm0" -p --query-pin-state
sudo mbimcli --device="/dev/cdc-wdm0" -p --quectel-query-radio-state
# not a typo, it is mmcli from modem manager
sudo mmcli -m 0

At times the modem becomes unresponsive and the only possible solution I found is to reboot. Unloading and re-loading the driver modules might be sufficient (untested).