HowTo use a Quectel EC20 MiniPCIe Modem on a Thinkpad T430 using the stock BIOS

Hi y’all!

I wanted to use a modern LTE modem on my Thinkpad T430 without modding the BIOS. Thinkpads only work with a certain number of Lenovo branded mPCIe cards (a whitelist), you can read more about this at ThinkWiki, If you try to use a non whitelisted card the system halts with this message: Halt Halted system image by erfur’s bits&pieces halt.

Fortunately Quectel EC20 allow us to change the usb IDs that the modem exposes to the system, Only 2 WWAN adapters are allowed for the T430:

I chose the H5321gw (0bdb:1926). The first step is converting the hexadecimal vendor and product IDs to decimal (I used the python interactive shell):

int('0bdb', 16)
int('1926', 16)

The resulting integer IDs will be used in an AT command for the Quectel EC20. On my system the AT interface for this modem is at /dev/ttyUSB2:

From this point on the Modem will use those IDs on the system:

Bus 003 Device 002: ID 0bdb:1926 Ericsson Business Mobile Networks BV H5321 gw Mobile Broadband Module

We can now modify the qcserial kernel module to use the correct driver even for the incorrect IDs. In my case I am using 5.4.63, but any other version will work fine:

--- drivers/usb/serial/qcserial.c.orig  2020-09-21 18:19:00.782018308 +0200
+++ drivers/usb/serial/qcserial.c       2020-09-21 20:50:56.697167693 +0200
@@ -18,7 +18,7 @@
 #define DRIVER_AUTHOR "Qualcomm Inc"
 #define DRIVER_DESC "Qualcomm USB Serial driver"

-#define QUECTEL_EC20_PID       0x9215
+#define QUECTEL_EC20_PID       0x1926

 /* standard device layouts supported by this driver */
 enum qcserial_layouts {
@@ -111,6 +111,7 @@
        {USB_DEVICE(0x16d8, 0x8002)},   /* CMDTech Gobi 2000 Modem device (VU922) */
        {USB_DEVICE(0x05c6, 0x9204)},   /* Gobi 2000 QDL device */
        {USB_DEVICE(0x05c6, 0x9205)},   /* Gobi 2000 Modem device */
+       {USB_DEVICE(0x0bdb, 0x1926)},   /* @Gerardo: Fake H5321gw */

        /* Gobi 3000 devices */
        {USB_DEVICE(0x03f0, 0x371d)},   /* HP un2430 Gobi 3000 QDL */

Compile and install the modified module:

make modules && make modules_install

If everything went well we can unload the old module and load the patched one:

rmmod qcserial; modprobe qcserial

If everything went as expected you should see the new usb/serial converters being loaded by the kernel:

qcserial 3-4:1.0: Qualcomm USB modem converter detected
usb 3-4: Qualcomm USB modem converter now attached to ttyUSB0
qcserial 3-4:1.1: Qualcomm USB modem converter detected
usb 3-4: Qualcomm USB modem converter now attached to ttyUSB1
qcserial 3-4:1.2: Qualcomm USB modem converter detected
usb 3-4: Qualcomm USB modem converter now attached to ttyUSB2
qcserial 3-4:1.3: Qualcomm USB modem converter detected
usb 3-4: Qualcomm USB modem converter now attached to ttyUSB3

If you use modemmanager (Network Manager) we can modify the udev rules that load this modem with the Ericsson plugin so it loads with the generic one. At /lib/udev/rules.d/77-mm-ericsson.mbm.rules comment out the lines with the idProduct 1926:

--- 77-mm-ericsson-mbm.rules.orig       2020-09-22 12:05:54.781309128 +0200
+++ 77-mm-ericsson-mbm.rules    2020-09-22 11:19:04.528633520 +0200
@@ -63,8 +63,8 @@
 ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1921", ENV{ID_MM_ERICSSON_MBM}="1"

 # Ericsson H5321gw
-ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1926", ENV{.MM_USBIFNUM}=="09", ENV{ID_MM_PORT_TYPE_GPS}="1"
-ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1926", ENV{ID_MM_ERICSSON_MBM}="1"
+# ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1926", ENV{.MM_USBIFNUM}=="09", ENV{ID_MM_PORT_TYPE_GPS}="1"
+# ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1926", ENV{ID_MM_ERICSSON_MBM}="1"
 ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1927", ENV{.MM_USBIFNUM}=="09", ENV{ID_MM_PORT_TYPE_GPS}="1"
 ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1927", ENV{ID_MM_ERICSSON_MBM}="1"

We can now reload the udev rules using:

udevadm control -R

And confirm that ModemManager is using the generic plugin:

# nmcli -m 0
  System   |               device: /sys/devices/pci0000:00/0000:00:14.0/usb3/3-4
           |              drivers: qcserial
           |               plugin: Generic
           |         primary port: ttyUSB2
           |                ports: ttyUSB0 (qcdm), ttyUSB2 (at), ttyUSB3 (at)
  Status   |       unlock retries: sim-pin (3), sim-puk (10), sim-pin2 (3), sim-puk2 (10)
           |                state: connected
           |          power state: on
           |          access tech: lte
           |       signal quality: 60% (recent)

As always your mileage can vary radically from mine. But I hope this post can help or inspire you ideas about how to use the hardware you want without artificially imposed limitations.