1
0
Fork 0
android_device_rockchip_tart/wifi/wireless_reprobe.sh

76 lines
3.2 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. Force-rebinds known WiFi USB drivers, so a USB WiFi adapter that was
# plugged in at power-on (and whose firmware request failed on the
# missing /vendor mount) gets a second, working probe. Confirmed on
# hardware (2026-07-13) that mt76-family drivers do NOT fail probe() on
# a missing-firmware error -- they bind "successfully" and then loop
# forever retrying an MCU handshake that can never succeed, so a plain
# driverless-only reprobe (the previous version of this script) never
# touches them. Unbind+rebind is required regardless of bound state.
# 2. Rebinds the Broadcom Bluetooth serdev device, so hci_bcm reloads its
# .hcd patch firmware (e.g. brcm/BCM.hcd). Without the patch the
# controller runs with unpatched defaults, which cripples TX power/range.
# Confirmed on hardware: firmware build version goes 0000 -> 1000 after
# this rebind.
#
# Both operations are idempotent and safe to run more than once.
# List of built-in USB WiFi driver names from tart_defconfig (see
# CONFIG_WLAN_VENDOR_MEDIATEK/_REALTEK/_ATH/_RALINK/_ZYDAS/CONFIG_MWIFIEX).
WIFI_USB_DRIVERS="mt7601u mt76x0u mt76x2u mt7921u mt7925u \
rt2500usb rt73usb rt2800usb \
rtl8187 rtl8xxxu rtw_8822bu rtw_8822cu rtw_8723du rtw_8821cu \
ath9k_htc carl9170 ar5523 \
zd1211rw mwifiex_usb"
is_wifi_driver() {
for d in $WIFI_USB_DRIVERS; do
[ "$d" = "$1" ] && return 0
done
return 1
}
# USB: for interfaces already bound to a known WiFi driver, force an
# unbind+rebind (their probe "succeeded" despite the firmware failure, so a
# driverless-only reprobe never reaches them). For genuinely unbound
# interfaces, just ask the kernel to re-run driver matching. Two passes with
# a delay: a probe already in flight when /vendor finished mounting can still
# fail after the first pass runs; the second pass catches what it leaves
# behind.
reprobe_usb() {
for intf in /sys/bus/usb/devices/*:*; do
name="${intf##*/}"
if [ -e "$intf/driver" ]; then
drv="$(basename "$(readlink -f "$intf/driver")")"
if is_wifi_driver "$drv"; then
echo "$name" > "$intf/driver/unbind" 2>/dev/null
echo "$name" > /sys/bus/usb/drivers_probe 2>/dev/null
fi
else
echo "$name" > /sys/bus/usb/drivers_probe 2>/dev/null
fi
done
}
reprobe_usb
sleep 3
reprobe_usb
# 2. Bluetooth: unbind + re-probe serdev devices so the hci_bcm driver's
# firmware patch request runs again with /vendor/firmware available.
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