majorwiki/05-troubleshooting/networking/steam-deck-wifi-flapping-iwd-periodic-scan-rtw88.md
majorlinux cb90bb69a2 wiki: add Steam Deck Wi-Fi flapping runbook (IWD periodic scan + rtw88 power save)
Client-side fix for OG Steam Deck (RTL8822CE/rtw88) flapping ~once a minute on
SteamOS: disable IWD periodic scan + disable Wi-Fi power save via NM dispatcher.
Cross-linked with the 160MHz airtime article; registered in SUMMARY.md nav.
2026-06-19 11:36:06 -04:00

133 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Steam Deck Wi-Fi Flapping: IWD Periodic Scan + rtw88 Power Save"
domain: troubleshooting
category: networking
tags: [wifi, steam-deck, steamos, iwd, networkmanager, rtw88, rtl8822ce, power-save, supplicant-disconnect, flapping]
status: published
created: 2026-06-19
updated: 2026-06-19
---
# 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
```bash
# 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:
```
activated -> failed (reason 'supplicant-disconnect')
... -> activated # reconnects ~1s later
```
### Step 2 — Prove the link is healthy *when it's up*
```bash
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
```bash
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 (869 ms to the gateway over Wi-Fi, where a healthy 5 GHz link is 210 ms).
## ✅ Fix
Two independent changes — the first stops the flap, the second smooths latency.
### 1. Disable IWD's periodic scan (stops the flap)
```bash
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:
```bash
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 `iw` call no-ops, and power save stays on. Verify with `iw get power_save` *after a real reboot*, not just after a service restart.
## 🔁 Verification
```bash
# 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 **611 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.conf` and 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.
- **Fully reversible:**
```bash
sudo rm /etc/iwd/main.conf /etc/NetworkManager/dispatcher.d/90-wifi-powersave
sudo systemctl restart iwd
```
- **Interface name** is usually `wlan0`; confirm with `iw dev` if different.
- The same IWD-periodic-scan behavior can affect other `iwd`-based distros (Arch, some Fedora spins) on flaky/older Wi-Fi chips — the `DisablePeriodicScan` fix is general, not Deck-specific.
## 🔗 Related
- [Wi-Fi Game Streaming Stutter: 160 MHz Channel Width Saturating the 5 GHz Radio](wifi-160mhz-airtime-saturation-game-streaming.md) — the *other* Steam Deck Wi-Fi issue (airtime contention, router-side), distinct from this client-side flap.