diff --git a/build/stage2.sh b/build/stage2.sh index f8b373c..8c3f342 100755 --- a/build/stage2.sh +++ b/build/stage2.sh @@ -278,11 +278,17 @@ echo "${DEFAULT_USER}:${DEFAULT_PASSWORD}" | chroot "$ROOTFS" chpasswd chroot "$ROOTFS" chage -d 0 "$DEFAULT_USER" # force a change at first login chroot "$ROOTFS" passwd -l root +# rmtfs and tqftpserv are both shipped disabled by Fedora. They are inert +# without modem firmware and cost nothing to have running, so enable them here +# rather than leaving a step to rediscover later — onboard WiFi cannot work +# without tqftpserv, since the modem fetches the WLAN firmware over TFTP. chroot "$ROOTFS" systemctl enable \ c630-growfs.service \ sshd.service \ NetworkManager.service \ - systemd-resolved.service + systemd-resolved.service \ + rmtfs.service \ + tqftpserv.service if [ "$VARIANT" = workstation ]; then chroot "$ROOTFS" systemctl set-default graphical.target diff --git a/config/packages/base.pkgs b/config/packages/base.pkgs index 352ce67..7fbbc20 100644 --- a/config/packages/base.pkgs +++ b/config/packages/base.pkgs @@ -28,6 +28,16 @@ atheros-firmware # partition. See docs/firmware.md — those cannot be redistributed. qcom-firmware-extract +# The modem has no storage of its own. rmtfs serves it the NV and calibration +# partitions (modemst1/2, fsg, fsc); tqftpserv serves it files over TFTP, +# including the WLAN firmware, which is why onboard WiFi depends on it. The +# other two services aarch64-laptops lists — pd-mapper and qrtr-ns — are in the +# kernel now. qrtr is here for qrtr-lookup, which is how you see whether the +# modem has registered its QMI services. See docs/firmware.md. +rmtfs +tqftpserv +qrtr + # --- boot --------------------------------------------------------------- grub2-efi-aa64 grub2-efi-aa64-modules diff --git a/docs/firmware.md b/docs/firmware.md index 9902940..c238f0a 100644 --- a/docs/firmware.md +++ b/docs/firmware.md @@ -199,15 +199,75 @@ Whichever route, drop the result into `firmware/local/` and rebuild — see Installing all of it still leaves two things broken, both for reasons that are not about firmware. Recorded here so nobody repeats the search. -### Onboard WiFi needs the modem, and the modem needs firmware nobody publishes +### Onboard WiFi: everything is in place except a working modem The name gives it away: **wlan*mdsp*** is the WLAN *Modem* DSP. On SDM845 the -WiFi firmware is loaded by the modem subsystem, so `ath10k_snoc` binds to -`18800000.wifi` and then sits silent, waiting on a QMI service that only appears -once the modem is up. It never logs an error, because from its point of view -nothing has gone wrong yet. +WiFi firmware runs on the modem, so `ath10k_snoc` binds to `18800000.wifi` and +then sits silent. It logs nothing and fails nothing — it has registered a QMI +client and is waiting for service 69, `wlfw`, which only appears once the modem +is up. `qrtr-lookup` shows what is and is not there. -The modem itself boots and then dies: +Everything on the WiFi side checks out: + +- `ath10k_snoc` binds successfully and is not in deferred probe +- the device tree carries `qcom,calibration-variant = "Lenovo_C630"` +- Fedora's `board-2.bin` contains a matching `variant=Lenovo_C630` entry +- `modemst1` and `modemst2` hold ~2 MB of real NV data — not wiped + +#### The userspace services are required, and mostly missing by default + +[aarch64-laptops' WiFi README][aal-wifi] lists four services. On a current +Fedora two of them are now in the kernel, and the other two are packaged but +inactive: + +| Service | Status here | +|---|---| +| `pd-mapper` | in-kernel as `qcom_pd_mapper` — nothing to install | +| `qrtr-ns` | in-kernel — the `qrtr` package supplies only `qrtr-lookup`/`qrtr-cfg` | +| `rmtfs` | packaged, **disabled by default** — serves the modem's NV partitions | +| `tqftpserv` | packaged, **not installed** — serves files to the modem over TFTP | + +```sh +sudo dnf install rmtfs tqftpserv qrtr +sudo systemctl enable --now rmtfs tqftpserv +``` + +Enabling these took `qrtr-lookup` from 19 services to 25. A working setup is +said to show around 40. + +[aal-wifi]: https://github.com/aarch64-laptops/build/tree/master/misc/lenovo-yoga-c630/wifi + +#### The modem fetches wlanmdsp over TFTP + +This is the step that is easy to miss, and the reason `tqftpserv` exists. +`tqftpserv` serves from `/lib/firmware/`, and the modem asks it for the WLAN +firmware by path: + +```sh +sudo mkdir -p /lib/firmware/readonly/firmware/image +sudo cp wlanmdsp.mbn /lib/firmware/readonly/firmware/image/ +``` + +The modem also wants a writable area, and says so in the `tqftpserv` journal: + +``` +[TQFTP] RRQ: /readwrite/ota_firewall/ruleset → unable to open (2), reject +[TQFTP] WRQ: /readwrite/server_check.txt +``` + +```sh +sudo mkdir -p /lib/firmware/readwrite/ota_firewall +sudo touch /lib/firmware/readwrite/ota_firewall/ruleset +sudo chmod -R 0777 /lib/firmware/readwrite +``` + +Watching `journalctl -u tqftpserv` while starting the modem is the best +available feedback channel — it shows exactly which paths the modem wants. + +#### Where it actually stops + +The modem boots and then dies at RF front-end initialisation, roughly every 42 +seconds until stopped: ``` qcom-q6v5-mss 4080000.remoteproc: MBA booted without debug policy, loading mpss @@ -216,32 +276,54 @@ qcom-q6v5-mss 4080000.remoteproc: fatal error received: remoteproc remoteproc0: crash detected ... recovering ``` -QLINK is the RF front-end interface. Why it hangs is **not established**. The -machine has a SIM slot and its modem worked under Windows, so the radio hardware -is present and functional — this is not a WiFi-only SKU. Candidates worth -investigating: a version mismatch between these images and what the device's -TrustZone or boot chain expects, missing calibration data the modem cannot -reach, or a kernel-side gap. It restarts about every 42 seconds until stopped. +It never gets far enough to request `wlanmdsp`, so WLAN never starts. -Note the same cabinets supply the GPU, DSP and venus firmware, all of which -work. Whatever is wrong is specific to the modem. +Three firmware pairings, three distinct failures — worth recording, because the +differences are informative: + +| MBA (stage 1) | mpss (stage 2) | Result | +|---|---|---| +| full | full | boots, dies at `RF stuck in QLINK start state` | +| `_nm` | `_nm` | `PBL returned unexpected status` — rejected by the boot ROM | +| full | `_nm` | `MPSS header authentication failed: -3` | + +The `_nm` ("no modem") variants are the obvious idea — Fedora ships the +equivalent `modem_nm.mbn` for generic sdm845, and skipping cellular RF is +exactly what is wanted here. They are not signed for this device and cannot be +made to load. + +#### Firmware has been eliminated as the variable + +The decisive test: [aarch64-laptops' wifi directory][aal-wifi] contains the +`qcdsp1v2850.mbn`, `qcdsp2850.mbn` and `wlanmdsp.mbn` from the setup whose +support table ticks WiFi. All three differ from the WOA-Project copies — the +modem pair matches on size but not checksum. Installed on this machine, with +`rmtfs` and `tqftpserv` running and `wlanmdsp` in the TFTP path, they produce +the **identical** QLINK failure. + +So the difference is not the firmware, and not the userspace services. What +remains is the kernel: that setup ran `aarch64-laptops/linux` branch `gpu`, +circa 2019 on 5.x, against 7.1.5 here. Both ath10k patches it applied are long +upstream — the device tree carries `qcom,snoc-host-cap-8bit-quirk` from the +first of them. Six years of `qcom-q6v5-mss` churn sits between the two. + +That points at a kernel regression rather than anything missing on disk. +Confirming it means bisecting or booting an older kernel, which nothing here +does yet. Things that sound like they should help and do not: -- **`rmtfs`.** The modem stores its NV and calibration on the `modemst1`, - `modemst2`, `fsg` and `fsc` partitions and reaches them through the `rmtfs` - daemon. Fedora packages it, and it is disabled by default. Enabling it is - correct and worth doing — `sudo systemctl enable --now rmtfs` — but the QLINK - failure persists with it running. Its "failed to update start state" warnings - are its optional remoteproc-control helper and are harmless. -- **The `_nm` firmware variants.** `qcdsp1v2850_nm.mbn` and `qcdsp2850_nm.mbn` - are the no-modem images, 5.7 MB against 60 MB, analogous to the `modem_nm.mbn` - Fedora ships for generic sdm845. They are rejected before they even run: - `PBL returned unexpected status`. -- **Unplugging the USB WiFi dongle.** Different bus, different driver, no - interaction. `ath10k_snoc` is waiting on the modem, not competing for a radio. +- **Unplugging the USB WiFi dongle.** Different bus, different driver. + `ath10k_snoc` is waiting on the modem, not competing for a radio. +- **`rmtfs` alone.** Necessary, not sufficient. Its "failed to update start + state" warnings are its optional remoteproc-control helper and are harmless. +- **The `_nm` variants.** See above. -A USB dongle or USB tethering from a phone is the practical answer. +Untried, in rough order of promise: the other eight driver versions under +`Lenovo/YogaC630/` (this machine's UEFI is `9UCN33WW(V2.06)` from 2019, and the +newest package may not be the right vintage); `mcfg_subsys_ext850.cab`, which +holds modem configuration data; and building `board-2.bin` from the C630's own +`bdwlan.*` files rather than relying on Fedora's. ### Audio is a kernel driver problem diff --git a/overlay/usr/local/sbin/c630-firmware b/overlay/usr/local/sbin/c630-firmware index 0f7dc21..16d4ad1 100755 --- a/overlay/usr/local/sbin/c630-firmware +++ b/overlay/usr/local/sbin/c630-firmware @@ -49,6 +49,20 @@ if [ -f "${FW_DIR}/qcdxkmsuc850.mbn" ]; then echo "GPU zap shader will be included in the initramfs." fi +# The modem does not read wlanmdsp.mbn from /lib/firmware directly — it asks +# tqftpserv for it by path. Without this, onboard WiFi cannot start even with +# every other file in place, and nothing says so: ath10k_snoc simply waits +# forever for a QMI service that never registers. It also wants somewhere +# writable. See docs/firmware.md. +if [ -f "${FW_DIR}/wlanmdsp.mbn" ]; then + install -D -o root -g root -m 644 \ + "${FW_DIR}/wlanmdsp.mbn" /lib/firmware/readonly/firmware/image/wlanmdsp.mbn + mkdir -p /lib/firmware/readwrite/ota_firewall + : > /lib/firmware/readwrite/ota_firewall/ruleset + chmod -R 0777 /lib/firmware/readwrite + echo "Placed wlanmdsp.mbn where tqftpserv will serve it to the modem." +fi + echo "Regenerating the initramfs..." dracut --force --regenerate-all