Files
mestre/wifi-bt-architecture.md
Joakim 2526d5b087 feat: M3 complete — WiFi, BT keyboard and mouse
Bluetooth (RTL8723D USB combo chip):
- GPIO pin 357 (active low) enables WiFi/BT hardware via x6200_gpio_set()
- bluez5_utils 5.64 (downgraded from 5.79 — HID input plugin broken in 5.79)
- rtl8723d_config.bin added to overlay (missing from linux-firmware package)
- S45wifi-bt: GPIO enable + modprobe btusb/uhid/hidp at boot
- S85bt-keyboard: auto-connect loop with scan+connect every 20s

WiFi (RTL8723DU):
- out-of-tree lwfinger/rtw88 driver (RTW88_8723DU not in kernel 6.1 mainline)
- linux-firmware RTL_RTW88 for rtw88/rtw8723d_fw.bin
- regulatory.db for cfg80211
- wpa_supplicant with multi-network config in /etc/wpa_supplicant.conf
- S46wifi: wpa_supplicant + udhcpc at boot

Key findings:
- RTL8723D USB WiFi (0bda:d723) requires out-of-tree rtw88 on kernel 6.1
- BT and WiFi share same USB device, both need GPIO 357 = 0 to power on
- bluez5 5.79 HID input plugin not linked into bluetoothd (build system bug)
2026-05-09 21:02:53 +02:00

327 lines
9.4 KiB
Markdown

# X6200 WiFi and Bluetooth Architecture
A detailed technical account of how WiFi and Bluetooth work on the
Xiegu X6200, reverse-engineered during Mestre development (May 2026).
## Hardware Overview
The X6200 uses a **Realtek RTL8723D** combo chip for both WiFi and
Bluetooth. It is connected to the Allwinner R16 SoC via USB and
appears as a single USB device:
```
USB ID: 0bda:d723 Realtek Semiconductor Corp. 802.11n WLAN Adapter
Bus: USB 3 (musb-hdrc, high-speed)
```
The device exposes three USB interfaces:
- Interface 0+1: Bluetooth (class 0xE0, Wireless, RF)
- Interface 2: WiFi (class 0xFF, Vendor Specific)
Both WiFi and Bluetooth share the same USB device and antenna.
## The Power Control Problem
**The RTL8723D chip is powered off at boot.** It does not appear on
the USB bus until explicitly powered on via a GPIO pin. Without this
step, neither WiFi nor Bluetooth will work regardless of what drivers
or software is loaded.
The power control pin is managed via the X6200Control library:
```
GPIO chip: 0 (sun8i-a33 main GPIO controller)
GPIO pin: 357
Logic: Active LOW (0 = powered ON, 1 = powered OFF)
```
This is controlled via the `x6200_gpio_set()` function from
`libaether_x6200_control.so`:
```python
import ctypes
lib = ctypes.CDLL("libaether_x6200_control.so")
lib.x6200_gpio_init.restype = ctypes.c_bool
lib.x6200_gpio_set.argtypes = [ctypes.c_int, ctypes.c_int]
lib.x6200_gpio_init()
lib.x6200_gpio_set(357, 0) # 0 = ON (active low!)
```
**Critical:** `gpio_init()` must be called before `gpio_set()`.
The active-low logic is counterintuitive — sending `1` powers the
chip OFF, sending `0` powers it ON.
After powering on, the USB device appears within 1-3 seconds:
```
usb 3-1: new high-speed USB device number 2 using musb-hdrc
usb 3-1: New USB device found, idVendor=0bda, idProduct=d723
```
## Bluetooth
### Driver
The Bluetooth interface of the RTL8723D is handled by the standard
Linux kernel `btusb` driver with the `btrtl` firmware loader.
Required kernel modules (compiled as `=m`):
```
CONFIG_BT=m
CONFIG_BT_HCIBTUSB=m
CONFIG_BT_RFCOMM=m
CONFIG_BT_BNEP=m
CONFIG_BT_HIDP=m
CONFIG_UHID=y ← required for HID input devices
CONFIG_INPUT_UINPUT=y ← required for HID input devices
```
Load order:
```bash
modprobe btusb # registers hci0 and loads firmware
modprobe uhid # userspace HID device support
modprobe hidp # HID over Bluetooth protocol
```
### Firmware
The RTL8723D Bluetooth requires two firmware files:
| File | Purpose |
|------|---------|
| `rtl_bt/rtw8723d_fw.bin` | Main BT firmware |
| `rtl_bt/rtw8723d_config.bin` | Configuration (10 bytes) |
**Both files are required.** Without `rtw8723d_config.bin`, `hciconfig
hci0 up` fails with:
```
Bluetooth: hci0: RTL: mandatory config file rtl_bt/rtw8723d_config not found
```
`rtw8723d_config.bin` is **not included** in Buildroot's
`BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX_BT` package (as of 2025.02).
It must be added to the rootfs overlay manually:
```
br2_external/board/x6200/rootfs-overlay/lib/firmware/rtl_bt/rtw8723d_config.bin
```
Source: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/rtl_bt/rtw8723d_config.bin
### BlueZ Version
**BlueZ 5.64 is required.** BlueZ 5.79 (Buildroot 2025.02 default)
has a build system bug where the HID input plugin (`input_init`) is
not linked into `bluetoothd` despite `--enable-hid` being passed to
configure. Symptoms:
```
Failed to connect: org.bluez.Error.NotAvailable br-connection-profile-unavailable
```
The bug manifests because `builtin_modules` in the generated Makefile
is empty and the input profile is never registered via
`btd_profile_register()`. Downgrading to BlueZ 5.64 resolves the
issue.
To force BlueZ 5.64 in Buildroot, override the version in a local
`.mk` file or patch `buildroot/package/bluez5_utils/bluez5_utils.mk`.
### HID Profile Requirements
For Bluetooth HID devices (keyboard, mouse) to connect, bluetoothd
must be started with `--compat`:
```bash
/usr/libexec/bluetooth/bluetoothd --compat &
```
And `/etc/bluetooth/input.conf` must have:
```ini
[General]
UserspaceHID=true
ClassicBondedOnly=false
```
### Pairing a Device
First-time pairing via `bluetoothctl`:
```
power on
agent on
default-agent
scan on
# Wait for device to appear, then:
pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX
```
Once trusted, subsequent connections are automatic via the
`S85bt-keyboard` init script.
### Auto-reconnect
The `S85bt-keyboard` init script polls every 20 seconds and
reconnects if the device is not connected. It uses `scan on` before
each connection attempt to make the device visible:
```sh
{
echo "power on"; sleep 1
echo "scan on"; sleep 8
echo "scan off"; sleep 1
echo "connect $KEYBOARD_ADDR"; sleep 3
echo "quit"
} | bluetoothctl
```
## WiFi
### Driver
**The RTL8723D USB WiFi interface is NOT supported by any in-tree
driver in Linux 6.1.** Specifically:
| Driver | Status in 6.1 |
|--------|---------------|
| `rtl8xxxu` | Does not support 0bda:d723 |
| `r8723bs` | SDIO only, not USB |
| `rtw88` | Only has PCIe variant (RTW88_8723DE), USB variant added in 6.2 |
The solution is the **out-of-tree `lwfinger/rtw88` driver**, which
backports USB support for RTL8723D to older kernels. This is the same
approach used by the Xiegu X6100 community.
Buildroot package: `br2_external/package/rtw88/rtw88.mk`
```makefile
RTW88_VERSION = 461b696b51317ba4ca585a4ddb32f2e72cd4efc9
RTW88_SITE = https://github.com/lwfinger/rtw88
RTW88_SITE_METHOD = git
RTW88_LICENSE = GPL-2.0
$(eval $(kernel-module))
$(eval $(generic-package))
```
After loading, the driver creates `wlan0`:
```
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
link/ether cc:64:1a:52:91:85 brd ff:ff:ff:ff:ff:ff
```
### Firmware
Two firmware components are required:
| Component | Buildroot symbol | File |
|-----------|-----------------|------|
| WiFi firmware | `BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88` | `rtw88/rtw8723d_fw.bin` |
| Regulatory DB | `BR2_PACKAGE_LINUX_FIRMWARE_REGULATORY` | `regulatory.db` |
**Note:** After adding `BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88`, you
must run `linux-firmware-dirclean` before rebuilding, otherwise the
`br-firmware.tar` archive is not regenerated and the firmware file
will not appear in the target:
```bash
./scripts/build.sh linux-firmware-dirclean
./scripts/build.sh linux-firmware
./scripts/build.sh
```
### Network Configuration
WiFi is configured via `wpa_supplicant` with a multi-network
configuration file at `/etc/wpa_supplicant.conf`:
```ini
ctrl_interface=/var/run/wpa_supplicant
update_config=1
country=SE
network={
ssid="Network_1"
psk="password_1"
priority=10
}
network={
ssid="Network_2"
psk="password_2"
priority=5
}
```
`wpa_supplicant` automatically connects to the highest-priority
available network. Add as many `network={}` blocks as needed.
The file is installed in the rootfs overlay but should be considered
sensitive — do not commit real passwords to git.
### Boot Sequence
```
S35wifi-bt (or S45wifi-bt)
→ x6200_gpio_init()
→ x6200_gpio_set(357, 0) ← powers on RTL8723D
→ modprobe btusb ← registers hci0
→ modprobe uhid
→ modprobe hidp
→ sleep 3 ← wait for USB enumeration
S40bluetoothd
→ bluetoothd --compat ← BlueZ daemon
S46wifi
→ ip link set wlan0 up
→ wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
→ udhcpc -i wlan0 ← DHCP client
S85bt-keyboard
→ auto-connect loop (scan + connect every 20s)
```
**Ordering is critical:** The GPIO power-on script must run before
`bluetoothd` and `wpa_supplicant`. Without GPIO 357 = 0, neither
WiFi nor Bluetooth hardware is visible on the USB bus.
## Known Quirks
**GPIO is active low.** `gpio_set(357, 0)` = ON, `gpio_set(357, 1)`
= OFF. This is the opposite of what one might expect.
**Single USB device, two functions.** WiFi and BT share `0bda:d723`.
Powering on the chip enables both simultaneously. There is no way to
enable one without the other.
**rtw8723d_config.bin is missing from linux-firmware package.**
Buildroot's `BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX_BT` does not include
this 10-byte config file. Must be added to overlay manually.
**BlueZ 5.79 HID input plugin is broken.** Downgrade to 5.64 for
working Bluetooth keyboard and mouse support.
**lwfinger/rtw88 is pinned to a specific commit.** The driver is
under active development; newer commits may break things. Pin to a
known-good commit in `rtw88.mk`.
**linux-firmware-dirclean required after adding RTW88 firmware.**
Buildroot caches `br-firmware.tar` and does not regenerate it when
new firmware symbols are added to `.config`. Always run
`linux-firmware-dirclean` after changing firmware selection.
## References
- [lwfinger/rtw88](https://github.com/lwfinger/rtw88) — out-of-tree
RTW88 driver with USB support for RTL8723DU
- [AetherRadio/X6200Control](https://github.com/gdyuldin/X6200Control) —
GPIO control library; `x6200_pin_wifi` (pin 357) is defined in
`include/aether_radio/x6200_control/low/gpio.h`
- [gdyuldin/AetherX6200Buildroot](https://github.com/gdyuldin/AetherX6200Buildroot) —
reference Buildroot configuration; provided the `rtw88` package
recipe that Mestre adapts
- Linux kernel `drivers/net/wireless/realtek/rtw88/` — mainline RTW88
driver (USB variant added in 6.2, not available in 6.1)
- Realtek RTL8723D datasheet — combo WiFi+BT chip used in X6200