From 126fb4e3c204a35c4a5516e15c9e53d36fa97203 Mon Sep 17 00:00:00 2001 From: Joseph <162703152+josephnef@users.noreply.github.com> Date: Wed, 10 Jun 2026 15:47:08 +0300 Subject: [PATCH] 8814: clamp CCK TX rate to OFDM on 5GHz channels (fixes 5GHz TX) send_packet defaults fixed_rate to MGN_1M (1M CCK) and only overrides it from the radiotap RATE/VHT fields (or HT-MCS when DEVOURER_TX_HT_MCS is set). CCK rates (1/2/5.5/11M) do not exist at 5GHz: the RTL8814AU silently drops a CCK-rated frame on a 5GHz channel -- the bulk-OUT completes (rc ok, 100% URB completion) but nothing goes on-air. 2.4GHz CCK transmits fine. On a 5GHz channel (Channel > 14), clamp a CCK fixed_rate to the lowest OFDM rate (MGN_6M). The 8812 chip happens to auto-fall-back CCK->OFDM at 5G; the 8814 does not, so devourer must do it in software. Verified on hardware (RTL8814AU 0bda:8813, 8821 kernel-monitor witness): 8814 TX at ch100 with the default rate goes 0 -> ~13770 on-air frames (6M OFDM, 11a); ch6 (2.4G CCK) unaffected. Addresses the 5GHz half of the 8814 devourer-TX on-air gate (#50). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/RtlJaguarDevice.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/RtlJaguarDevice.cpp b/src/RtlJaguarDevice.cpp index f10afca..b794afb 100644 --- a/src/RtlJaguarDevice.cpp +++ b/src/RtlJaguarDevice.cpp @@ -151,6 +151,19 @@ bool RtlJaguarDevice::send_packet(const uint8_t *packet, size_t length) { } } + /* CCK rates (1/2/5.5/11M) do not exist at 5GHz. The RTL8814AU silently + * drops a CCK-rated frame on a 5GHz channel — the bulk-OUT completes but + * nothing goes on-air (verified on hardware: default MGN_1M beacon = 0 + * frames at ch36/ch100, but ~14k on-air once the rate is OFDM). 2.4GHz + * CCK is fine. So on a 5GHz channel, clamp a CCK rate to the lowest OFDM + * rate. (The 8812 chip happens to auto-fall-back CCK->OFDM at 5G; the + * 8814 does not, so we must do it in software.) */ + if (_channel.Channel > 14 && + (fixed_rate == MGN_1M || fixed_rate == MGN_2M || + fixed_rate == MGN_5_5M || fixed_rate == MGN_11M)) { + fixed_rate = MGN_6M; + } + usb_frame = new uint8_t[usb_frame_length](); ptxdesc = (struct tx_desc *)usb_frame;