Quectel Linux USB Drivers Troubleshooting

Quectel Linux USB Drivers Troubleshooting

This post, I am going to show you how to do troubleshooting the USB device drivers between Linux box and Quectel IoT Modules.

Introduction

There are some common problems when USB interface of Quectel IoT Modules pluged into the Linux box:

  • There is no /dev/ttyUSB2, /dev/ttyUSB3, so I can't create PPP connection
  • There is no qmi interface /dev/cdc-wdm0 , so I can't create qmi wan connection
  • How can I know Linux box problem or Quectel IoT modules problems ?
  • ...

Below is the hardware configuration where Linux box could be the router (MIPS) running OpenWrt, Rasberry Pi (ARM or ARM64) running Raspbian, ...

Linux Box connected to Quectel Module

Below are all supported drivers of Quectel modules:

Module Series Modules Supported Driver
WCDMA UC15 USB Serial
UC20 USB Serial/GobiNet/QMI
UG95/UG96 CDC ACM
LTE Standard EC25/EC21/EC20/EG91/EG95 USB Serial /GobiNet/QMI
Automotive AG35 USB Serial/GobiNet/QMI
LTE-A EG06/EP06/EM06/EG12/EP12/ EM12/EG16/EG18 USB Serial/GobiNet/QMI

Check if Linux OS can recognize Quectel Modules

From the physical level without any Linux driver, Linux box should recognize USB Device included Vendor ID (VID), Product ID (PID). EC25 has VID = 0x2c7c and PID = 0x0125. Other completed VID, PID list with supported USB driver can be found from Product Overview.

Product Vendor ID Product ID Remarks
UC15 0x06c6 0x9090
UC20 0x05c6 0x9003
EC25 0x2c7c 0x0125
EC21 0x2c7c 0x0121
EC20 0x05c6 0x9215
EG91 0x2c7c 0x0191
EG95 0x2c7c 0x0195
BG96 0x2c7c 0x0296
AG35 0x2c7c 0x0435
Ex06 0x2c7c 0x0306 EG06, EP06, EM06
Ex12 0x2c7c 0x0512 EG12, EP12, EM12
Ex1x 0x2c7c 0x0512 EG16, EG18

The first step is to check the usb devices from kernel debug cat /sys/kernel/debug/usb/deviceswith root permission, if you see the correct vendor ID and product ID, then USB connection is OK. Otherwise, you must check USB hardware connection between Linux box and Quectel IoT Module.

Below is the oputput from the Linux system which can recognize EC25 with correct   driver USB Serial Option and QMI WWAN, which has VID, PID information: P:  Vendor=2c7c ProdID=0125 Rev= 3.18.

# cat /sys/kernel/debug/usb/devices

T:  Bus=01 Lev=01 Prnt=01 Port=03 Cnt=03 Dev#= 11 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=0125 Rev= 3.18
S:  Manufacturer=Android
S:  Product=Android
C:* #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=83(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=85(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E:  Ad=87(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
E:  Ad=89(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
E:  Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
USB Kernel debug from Ubuntu 18.04 LTS with EC25-E

Alternative tool is lsusb - list all USB devices, I can see EC25-E VID, PID Bus 001 Device 011: ID 2c7c:0125. For Ubuntu users, pls install with sudo apt-get install usbutils.

$ lsusb
Bus 001 Device 008: ID 203a:fffa  
Bus 001 Device 011: ID 2c7c:0125  
Bus 001 Device 010: ID 203a:fffa  
Bus 001 Device 009: ID 203a:fffa  
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 004: ID 203a:fffc  
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
lsusb output from Ubuntu 18.04 LTS with EC25-E

USB Serial Option driver

USB Serial Option driver is a common interface which is supported by all Quectel driver which has USB interface included WCDMA(UC15, UC20), LTE(EC20, EC21, EC25, ... ). When there is only one LTE Module is in your system, below is the common USB Serial interface:

  • /dev/ttyUSB0 - DM
  • /dev/ttyUSB1 - For GPS NMEA message output
  • /dev/ttyUSB2 - For AT command communication
  • /dev/ttyUSB3 - For PPP connection or AT command communication

If there is more than one USB drive with Option driver, the device name could be different or not in order, you must know how to deal with it by using device mapping.

If you don't see any device node:

1) Your system does not install USB Serial Option Driver, thus pls install or include it when you make the image.

OpenWrt, you need below kernel packages: +comgt +usb-modeswitch +kmod-mii +kmod-usb-net +kmod-usb-serial +kmod-usb-serial-option +kmod-usb-serial-wwan

2) Your system has USB Serial Option Driver, however it can't recognize your module. Then, you can manually bind VID, PID for Option driver or rebuild Option Driver with mentioned VID, PID.

Load option driver manually with respective $VID, $PID

# Change to root user
sudo -i

# Load option driver
modprobe option

# Add new ID to option driver
echo "$VID $PID" > /sys/bus/usb-serial/drivers/option1/new_id 

For example, with AG35 VID=`0x2C7C`, PID=`0x0435`

echo "2c7c 0435" > /sys/bus/usb-serial/drivers/option1/new_id 

Then, option driver will recognize AG35 interfaces and map accourdingly:

[  585.258101] usbcore: registered new interface driver usbserial_generic
[  585.258107] usbserial: USB Serial support registered for generic
[  585.264310] usbcore: registered new interface driver option
[  585.264317] usbserial: USB Serial support registered for GSM modem (1-port)
[ 1013.185119] option 1-4:1.0: GSM modem (1-port) converter detected
[ 1013.185301] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB0
[ 1013.185334] option 1-4:1.1: GSM modem (1-port) converter detected
[ 1013.185397] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB1
[ 1013.185421] option 1-4:1.2: GSM modem (1-port) converter detected
[ 1013.185457] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB2
[ 1013.185478] option 1-4:1.3: GSM modem (1-port) converter detected
[ 1013.185514] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB3
[ 1013.185544] option 1-4:1.4: GSM modem (1-port) converter detected
[ 1013.185588] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB4
[ 1013.185625] option 1-4:1.7: GSM modem (1-port) converter detected
[ 1013.185658] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB5

However, only interface 0-3 are serial interfac, you need to unbind all other interfaces which are 1-4:1.4 and 1-4:1.7 for AG35.

echo "1-4:1.4" > /sys/bus/usb/drivers/option/unbind
echo "1-4:1.7" > /sys/bus/usb/drivers/option/unbind

Then, you could see all supported interface listed in option driver:

ls -la /sys/bus/usb/drivers/option/
total 0
drwxr-xr-x  2 root root    0 Apr  8 14:54 .
drwxr-xr-x 13 root root    0 Apr  8 11:20 ..
lrwxrwxrwx  1 root root    0 Apr  8 17:08 1-4:1.0 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.0
lrwxrwxrwx  1 root root    0 Apr  8 17:08 1-4:1.1 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.1
lrwxrwxrwx  1 root root    0 Apr  8 17:08 1-4:1.2 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.2
lrwxrwxrwx  1 root root    0 Apr  8 17:08 1-4:1.3 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.3
--w-------  1 root root 4096 Apr  8 17:08 bind
lrwxrwxrwx  1 root root    0 Apr  8 17:08 module -> ../../../../module/usbserial
--w-------  1 root root 4096 Apr  8 17:08 uevent
--w-------  1 root root 4096 Apr  8 17:01 unbind

To do this permanently, you need to add into your startup script or udev rules.

To test AT command with AT port using either picocom or microcom:

sudo picocom -b 115200 /dev/ttyUSB2

QMI WAN Driver

In order to use QMI WAN with Quectel modules, qmi_wwan driver must be compiled and installed. In OpenWrt, install kernel module kmod-usb-net-qmi-wwan.

If module is powered on, but does not see qmi_wwan log from dmesg, you need to load driver manually and add $VID, $PID similar to above Serial Option Driver.

# Change to root user
sudo -i

# Load qmi_wwan driver
modprobe qmi_wwan

# Add vid, pid to qmi_wwan driver
echo "2c7c 0435" > /sys/bus/usb/drivers/qmi_wwan/new_id

then you will see interface 4 is listed inside qmi_wwan driver and there is a node named /dev/cdc-wdm0

 ls -la /sys/bus/usb/drivers/qmi_wwan/
total 0
drwxr-xr-x  2 root root    0 Apr  8 17:01 .
drwxr-xr-x 13 root root    0 Apr  8 11:20 ..
lrwxrwxrwx  1 root root    0 Apr  8 17:04 1-4:1.4 -> ../../../../devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4:1.4
--w-------  1 root root 4096 Apr  8 17:04 bind
lrwxrwxrwx  1 root root    0 Apr  8 17:04 module -> ../../../../module/qmi_wwan
-rw-r--r--  1 root root 4096 Apr  8 17:04 new_id
-rw-r--r--  1 root root 4096 Apr  8 17:04 remove_id
--w-------  1 root root 4096 Apr  8 17:01 uevent
--w-------  1 root root 4096 Apr  8 17:04 unbind

Raw IP Mode

EC21/EC25/EG91/EG95/BG96/AG35/EG06/EP06/EM06/EG12/EP12/EM12/EG16/EG18 only support raw IP mode (IP packets not encapsulated in Ethernet frames). So Ethernet header must be stripped when packets are sent to the module, and be added when packets are received from the module.

As Linux kernel higher than 4.9.0 already supported raw IP mode from this patch, you can enable raw IP mode by:

ifconfig wwan0 down
echo 1 >  /sys/class/net/wwan0/qmi/raw_ip

For older kernel version, you need to apply a patch to qmi_wwan driver as the last session.

For OpenWrt, at time of writing, the latest uqmi package arleady taken care of raw IP mode switching from this patch.

Test QMI WAN Driver

To test with qmi_wwan, you could use qmicli, qmi-network in Ubuntu or uqmi in OpenWrt.

Patch kernel drivers

This depends on the kernel version and Linux distro, generally we create a kernel driver patch followed Quectel guidance.

For OpenWrt, Linux kernel is built as Makefile and patch, thus pls following this official guide.

# Prepare the kernel tree
make target/linux/{clean,prepare} V=s QUILT=1
# Go to the source tree and manipulate with patch series via `quilt series`
cd build_dir/target-*/linux-*/linux-*

# Create a option driver patch
quilt new platform/500-patch-option-kernel-driver.patch

# Edit files
quilt edit drivers/usb/serial/option.c
quilt edit drivers/usb/serial/qcserial.c
quilt edit drivers/usb/serial/usb-wwan.h
quilt edit drivers/usb/serial/usb-wwan.c

quilt edit drivers/net/usb/qmi_wwan.c
quilt edit drivers/net/usb/usbnet.c

# Refresh the patch
quilt refresh

# Update the patch to the main source tree
cd ../../../../
make target/linux/update pacakge/index V=s
OpenWrt Kernel driver patch with Quilt

About Quectel Wireless Solutions

Quectel Wireless Solutions is the leading global supplier of 5G, LTE, LTE-A, LPWA, Automotive, Android Smart, UMTS/HSPA(+), GSM/GPRS and GNSS modules. As a professional IoT technology developer and cellular module supplier, Quectel is able to provide one-stop service for IoT cellular modules. Quectel's products have been widely applied in IoT/M2M fields including telematics and transport, smart payment, smart energy, smart city, security, wireless gateway, industry, healthcare, agriculture and environment monitoring.