Steam Deck Wi-Fi Flapping: IWD Periodic Scan + rtw88 Power Save¶
🛑 Problem¶
An OG Steam Deck (LCD model, Realtek RTL8822CE on the rtw88_8822ce driver) kept "losing" Wi-Fi — it would connect, hold for around a minute, drop, then reconnect a second later, over and over. From the router side the device looked like it was constantly coming and going; from the couch it felt like the network "wouldn't stay connected."
Crucially, this was not a router problem. The AP config was correct, RF was clean (strong signal, zero tx retries / beacon loss), and every other client on the network was rock-solid. The fault was entirely on the Deck.
🔍 Diagnosis¶
SteamOS uses NetworkManager with the iwd backend (not wpa_supplicant). That detail is the whole ballgame.
Step 1 — Confirm the flap and its cadence¶
# how many disconnects this boot?
journalctl -b -u NetworkManager --no-pager | grep -c supplicant-disconnect
# 50
# when did they happen?
journalctl -b -u NetworkManager --no-pager | grep supplicant-disconnect \
| awk '{print $1,$2,$3}' | tail
# 10:20:52 · 10:21:54 · 10:22:57 · 10:24:00 · 10:25:03 · 10:26:05 · 10:27:08 ...
~63 seconds between every drop. A fixed, metronome-like interval is the tell — this is a timer, not RF noise. The NetworkManager log shows the pattern plainly:
Step 2 — Prove the link is healthy when it's up¶
iw dev wlan0 station dump | grep -iE 'signal|bitrate|failed|retries|beacon loss'
# signal: -65 dBm
# tx retries: 0
# tx failed: 0
# beacon loss: 0
Strong signal, zero retries, zero beacon loss — the association is clean while it lasts. So the drop is being commanded, not caused by a bad radio link.
Step 3 — Identify the chip and the backend¶
lspci -k | grep -A3 -iE 'network|wireless'
# Realtek RTL8822CE ... Kernel driver in use: rtw88_8822ce
The ~63s interval is IWD's default periodic background scan. With no /etc/iwd/main.conf present, IWD scans on a timer even while connected, and on the rtw88 driver that scan knocks the current association over — producing the supplicant-disconnect every minute.
A secondary annoyance: iw dev wlan0 get power_save reported on, which showed up as wildly jittery LAN latency (8–69 ms to the gateway over Wi-Fi, where a healthy 5 GHz link is 2–10 ms).
✅ Fix¶
Two independent changes — the first stops the flap, the second smooths latency.
1. Disable IWD's periodic scan (stops the flap)¶
sudo mkdir -p /etc/iwd
printf '[Scan]\nDisablePeriodicScan=true\n' | sudo tee /etc/iwd/main.conf
sudo systemctl restart iwd # briefly drops Wi-Fi; NetworkManager auto-reconnects
Trade-off: with periodic scanning off, the Deck roams to a different/stronger AP (e.g. another AiMesh node) more lazily. Fine for a device that mostly sits in one spot.
2. Disable Wi-Fi power save (kills the latency jitter)¶
The obvious nmcli connection modify <name> 802-11-wireless.powersave 2 does not work under the IWD backend — NetworkManager doesn't enforce that property when iwd is managing the radio. Use a dispatcher script instead, with a retry loop because rtw88 won't accept the setting in the first instant after association on a cold boot:
sudo tee /etc/NetworkManager/dispatcher.d/90-wifi-powersave >/dev/null <<'SCRIPT'
#!/bin/sh
# Disable Wi-Fi power save on the wireless iface (retry: rtw88 may not accept it instantly on boot)
case "$2" in
up|dhcp4-change|connectivity-change)
case "$1" in
wl*)
for n in 1 2 3 4 5; do
/usr/bin/iw dev "$1" set power_save off 2>/dev/null
[ "$(/usr/bin/iw dev "$1" get power_save 2>/dev/null)" = "Power save: off" ] && break
sleep 1
done
;;
esac
;;
esac
SCRIPT
sudo chmod +x /etc/NetworkManager/dispatcher.d/90-wifi-powersave
sudo iw dev wlan0 set power_save off # apply now without waiting for a reconnect
💡 A single-shot dispatcher (no retry) silently fails on a cold boot — it fires before the interface is ready, the
iwcall no-ops, and power save stays on. Verify withiw get power_saveafter a real reboot, not just after a service restart.
3. Belt-and-suspenders: a boot-ordered oneshot service (recommended)¶
Even with the retry loop, the dispatcher fires on NetworkManager events and can still lose the race on a cold boot if the radio comes up late. A systemd oneshot ordered after network-online.target is far more reliable — it runs the restore script once the link is genuinely up, re-asserts power_save off, and re-creates the /etc files if an update wiped them. Because it calls the restore script in /home (which survives updates), it also self-heals the whole fix on every boot.
sudo tee /etc/systemd/system/wifi-powersave-fix.service >/dev/null <<'EOF'
[Unit]
Description=Steam Deck WiFi stability fix (iwd DisablePeriodicScan + rtw88 power save off)
After=network-online.target NetworkManager.service
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/home/deck/restore-wifi-fix.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now wifi-powersave-fix.service
The staged restore-wifi-fix.sh (below) installs and enables this unit itself, so running that one script is all that's needed. Caveat: the unit lives in /etc, so a major A/B update wipes it too — re-running the restore script reinstalls it.
🔁 Verification¶
# was 50/boot, ~once a minute:
journalctl -b -u NetworkManager --no-pager | grep -c supplicant-disconnect
# 0
iw dev wlan0 get power_save
# Power save: off
A 3-minute continuous ping showed 180/180 replies, 0 loss, latency tightened to 6–11 ms. Confirmed across a full cold reboot: the Deck auto-rejoins Wi-Fi, both settings persist, and the disconnect counter stays at 0.
📌 Notes¶
- Persistence:
/etc/iwd/main.confand the dispatcher live in/etc, which survives reboots. A major SteamOS update can reset/etc— re-apply if the flapping returns after an OS update. - Why
/etcresets: SteamOS uses an immutable A/B root filesystem. An update writes a fresh root image to the other partition and boots it, replacing everything on root —/etc,/usr, installed packages. Only/homeand/var(separate partitions) survive. Anything that must auto-run as root at boot (systemd units, NM dispatcher scripts, sudoers) has to be registered in/etc. Between updates, the boot-orderedwifi-powersave-fix.service(above) re-asserts the fix on every cold boot. A major A/B update still wipes the unit along with the rest of/etc, so the durable artifact is the re-run-after-update script in/home(below); a community overlay tool likerwfus(makes/etc+/usrpersistent) is the alternative if even the post-update re-run becomes a nuisance. - One-command recovery: a self-contained restore script is staged on the Deck at
/home/deck/restore-wifi-fix.sh(lives in/home, so it survives updates). It installs all three fixes including the boot service, so one run fully restores everything. After any update that wipes the fix, re-apply with: - Recurrence log:
- 2026-06-22 — flap returned (Wi-Fi did not reconnect after wake). A SteamOS update had wiped
/etc(both fix files gone;~/.sshand thedeckSSH password were also reset, the smoking gun that an update ran). Re-applied via the stagedrestore-wifi-fix.sh; verifiedpower_save off,DisablePeriodicScanpresent, 60/60 pings 0% loss. MajorAir's SSH public key was added todeck@192.168.50.173:~/.ssh/authorized_keysduring this session. - 2026-06-25 — recurred after switching from the Beta → Stable SteamOS channel (now build
20260620.1, SteamOS3.8.11). This time/etchad not been wiped —/etc/iwd/main.confand the dispatcher were intact — butpower_savewas back on: the exact cold-boot race the single-shot dispatcher loses. Root-caused and fixed permanently by adding the boot-orderedwifi-powersave-fix.service(Fix #3 above) and folding its install intorestore-wifi-fix.sh. Verifiedpower_save off, serviceenabled/active, 25/25 pings 0% loss. Lesson: a channel switch pulls a fresh image and re-exposes the cold-boot race even when the/etcconfig files survive — the dispatcher alone is not enough. - Fully reversible:
- Interface name is usually
wlan0; confirm withiw devif different. - The same IWD-periodic-scan behavior can affect other
iwd-based distros (Arch, some Fedora spins) on flaky/older Wi-Fi chips — theDisablePeriodicScanfix is general, not Deck-specific.
🔗 Related¶
- Wi-Fi Game Streaming Stutter: 160 MHz Channel Width Saturating the 5 GHz Radio — the other Steam Deck Wi-Fi issue (airtime contention, router-side), distinct from this client-side flap.