Issue activating mobile internet modem on a Lenovo ThinkPad X1 Yoga (Gen 8)

Hey Alex,

Looking at your logs, the driver patch and FCC unlock are both working — your modem connects fine on boot. The issue is only after sleep/resume, where the MBIM session goes stale and ModemManager can’t recover.

The sleep hook that’s supposed to restart ModemManager after resume works on my machine, but from your logs it doesn’t seem to be firing on yours. I pushed an update that adds logging to the hook so we can narrow it down.

Can you pull the latest and reinstall?

cd mtk-t7xx-fix
git pull
bash reinstall.sh

After reboot, do a sleep/wake cycle, then run:

journalctl -b | grep modem-fix

and paste the output here. Also grab the driver side while you’re at it:

dmesg | grep t7xx

Also im still a little bit confused. Does your mobile connection work after a fresh reboot (before any sleep)?
Or is it only the powerstate? From the logs it looks like it does, but just want to confirm.

Kind regards
Flo

Hey Alex,

I need to give you a heads-up. I’m experiencing intermittent kernel panics on my own machine during boot — the system freezes completely, Caps Lock LED blinks, and only a hard reset helps. That’s a textbook kernel panic.

Since you’re running the same patched DKMS module from my repo, there’s a real chance this could affect you too. I suspect the patched mtk_t7xx driver is the cause — the symptoms point to the same PM timeout and NULL pointer dereference issues the fix was supposed to address, so it’s possible the patches aren’t fully correct or there’s a regression I missed.

I’m actively investigating this right now. In the meantime, if you experience any boot hangs or instability, you can remove the patched module to go back to the stock in-tree driver:

cd mtk-t7xx-fix
git pull
sudo bash uninstall.sh

That will restore the original kernel module. You’ll lose WWAN functionality, but your system will be stable.

I’m sorry about this — I recommended you install this fix and it might be causing more harm than good. I’ll update the thread once I’ve tracked down the root cause.

Kind regards
Flo

Hi Flo! Thank you for letting me know. I’m going to uninstall everything in a moment but I’ve removed the portion of the uninstall script that removes the FCC unlock because that was present on my device before I need it.
I’ve done some experimenting on my own (within my limited capabilities) and I’m starting to get the feeling that the problem is really limited to a bug in ModemManager.

Referring to your previous questions about the state of things before I ran your scripts:

  • When I reboot, the cellular connection work immediately,
    • no matter if it was disabled or active prior to rebooting.
  • When I sleep the machine and wake it up again, the cellular connection cannot be re-initialized until I
    • reboot the machine or
    • restart the ModemManager.

I’ve uninstalled your scripts and modified drivers. I left the FCC unlock in place, as noted. And things still work. For some strange reason the modem is even in the power state on, unlike before where it was only ever in low.

Hey Alex,

Quick update — I think I’ve fixed the kernel module (mtk_t7xx), but still testing. The boot crash issue seems resolved, now stress-testing it.

If your problem was mainly the modem dying after sleep/resume: I just found that the fix I had for that wasn’t actually working. The systemd sleep hook was spawning a background process to restart ModemManager, but systemd killed it before it could run (cgroup cleanup).

Save this as fix-sleep-hook.sh and run it with sudo bash fix-sleep-hook.sh:

#!/bin/bash
set -euo pipefail

SLEEP_HOOK="/usr/lib/systemd/system-sleep/99-modem-fix.sh"

cat > "$SLEEP_HOOK" << 'EOF'
#!/bin/bash
LOG_TAG="modem-fix"
logger -t "$LOG_TAG" "hook called: action=$1 target=${2:-unknown}"
case "$1" in
    post)
        logger -t "$LOG_TAG" "resume detected, restarting ModemManager in 2s"
        systemd-run --no-block --unit=modem-fix-resume \
            bash -c 'sleep 2; systemctl restart ModemManager; logger -t modem-fix "ModemManager restart exit code: $?"'
        ;;
esac
EOF
chmod 755 "$SLEEP_HOOK"
restorecon "$SLEEP_HOOK" 2>/dev/null || true

echo "Sleep hook installed. Test by suspending and checking:"
echo "  journalctl -b 0 -t modem-fix --no-pager"

After suspend/resume you can verify it worked with:

journalctl -b 0 -t modem-fix --no-pager

You should see “ModemManager restart exit code: 0” — that means MM actually restarted with a fresh MBIM session.
Could you try it out?
Kindly
Flo

Hey Alex,

Here’s an update on the fixes.

Sleep hook fix

The fix-sleep-hook.sh I posted above (post 25) uses systemd-run instead of a background subshell. The old version was silently killed by systemd’s cgroup cleanup before ModemManager could restart — that’s why it didn’t work for you.

On my machine it works reliably through 8 suspend/resume cycles so far. After resume you should see three log entries:

journalctl -b 0 -t modem-fix --no-pager
hook called: action=post target=suspend
resume detected, restarting ModemManager in 2s
ModemManager restart exit code: 0

If you’re still having the modem-dies-after-sleep issue, it might help. The reinstall.sh in the repo now includes this corrected version.

Kernel crash fix

I ran a stress test suite (now included in the repo as stresstest.sh). Results on my machine:

  • 43 tests passed, 0 failures
  • 16x fastboot_switching triggers (the exact crash trigger from the Fibocom services) — 0 kernel panics
  • 8x suspend/resume cycles — modem recovered every time
  • 3x ModemManager restart cycles
  • 3x full disconnect/reconnect cycles
  • Mixed stress combos (fastboot + suspend + MM restart)
  • No kernel taint changes throughout

The three driver fixes are:

  1. PM timeout non-fatal — the PCIe power management register sometimes never becomes ready; the patched driver warns and continues instead of aborting
  2. NULL pointer double-uninitport->thread is now set to NULL after kthread_stop(), preventing crash on second call
  3. kthread_run failureport->thread is cleared on kthread_run() failure so port_ctl_uninit() doesn’t try to stop a non-existent thread

Your situation

Interesting that it works for you without the patched driver and the power state is now on instead of low. A few thoughts:

  • The power state: on vs low difference is the FCC unlock — when it succeeds, power goes to on. Since you kept the FCC unlock script in place, that’s working correctly.
  • The kernel crash (blinking Caps Lock bootloop) I warned about in post 22 is caused by Lenovo’s fibo_helper service writing fastboot_switching to the driver. You don’t have those services installed (you confirmed in post 6), so you were never at risk of that particular crash.
  • If your modem works reliably after boot and you only need the sleep fix, you could just install the sleep hook standalone (the fix-sleep-hook.sh from post 25) without the full DKMS module.

Repo status

The repo now includes:

  • reinstall.sh — full install (DKMS module + FCC unlock + sleep hook + MM dropin)
  • uninstall.sh — clean removal of everything (improved, with confirmation prompts)
  • verify.sh — comprehensive system check (module source, FCC unlock, sleep hook version, services, iommu)
  • stresstest.sh — full stress test suite (requires sudo, runs ~15 min)

Let me know if the sleep hook helps on your end!
Kindly
Flo

Hey Flo! I finally found some time to give this a try.

Everything seems to work as you described it would using the fix-sleep-hook.sh. I’ve put the machine to sleep three times now and after it is woken up again, it restarts ModemManager and the connection is automatically reestablished.

Thank you so much for your work on this. Any way I can gift you a coffee or something?

I’m going to roll with this over the next few days and will report back.

Not sure if you want to do this but I would suggest getting in touch with the maintainers of ModemManager and the Lenovo folks in their GitHub to tell them about this. Maybe this helps them to discover a permanent solution that will make this more reliable.

Dear Flo!
I just woult like to thanks your works, because I had same problem with my Lenovo X1 Yoga Gen 8 & fedora43.
I’ve installed your patch as you described, and now finally working my 5G net on my laptop!

I don’t know what can be done to make this work in future Fedora releases, but I’m still very happy with it
What I don’t fully understand now: So is the lenovo fcc unlocker software needed in the future or not?
Thanks,
Tibor

Hey Alex,

Glad to hear the sleep hook works! And thanks for sticking with it through all the testing — that really helped nail down every issue one by one. Wouldn’t have found the sleep hook bug without your logs. That’s honestly what makes this fun for me, solving stuff that’s been bugging people.

About reaching out to maintainers — I actually did contact RHEL about the upstream driver issues, but never got an answer. So for now the out-of-tree DKMS module is the way to go.

Since the last update I also fixed a shutdown hang — when the modem was unresponsive, t7xx_pci_shutdown() only ran the suspend path which left the TX thread alive. That thread would poll forever and block poweroff for hours. Fixed by calling t7xx_md_exit() after suspend to stop all threads cleanly.

I stresstested it over the weekend — multiple suspend/resume cycles, unbind/rebind, fastboot_switching trigger (the original crash scenario), shutdown, the whole thing. Also wrote a dedicated stresstest shell script (stresstest.sh in the repo) that covers every scenario I could imagine. Everything passed, so I’d call it stable now. The repo README is also updated with all 7 fixes documented.


Hey Tibor,

Welcome, nice to hear it works on your X1 Yoga Gen 8 too!

To answer your question: no, you don’t need Lenovo’s FCC unlock software (DPR_Fcc_unlock_service). It actually segfaults on Fedora — the binary does a NULL pointer dereference in libmodemauth.so. The reinstall.sh script already sets up ModemManager’s own built-in FCC unlock for the FM350 instead. It uses AT commands and works reliably. So as long as you ran reinstall.sh, you’re good — just forget about Lenovo’s version.

One thing — if you cloned the repo before some hours ago, you might want to pull the latest and re-run reinstall.sh. I fixed a shutdown hang since then where the system could block poweroff for hours when the modem was unresponsive. Just a git pull && bash reinstall.sh and you’re up to date.

Kindly
Flo :slight_smile: