Skip to content

Jaguar3: 40 MHz + 80 MHz TX/RX (incl. 40-in-80)#166

Merged
josephnef merged 1 commit into
masterfrom
jaguar3-40-80mhz-tx
Jul 4, 2026
Merged

Jaguar3: 40 MHz + 80 MHz TX/RX (incl. 40-in-80)#166
josephnef merged 1 commit into
masterfrom
jaguar3-40-80mhz-tx

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

What

Extends the Jaguar3 HAL beyond 20 MHz + the 5/10 MHz narrowband re-clock to full 40 MHz and 80 MHz channels, plus a 40-in-80 mode (a 40 MHz frame on an 80 MHz-tuned channel).

  • RadioManagementJaguar3::set_channel_bwmode ports the vendor config_phydm_switch_bandwidth CH_40 / CH_80 cases + the halmac cfg_bw / cfg_pri_ch_idx MAC-side (0x668, 0x483).
  • HT40 tunes the central channel (primary ± 2, DEVOURER_HOP_BW=40 / DEVOURER_HOP_OFFSET); 80 MHz takes the block's lowest 20 MHz as primary (DEVOURER_HOP_BW=80).
  • 40-in-80: a 40 MHz frame on an 80 MHz channel is placed on the lower 40 via the TX-descriptor DATA_SC field (VHT_DATA_SC_40_LOWER_OF_80MHZ) — the userspace equivalent of iw 80MHz + a 40 MHz radiotap. It rides the 80 MHz RF path and decodes on a standard HT40 receiver on the lower-40 channel.

Bug fixed along the way

The 8822c RF18 channel-tune is a read-modify-write whose mask (~0x703ff) preserved the BW bits [13:12], so a 40/80 MHz tune kept a prior tune's BIT12 and ended up 20 MHz-RF while BB/descriptor said 40/80 — halting the TX engine on the CU. The vendor clears BIT13|BIT12 first; the mask is now ~0x733ff. (The 8822e uses a plain RF18 write and was unaffected.)

Details

  • RF18 BW bits: BW20 = BIT13|BIT12, BW40 = BIT13, BW80 = BIT12.
  • Per-variant RXBB (8822c RF 0x3f = 0x18/0x10/0x08; 8822e RF 0x1a).
  • 80 MHz decimation/DFIR (0x810/0x88c/0x1944/0x4044) matched against a register dump of the kernel's iw 149 80MHz.
  • halrf_ex_dac_fifo_rst after the wide-BW TXCK change (vendor parity).
  • 8822e per-channel IQK runs for all widths (iqk_bw derives 0/1/2 from RF18[13:12], kernel-correct).
  • FrameParserJaguar3 gains SET_TX_DESC_DATA_SC_8822C.
  • txdemo adds DEVOURER_TX_MAXFAIL; jaguar3_devourer_run.sh passes HOP_BW/HOP_OFFSET/TX_RATE/TX_MAXFAIL/TX_PAYLOAD_BYTES through. DEVOURER_TX_RF_BW is a debug/research knob on the 40 MHz path.

Validation (RTL8812EU, USRP B210 + a standard rtw88 HT40 monitor)

  • 20/10/5 MHz SDR narrowband regression unchanged.
  • Native 40 MHz decodes ~14.8k frames/12s under 800-byte saturation.
  • 40-in-80 (HOP_BW=80, ch36 block) decodes 12.3k frames on the lower-40 channel (ch36 HT40+) and ~0 on the upper-40 (ch44) — confirming the DATA_SC placement.

🤖 Generated with Claude Code

Extend RadioManagementJaguar3::set_channel_bwmode beyond 20 MHz and the
5/10 MHz narrowband re-clock to full 40 MHz and 80 MHz, ported from the
vendor config_phydm_switch_bandwidth CH_40 / CH_80 cases plus the halmac
cfg_bw / cfg_pri_ch_idx MAC-side (REG_WMAC_TRXPTCL_CTL 0x668, REG_DATA_SC
0x483). HT40 tunes the central channel (primary ± 2); 80 MHz takes the
block's lowest 20 MHz as primary (central = +6 ch).

Also adds a 40-in-80 mode: a 40 MHz frame on an 80 MHz-tuned channel, placed
on the lower 40 via the TX-descriptor DATA_SC field (VHT_DATA_SC_40_LOWER_OF
_80MHZ) — the userspace equivalent of `iw 80MHz` + a 40 MHz radiotap. The
40 MHz frame rides the 80 MHz RF path and decodes on a standard HT40 receiver
on the lower-40 channel.

Bug fixed along the way: the 8822c RF18 channel-tune is a read-modify-write
whose mask (~0x703ff) preserved the BW bits [13:12], so a 40/80 MHz tune kept
a prior tune's BIT12 and ended up 20 MHz-RF while BB/descriptor said 40/80 —
which halted the TX engine on the CU. The vendor clears BIT13|BIT12 first;
the mask is now ~0x733ff. (The 8822e uses a plain RF18 write and was
unaffected.)

Details: RF18 BW bits BW20=BIT13|BIT12 / BW40=BIT13 / BW80=BIT12; per-variant
RXBB (8822c RF 0x3f 0x18/0x10/0x08, 8822e RF 0x1a); the 80 MHz decimation/DFIR
set (0x810/0x88c/0x1944/0x4044) matched against a register dump of the kernel's
`iw 149 80MHz`; and halrf_ex_dac_fifo_rst after the wide-BW TXCK change for
vendor parity. The 8822e per-channel IQK runs for all widths (iqk_bw derives
0/1/2 from RF18[13:12], kernel-correct).

Demo/harness: FrameParserJaguar3 gains SET_TX_DESC_DATA_SC_8822C; txdemo adds
DEVOURER_TX_MAXFAIL (raise the bulk-OUT abort threshold for sustained-TX
benchmarking); jaguar3_devourer_run.sh passes HOP_BW/HOP_OFFSET/TX_RATE/
TX_MAXFAIL/TX_PAYLOAD_BYTES through. DEVOURER_TX_RF_BW is a debug/research knob
on the 40 MHz path (override 0x9b0[1:0]).

Validated on-air (RTL8812EU, USRP B210 + a standard rtw88 HT40 monitor):
20/10/5 MHz SDR regression unchanged; native 40 MHz decodes ~14.8k frames/12s
under 800-byte saturation; 40-in-80 (ch149-block via HOP_BW=80) decodes 12.3k
frames on the lower-40 channel (ch36 HT40+) and ~0 on the upper-40 (ch44),
confirming the DATA_SC placement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef josephnef force-pushed the jaguar3-40-80mhz-tx branch from 8168dca to 5effa35 Compare July 4, 2026 16:04
@josephnef josephnef merged commit 9f887f8 into master Jul 4, 2026
13 checks passed
@josephnef josephnef deleted the jaguar3-40-80mhz-tx branch July 4, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant