How to use an LTE modem in QMI/MBIM mode for WWAN connection

Many currently-available 4G/5G modems use QMI or MBIM protocol to interact with the host system, e.g. with a router. For your information, QMI is a proprietary protocol by Qualcomm used by many devices. MBIM is a protocol from the USB Implementer's Forum.

This recipe explains how to setup and configure OpenWrt for using 4G/5G USB modems for WAN connection, using QMI or MBIM protocol.

The same applies to external modems connected to USB ports and internal models installed into M.2(NGFF) or mPCIe slots.

You may want to checkout the mwan3 (Multi WAN load balancing/failover) package to use this simultaneously with other connections to the Internet.

Also, see the Optimization sub-section of this page, for certain issues with MTU and Bufferbloat management.

Many modern USB modems may operate in different modes. If your modem provides only serial interface(s) like /dev/ttyUSBx PPP - please refer to the 3GDongle Wiki Page on how to use 3g/UMTS USB Dongle for WAN connection. For more information about other protocols commonly used:

If it is possible to switch your modem to provide QMI or MBIM interface - then this article is for you.

1. Install OpenWrt release image for your device.

2. Complete Steps OpenWrt Configuration

3. Router should be turned on and connected to the Internet to get the needed packages. Please refer to: Internet Connection.

To make use of QMI protocol, packages kmod-usb-net-qmi-wwan (driver) and uqmi (control utility) are needed. For MBIM protocol the packages are kmod-usb-net-cdc-mbim and umbim. Alternatively, there is the ModemManager package.

Add support for the modem's serial interfaces (/dev/ttyUSBx) - install kmod-usb-serial-option, kmod-usb-serial-qualcomm or kmod-usb-serial-sierrawireless, depending on the modem. They are needed to interact with the modem using AT commands, for configuration purposes or to be able to send/receive SMS and USSD. A terminal program like picocom will be needed to interactively send & receive AT commands.

1. Add protocol support to LuCI - install luci-proto-qmi for QMI or luci-proto-mbim for MBIM, to use the web interface to configure and visualize your connection.

2. Install usb-modeswitch package only if that is needed for switching the modem into a “working” state. More about: USB mode switch

3. If available, add support for storage component of your modem - refer to: USB Storage

1. Install all the needed packages either in LuCI → System → Software or via command line: See Modem Preparation below, if you have picocom serial interface working, but are not sure what mode the modem is in.

  • if the modem is in QMI mode:
root@OpenWrt:~# opkg update
root@OpenWrt:~# opkg install kmod-usb-net-qmi-wwan uqmi luci-proto-qmi kmod-usb-serial-option picocom
  • if the modem is in MBIM mode:
root@OpenWrt:~# opkg update
root@OpenWrt:~# opkg install kmod-usb-net-cdc-mbim umbim luci-proto-mbim kmod-usb-serial-option picocom

:!: If your have not enough space on your device - think about upgrading your hardware or installing Rootfs on External Storage (extroot). Refer to your router wiki page or forum thread for possibility and instructions.

2. Reboot the router by executing reboot on the console.

3. Check if you got a new device:

root@OpenWrt:~# ls -l /dev/cdc*

crw-r--r--    1 root     root      180, 176 Oct  1 12:03 /dev/cdc-wdm0

If there is no such device found - try to get more details:

  • Open System Log from LuCI web interface and see what it shows regarding newly discovered USB device(s)
  • execute dmesg on the console and see if any relevant information is present in the kernel log
  • check the details about USB devices detected by the system by running cat /sys/kernel/debug/usb/devices on the console:
[...]
T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=0306 Rev= 3.10
S:  Manufacturer=Quectel
S:  Product=EP06-E
S:  SerialNumber=0123456789ABCDEF
C:* #Ifs= 5 Cfg#= 1 Atr=a0 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

See Troubleshooting Section of this page for more information.

Unlike conventional interfaces, cell modems have to be 'prepared' to be in the right mode. They may come shipped in one mode, but you prefer to use another. Or your needs require a different mode.

If QMI or MBIM interface is not exposed by the modem initially you may need to switch it to another mode or composition by using USB mode switch tool or a vendor-specific AT command.

:!: You can read further about AT commands for your modem. Typically, the command is 'picocom /dev/ttyUSB2'.

More recent modems are set by default to MBIM or QMI mode.

This is an example of switching modes for popular Quectel modems (these are manufacturer-specific command sets):

AT+QCFG="usbnet"	# check the current mode
AT+QCFG="usbnet",0	# set QMI or RMNET mode
AT+QCFG="usbnet",1	# set ECM mode
AT+QCFG="usbnet",2	# set MBIM mode

Reset the modem to apply changes - power toggle it or send AT+CFUN=1,1 command.

The equivalent commands for Sierra Wireless (SEMTECH) modems:

QMI:

AT!ENTERCND="A710" # enter the configuration mode allowing you to make certain administrative changes
AT!USBCOMP=1,1,10D       # Set the mode to QMI
AT!RESET                 # Reset and implement the changes.

MBIM:

AT!ENTERCND="A710"
AT!USBCOMP=1,1,100D
AT!RESET

Show the current mode:

AT!USBCOMP?


Although the APN, Authentication Type and PDP (IPv4, v6 or both) are set through the LuCI web interface, it may be worth familiarizing yourself with the list of stored PDP Contexts and APNs configured on the modem.

To see the stored values, you will send some variation on AT+CGDCONT? Quectel and Sierra Wireless:

AT+CGDCONT?
+CGDCONT: 1,"IPV4V6","internet",...
+CGDCONT: 2,"IPV4V6","ims",...
+CGDCONT: 3,"IPV4V6","sos",...

To write a Context:

AT+CGDCONT=1,"IP","internet"

Replace IP with IPV4V6 or IPV6 if necessary and use your APN instead of internet.

E.G.

at+cgdcont=1,"ipv4v6","fast.t-mobile.com" # sets for TMOBILE
at+cgdcont=1,"ipv4v6","vzwinternet" # sets for VERIZON

Typically, but not always, context #1 is used for the Internet connection. On Verizon, it's Context 3, and Context 1 is used for IMS (Messaging services, SMS). If it is not configured with the correct information (IP type and APN), it is recommended to set the desired parameters. Example:

For an alternative method, see Manual validation section below.


While in the terminal, check the modem firmware version with ATI, and see if there is an upgrade available on the manufacturer's support website or forum. Oftentimes, it improves performance. But on some modems, it may have unintended consequences. It is best, but not necessary, if you have your original firmware available to go back to.

[QMI]: Assuming luci-proto-qmi package is installed, navigate to Network → Interfaces, then Add new interface… → Protocol: QMI Cellular

[MBIM]: Assuming luci-proto-mbim package is installed, navigate to Network → Interfaces, then Add new interface… → Protocol: MBIM Cellular

[Common]:

Select Interface “cdc-wdm0” in the drop-down. If it is not available there, check if the corresponding driver (kmod-usb-net-*) is loaded, reset the modem if its mode has recently been changed.

Enter your APN and select the IP type as per the carrier, that is critical to get it working properly in QMI mode. Most are using IPv4/6 (both), or only IPv6.

Note: in IPv6-only mode it is recommended to enable dhcpv6 option in order to automatically start the 464XLAT interface (that requires 464xlat package).

Assign the firewall zone (wan) on 'Firewall Settings' tab. You will need to enable masquerading (checked ON by default for the pre-defined 'wan' zone), usually, and depending on the provider, if you do not get a -PD, 'IPv6 Masquerading', under the 'Advanced Settings' tab. There is a work-around for Quectel devices that crash when their MTU is set, below ('MTU Issues' under Troubleshooting & Optimization). If you are not doing that, MSS Clamping should also be enabled here.

Instead of using the web interface, this is how the files can be manually edited: Add new interface to /etc/config/network using a text editor like vi or nano:

config interface 'wwan'
        option proto 'qmi'
        option device '/dev/cdc-wdm0'
        option apn 'internet' # Your provider's APN here
	option v6apn 'internet' # usually the same as the 'apn' setting
        option auth 'none'
        option pdptype 'ipv4v6'

Replace “qmi” with “mbim” if necessary to match the modem configuration. Make sure the APN name is one provided by your carrier.

Add the same interface name to the existing “wan” firewall zone in /etc/config/firewall:

config zone
    option name 'wan'
    [...]
    list network 'wwan'

QMI (and MBIM) interfaces could be manually configured in UCI using uci command line or text editor.

Name Type Required Default Description
device file path yes (none) QMI device node, typically /dev/cdc-wdm0
apn string yes (none) Used APN
v6apn string no (none) APN for IPv6, if different from IPv4 APN
auth string no (none) Authentication type: pap, chap, both, none
username string no (none) Username for PAP/CHAP authentication
password string no (none) Password for PAP/CHAP authentication
pincode number no (none) PIN code to unlock SIM card
delay number no 0 Seconds to wait before trying to interact with the modem (some ZTE modems require up to 30 s.)
modes string no (modem default) Allowed network modes, comma separated list of: all, lte, umts, gsm, cdma, td-scdma
pdptype string no IP PDP Context Type, IP (for IPv4), IPV6 (for IPv6) or IPV4V6 (for dual-stack). Connection will fail if selected type is unsupported by the carrier.
profile number no 1 PDP Context Identifier
v6profile number no (none) PDP Context Identifier for IPv6 if different from IPv4 profile
dhcp boolean no 1 Whether to use DHCP (default) or uqmi (0) to get IPv4 interface configuration
dhcpv6 boolean no 0 Whether to use DHCP (1) or uqmi (default) to get IPv6 interface configuration
sourcefilter boolean no 1 Used to disable source-based IPv6 routing
delegate boolean no 1 Used to disable IPv6 Prefix Delegation
autoconnect boolean no 1
plmn number no (none) Limit network registration to specific operator. First 3 digits is the MCC (Mobile Country Code) and last 3 digits is the MNC (Mobile Network Code); for example, if lock is required for a network with MCC 338 and MNC 20, then plmn should be set to 338020
timeout number no 10 Timeout (in seconds) to wait for SIM operations
mtu number no (none) Interface MTU size

Here is a brief help about uqmi command line usage:

Click to display ⇲

Click to hide ⇱

Usage: uqmi <options|actions>
Options:
  --single, -s:                     Print output as a single line (for scripts)
  --device=NAME, -d NAME:           Set device name to NAME (required)
  --keep-client-id <name>:          Keep Client ID for service <name>
  --release-client-id <name>:       Release Client ID after exiting
  --mbim, -m                        NAME is an MBIM device with EXT_QMUX support
  --timeout, -t                     response timeout in msecs
 
Services:                           dms, nas, pds, wds, wms
 
Actions:
  --get-versions:                   Get service versions
  --set-client-id <name>,<id>:      Set Client ID for service <name> to <id>
                                    (implies --keep-client-id)
  --get-client-id <name>:           Connect and get Client ID for service <name>
                                    (implies --keep-client-id)
  --sync:                           Release all Client IDs
  --start-network:                  Start network connection (use with options below)
    --apn <apn>:                    Use APN
    --auth-type pap|chap|both|none: Use network authentication type
    --username <name>:              Use network username
    --password <password>:          Use network password
    --ip-family <family>:           Use ip-family for the connection (ipv4, ipv6, unspecified)
    --autoconnect:                  Enable automatic connect/reconnect
    --profile <index>:              Use connection profile
  --stop-network <pdh>:             Stop network connection (use with option below)
    --autoconnect:                  Disable automatic connect/reconnect
  --get-data-status:                Get current data access status
  --set-ip-family <val>:            Set ip-family (ipv4, ipv6, unspecified)
  --set-autoconnect <val>:          Set automatic connect/reconnect (disabled, enabled, paused)
  --get-profile-settings <val,#>:   Get APN profile settings (3gpp, 3gpp2),#
  --get-default-profile <val>:      Get default profile number (3gpp, 3gpp2)
  --create-profile <val>            Create profile (3gpp, 3gpp2)
    --apn <apn>:                    Use APN
    --pdp-type ipv4|ipv6|ipv4v6>:   Use pdp-type for the connection
    --username <name>:              Use network username
    --password <password>:          Use network password
    --auth-type pap|chap|both|none: Use network authentication type
    --no-roaming false|true         To allow roaming, set to false
  --modify-profile <val>,#          Modify profile number (3gpp, 3gpp2)
    --apn <apn>:                    Use APN
    --pdp-type ipv4|ipv6|ipv4v6>:   Use pdp-type for the connection
    --username <name>:              Use network username
    --password <password>:          Use network password
    --auth-type pap|chap|both|none: Use network authentication type
    --no-roaming false|true         To allow roaming, set to false
  --get-current-settings:           Get current connection settings
  --get-capabilities:               List device capabilities
  --get-pin-status:                 Get PIN verification status
  --verify-pin1 <pin>:              Verify PIN1
  --verify-pin2 <pin>:              Verify PIN2
  --set-pin1-protection <state>:    Set PIN1 protection state (disabled, enabled)
    --pin <pin>:                    PIN1 needed to change state
  --set-pin2-protection <state>:    Set PIN2 protection state (disabled, enabled)
    --pin <pin2>:                   PIN2 needed to change state
  --change-pin1:                    Change PIN1
    --pin <old pin>:                Current PIN1
    --new-pin <new pin>:            New pin
  --change-pin2:                    Change PIN2
    --pin <old pin>:                Current PIN2
    --new-pin <new pin>:            New pin
  --unblock-pin1:                   Unblock PIN1
    --puk <puk>:                    PUK needed to unblock
    --new-pin <new pin>:            New pin
  --unblock-pin2:                   Unblock PIN2
    --puk <puk>:                    PUK needed to unblock
    --new-pin <new pin>:            New pin
  --get-iccid:                      Get the ICCID
  --get-imsi:                       Get International Mobile Subscriber ID
  --get-imei:                       Get International Mobile Equipment ID
  --get-msisdn:                     Get the MSISDN (telephone number)
  --reset-dms:                      Reset the DMS service
  --get-device-operating-mode       Get the device operating mode
  --set-device-operating-mode <m>   Set the device operating mode
                                    (modes: online, low_power, factory_test, offline
                                     reset, shutting_down, persistent_low_power,
                                     mode_only_low_power)
  --fcc-auth:                       Set FCC authentication
  --uim-verify-pin1 <pin>:          Verify PIN1 (new devices)
  --uim-verify-pin2 <pin>:          Verify PIN2 (new devices)
  --uim-get-sim-state:              Get current SIM state
  --uim-power-off:                  Power off SIM card
    --uim-slot:                     SIM slot [1-2]
  --uim-power-on:                   Power on SIM card
    --uim-slot:                     SIM slot [1-2]
  --set-network-modes <modes>:      Set usable network modes (Syntax: <mode1>[,<mode2>,...])
                                    Available modes: all, lte, umts, gsm, cdma, td-scdma
  --set-network-preference <mode>:  Set preferred network mode to <mode>
                                    Available modes: auto, gsm, wcdma
  --set-network-roaming <mode>:     Set roaming preference:
                                    Available modes: any, off, only
  --network-scan:                   Initiate network scan
  --network-register:               Initiate network register
  --set-plmn:                       Register at specified network
    --mcc <mcc>:                    Mobile Country Code (0 - auto)
    --mnc <mnc>:                    Mobile Network Code
  --get-plmn:                       Get preferred network selection info
  --get-signal-info:                Get signal strength info
  --get-serving-system:             Get serving system info
  --get-system-info:                Get system info
  --get-lte-cphy-ca-info:           Get LTE Cphy CA Info
  --get-cell-location-info:         Get Cell Location Info
  --get-tx-rx-info <radio>:         Get TX/RX Info (gsm, umts, lte)
  --list-messages:                  List SMS messages
    --storage <mem>:                Messages storage (sim (default), me)
  --delete-message <id>:            Delete SMS message at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --get-message <id>:               Get SMS message at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --get-raw-message <id>:           Get SMS raw message contents at index <id>
    --storage <mem>:                Messages storage (sim (default), me)
  --send-message <data>:            Send SMS message (use options below)
    --send-message-smsc <nr>:       SMSC number
    --send-message-target <nr>:     Destination number (required)
    --send-message-flash:           Send as Flash SMS
  --wda-set-data-format <type>:     Set data format (type: 802.3|raw-ip)
  --wda-get-data-format:            Get data format


MBIM configuration is very similar to QMI. Supported interface configuration options:

Name Type Required Default Description
device file path yes (none) MBIM device node, typically /dev/cdc-wdm0
apn string yes (none) Used APN
auth string no (none) Authentication type: pap, chap, both, none
username string no (none) Username for PAP/CHAP authentication
password string no (none) Password for PAP/CHAP authentication
pincode number no (none) PIN code to unlock SIM card
delay number no 0 Seconds to wait before trying to interact with the modem
pdptype string no IP PDP Context Type, IP (for IPv4), IPV6 (for IPv6) or IPV4V6 (for dual-stack)
ipv6 boolean no 1 Set it to 0 to disable IPv6 operation
dhcp boolean no 0 Whether to use DHCP (1) or “umbim” tool (default) to get IPv4 interface configuration
dhcpv6 boolean no 0 Whether to use DHCPv6 (1) or “umbim” tool (default) to get IPv6 interface configuration
sourcefilter boolean no 1 Used to disable source-based IPv6 routing
extendprefix boolean no 0 Accept a /64 IPv6 prefix via SLAAC and extend it on one downstream interface
delegate boolean no 1 Used to disable IPv6 Prefix Delegation
allow_roaming boolean no 0 Allow connection if the modem is registered to the network in roaming
allow_partner boolean no 0 Allow connection if the modem is registered to a partner network
mtu number no (none) Interface MTU size

Here is a brief help about umbim command line:

root@OpenWrt:~# umbim help
Usage: umbim <caps|pinstate|unlock|home|registration|subscriber|attach|detach|connect|disconnect|config|radio> [options]
Options:
    -d <device>         the device (/dev/cdc-wdmX)
    -t <transaction>    the transaction id
    -n                  no close
    -v                  verbose

uqmi tool can talk to MBIM modems using --mbim or -m option on the command line.

Check the currently configured APN:

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --get-profile-settings 3gpp,1
{
        "apn": "internet",
        "pdp-type": "ipv4v6",
        "username": "",
        "password": "",
        "auth": "none",
        "no-roaming": false,
        "apn-disabled": false
}

Change the APN and/or IP type (an alternative method to using AT commands mentioned above):

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --set-device-operating-mode low_power
root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --modify-profile 3gpp,1 --apn internet --pdp-type=ipv4 --username="" --password="" --auth=none
root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --set-device-operating-mode online

where “internet” is the APN of your provider

Check network registration and signal strength:

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --get-serving-system
{
        "registration": "registered",
        "plmn_mcc": 123,
        "plmn_mnc": 45,
        "plmn_description": "OperatorName",
        "roaming": false
}

and

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --get-signal-info
{
        "type": "lte",
        "rssi": -71,
        "rsrq": -9,
        "rsrp": -94,
        "snr": 70
}

Check the connection status:

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --get-data-status
"disconnected"

To manually start the Internet connection issue a command:

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --start-network internet --autoconnect

where “internet” is the APN of your provider

:!: Some providers will accept almost any APN, in this case using “internet” is fine.

Check the status:

root@OpenWrt:~# uqmi -d /dev/cdc-wdm0 --get-data-status
"connected"

--autoconnect key says that you want always be connected, once the modem is physically connected to the router and cellular network is in range. :!: It will be kept after reboot.

In case you need additional authentication, please look at the possible arguments for uqmi utility:

  --start-network <apn>:            Start network connection (use with options below)
    --auth-type pap|chap|both|none: Use network authentication type
    --username <name>:              Use network username
    --password <password>:          Use network password
    --autoconnect:                  Enable automatic connect/reconnect
  --stop-network <pdh>:             Stop network connection (use with option below)
    --autoconnect:                  Disable automatic connect/reconnect

To check your balance or send any other AT commands, you need to have USB serial device like: /dev/ttyUSB0

If you have it (if not then install missing USB serial drivers), you can run in first terminal:

cat /dev/ttyUSB0

and in the second (*101# is my USSD code):

echo -ne 'AT+CUSD=1,"*101#",15\r\n' > /dev/ttyUSB0

You should see in first terminal USSD response.

WAN status is available in Dashboard and System→Overview in LuCI web interface. ModemManager is a managed QMI/MBIM interface that has a page showing signal strength and other values. There are also external packages like https://github.com/4IceG/luci-app-modemdata or https://github.com/4IceG/luci-app-3ginfo-lite for displaying modem status and https://github.com/4IceG/luci-app-sms-tool-js for SMS support.

Stability issues with the connection

Read-on, but also see the Optimization section, below.

Everything is okay but modem doesn't establish connection. What can I try?

You may want to try adding the argument --get-client-id wds and --set-client-id when running uqmi like:

wds=`uqmi -s -d /dev/cdc-wdm0 --get-client-id wds`
uqmi -d /dev/cdc-wdm0 --set-client-id wds,"$wds" --start-network your_apn

Moreover based on this article I discovered that need to reset my modem (tested on Dell Wireless 5804 413c:819b) in boot process, so you can try add the following commands in your /etc/rc.local:

/sbin/uqmi -d /dev/cdc-wdm0 --set-device-operating-mode offline
/sbin/uqmi -d /dev/cdc-wdm0 --set-device-operating-mode reset
/bin/sleep 20
/sbin/uqmi -d /dev/cdc-wdm0 --set-device-operating-mode online
/sbin/uqmi -d /dev/cdc-wdm0 --set-autoconnect enabled
/sbin/uqmi -d /dev/cdc-wdm0 --network-register

My router is not detecting the modem. What should I do?

Try the following commands:

usbmode -l

It should respond with a message about your USB device is detected. If it does, issue the next command. If it doesn't, you might want to get help from the forum.

usbmode -s

Then wait for the modem to get issued an IP from your ISP.

No serial or network device is present (/dev/ttyUSB, /dev/cdc-wdm)

You may need to install the missing packages

opkg install kmod-usb-net-qmi-wwan kmod-usb-serial-option kmod-usb-serial-qualcomm

As explained elsewhere, your modem might suffer regular or irregular disconnections. First, see the Optimization guide below.

Irregular disconnections might be caused by incorrect MSS/MTU settings, or the software and hardware of the modem, whose symptoms are generally loss of connectivity minutes after rebooting the router, very high latency and high packet loss on heavy load, modem software hanging and becoming irresponsive on certain events or during transmission of specific data. For these kind of situations, a firmware upgrade, watchdog script or watchcat package is recommended. See :docs:guide-user:network:wan:wwan:ltedongle#sample_cell_modem_wan_watchdog_script_basic_simple or watchcat

Regular disconnections (at specific times of the day, or after an exact number of hours) are generally when the mobile provider is force-issuing them. These should be normally handled transparently by the modem, but this may not the case that the modem handles it correctly. For this, you might want to perform a regular reboot of the only the modem, to keep it working. However, [as a contributor who has read ALL of Quectel's 300+ pages of modem documentation, and has had several of them, talked with others who have managed over 1000 quectel devices, and has been using them for years successfully with Openwrt] for another perspective, it may simply be an issue with your configuration. Chronically-bad stability issues, of the type mentioned, went away with use of pure QMI, and no MTU value assignment or APN assignment, besides selecting the correct SIM profile. [End comment]

If you find there is a specific period needed for restarting only the modem device, and you want to do it based on time instead of status of the connection, here is a sample script: For example, to perform a modem reboot every 24 hours (during the night) you can add this line to the cron:

0 3 * * *  echo -n -e 'AT+CFUN=1,1\r\n' > /dev/ttyUSB3

The modem will reboot, OpenWrt will detect the USB and CDC interfaces disappearing and reappearing again, and restart the WAN interface, effectively requesting a new connection to the network and acquiring a new IP.

While those above commands will do the described action, it's generally better to fix the stability issues, and probe the connection periodically with the advanced connectivity script, allowing it to log and take action as necessary.

The modem responds not_initialized during the QMI start-up process, producing a PIN_STATUS_FAILED error on the QMI Interface. But there is no PIN required (and pin1 value is blank). A workaround is editing the '/lib/netifd/proto/qmi.sh' script, at line 158, adding/editing the response 'not_initialized' instead of 'disabled'.

There are known issues with the most common modem chipset found in routers that have internal Quectel-brand modems. If you find that doing anything other than using the plain (and default) QMI-support libraries, and only selecting the Profile number (which pulls the APN and other details from the SIM), such as specifically setting the MTU causes stability or crashes, or when using the MBIM protocol or ModemManager, which in turn, set the MTU, and causes the same crashing hard-lock of the chip - but still need to set the MTU for optimal performance, read-on:

  • Use plain QMI protocol, and do not set the MTU at the Device Interface level
  • To work-around the inability to set the Device Interface MTU directly, edit your /etc/config/firewall to include:
    config include
    	option path '/etc/firewall.user'
    	option fw4_compatible '1'
  • In /etc/firewall.user, put:
    # Dealing with the MSS and MTU without adjusting the Device Interface MTU
    # For the outbound packets:
    nft add rule inet fw4 mangle_postrouting 'oifname "wwan0" tcp flags & (fin | syn | rst) == syn tcp option maxseg size set 1400'
    # For incoming / returning packets:
    nft add rule inet fw4 mangle_forward 'iifname "wwan0" tcp flags & (fin | syn | rst) == syn tcp option maxseg size set 1400'

This command sets the MSS maximum segment size to a factor of a fixed value of 1400, not the default interface MTU which is 1500. tracepath <destination>, without this firewall instruction, can help you determine an MTU suitable for you, although 1400 is almost certainly small enough to work on your cell network link.

The standard MSS Clamping option in Luci Web Firewall interface, is meant to calculate MSS from Device Interface MTU, and so does not have a field for setting a specific MTU value. Therefore, it's suggested to uncheck it, or remark-out or remove the mtu_fix '1' option for the WAN Zone in your /etc/config/firewall config.

  • If you have provider tethering-related issues: in /etc/firewall.user add
# For the outbound packets:
nft add rule inet fw4 mangle_postrouting oifname wwan0 ip ttl set 66
nft add rule inet fw4 mangle_postrouting oifname wwan0 ip6 hoplimit set 66
# And as it's bi-directional, for the returning / inbound packets:
nft add rule inet fw4 mangle_forward iifname wwan0 ip ttl set 66
nft add rule inet fw4 mangle_forward iifname wwan0 ip6 hoplimit set 66

Note: 66 is the value given here, although your particular cellular service provider may require a different value. Usually other users have already reported successful values online, and you can do an internet search to find it.

  • Quectel modems in general have an earned reputation for having firmware stability issues and design flaws. However, if you figure out how to work around them, they work quite well. If you run into frustrating issues specifically with regards to the cell connection/modem, it is not likely to be Openwrt. The modem runs its own closed-source firmware, like a router within a router. What it means is that, depending on how the mobile provider do it's IP assignment and handles connectivity, you might suffer disconnections after some time (generally a fixed number of hours like 2, 6, 24, 48 hours). For the moment, OpenWrt does not have a built-in routine to handle these modem issues, so you might want to set a periodic reboot of the modem itself, or add a watchdog script to restart the WAN / wwan0 / qmippp interface, or if needed, reboot the router.

Here is a wan_watchdog.sh script that tests the connection, and if it receives no response from several well-known DNS providers, it can:

  1. Tell the modem to soft-off.
  2. Tell the modem to soft-on (boot up).
  3. Restart the interface, and
  4. Reboot the router (if everything prior was unsuccessful).
sleep 45 # you may have to lengthen or shorten this 45 second-delay, depending on how much time it takes for the wwan0 (cell connection modem) to link to the cell provider (radio tower) and establish an uplink (internet connection).
service sysntpd restart # Overcomes a NTP time issue (wrong time) issue after boot, due to lag time in the 4G connection coming up.
/root/wan-watchdog.sh & # The ampersand is important! Reboots will not work without it.
exit 0
  • Save the following as 'wan-watchdog.sh' in your /root/. Make it executable (chmod +x wan-watchdog.sh)
#!/bin/sh
 
#wan-watchdog.sh v.20250326

check_fping() {
    # Run the fping command
    fping --alive --interval=400 --count=5 --fast-reachable=1 --addr 1.1.1.1 9.9.9.8 8.8.8.8 2001:4860:4860::8888 2620:fe::fe
}

#call from rc.local with /root/wan_watchdog.sh &
#bootscript startup. wait 360 seconds after restart before checking connection.
echo "Sleeping x seconds (60-180 typically). Initial startup after boot"
sleep 200
echo "Script started. Router booted on $(date)"
echo "Script startup, router booted on $(date)" >> /root/wan_reset_log.txt
#ping x times to see if common DNS servers are accessible.
#if at least one of them is responsive, pause 60 seconds, and try again.

echo "Entering ping-testing loop:"
CONNECTION="1"
while [[ $CONNECTION -gt 0 ]]; do
	echo "Value of CONNECTION so-far is:" $CONNECTION
	echo "Pinging a variety of well-known ipv4 and ipv6 addresses..."
	# ONE site success is enough. All of them failing, will cause corrective actions.
	if check_fping ; then
			echo "Successful response. Waiting 60 seconds and trying again."
			CONNECTION="1"
			sleep 60
		else
			echo "All Fpings failed." 
			echo "All Fpings failed. Attempting to restart wwan interface on $(date)" >> /root/wan_reset_log.txt
			echo "Turning off the qmippp wwan interface in 5 seconds.."
			sleep 5
			echo "ifdown qmippp"
			ifdown qmippp
			echo "Wait 5 seconds then bringing up the qmippp interface.."
			sleep 5
			echo "ifup qmippp"
			ifup qmippp
			echo "Wait 45 seconds to give the modem time to reconnect..."
			sleep 45 # give the modem time to reconnect (takes 25 seconds for a typical QMI Quectel config, longer with VPN added)
			if check_fping ; then
				echo "SUCCESS: Quectel modem wwan restart worked, no need for reboot" >> /root/wan_reset_log.txt
				echo "SUCCESS: Quectel modem wwan restart worked, no need for reboot"
				CONNECTION="1"
			else
				echo "FAILURE: reboot required. Rebooting router..." >> /root/wan_reset_log.txt
				echo "FAILURE: reboot required. Rebooting..."
				sleep 5
				CONNECTION="0"
			fi
		fi
done
reboot

If you need to edit this script, while your router is running, first stop it by doing a ps | grep wan, and you'll see the process ID. Then do a kill (id), then nano wan-watchdog.sh. When finished, do a /root/wan-watchdog.sh & and the script will execute in the background (you can close the shell/ssh session).

Setting the time & date (NTPd)

The sleep delay timer, and then the NTP service restart, in the /etc/rc.local script above, corrects a common issue issue on Openwrt routers with internal cellular modem chips, where since most router-boards do not have a battery-backup for their clock, to maintain correct time & date between reboots, they have to pull the time from the internet (upstream), every time they power-up. Ordinarily, the WAN on a cell-modem router takes 30-45 seconds to connect, and time-retrieval services (NTPd) start before an upstream provider (internet) connection is established. Openwrt devices with built-in modems, can thus have the wrong time, initially. If you do not need the delay and ntpd restart, it does not negatively affect your router. The Openwrt device will eventually get the correct time, however, without this command, the initial boot time, e.g. for logging messages (the wan-watchdog.sh script) would be incorrect, leading to startup times and dates in the log that are not correct, hindering trouble-shooting.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2025/11/27 14:40
  • by s2s2