Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sierra em7565 LTE Modem Linux Guide
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/wwan up
[Install]
# replace this with your modems persistent device name!
WantedBy=sys-subsystem-net-devices-wwp0s20f0u6i8.device
#!/bin/bash
# This script is used to configure a Sierra EM7565 on Linux. This modem uses raw-ip only
# so you can't just use normal DHCP. You have to get the IP information from the modem and
# manually set the linux-side network interface to match. You also have to set the IP mode
# to "raw" every time the interface appears (on boot and after suspend/resume).
#
# You may need to configure udev rules to put your modem in the right mode for the ttyUSB devices
# to show up. On Arch this is accomplished by installing the `usb_modeswitch` package.
#
# Assumptions:
# - you're using systemd-networkd
#
# - you have the following modules loaded (/etc/modules-load.d):
# qmi_wwan
# pcserial
#
# - you've gotten the modem connect successfully at least once, using something like the following:
# qmicli -d /dev/cdc-wdm1 --device-open-"net=net-raw-ip|net-no-qos-header" --wds-start-network=fast.t-mobile.com --client-no-release-cid
#
# - you've configured an autoconnect profile, so you don't have to start the modem manually each time:
# qmicli -d /dev/cdc-wdm1 --wds-create-profile=3gpp,name=t-mobile,apn=fast.tmobile.com,pdp-type=IPV4V6
# qmicli -d /dev/cdc-wdm1 --wds-set-autoconnect-settings=enabled
#
# - you've properly configured the modem using the following AT commands. Note that MBIM does NOT seem to work
# (tested on Arch Linux, kernel 4.20) with this card, so I disable it via USBCOMP setting below. QMI FTW. Also,
# for thinkpads you have to disable USB fast enumeration on boot to allow the card to bypass the bios whitelist.
# This is done with the AT!CUSTOM command below. See https://github.com/danielewood/sierra-wireless-modems for more.
#
# Enter these commands by accessing the modem's serial console (screen /dev/ttyUSB2). Note that you have to
# `ip link set down $interface` on your modem first or it will lag out like crazy:
#
# ATE1
# AT!ENTERCND="A710"
# AT!IMPREF="GENERIC"
# AT!USBCOMP=1,3,0000050D
# AT!SELRAT=06
# AT!BAND=00
# AT!BAND=09
# AT!CUSTOM="FASTENUMEN",2
# AT!RESET
#
# - Once you've put this script somewhere, create and enable a systemd unit file like the following, so it
# will get executed every time the modem's network device is brought up:
# $ cat /etc/systemd/system/wwan-config.service ~
# [Service]
# Type=oneshot
# ExecStart=/usr/local/sbin/wwan up
#
# [Install]
# # replace this with your modems persistent device name!
# WantedBy=sys-subsystem-net-devices-wwp0s20f0u6i8.device
#
# This took me multiple sleepless nights to figure out. You're welcome.
DEV=/dev/cdc-wdm1
ROUTE_METRIC=30
IFACE=$(qmicli -d $DEV -w)
die() {
echo "$@" 1>&2
exit 1
}
mask2cdr () {
# Assumes there's no "255." after a non-255 byte in the mask
local x=${1##*255.}
set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
x=${1%%$3*}
echo $(( $2 + (${#x}/4) ))
}
ifdown() {
cat > /etc/systemd/network/30-wwan.network << EOF
[Match]
Name=$IFACE
[Link]
Unmanaged=true
EOF
systemctl restart systemd-networkd
ip link set "$IFACE" down
}
ifup() {
ifdown
eval $(qmicli -d "$DEV" --wds-get-current-settings \
| tail -n+2 \
| tr '[:lower:]' '[:upper:]' \
| sed -e 's/: /=/;s/^\s*//;s/ /_/g')
IPV4_CIDR=$IPV4_ADDRESS/$(mask2cdr $IPV4_SUBNET_MASK)
cat > /etc/systemd/network/30-wwan.network << EOF
[Match]
Name=$IFACE
[Link]
MTUBytes=$MTU
Multicast=true
ARP=false
[Network]
Address=$IPV4_CIDR
DNS=$IPV4_PRIMARY_DNS
DNS=$IPV4_SECONDARY_DNS
[Route]
Gateway=$IPV4_GATEWAY_ADDRESS
Metric=$ROUTE_METRIC
EOF
echo Y > "/sys/class/net/$IFACE/qmi/raw_ip"
systemctl restart systemd-networkd
}
status() {
qmicli -d "$DEV" --wds-get-current-settings ~
qmicli -d "$DEV" --wds-get-packet-service-status
qmicli -d "$DEV" --wds-get-packet-statistics
qmicli -d "$DEV" --nas-get-signal-info
qmicli -d "$DEV" --nas-get-serving-system
}
case $1 in
up) ifup ;;
down) ifdown ;;
status) status ;;
*) die "usage: $1 up|down|status" ;;
esac
@charlesbdudley

This comment has been minimized.

Copy link

@charlesbdudley charlesbdudley commented May 24, 2019

This was so helpful, thank you! One thing that tripped me up is I believe line 16 should be qcserial not pcserial. Quick question, I've successfully obtained an ip address and a connected state however I can't seem to ping out via wwan0 (no connectivity at all). Did you happen to run into that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment