fix(ansible): resolve LTE failover data-plane bug on BroadMobi BM806C
ci/woodpecker/push/flux-reconcile-source Pipeline was successful
ci/woodpecker/cron/renovate Pipeline was successful

The embedded BroadMobi BM806C modem (Qualcomm MDM9225, firmware
M1.2.0_E1.0.1_A1.1.8) in the D-Link DWR-921 C1 has two independent
firmware bugs that together break the QMI data plane:

1.  Modem accepts 802.3 framing but its 802.3 path is buggy — downlink
    frames never reach the host kernel. raw-ip framing works.

2.  qmish calls uqmi --start-network --apn <foo>, which triggers
    FS#1363: the modem establishes a phantom bearer that gets IP
    addresses but has no working data path. Using --start-network
    --profile <N> (referencing a pre-configured NVRAM profile with
    the same APN) works correctly.

Fixes applied:

- qmish patches (3x community.openwrt.lineinfile):
  * Replace --set-data-format 802.3 with raw-ip
  * Replace --wda-set-data-format 802.3 with raw-ip
  * Bracket raw_ip sysfs write with ip link down/up (kernel rejects
    write with -EBUSY when wwan0 is already up)
- Modem NVRAM: create/modify profile 2 (internetipv6, ipv6) for the
  IPv6 APN — profile 1 is already managed by qmish's --modify-profile
- UCI wwan: add profile=1 and v6profile=2 so qmish uses --start-network
  --profile instead of --apn on both the v4 and v6 legs
- Firewall: add wwan zone (input REJECT, output ACCEPT, forward REJECT)
  and Allow-ICMPv6-wwan rule
- main.yml: reorder — packages (including usb-modeswitch) now run
  before wwan setup, so the modem is out of EDL mode when wwan.yml
  queries it for profile creation

See docs/wwan-bm806c-qmi-workaround.md for the full diagnosis
(what we ruled out, how we confirmed, manual setup steps, component
versions, future upstreaming).
This commit is contained in:
2026-05-16 19:54:46 +02:00
parent 92447996fc
commit 2d69cc6569
6 changed files with 757 additions and 4 deletions
+34
View File
@@ -14,6 +14,8 @@
# lan — bridge (br-lan) on eth0.2, LAN clients via LAN ports
# iot — bridge (br-iot) on eth0.5, IoT clients via wifi only
# uplink — static 192.168.6.2/24 + 2001:470:61a3:600::2/64 on eth0.6, internet access for opkg
# wwan — QMI LTE modem (/dev/cdc-wdm0), Orange PL dual-stack failover (APNs: internet + internetipv6)
# Manual ifup only (option auto '0'); modem-specific quirks handled in wwan.yml.
- name: Configure network
community.openwrt.uci:
@@ -126,6 +128,38 @@
option device 'br-iot'
option proto 'none'
# LTE failover via embedded BroadMobi BM806C (Qualcomm MDM9225, fw M1.2.0_E1.0.1_A1.1.8).
# This modem has a firmware bug: when QMI --start-network is invoked with --apn
# (a WDS TLV), the modem establishes a phantom bearer that gets assigned IP
# addresses but cannot pass downlink data — TX packets egress, zero replies arrive.
# See https://forum.openwrt.org/t/problem-with-bm806u-e1-dwr-921-c3/130094 and
# https://github.com/openwrt/openwrt/issues/6295 (FS#1363). Workaround: configure
# the APN via NVRAM profile (uqmi --modify-profile, done by qmi.sh) and reference
# the profile via --start-network --profile, NOT --apn. qmi.sh already supports
# passing --profile when UCI option 'profile' is set — and 'apn' is kept because
# qmi.sh's --modify-profile call (line 314) still needs it to write the profile.
# qmi.sh only writes profile 1; profile 2 (used for the IPv6 v6apn) is created by
# the wwan role task.
#
# The BM806C also requires raw-ip framing (kernel qmi_wwan driver mode) to
# work properly. qmi.sh defaults to 802.3 mode; a patch in the wwan role task
# changes this to raw-ip for our setup.
config interface 'wwan'
option device '/dev/cdc-wdm0'
option proto 'qmi'
option apn 'internet'
option v6apn 'internetipv6'
option profile '1'
option v6profile '2'
option auth 'pap'
option username 'internet'
option password 'internet'
option pdptype 'ipv4v6'
option dhcp '0'
option dhcpv6 '0'
option metric '100'
option auto '0'
config interface 'uplink'
option device 'eth0.6'
option proto 'static'