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.
78 lines
3.7 KiB
Bash
78 lines
3.7 KiB
Bash
#!/vendor/bin/sh
|
|
#
|
|
# wireless_reprobe.sh - re-probe wireless drivers once /vendor is mounted.
|
|
#
|
|
# Built-in wireless drivers probe during early kernel init, before /vendor
|
|
# (which holds all firmware; see the kernel's patched fw_path[]) is mounted.
|
|
# Their firmware requests fail fast with ENOENT and the kernel never retries,
|
|
# 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:
|
|
#
|
|
# 1. Re-probes every driverless USB interface, so any USB adapter that was
|
|
# plugged in at power-on gets a second probe with /vendor/firmware available.
|
|
# 2. Force-unbinds and re-probes USB interfaces already bound to known WiFi
|
|
# 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
|
|
# controller runs with unpatched defaults, which cripples TX power/range.
|
|
#
|
|
# All three operations are idempotent and safe: already-bound interfaces not
|
|
# matching a known WiFi driver are untouched during phase 2, and the BT rebind
|
|
# simply re-registers hci0 before the Bluetooth stack starts.
|
|
|
|
# Known USB WiFi driver names (matches the built-in =y drivers in tart_defconfig)
|
|
WIFI_USB_DRIVERS="mt7921u mt76x0u mt76x2u mt7601u rtw88_8822bu rtw88_8822cu \
|
|
rtw88_8821cu rtw88_8723du ath9k_htc carl9170 ar5523 rt2800usb mwifiex_usb"
|
|
|
|
#---------------------------------------------------------------------
|
|
# 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() {
|
|
for intf in /sys/bus/usb/devices/*:*; do
|
|
[ -e "$intf/driver" ] && continue
|
|
echo "${intf##*/}" > /sys/bus/usb/drivers_probe 2>/dev/null
|
|
done
|
|
}
|
|
reprobe_usb
|
|
sleep 3
|
|
reprobe_usb
|
|
|
|
#---------------------------------------------------------------------
|
|
# 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
|
|
[ -e "$dev/driver" ] || continue
|
|
name="${dev##*/}"
|
|
echo "$name" > "$dev/driver/unbind" 2>/dev/null
|
|
echo "$name" > /sys/bus/serial/drivers_probe 2>/dev/null
|
|
done
|
|
|
|
exit 0
|