Using Ericsson H5321 gw Mobile Broadband Module under Linux

2023-10-02

My daily driver is a Thinkpad x230 that contains a Mobile Broadband Module:

1
2
3
4
$ lsusb
[…]
Bus 003 Device 002: ID 0bdb:1926 Ericsson Business Mobile Networks BV H5321 gw Mobile Broadband Module
[…]

From my mobile phone provider, I got an additional SIM card that only works for Data but not Voice. I have been wanting to use that in my laptop for some time but never had enough time to figure out how to properly use it. You’d think I had invested enough time but there was not quite enough information to dispel the confusion the existing information and the numerous possibilities to go about this created.

I finally found time to get back to this topic last week and managed to figure out how to get it to work and what was so confusing the last time(s) I tried it. Some of these things might help clarify things for others, so I’m writing them down here.

BTW: the “easy” way to do this is to use ModemManager but this gets me into dependency hell. Also I’m a bit of a masochist and like doing things the “hard” or “low-level” way because my impression is that I learn a bit more that way.

The Gist of It

After getting it to work I think I now understand what is needed to get it working, so I want to summarize this at the top as a kind of TL;DR before going into some of the topics I encountered on the way.

Make Kernel Module Prefer MBIM over NCM

1
2
$ cat /etc/modprobe.d/00-local-wwan.conf
options cdc_ncm prefer_mbim=Y

I’m actually not sure whether this is really necessary. It works with this and I didn’t test whether it works without it.

Note on changing module parameters

Note that creating this file does not change this option for an already loaded module; it will only take effect the next time the module is loaded. You have three possibilities here:

  • change the parameter for the loaded module with:
1
echo Y >| /sys/module/cdc_ncm/parameters/prefer_mbim
  • unload and load the module with modprobe
  • reboot

Reference: https://www.kernel.org/doc/html/latest/networking/cdc_mbim.html

Unlock the SIM

1
2
3
4
5
# mbimcli --device-open-proxy --device /dev/cdc-wdm2 --enter-pin=1234
[/dev/cdc-wdm2] PIN operation successful

[/dev/cdc-wdm2] PIN info:
                 PIN state: 'unlocked'

See below for finding the correct device to use. And, obviously, you will probably need to adjust the PIN.

Enable the Radio

1
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --set-radio-state=on

See below for troubles with this.

Bring Up Network Interface

1
ip link set wwan0 up

Connecting / Disconnecting

1
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --connect=access-string='Internet'

This command will show the IP configuration that can also be seen with a command for querying, see below.

1
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --disconnect

See below for an alternative.

Configure the Network

The IP configuration shown by the command for connecting now has to be applied to the network interface:

1
2
ip address add 192.0.2.42/29 dev wwan0
ip route add default via 192.0.2.1 dev wwan0

The Details, Problems, Oddities, Alternatives

Information About the Devices

With lsusb -t you can find more information about your device. The relevant part of the output looks like this on my system:

1
2
3
4
5
6
7
8
9
10
11
12
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 4: Dev 2, If 0, Class=Communications, Driver=, 480M
    |__ Port 4: Dev 2, If 1, Class=Communications, Driver=cdc_acm, 480M
    |__ Port 4: Dev 2, If 2, Class=CDC Data, Driver=cdc_acm, 480M
    |__ Port 4: Dev 2, If 3, Class=Communications, Driver=cdc_acm, 480M
    |__ Port 4: Dev 2, If 4, Class=CDC Data, Driver=cdc_acm, 480M
    |__ Port 4: Dev 2, If 5, Class=Communications, Driver=cdc_wdm, 480M
    |__ Port 4: Dev 2, If 6, Class=Communications, Driver=cdc_mbim, 480M
    |__ Port 4: Dev 2, If 7, Class=CDC Data, Driver=cdc_mbim, 480M
    |__ Port 4: Dev 2, If 8, Class=Communications, Driver=cdc_wdm, 480M
    |__ Port 4: Dev 2, If 9, Class=Communications, Driver=cdc_acm, 480M
    |__ Port 4: Dev 2, If 10, Class=CDC Data, Driver=cdc_acm, 480M

Lines 9 and 10 show a device using the cdc_mbim driver.

With ls -l /sys/class/usbmisc I can find some cdc-wdmX devices:

1
2
3
lrwxrwxrwx 0 root  3 Okt 13:19 cdc-wdm0 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4:1.5/usbmisc/cdc-wdm0
lrwxrwxrwx 0 root  3 Okt 13:19 cdc-wdm1 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4:1.8/usbmisc/cdc-wdm1
lrwxrwxrwx 0 root  3 Okt 10:37 cdc-wdm2 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4:1.6/usbmisc/cdc-wdm2

In the links’ targets we will find the USB Bus, Port, and If as already seen in the lsusb output before. In my case, the cdc_mbim device with Class=Communications was If 6 and we find 3-4:1.6 again for cdc-wdm2. So that’s the device we need to use for our mbimcli commands.

Another way to find the correct device might be:

1
2
3
4
5
6
7
$ for n in `ls /sys/class/*/*{ACM,wdm}*/device/interface`; do echo $(echo $n|awk -F '/' '{print $5}') : $(cat $n); done
ttyACM0 : H5321 gw Mobile Broadband Modem
ttyACM1 : H5321 gw Mobile Broadband Data Modem
ttyACM2 : H5321 gw Mobile Broadband GPS Port
cdc-wdm0 : H5321 gw Mobile Broadband Device Management
cdc-wdm1 : H5321 gw Mobile Broadband USIM Port
cdc-wdm2 : Ericsson H5321 gw

Querying the State

The following commands query the device’s state, remember to adjust the actual device file used to your system:

1
2
3
4
5
6
7
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-device-caps
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-subscriber-ready-status
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-radio-state
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-pin-state
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-packet-service-state
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-ip-configuration
mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-device-services

Controlling Radio State

As shown before there is a command to query and set the radio state of the device:

1
2
3
4
# mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-radio-state
[/dev/cdc-wdm2] Radio state retrieved:
             Hardware radio state: 'on'
             Software radio state: 'off'

In this state with the Software radio state being off the radio can be switched on with the mbimcli command shown before.

After using the connection and then suspending my machine I usually end up with this state:

1
2
3
4
# mbimcli --device-open-proxy --device /dev/cdc-wdm2 --query-radio-state
[/dev/cdc-wdm2] Radio state retrieved:
             Hardware radio state: 'off'
             Software radio state: 'on'

Then I get errors when trying to connect again and it took me quite some time to figure out how to solve it. It turns out that rfkill can fix this by blocking and then unblocking the device. In my case:

1
2
3
4
5
6
7
$ rfkill
ID TYPE      DEVICE                   SOFT      HARD
 0 bluetooth tpacpi_bluetooth_sw unblocked unblocked
 1 wwan      tpacpi_wwan_sw      unblocked unblocked
 2 wlan      phy0                unblocked unblocked
 3 bluetooth hci0                unblocked unblocked
 4 bluetooth hci1                unblocked unblocked

I need to run the following commands:

1
2
rfkill block 1
rfkill unblock 1

Subsequently querying the radio state with the mbimcli command above shows the Hardware radio state as on again.

Conflict with WLAN

I found information that one needs to use rfkill or, if available, a hardware switch to block WLAN because otherwise WWAN won’t work at all. This is not true in my case. I have not dug into this deeper.

Alternative Way of Establishing the Connection

Instead of the mbimcli command I used to establish and tear down the connection there is also mbim-network which can be used.

mbim-network requires a config file:

1
2
3
$ cat /etc/mbim-network.conf
APN="Internet"
PROXY=yes

To connect and disconnect you’d then use:

1
2
3
mbim-network /dev/cdc-wdm2 start
mbim-network /dev/cdc-wdm2 status
mbim-network /dev/cdc-wdm2 stop

I did not see much of an advantage so decided to do everything with mbimcli. In fact, IIRC I saw a disadvantage: mbimcli shows the IP configuration after connecting, while mbim-network does not.

bConfigurationValue

I found information that I need to switch the “configuration” (a kind of mode this device operates in) of the USB device using the following commands:

1
2
3
echo 0 >| /sys/bus/usb/devices/3-4/bConfigurationValue
echo 1 >| /sys/bus/usb/devices/3-4/bConfigurationValue
echo 3 >| /sys/bus/usb/devices/3-4/bConfigurationValue

“0” is for “resetting” the configuration, while “1” and “3” are for the different “configurations” the device supports. Ultimately it turned out that this was not necessary.

My device seems to default to “1”. Switching it to “3” resulted in only one cdc-wdmX device being present. Switching it back to “1”, there were three again BUT their order was changed: what was cdc-wdm2 before had become cdc-wdm1. Maybe you can imagine how confusing it was until I figured that out …

Reference: https://medium.com/@yildirimabdrhm/how-to-use-mobile-modem-on-linux-f61a5b83cc35

Reconnecting or Resetting Devices

During all this I found out about 3 different ways of “reconnecting” or “resetting” USB devices that I just want to mention here quickly:

Method 1

1
usbreset 0bdb:1926

This is the USB device ID you see in lsusb.

Method 2

Reconnecting the hub it’s connected to:

1
2
print 0 >| /sys/bus/usb/devices/usb3/bConfigurationValue
print 1 >| /sys/bus/usb/devices/usb3/bConfigurationValue

Method 3

Rebinding the driver:

1
2
echo "3-4" >| /sys/bus/usb/drivers/usb/unbind
echo "3-4" >| /sys/bus/usb/drivers/usb/bind

General References

Disclaimers

I wrote this post because I did not find a lot of usable information about this topic in general and hope that adding what worked for me to the pool can help someone else in a similar situation.

Particularly, I did not write it because I have a deep understanding of what I’m doing here, neither for USB, nor for MBIM, nor for mobile broadband networking, etc.

I do not have a thorough understanding of what some of these commands do, especially the ones about reconnecting or resetting USB devices or switching the configuration modes and if they are even helpful in this context.

It may be possible to use this device in other ways, e.g. as a PPP or Ethernet device. I did not really look into that as MBIM seemed to be more modern than PPP and not a bad choice altogether.

My shell might work different than yours, e.g. with regards to overwriting files during output redirection, or filename generation/expansion. I do not mention how the commands given here may have to look for other shells or shell configurations as it’s out of scope.

Please let me know if you have any corrections, optimizations, clarifications, or (pointers to) additional information!

Thanks

Thanks to the people in #networking on irc.libera.chat who gave me valuable input for figuring this out. Also to all the authors of the sites I referenced in this post.

Tags: ,

Other formats: markdown