* Stop a firmware lockup from deadlocking the whole system
A wedged IW620 firmware used to freeze the entire machine, not just wifi.
woal_cfg80211_dump_station_info() runs while cfg80211 holds the wiphy mutex
and nl80211_pre_doit() holds RTNL. MOAL_IOCTL_WAIT has no timeout, so once
the command queue wedged NetworkManager blocked there forever, RTNL stayed
held, and every network-touching syscall on the box blocked in D state --
no desktop icons, nothing responsive, hard power-off the only way out:
NetworkManager (S) woal_wait_ioctl_complete [moal] <- holds WIPHY mutex
wpa_supplicant (D) nl80211_pre_doit -> mutex_lock <- holds RTNL
geoclue (D) rtnl_dumpit -> rtnl_lock <- waits RTNL
Two independent causes, so two patches.
1. The command queue wedged. On a timeout the driver only released curr_cmd
for a small whitelist of commands; anything else (MAC_MULTICAST_ADR, in
the observed failure) left curr_cmd set and cmd_sent MTRUE, so every
later ioctl queued behind a command that would never be sent. Releasing
the command and completing its ioctl now happens on every timeout; the
whitelist only chooses between carrying on and declaring a hang.
The retry cap gets its own soft_cmd_timeout counter, cleared whenever a
response arrives so it really counts consecutive timeouts. It cannot
reuse num_cmd_timeout: wlan_process_cmdresp() discards every command
response while that is non-zero, so it must keep being cleared after a
recovery.
2. The wait was unbounded. The four firmware round-trips in
woal_cfg80211_dump_station_info() (signal, stats, bss_info, dtim_period)
now use MOAL_IOCTL_WAIT_TIMEOUT, capping each at 20s so a dead firmware
can no longer strand RTNL. That function backs both .get_station and
.dump_station.
Also in install.sh:
- Reset the driver tree to a pristine $REF before patching. Without it a
tree left from a previous run still carries the old version of a patch,
which then matches neither the apply nor the reverse-apply check, and the
run dies with "does not apply cleanly".
- Switch the default tuning from ps_mode=0 auto_ds=0 amsdu_disable=0 to
2 2 1, verified on a cold boot on 7.1.3-hdmifix with this patch stack.
This also matches the linux-ps5 package's moal.conf, which previously
disagreed -- and since ps5-iw620.conf sorts after moal.conf, the value
written here silently wins.
- Add FW_RESET_OPTIONS for opting into firmware auto-reset. Off by default:
woal_request_fw_reload() rejects every mode with -EINVAL unless the low
byte of indrstcfg is 1 or 2 (module default 0xffffffff), so auto_fw_reload
alone is a no-op, and neither is tested on PS5 hardware.
Verified: patches apply cleanly to a pristine lf-6.18.2_1.0.0 checkout in
install.sh order and build without warnings; a cold boot onto the result
downloads firmware, associates, and runs clean. The lockup is sporadic, so
the recovery paths themselves are not yet exercised in the field.
Assisted-by: Claude <noreply@anthropic.com>
* Explain in the generated modprobe config that it overrides moal.conf
install.sh writes /etc/modprobe.d/ps5-iw620.conf, and the linux-ps5 package
ships /etc/modprobe.d/moal.conf. Both set "options moal", and modprobe
concatenates those lines across every *.conf rather than letting one file
replace another, so the module receives the whole list twice and a repeated
scalar resolves to the last one read. ps5-iw620.conf sorts after moal.conf,
so it silently wins and edits to moal.conf appear to do nothing.
Nothing functional changes; the generated options line is byte-identical.
The header just makes the precedence discoverable from the file itself,
which a hand-added comment could not do because the next run overwrites it.
Assisted-by: Claude <noreply@anthropic.com>
* changes for 7.2.y: add separate patch file
---------
Co-authored-by: Nikolai Shcheglov <ndnd@mail.ru>