
Lenovo поставляет свои ноутбуки P16 gen 2 (сертифицированные для Ubuntu linux) со следующей картой wwan: Intel MBIM [8086:7560]. Менеджер модема видит модем wwan, но не может его включить (сообщение об ошибке: ** (modem-manager-gui:9178): ПРЕДУПРЕЖДЕНИЕ **: 10:33:30.084: Менеджер модема >= 0.7.0: GDBus.Error:org.freedesktop.ModemManager1.Error.Core.Retry: Недопустимый переход
Согласно инструкциям Lenovo (руководство пользователя ThinkPad P16 Gen 2 Linux): следует «Перейти кhttps://support.lenovo.comи выберите запись для вашего компьютера. Загрузите пакет wwan-linux-fcc-unlock со страницы поддержки продукта. Обязательно проверьте README, чтобы подтвердить, применяются ли какие-либо ограничения для вашего региона, и получить инструкции по установке приложения.)
Однако, к сожалению, на сайтах lenovo такого файла нет. И нет никаких комментариев от Lenovo по поводу этой неспособности предоставить файл разблокировки fcc.
Эта ссылка также, похоже, пуста:https://www.lenovo.com/linux/wwan-enablement-on-Linux.pdf
Если кто-нибудь не знает, где можно найти файл fcc ulock для вышеупомянутой карты wwan, модем wwan серии P16 не может использоваться в ubuntu или linux, если на то пошло. Есть ли какая-нибудь информация об этом?
заранее спасибо
решение1
Для разблокировки 8086:7560 мне удалось успешно выполнить разблокировку на ThinkPad X1 Yoga Gen 7 с помощью скрипта, который находится здесь:https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/751.
Вы можете сохранить скрипт как /etc/ModemManager/fcc-unlock.d/8086:7560
и убедиться, что он исполняемый ( chmod +x
). Вам также нужно будет изменить shebang заголовка с python
на python3
.
Потребуются некоторые обходные пути, особенно если вы используете режим ожидания/гибернации, поскольку сам модем довольно привередлив.
Одной из основных проблем является то, что как только модем отключается от шины PCI, его нельзя будет включить снова, и его нужно будет включить снова. Это влияет на сам модем и шину, к которой он подключен.
Вам понадобится следующее правило udev:
/etc/udev/rules.d/99-modem-suspend.rules
# The modem fails to wake up ever again after suspend
SUBSYSTEM=="pci", ATTR{vendor}=="0x1cf8", ATTR{device}=="0x8653", ATTR{power/control}="on", GOTO="pci_pm_end"
SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", ATTR{device}=="0x7560", ATTR{power/control}="on", GOTO="pci_pm_end"
SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", ATTR{device}=="0x51b8", ATTR{power/control}="on", GOTO="pci_pm_end"
# Use normal sleeping otherwise
SUBSYSTEM=="pci", ATTR{power/control}="auto"
LABEL="pci_pm_end"
Затем вам понадобится скрипт, который запускается при загрузке, чтобы задать некоторые начальные свойства энергосбережения устройства, чтобы модем или Linux не приостанавливали работу устройства, а всегда поддерживали его включенным.
/opt/keep-modem-awake.sh
#!/bin/sh
# Enable wakeups
## Bus the modem is on
if grep 'pci:0000:00:1c.0' < /proc/acpi/wakeup | grep disabled
then
echo "Enabling wakeup for bus owning Modem..." > /dev/kmsg
echo RP01 > /proc/acpi/wakeup
fi
## Modem
if grep 'pci:0000:08:00.0' < /proc/acpi/wakeup | grep disabled
then
echo "Enabling wakeup for modem..." > /dev/kmsg
echo PXSX > /proc/acpi/wakeup
fi
# Disable d3cold for the modem
# It is behind the bridge: 00:1c.0 PCI bridge: Intel Corporation Device 51b8 (rev 01)
# https://patchwork.kernel.org/project/linux-pci/patch/[email protected]/
echo "Disabling modem d3cold..." > /dev/kmsg
## The actual modem
echo 0 > /sys/bus/pci/devices/0000:08:00.0/d3cold_allowed
## The owning buses
echo 0 > /sys/devices/pci0000:00/0000:00:1c.0/d3cold_allowed
echo 0 > /sys/bus/acpi/devices/PNP0A08:00/device:4f/physical_node/d3cold_allowed
echo 0 > /sys/bus/acpi/devices/PNP0A08:00/device:4f/device:50/physical_node/d3cold_allowed
# Use ACPI to reset the PCI and not just power off and power on the device
echo "Setting modem reset method to ACPI..." > /dev/kmsg
echo acpi > /sys/bus/pci/devices/0000:08:00.0/reset_method
ПРИМЕЧАНИЕ: в вашей системе могут быть разные пути к устройствам. Например, на Lenovo ThinkPad Z16 Gen 1 модем — это 0000:05:00.0
, владеющая шина — 0000:00:01.3
и устройства ACPI PNP0A08:00/device:07/device:08
. Чтобы правильно определить, какие идентификаторы использовать, вы можете сделать следующее:
- Определите свой модем с помощью
lspci
команды. Например:
❯ lspci | grep Modem
05:00.0 Wireless controller [0d40]: Intel Corporation XMM7560 LTE Advanced Pro Modem (rev 01)
Это дает нам путь к устройству/sys/bus/pci/devices/0000:05:00.0
- Определите владельца автобуса:
❯ ls -l /sys/bus/pci/devices/0000:05:00.0
lrwxrwxrwx. 1 root root 0 Apr 14 10:24 /sys/bus/pci/devices/0000:05:00.0 -> ../../../devices/pci0000:00/0000:00:01.3/0000:05:00.0
Дает нам право собственности на автобусный маршрут/sys/bus/pci/devices/0000:00:01.3
- Определите автобусы, принадлежащие ACPI:
❯ find /sys/bus/acpi/devices/PNP0A08:00/ -type l -exec ls -l {} + | grep '05:00.0'
lrwxrwxrwx. 1 root root 0 Apr 14 14:25 /sys/bus/acpi/devices/PNP0A08:00/device:07/device:08/physical_node -> ../../../../../pci0000:00/0000:00:01.3/0000:05:00.0
Дает нам пути /sys/bus/acpi/devices/PNP0A08:00/device:07
и/sys/bus/acpi/devices/PNP0A08:00/device:07/device:08
Затем для запуска скрипта при загрузке:
/etc/systemd/system/keep-modem-awake.service
[Unit]
Description="Keep modem awake for suspend."
After=ModemManager.service NetworkManager.service
Wants=ModemManager.service NetworkManager.service
[Service]
ExecStart=/opt/keep-modem-awake.sh
[Install]
WantedBy=multi-user.target
Для последующих сценариев вам понадобится сценарий, который сможет найти модем, поскольку при приостановке и возобновлении работы системы идентификатор модема каждый раз будет меняться.
/opt/find-modem.sh
#!/bin/sh
# Make sure path is set
export PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
for __i in $(seq 1 10)
do
__modem="$(/opt/find-modem-sub.sh | head -n 1)"
if [ -z "$__modem" ]
then
sleep 0.5
else
break
fi
done
if [ -z "$__modem" ]
then
exit 1
fi
echo "$__modem"
exit 0
/opt/find-modem-sub.sh
#!/bin/sh
# Make sure path is set
export PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Read in commands
mmcli -L | grep '\/Modem\/' | while read __line
do
echo "$__line" | sed 's/^.*\/Modem\/\([0-9]\{1,\}\).*$/\1/'
exit 0
done
exit 1
Затем, если вы планируете использовать режимы приостановки и гибернации, вам придется соответствующим образом настроить скрипты, чтобы они запускались до и после этого:
/opt/suspend-modem.sh
#!/bin/sh
# Make sure path is correct
export PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Get modem ID
__modem="$(/opt/find-modem.sh)"
if [ "$1" = "0" ]
then
echo "Telling NM to not use the modem..." > /dev/kmsg
nmcli c down NetworkName
# Make sure the connection is deactivated
echo "Waiting for NM to show disconnected..." > /dev/kmsg
while nmcli con show --active | grep NetworkName
do
sleep 0.5
done
# Deactivate the modem before suspend as the connection freezes and never comes back
echo "Disabling modem..." > /dev/kmsg
mmcli -m "$__modem" --disable
elif [ "$1" = "1" ]
then
echo "Disabling modem after resume..." > /dev/kmsg
mmcli -m "$__modem" --disable
echo "Entering low power mode after disable..." > /dev/kmsg
mmcli -m "$__modem" --set-power-state-low
echo "Performing enabling loops..." > /dev/kmsg
for __i in $(seq 1 5)
do
echo "Loop $__i..." > /dev/kmsg
echo "Turning on modem and enabling..." 1>&2
mmcli -m "$__modem" --set-power-state-on
if mmcli -m "$__modem" --enable
then
echo "Modem was enabled..." > /dev/kmsg
break
else
echo "Did not enable modem..." > /dev/kmsg
sleep 0.5
fi
done
echo "Telling NM to use the modem now..." > /dev/kmsg
nmcli c up NetworkName
fi
Затем соответственно следующая systemd, на этот раз для резюме:
rfkill-modem-resume.service
[Unit]
Description=Enable modem after wake-up
After=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
[Service]
Type=simple
ExecStart=/opt/suspend-modem.sh 1
[Install]
WantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
А это для приостановки:
rfkill-modem-suspend.service
[Unit]
Description=rfkill modem before sleep
Before=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
[Service]
Type=simple
ExecStart=/opt/suspend-modem.sh 0
[Install]
WantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
С помощью этих скриптов и других средств мне удалось сохранить работоспособность модема после многократных переходов в режим ожидания и гибернации.
В качестве дополнения вы также можете настроить соединение NetworkManager так, чтобы приоритет DNS и маршрута был ниже (более высокие значения), чем у вашего основного соединения, чтобы оно использовалось в качестве резервного.
решение2
Также естьожидающий запрос на слияниес помощью скрипта разблокировки на основе bash.
я сделалмодифицированная версиякоторый также отправляет AT+XDNS=0,1
команду, потому что без него соединение постоянно обрывается.