Solution for Wifi adapter not found.

For a year or so I have been having a problem whereby no matter what I could not get the L5 to be able to pick up the wifi card. I had a ton of trouble figuring it out and even flashed the phone once when it came back for 1 reboot and then started failing again. I largely did this with Grok obviously but hopefully it helps some people experiencing the same issue.

The phone boots, Settings shows no Wi-Fi hardware, nmcli has no wlan0, and a reboot does not help. The radio is usually still there. The Redpine RS9116 driver fails its first probe, then never creates the interface.

Access when Wi-Fi is down is USB serial and/or USB Ethernet (the gadget NCM interface).

What you see

  • Settings / Phosh: no Wi-Fi device
  • ip -br link has lo, usb0, wwan0, maybe lxcbr0 β€” no wlan0
  • Hardware kill switch for WLAN is unblocked
  • Bluetooth may be missing too (same chip)

That looks like a missing card. Check before you RMA it.

Two different failures

A. The chip never enumerates on SDIO

ls /sys/bus/sdio/devices
# empty
sudo dmesg | grep -iE 'mmc1|9116|redpine'

No 041B:9116, mmc1 may be power mode: off. Then you are in kill-switch / 3V3 / pwrseq / hardware territory. Toggling the WLAN switch or a full power-off is the usual advice.

B. The chip enumerates, then the driver dies (the post-update case)

ls /sys/bus/sdio/devices
# mmc1:fffd:1

cat /sys/bus/sdio/devices/mmc1:fffd:1/uevent
# SDIO_ID=041B:9116
# no DRIVER= line

lsmod | grep redpine
# redpine_sdio and redpine_91x are loaded

ip link show wlan0
# Device does not exist

dmesg looks like this:

redpine_91x: rsi_probe: ***** 9116 Module *****
redpine_91x: rsi_load_firmware: Loading file RS9116_NLINK_WLAN_BT_IMAGE.rps
redpine_91x:  Burn Command Pass.. Upgrading the firmware
redpine_91x: Firmware upgradation Done
redpine_91x: ***** Loaded Firmware *****
mmc1: Timeout waiting for hardware interrupt.
redpine_91x: rsi_sdio_read_register_multiple: Synch Cmd53 read failed
redpine_91x: redpine_hal_device_init: Failed to load TA instructions
redpine_91x: rsi_probe: Failed in device init
RSI-SDIO WLAN: probe of mmc1:fffd:1 failed with error 1

The module answered on SDIO. Firmware even flashed. Then a Cmd53 timed out and probe exited. NetworkManager never gets a netdev, so the UI says β€œno adapter.”

On 6.6.147 the device tree also has cd-gpios on mmc1 (GPIO2_IO12 / SD2_CD_B). If you unbind that host to β€œreset” it, USDHC often leaves the bus powered off (mmc1 clock 0, no SDIO devices). Do not unbind 30b50000.mmc.


Immediate recovery (do not unbind mmc1)

If mmc1:fffd:1 exists and wlan0 does not:

  1. Unload the vendor driver.
  2. Keep 3V3_WIFI on.
  3. Pulse the two pwrseq reset GPIOs (GPIO3_IO25 and GPIO4_IO29, active-high in the DT), then deassert them.
  4. Load redpine_91x and redpine_sdio again.
  5. Wait for wlan0 (often a few seconds; firmware can take ~15–25 s).

A compact script (needs root and /dev/mem):

#!/usr/bin/env python3
import mmap, os, struct, time, subprocess, sys

GPIO3, GPIO4 = 0x30220000, 0x30230000
WIFI_3V3, RST0, RST1 = 10, 25, 29

def mp(base):
    fd = os.open("/dev/mem", os.O_RDWR | os.O_SYNC)
    m = mmap.mmap(fd, 0x1000, mmap.MAP_SHARED,
                  mmap.PROT_READ | mmap.PROT_WRITE, offset=base)
    os.close(fd)
    return m

def rd(m, o):
    return struct.unpack_from("<I", m, o)[0]

def wr(m, o, v):
    struct.pack_into("<I", m, o, v & 0xFFFFFFFF)

def setb(m, n, lvl):
    dr, gdir = rd(m, 0), rd(m, 4)
    if not (gdir >> n) & 1:
        wr(m, 4, gdir | (1 << n))
        dr = rd(m, 0)
    wr(m, 0, (dr | (1 << n)) if lvl else (dr & ~(1 << n)))

g3, g4 = mp(GPIO3), mp(GPIO4)
subprocess.call(["modprobe", "-r", "redpine_sdio"])
subprocess.call(["modprobe", "-r", "redpine_91x"])
time.sleep(0.4)
setb(g3, WIFI_3V3, 1)
setb(g3, RST0, 1); setb(g4, RST1, 1)
time.sleep(0.12)
setb(g3, RST0, 0); setb(g4, RST1, 0)
time.sleep(0.4)
subprocess.call(["modprobe", "redpine_91x"])
subprocess.call(["modprobe", "redpine_sdio"])
for i in range(40):
    time.sleep(1)
    if "wlan0" in os.listdir("/sys/class/net"):
        subprocess.call(["ip", "link", "set", "wlan0", "up"])
        print("wlan0 up after", i + 1, "s")
        sys.exit(0)
print("failed"); sys.exit(1)

Run it as root. If it works, Settings will show Wi-Fi and NetworkManager will reconnect to a saved SSID.


Make it survive reboot

The first probe still fails after an update. Install a oneshot that retries.

Put the recover logic in /usr/local/sbin/librem5-wifi-up: wait for SDIO; if wlan0 never appears, run the recover sequence above. Log to /var/log/librem5-wifi-up.log.

/etc/systemd/system/librem5-wifi-up.service:

[Unit]
Description=Recover Librem 5 RS9116 Wi-Fi after failed first probe
After=systemd-modules-load.service sysinit.target
Before=NetworkManager.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/librem5-wifi-up
TimeoutStartSec=120

[Install]
WantedBy=multi-user.target

Optional udev so it also fires when the SDIO function appears:

ACTION=="add", SUBSYSTEM=="sdio", ATTR{device}=="0x9116", TAG+="systemd", ENV{SYSTEMD_WANTS}="librem5-wifi-up.service"
sudo chmod 755 /usr/local/sbin/librem5-wifi-up
sudo systemctl daemon-reload
sudo udevadm control --reload-rules
sudo systemctl enable --now librem5-wifi-up.service

On a cold boot, wait about a minute. The first probe may still fail; the service then pulses reset and reloads the driver.


How to get a shell when Wi-Fi is dead

USB gadget serial:

screen /dev/cu.usbmodem01234567891 115200   # macOS
# or /dev/ttyACM0 on Linux

Then give USB Ethernet a pair of addresses (example):

# on the phone
sudo ip link set usb0 up
sudo ip addr add 192.168.42.2/24 dev usb0
sudo systemctl start ssh

# on the computer
sudo ip addr add 192.168.42.1/24 dev <usb-ncm-if>
ssh purism@192.168.42.2

Do not use mmcli for this. That is the WWAN modem.

1 Like