1
0
Fork 0

wireless_reprobe.sh: force-unbind+rebind already-bound WiFi USB drivers

The old script only re-probed driverless USB interfaces.  Some built-in
USB WiFi drivers (notably mt7921u) do NOT fail probe() when firmware is
missing — they bind 'successfully', then loop on the MCU handshake until
a timeout kills hardware init.  The driverless-only reprobe never
touches them, so the adapter stays dead after the initial probe.

Fix: add phase 2 that force-unbinds and re-probes every USB interface
already bound to a known built-in WiFi driver, so their firmware request
runs again now that /vendor/firmware is available on the kernel's
fw_path[].

Also increase the driver list to match all built-in =y USB WiFi drivers
from tart_defconfig.
This commit is contained in:
Brendan Szymanski 2026-07-14 13:18:39 -04:00
parent 9e8d38a0c8
commit cac2f751ac

View file

@ -8,22 +8,30 @@
# leaving the hardware driverless or degraded. Run from init at post-fs # leaving the hardware driverless or degraded. Run from init at post-fs
# (i.e. after /vendor is mounted) via init.tart.wifi.rc, this script: # (i.e. after /vendor is mounted) via init.tart.wifi.rc, this script:
# #
# 1. Re-probes every driverless USB interface, so a USB WiFi adapter that # 1. Re-probes every driverless USB interface, so any USB adapter that was
# was plugged in at power-on (and whose driver probe failed on the # plugged in at power-on gets a second probe with /vendor/firmware available.
# missing firmware) gets a second probe that can now load firmware. # 2. Force-unbinds and re-probes USB interfaces already bound to known WiFi
# 2. Rebinds the Broadcom Bluetooth serdev device, so hci_bcm reloads its # drivers, because some drivers (notably mt7921u) bind "successfully" even
# without firmware, then loop on hardware init forever. Rebinding after
# /vendor is mounted lets the firmware request succeed.
# 3. Rebinds the Broadcom Bluetooth serdev device, so hci_bcm reloads its
# .hcd patch firmware (e.g. brcm/SYN43711A0.hcd). Without the patch the # .hcd patch firmware (e.g. brcm/SYN43711A0.hcd). Without the patch the
# controller runs with unpatched defaults, which cripples TX power/range. # controller runs with unpatched defaults, which cripples TX power/range.
# #
# Both operations are idempotent and safe: already-bound USB interfaces are # All three operations are idempotent and safe: already-bound interfaces not
# skipped, and the BT rebind simply re-registers hci0 before the Bluetooth # matching a known WiFi driver are untouched during phase 2, and the BT rebind
# stack starts. # simply re-registers hci0 before the Bluetooth stack starts.
# 1. USB: ask the kernel to re-run driver matching for unbound interfaces # Known USB WiFi driver names (matches the built-in =y drivers in tart_defconfig)
# (directories like 1-1:1.0 without a "driver" symlink). Two passes with a WIFI_USB_DRIVERS="mt7921u mt76x0u mt76x2u mt7601u rtw88_8822bu rtw88_8822cu \
# delay: a probe that was already in flight (started just before /vendor rtw88_8821cu rtw88_8723du ath9k_htc carl9170 ar5523 rt2800usb mwifiex_usb"
# finished mounting) can still fail after the first pass runs; the second
# pass catches the interface it leaves behind. #---------------------------------------------------------------------
# Phase 1: re-probe USB interfaces that are still driverless (the
# driver's initial probe failed, e.g. on missing firmware, and never
# bound). Two passes: a probe that was in-flight as /vendor mounted
# may still fail on the first pass, so the second catches its residue.
#---------------------------------------------------------------------
reprobe_usb() { reprobe_usb() {
for intf in /sys/bus/usb/devices/*:*; do for intf in /sys/bus/usb/devices/*:*; do
[ -e "$intf/driver" ] && continue [ -e "$intf/driver" ] && continue
@ -34,8 +42,32 @@ reprobe_usb
sleep 3 sleep 3
reprobe_usb reprobe_usb
# 2. Bluetooth: unbind + re-probe serdev devices so the hci_bcm driver's #---------------------------------------------------------------------
# firmware patch request runs again with /vendor/firmware available. # Phase 2: force-unbind + rebind USB interfaces already matched to one
# of the known WiFi drivers. The original probe succeeded (driver bound
# OK) but the hardware init / firmware load that follows (e.g. the MCU
# handshake in mt7921u) failed because firmware wasn't available yet.
# Rebinding now, with /vendor/firmware on the kernel's fw_path[], lets
# the full init sequence succeed.
#---------------------------------------------------------------------
for drv in $WIFI_USB_DRIVERS; do
drvdir="/sys/bus/usb/drivers/$drv"
[ -d "$drvdir" ] || continue
for dev_path in "$drvdir"/*/; do
[ -L "$dev_path" ] || continue
name="${dev_path%/}"
name="${name##*/}"
# Skip the driver's own 'module' symlink and similar metadata
[ "$name" = "module" ] || [ "$name" = "uevent" ] || [ "$name" = "new_id" ] && continue
echo "$name" > "$drvdir/unbind" 2>/dev/null
echo "$name" > /sys/bus/usb/drivers_probe 2>/dev/null
done
done
#---------------------------------------------------------------------
# Phase 3: Bluetooth serdev rebind (same reasoning — the .hcd patch
# request fires pre-/vendor the first time and fails).
#---------------------------------------------------------------------
for dev in /sys/bus/serial/devices/*; do for dev in /sys/bus/serial/devices/*; do
[ -e "$dev/driver" ] || continue [ -e "$dev/driver" ] || continue
name="${dev##*/}" name="${dev##*/}"