Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/DeviceConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ struct DeviceConfig {
struct Rx {
/* env: DEVOURER_RX_KEEP_CORRUPTED — pass frames that fail the 802.11 FCS
* (CRC32) or decryption-ICV check up to the host instead of dropping them
* at the WMAC filter (sets RCR ACRC32|AICV). Jaguar1 + Jaguar2. */
* at the MAC RX filter (Realtek: RCR ACRC32|AICV; MT7612U: its monitor
* RX filter). Jaguar1, Jaguar2, Jaguar3, the RTL8733B and the MT7612U;
* not ported on Kestrel, where it is silently inert. */
bool keep_corrupted = false;
/* env: DEVOURER_TX_WITH_RX — Jaguar3 only: keep the RX filters open and
* enable the RX path during a TX (InitWrite) bring-up so StartRxLoop can
Expand Down
24 changes: 19 additions & 5 deletions src/jaguar3/HalJaguar3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,13 @@ void HalJaguar3::rtw_hal_deinit() {
}

/* Monitor-mode RX configuration (devourer-specific; the vendor driver has no
* pure-monitor path). Accept all frames incl. CRC/ICV errors, append PHY status
* drvinfo (so parse_rx_8822c's drvinfo_size is consistent), all RX filter maps
* open. RCR bits: AAP/APM/AM/AB/ACF/AICV/ACRC32 + APP_PHYSTS. */
* pure-monitor path). Accept all frames, append PHY status drvinfo (so
* parse_rx_8822c's drvinfo_size is consistent), all RX filter maps open.
* RCR base 0xF410400F = AAP/APM/AM/AB + HTC_LOC_CTRL + PKTCTL_DLEN + VHT_DACK
* + APP_FCS/APP_MIC/APP_ICV/APP_PHYSTS (halmac_bit_8822c.h). ACRC32 (BIT8)
* and AICV (BIT9) are NOT in the base — the WMAC drops FCS/ICV-failed frames
* — and are added only under rx.keep_corrupted, same as Jaguar1/2 and the
* RTL8733B. */
void HalJaguar3::monitor_rx_cfg() {
constexpr uint16_t REG_RCR_8822C = 0x0608;
constexpr uint16_t REG_RXFLTMAP0_8822C = 0x06A0;
Expand All @@ -474,14 +478,24 @@ void HalJaguar3::monitor_rx_cfg() {
* MACRXEN(+ENSWBCN). init_mac_cfg only set CR=0x0F (DMA enable); without
* MACRXEN (BIT7) the MAC RX engine never runs — the structured-path RX gap. */
_device.rtw_write16(0x0100, 0x06FF);
/* accept-all + keep FCS/ICV-error frames + append phy-status (BIT28).
/* accept-all + append phy-status (BIT28 is inside the leading 0xF nibble).
* BIT0 (AAP) is what makes monitor mode promiscuous for unicast: without it
* the WMAC passes only broadcast/multicast/physical-match (APM|AM|AB) up,
* silently dropping unicast frames addressed to third parties — e.g. NDPA
* control frames and VHT beamforming reports, which is why the beamformee
* (whose arm programs the self-MAC to the NDPA RA) saw sounding frames while
* a plain monitor did not. */
_device.rtw_write32(REG_RCR_8822C, 0xF410400F | (1u << 28));
uint32_t rcr = 0xF410400F;
/* DEVOURER_RX_KEEP_CORRUPTED: also pass FCS/ICV-failed frames (ACRC32 BIT8,
* AICV BIT9). The vendor 8822E driver clears both in init_misc and on every
* opmode change except monitor; the RX descriptor's crc_err/icv_err bits
* (parse_rx_8822c) mark the frames so a FEC consumer can salvage them.
* Verified on one 8812EU unit: with the bits set, FCS-failed frames reach
* the host; without them the count is zero regardless of channel
* conditions. */
if (_cfg.rx.keep_corrupted)
rcr |= (1u << 8) | (1u << 9);
_device.rtw_write32(REG_RCR_8822C, rcr);
_device.rtw_write8(REG_RX_DRVINFO_SZ_8822C, 0x04);
_device.rtw_write16(REG_RXFLTMAP0_8822C, 0xFFFF);
_device.rtw_write16(REG_RXFLTMAP1_8822C, 0xFFFF);
Expand Down
48 changes: 48 additions & 0 deletions tests/keep_corrupted_j3_ab.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# A/B for DEVOURER_RX_KEEP_CORRUPTED on a Jaguar3 DUT: run rxdemo twice on the
# same channel (knob off, then on), count frames the host saw with the RX
# descriptor's crc_err bit set. Expected: 0 with the knob off (WMAC drops them),
# non-zero with it on — given any ambient traffic weak enough to fail FCS.
#
# sudo tests/keep_corrupted_j3_ab.sh <pid-hex> [channel] [seconds]
set -euo pipefail
PID=${1:?usage: $0 <pid-hex e.g. 0xc812> [channel] [seconds]}
CH=${2:-6}
SECS=${3:-20}
ROOT=$(cd "$(dirname "$0")/.." && pwd)
RX=$ROOT/build/rxdemo
OUT=${OUT:-/tmp/keep_corrupted_j3_ab}
mkdir -p "$OUT"
pids=()
cleanup() { for p in "${pids[@]:-}"; do [ -n "$p" ] && kill -INT "$p" 2>/dev/null || true; done; }
trap cleanup EXIT

run_cell() {
local knob=$1
local log=$OUT/pid${PID}_keep${knob}.jsonl
# The off arm scrubs the knob from the environment (env -u) rather than
# relying on the caller not having exported it; the on arm sets it. Events
# are forced to stdout because that is the stream the counts come from.
local env=(-u DEVOURER_RX_KEEP_CORRUPTED
DEVOURER_PID="$PID" DEVOURER_CHANNEL="$CH" DEVOURER_RX_DUMP_ALL=1
DEVOURER_EVENTS=stdout DEVOURER_LOG_LEVEL=warn)
[ "$knob" = 1 ] && env+=(DEVOURER_RX_KEEP_CORRUPTED=1)
env "${env[@]}" "$RX" >"$log" 2>"$log.err" &
local p=$!; pids+=("$p")
sleep "$SECS"
# A cell whose rxdemo is no longer running did not measure anything (device
# open / claim / bring-up failed) — refuse to print a zero as a result.
if ! kill -0 "$p" 2>/dev/null; then
local rc=0; wait "$p" 2>/dev/null || rc=$?
echo "FAIL: pid=$PID keep_corrupted=$knob rxdemo exited early (rc=$rc); stderr tail:" >&2
tail -n 5 "$log.err" >&2
exit 1
fi
kill -INT "$p" 2>/dev/null || true; wait "$p" 2>/dev/null || true
Comment thread
josephnef marked this conversation as resolved.
local total crc
total=$(grep -c -F '"ev":"rx.corrupt"' "$log" || true)
crc=$(grep -F '"ev":"rx.corrupt"' "$log" | grep -c -F '"crc":1' || true)
echo "pid=$PID keep_corrupted=$knob ch=$CH secs=$SECS frames=$total crc_err=$crc"
}
run_cell 0
run_cell 1
Loading