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)
327 lines
9.4 KiB
Markdown
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
|