钢镚儿的开发日志
耐得住寂寞 方能一鸣惊人

ThinkPad 在 Linux 睡眠唤醒后 LTE 网卡消失:一次 Quectel EM05-CE 排障记录

2026年09月24日
开发
,

最近遇到一个颇有迷惑性的问题:笔记本正常启动后,内置 4G LTE 网卡可以连接网络;但从睡眠状态唤醒后,桌面中的“移动网络”入口直接消失。重启 ModemManager 也无法恢复,只有重启电脑才会重新出现。

表面上看像是 LTE 网卡掉电或硬件失联,实际排查下来,设备并没有真正消失。问题发生在 USB MBIM 设备恢复之后,ModemManager 没能重新建立正确的控制端口。

本文记录完整的定位过程,以及最终采用的自动恢复方案。

环境

  • ThinkPad,Intel Tiger Lake 平台
  • Ubuntu 26.04.1 LTS
  • Linux 7.0.0-34-generic
  • Quectel EM05-CE LTE 模组
  • USB ID:2c7c:0127
  • ModemManager 1.25.95
  • NetworkManager 1.54.3
  • 睡眠模式:S3 deep sleep

不同发行版和模组也可能出现相似问题,但文中的设备 ID 和恢复脚本需要根据实际硬件调整。

第一步:确认设备类型

先查看 PCI 和 USB 设备:

1
2
lspci -nnk
lsusb

LTE 模组没有出现在 PCI 设备中,而是作为内部 USB 设备连接。启动日志中可以看到:

1
2
3
usb 3-2: New USB device found, idVendor=2c7c, idProduct=0127
usb 3-2: Product: Quectel EM05-CE
usb 3-2: Manufacturer: Quectel

随后,内核的 cdc_mbim 驱动创建控制和网络接口:

1
2
3
cdc_mbim 3-2:1.1: cdc-wdm0: USB WDM device
cdc_mbim 3-2:1.1 wwan0: register 'cdc_mbim'
cdc_mbim 3-2:1.1 wwp0s20f0u2i1: renamed from wwan0

这说明该模组工作在 MBIM 模式。正常情况下:

  • /dev/cdc-wdm0 是 MBIM 控制端口;
  • wwp0s20f0u2i1 是数据网络接口;
  • ModemManager 管理蜂窝注册、SIM 卡和连接状态;
  • NetworkManager 在其上建立移动网络连接。

第二步:检查睡眠和唤醒日志

下面的命令可以集中查看本次启动中与睡眠、USB 和蜂窝网络有关的日志:

1
2
3
4
journalctl -b -k --no-pager | \
grep -Ei 'suspend|resume|usb|cdc_mbim|cdc-wdm|wwan|qmi|mbim|modem|error|fail'

journalctl -b -u ModemManager -u NetworkManager --no-pager

睡眠前,LTE 连接完全正常:

1
2
ModemManager: state changed (registered -> connecting)
ModemManager: state changed (connecting -> connected)

系统随后进入 S3:

1
2
PM: suspend entry (deep)
ACPI: PM: Preparing to enter system sleep state S3

唤醒时,内核确实重新设置了设备:

1
2
3
ACPI: PM: Waking up from system sleep state S3
usb 3-2: reset high-speed USB device number 2 using xhci_hcd
PM: suspend exit

这条记录很关键:USB 总线仍能看到 EM05-CE,说明它没有在硬件层面彻底消失。

真正的失败点

唤醒后,ModemManager 重新探测 cdc-wdm0,但最终失败:

1
2
3
4
5
6
[cdc-wdm0/probe] probe step: MBIM
[device .../usb3/3-2] creating modem with plugin 'quectel'
[plugin/quectel] could not grab port cdc-wdm0:
Cannot add port 'usbmisc/cdc-wdm0', unhandled port type
[base-manager] couldn't create modem:
Failed to find primary AT port

冷启动时,同一个仅暴露 MBIM 接口的模组可以被正确识别:

1
2
[modem0/cdc-wdm0/mbim] (shared-quectel) MBIM device is AT capable
[base-manager] modem ... successfully created

因此可以排除以下方向:

  • SIM 卡或运营商网络故障;
  • NetworkManager 连接配置丢失;
  • LTE 模组物理损坏;
  • 单纯的桌面 UI 显示问题。

更符合日志的解释是:EM05-CE 从 S3 恢复后,USB 设备虽然仍在,但 MBIM 控制端口处于不完整状态。ModemManager 在重新探测时发生端口识别竞态,未能再次确认 AT-over-MBIM 能力,最终没有创建 Modem 对象。桌面自然也就不再显示移动网络。

为什么重启 ModemManager 没用

首先尝试了最常见的恢复方式:

1
sudo systemctl restart ModemManager

但日志仍然是:

1
2
Cannot add port 'usbmisc/cdc-wdm0', unhandled port type
Failed to find primary AT port

原因是问题已经落在 USB/MBIM 设备状态上。重启用户态服务不会重新枚举 USB 设备,所以 ModemManager 得到的仍是同一个异常端口状态。

无需重启电脑的恢复方法

当前机器上,EM05-CE 位于 USB 路径 3-2。对这个设备执行一次解绑和重新绑定即可恢复:

1
2
3
sudo sh -c 'printf "%s" 3-2 > /sys/bus/usb/drivers/usb/unbind'
sleep 3
sudo sh -c 'printf "%s" 3-2 > /sys/bus/usb/drivers/usb/bind'

注意:3-2 是本次机器上的 USB 路径,不应直接照抄到其他电脑。可以通过下面的方式确认设备:

1
2
3
4
5
6
7
8
for device in /sys/bus/usb/devices/*; do
[ -f "$device/idVendor" ] || continue
[ -f "$device/idProduct" ] || continue
printf '%s %s:%s\n' \
"${device##*/}" \
"$(cat "$device/idVendor")" \
"$(cat "$device/idProduct")"
done

重新枚举之后,日志显示:

1
2
3
4
cdc_mbim 3-2:1.1: cdc-wdm0: USB WDM device
cdc_mbim 3-2:1.1 wwan0: register 'cdc_mbim'
ModemManager: modem ... successfully created
ModemManager: state changed (connecting -> connected)

这也最终验证了问题所在:只有让 USB 设备重新枚举,ModemManager 才能获得一个干净的 MBIM 控制端口。

每次唤醒后自动恢复

手动执行解绑和绑定并不方便,可以使用 systemd 的睡眠钩子自动完成。

创建 /usr/lib/systemd/system-sleep/quectel-em05-resume:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/sh

# Re-enumerate the Quectel EM05-CE after resume.

[ "$1" = "post" ] || exit 0
[ "$2" = "suspend" ] || exit 0

sleep 2

for device_path in /sys/bus/usb/devices/*; do
[ -f "$device_path/idVendor" ] || continue
[ -f "$device_path/idProduct" ] || continue
[ "$(cat "$device_path/idVendor")" = "2c7c" ] || continue
[ "$(cat "$device_path/idProduct")" = "0127" ] || continue

device_name=${device_path##*/}
logger -t quectel-em05-resume \
"resetting USB device $device_name after resume"

printf '%s' "$device_name" > /sys/bus/usb/drivers/usb/unbind
sleep 3
printf '%s' "$device_name" > /sys/bus/usb/drivers/usb/bind

logger -t quectel-em05-resume \
"USB device $device_name rebound successfully"
exit 0
done

logger -t quectel-em05-resume \
"Quectel EM05-CE (2c7c:0127) not found"
exit 0

赋予执行权限:

1
sudo chmod 0755 /usr/lib/systemd/system-sleep/quectel-em05-resume

这个脚本没有写死 3-2,而是根据 USB VID/PID 动态查找设备。即使某次启动后的总线编号发生变化,它仍能找到正确的模组。同时,它只重置 LTE 模组,不会重置整条 USB 控制器,因此不会连带影响摄像头、蓝牙或外接 USB 设备。

验证自动恢复

执行一次睡眠:

1
systemctl suspend

唤醒后等待约 5 至 10 秒,然后检查钩子日志:

1
journalctl -b -t quectel-em05-resume

正常情况下会看到:

1
2
resetting USB device 3-2 after resume
USB device 3-2 rebound successfully

还可以检查内核和 ModemManager:

1
2
3
ip link show
mmcli -L
journalctl -b -u ModemManager --since '-2 min'

如果看到 wwp... 网络接口,且 mmcli -L 列出了 Quectel Modem,说明恢复成功。

如何撤销

如果安装钩子后出现其他问题,删除它即可:

1
sudo rm /usr/lib/systemd/system-sleep/quectel-em05-resume

删除后不需要执行 daemon-reload,下一次睡眠时它就不会再运行。

总结

这次故障最容易误判成“LTE 网卡睡眠后掉电”。实际上,内核始终能够看到 USB 设备,真正失败的是恢复后的 MBIM 控制端口和 ModemManager 重新识别过程。

排查这类问题时,可以按以下层次逐级确认:

  1. lsusb 或 sysfs 中是否仍有设备;
  2. cdc_mbim 是否绑定、网络接口是否存在;
  3. /dev/cdc-wdm* 是否生成;
  4. ModemManager 是否成功创建 Modem 对象;
  5. NetworkManager 是否建立蜂窝连接。

当重启 ModemManager 无效,而 USB 设备仍在时,针对目标设备做一次解绑和重新绑定,往往比重启整机更快,也比重置整个 USB 控制器更安全。长期仍应关注内核、ModemManager 和设备固件更新;睡眠钩子属于针对当前恢复兼容性问题的实用规避方案。

如果喜欢这篇文章,可以给作者评个份哦~

转载本站文章请注明作者“钢镚儿”及原文出处。