Skip to content

RTL8733BU support — new halmac 87xx HAL (USB-first) #233

Closed

Description

@josephnef

Summary

Add userspace support for the RTL8733BU (USB) — a 1×1 (2T2R-capable) dual-band 802.11ac + BT5 combo that is a current sweet-spot FPV adapter for OpenIPC air/ground links. The motivating feature is the same one devourer already serves elsewhere: 5/10 MHz narrowband long-range video.

This needs a new chip HAL generation, not a variant of an existing one.

Why a new HAL (not a Jaguar2/3 variant)

Investigation of the vendor tree (libc0607/rtl8733bu-20240806) established that 8733B is halmac 87xx (hal/halmac-rs/halmac-rs.mk: series:=87xx ic:=8733b; siblings 8812F/8814B/8197F — none in devourer). Devourer's Jaguar2 (8822B/8821C) and Jaguar3 (8822C/8822E) are all halmac 88xx-common. Different MAC generation ⇒ it cannot slot in as a ChipVariant; it gets its own HAL dir dispatched by chip-id like every generation.

De-risking discovery: 8733B narrowband uses the exact R_0x9b0 / R_0x9b4 re-clock dividers as devourer's Jaguar3 (hal/phydm/rtl8733b/phydm_hal_api8733b.c:1316–1400), not the Jaguar2 0x8ac path. So although the MAC layer is new (87xx), the RF/narrowband layer is a Jaguar3 twin — RadioManagementJaguar3 is a direct port reference for the feature that matters most.

Scope

In: RTL8733BU (USB) RX + TX on 2.4/5 GHz at 20/40/80 MHz and 5/10 MHz narrowband; BT-combo coex runtime; TX-power knobs; FastRetune; AdapterCaps; demos + CI configs. Neutral naming src/rtl8733b/, CMake option DEVOURER_8733B / define DEVOURER_HAVE_8733B.

Out (follow-ups): SDIO transport + 8733BS (needs a brand-new SDIO IRtlTransport — separate linked issue); PCIe (no 8733 PCIe part); WoWLAN firmware.

Confirmed vendor facts

  • RF type: hal/rtl8733b/rtl8733b_ops.c:196 — BIT_RF_TYPE_ID_8733B ? 2T2R : 1T1R (runtime, from a reg bit).
  • Dual-band: BAND_ON_2_4G / BAND_ON_5G both handled (rtl8733b_phy.c:587,701).
  • Bandwidths: 20/40/80 (phydm_hal_api8733b.c:1293–1486) + 5/10 MHz (:1316–1400).
  • Firmware: hal/rtl8733b/hal8733b_fw.c (~3 MB C source), NIC blob array_mp_8733b_fw_nic = 124552 B (NIC only needed).
  • BT coex: hal/btc/halbtc8733b.c + halbtc8733bwifionly.c → combo; wifionly path = the coex-thread re-apply pattern Jaguar3 already uses.
  • halmac 87xx port surface: halmac_init_87xx.c (897 L) + halmac_fw_87xx.c (1394 L) + halmac_bb_rf_87xx.c, halmac_efuse_87xx.c, halmac_usb_87xx.c, halmac_cfg_wmac_87xx.c.
  • Open (source-verify before M1): exact SYS_CFG2 chip-id byte + USB PID(s) under VID 0x0bda — read rtl8733b_ops.c version block + os_dep/linux/usb_intf.c id table, or read reg 0x00FC live.

Integration map (Jaguar3 is the wiring template)

  • Factory dispatch: src/WiFiDriver.cpp read_chip_id() (REG_SYS_CFG2 0x00FC); add chip-id constant + if (chip_id == k8733B) block guarded by #if defined(DEVOURER_HAVE_8733B) → construct Rtl8733bDevice; nullptr+log when unbuilt.
  • HAL dir (mirror src/jaguar3/): orchestrator, Hal8733b, Halmac8733bFw + MacInit + Regs, RadioManagement8733b, Halrf8733b + Calibration8733b.h, Phy8733bTables + PhyTableLoader8733b, FrameParser8733b, ChipVariant.h.
  • Build: CMakeLists.txt per-chip option() + PUBLIC DEVOURER_HAVE_8733B + gated target_sources + reject-bad-configs. Mirror the Jaguar3 block.
  • Interfaces: implement src/IRtlDevice.h surface; populate src/AdapterCaps.h.
  • Coex thread: src/jaguar3/RtlJaguar3Device.cpp coex_runtime_loop() (~L248–287, spawned end of InitWrite ~L455, _reg_mu-serialized, ~2 s cadence).
  • Transport: src/RtlAdapter + src/UsbTransport reused unchanged; is_usb() gates USB-only steps. No PCIe/SDIO in the HAL.
  • Generated code: new tools/extract_8733b_phy_tables.py + tools/extract_8733b_fw.py (mirror tools/extract_8822c_*). Edit generators, never outputs.

Milestones (land order — each independently mergeable)

  • M0 — Recon + scaffold. Source-verify chip-id + USB PID. src/rtl8733b/ skeleton (Rtl8733bDevice : IRtlDevice, stubs), DEVOURER_8733B option, factory dispatch, identity-only probe. Gate: device constructs + logs identity on real 8733BU.
  • M1 — Firmware + halmac 87xx bring-up. extract_8733b_fw.py → embed NIC blob; port Halmac8733bFw/MacInit/Regs from halmac_87xx. Gate: GetFwBootStatus() booted; EFUSE reads stable (ProbeEfuseStability). (crux milestone — no existing code to copy)
  • M2 — PHY tables + RX. extract_8733b_phy_tables.py; PhyTableLoader8733b; RadioManagement8733b channel/BW (port RadioManagementJaguar3); FrameParser8733b RX desc. Gate: ambient beacons CRC-clean on ch 6 + 36 via rxdemo.
  • M3 — TX + coex thread. TX descriptor + send_packet + InitWrite; spawn coex_runtime_loop() (port halbtc8733bwifionly); Halrf8733b IQK/DACK/thermal + TX-power. Gate: txdemo canonical beacon (SA 57:42:75:05:d6:00) decoded by a 2nd adapter; sustained 5 GHz TX stays up.
  • M4 — Narrowband + FastRetune. Port 0x9b0/0x9b4 NB retune from Jaguar3 as end-of-bring-up retune; FastRetune compose-cache; txpwr_lmt folds to 20 MHz column. Gate: 5/10 MHz TX/RX link at 2.4 GHz (5 MHz-at-5 GHz CFO caveat noted).
  • M5 — Integration polish. regress.py 2×2 vs vendor kernel (ch 6 + 36); bench_init.py; demos/env docs; CI build-configs subset + reject-bad-configs; ctest green; README Supported hardware + CLAUDE.md update.

Effort / risk

  • Effort ≈ "add Jaguar3 again": ~6–8k lines HAL, one fresh halmac port, one table extractor, coex, bring-up loop. Not a cheap variant add.
  • Biggest risk: 87xx halmac DLFW/MAC-init differs from the 88xx flow we have — must port from scratch (M1).
  • Lowest risk: narrowband + RF/channel mgmt (Jaguar3 twin) and transport (unchanged USB plane).
  • Needs an 8733BU adapter on the host rig (VBUS cold-cycle per HW-testing docs) for the M0–M5 gates.

Verification (end-to-end)

  1. cmake -S . -B build -DDEVOURER_8733B=ON && cmake --build build -j; plus an "8733B-only, others OFF" config; reject-bad-configs still fails the empty set; ctest green.
  2. Identity: rxdemo adapter.caps event — chip-id, generation, 1T1R/2T2R, bands, narrowband_ok=true.
  3. RX: DEVOURER_CHANNEL=6 then 36 rxdemo (2>/dev/null) — ambient beacons CRC-clean.
  4. TX: txdemo beacon confirmed on a 2nd adapter + tests/regress.py --channel 36.
  5. Narrowband: 5/10 MHz cross-RX at 2.4 GHz; on-air Mbps via SDR duty × PHY-rate (bench_onair.py), not sniffer counts.
  6. Coex soak: sustained 5 GHz TX ≥ few minutes — antenna stays live.

Scoped from vendor tree libc0607/rtl8733bu-20240806. SDIO/8733BS to be filed as a linked follow-up.

Activity

  1. added a commit that references this issue on Aug 12, 2026
  2. josephnef commented on Sep 23, 2026

    @josephnef
    CollaboratorAuthor

    Closing: the backend this issue asked for shipped and every milestone has landed in the tree — src/rtl8733b/ behind DEVOURER_8733B with factory dispatch (M0), embedded firmware + HALMAC 87xx bring-up with EFUSE stability (M1), PHY tables and RX (M2), TX with the TSSI-based power path and the witnessed surface in docs/rtl8733b.md (M3), 10 MHz narrowband and a ported FastRetune (M4; 5 MHz is refused by measurement, recorded in src/rtl8733b/CLAUDE.md), and the README row, CI config subsets, ctest cells and CLAUDE.md coverage (M5).

    What is still open from M5 lives in its own issues rather than here: the vendor-kernel A/B in regress.py is #393, and the unadvertised-capability matrix (SGI, LDPC/STBC, ACK/A-MPDU, CCA disable) is #394.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions