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
12 changes: 12 additions & 0 deletions src/jaguar1/HalModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,18 @@ bool HalModule::rtl8812au_hal_init(uint8_t init_channel) {

void HalModule::rtw_hal_deinit() {
_logger->info("Jaguar1: clean de-init (stop TRX + card-disable)");
/* Stop the phydm watchdog FIRST, before any of the writes below. Its
* thread does periodic BB reads/writes (FA counters, DIG on 0xc50/0xe50,
* the EDCCA thresholds), and everything after this point is tearing the
* chip down underneath it — MAC engines off, RX FIFO off, then the
* card-disable power sequence. Left running it races register access
* against power-off, which is the teardown-ordering hazard this driver
* takes seriously everywhere else. Stop() is idempotent (it
* compare-exchanges _running), so the destructor's own Stop() after this
* is a no-op, and a chip torn down twice is still safe. Null whenever
* tuning.phydm_watchdog did not build one, which is the default. */
if (_phydmWatchdog)
_phydmWatchdog->Stop();
/* Halt the MAC engines before pulling power out from under them, so the
* sequence isn't racing DMA that is still moving frames. Mirrors
* HalJaguar3::rtw_hal_deinit. */
Expand Down
25 changes: 22 additions & 3 deletions tests/cca_gates_probe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
*
* sudo build/CcaGatesProbe --pid 0xc812 --channel 36
* sudo build/CcaGatesProbe --pid 0x8812 --channel 36 --hold 12
* sudo build/CcaGatesProbe --pid 0x0120 --vid 0x2357 --phydm-watchdog
*
* --phydm-watchdog builds Jaguar1's optional phydm thread. Its EDCCA
* tracker is what SetCcaGates has to stop, and it does not exist without
* it, so the tracker cell needs this on Jaguar1 (Jaguar3 ignores it).
* A test lever, not a hint at a better default: that thread is opt-in
* because its periodic BB traffic shares the libusb queue with the TX bulk
* path and costs throughput (see HalModule). This probe never transmits,
* so it pays none of that.
*
* --hold N keeps each state applied for N seconds so an external peek can
* sample it. Exit 0 = every step behaved; 4 = not a Realtek radio; 5 = the
Expand Down Expand Up @@ -56,7 +65,7 @@ void report(const char *tag, bool ret, bool primary, bool edcca) {

int main(int argc, char **argv) {
uint16_t vid = 0x0bda, pid = 0xc812;
int channel = 36, retune = 0, fast_retune = 0, hold = 0;
int channel = 36, retune = 0, fast_retune = 0, hold = 0, phydm_wd = 0;
for (int i = 1; i < argc; i++) {
if (!std::strcmp(argv[i], "--vid") && i + 1 < argc)
vid = (uint16_t)std::strtoul(argv[++i], nullptr, 0);
Expand All @@ -70,6 +79,8 @@ int main(int argc, char **argv) {
fast_retune = std::atoi(argv[++i]);
else if (!std::strcmp(argv[i], "--hold") && i + 1 < argc)
hold = std::atoi(argv[++i]);
else if (!std::strcmp(argv[i], "--phydm-watchdog"))
phydm_wd = 1;
}

auto logger = std::make_shared<Logger>();
Expand All @@ -95,6 +106,13 @@ int main(int argc, char **argv) {
session.adopt_lock(lock);

devourer::DeviceConfig cfg;
/* Jaguar1's EDCCA tracker only EXISTS when the phydm watchdog is built —
* HalModule constructs it solely under tuning.phydm_watchdog, which is off
* by default. Without this the tracker cell has nothing to catch tracking,
* and reports "no tracker running" on a backend whose tracking path is
* simply not instantiated. Jaguar3 ignores the field (its phydm runtime
* rides the RX/coex thread), so passing it there costs nothing. */
cfg.tuning.phydm_watchdog = phydm_wd != 0;
Comment thread
josephnef marked this conversation as resolved.
WiFiDriver driver(logger);
std::unique_ptr<IRadio> owned = driver.CreateRadio(handle, ctx, lock, cfg);
if (!owned) {
Expand All @@ -114,8 +132,9 @@ int main(int argc, char **argv) {
* pokes the wrong one reports "no tracker running" instead of failing —
* a false negative on exactly the arm the split exists to serve. Caps are
* resolved at construction, so this is readable before bring-up. */
std::printf("GATES-GEN %s\n",
devourer::generation_name(dev->GetAdapterCaps().generation));
std::printf("GATES-GEN %s phydm_watchdog=%d\n",
devourer::generation_name(dev->GetAdapterCaps().generation),
phydm_wd);
Comment thread
josephnef marked this conversation as resolved.
std::fflush(stdout);

/* Pre-bring-up: both calls must refuse, and the refusal must not write the
Expand Down
31 changes: 26 additions & 5 deletions tests/cca_gates_regcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,18 @@
# poking the other family's register reports "no tracker" and
# passes a broken tracker silently. Skipped where no tracker runs
# in the default arm, or where the generation has no known
# threshold register.
# threshold register. Runs the probe with --phydm-watchdog:
# Jaguar1's tracker IS the optional phydm thread, off by default,
# so without it this cell measures a backend whose tracking path
# was never built and calls that "no tracker".
# DEPENDS ON DIG BEING IN MOTION. The tracker is write-on-change
# (l2h != _edcca_last_l2h), so it only rewrites the marker while
# DIG is still walking IGI. Each arm restarts the probe, so DIG
# restarts with it and is walking during the sample window; if it
# has converged instead, the default arm reads as "no tracker"
# and the EDCCA-off arm SKIPs. That degrades to no verdict rather
# than a false one, but a SKIP here means the cell could not
# create the condition, not that the tracker behaved.
# retune the state survives SetMonitorChannel and FastRetune, within a
# band and across a band change. Jaguar3 re-asserts by design;
# Jaguar1 merely is not clobbered (see src/IRtlRadio.h) — so this
Expand All @@ -51,6 +62,12 @@
#
# Usage: sudo -v && tests/cca_gates_regcheck.sh # every plugged part
# PIDS=0xc812 sudo -v && tests/cca_gates_regcheck.sh
# VID=0x2357 PIDS=0x0120 tests/cca_gates_regcheck.sh # non-Realtek VID
#
# VID applies to the register peeks as well as the probe, so an adapter that
# enumerates under a vendor's own VID (TP-Link 0x2357, and most retail parts)
# is checkable — addressing chipstate by PID alone silently looked for it
# under 0x0bda and failed every register cell.
set -u
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="${CCA_GATES_OUT:-/tmp/devourer-cca-gates}"
Expand Down Expand Up @@ -100,7 +117,7 @@ done
# dead probe, i.e. the default arm would pass on no evidence.
peek32() { # $1=pid $2=addr
local bytes n
bytes=$(sudo -n "$BUILD/chipstate" --pid "$1" --no-claim \
bytes=$(sudo -n "$BUILD/chipstate" --vid "$VID" --pid "$1" --no-claim \
--peek "$(printf '0x%x-0x%x' "$2" $(( $2 + 3 )))" 2>&1 |
sed -n 's/^0x[0-9a-fA-F]\{4\}://p' | tr -s ' ' '\n' |
grep -E '^[0-9a-f]{2}$' | head -4)
Expand All @@ -109,7 +126,7 @@ peek32() { # $1=pid $2=addr
printf '%s\n' "$bytes" |
awk '{b[NR]=strtonum("0x"$1)} END{printf "%u\n", b[1]+b[2]*256+b[3]*65536+b[4]*16777216}'
}
poke32() { sudo -n "$BUILD/chipstate" --pid "$1" --no-claim \
poke32() { sudo -n "$BUILD/chipstate" --vid "$VID" --pid "$1" --no-claim \
--poke "$(printf '0x%x=0x%x:4' "$2" "$3")" >/dev/null 2>&1; }
bit() { echo $(( ( $1 >> $2 ) & 1 )); }

Expand Down Expand Up @@ -185,7 +202,7 @@ for pid in $PIDS; do
[ $rc -eq 0 ] && pass "$pid api: probe walk clean" \
|| fail "$pid api: probe reported failures (see $log)"

gen=$(sed -n 's/^GATES-GEN //p' "$log" | head -1)
gen=$(sed -n 's/^GATES-GEN //p' "$log" | head -1 | cut -d' ' -f1)
note "$pid generation: ${gen:-unknown}"

# --- regs + cntdown ---------------------------------------------------
Expand Down Expand Up @@ -282,7 +299,11 @@ for pid in $PIDS; do
for arm in "0 0" "0 1"; do
set -- $arm; want_p=$1; want_e=$2
tlog="$OUT/track-$pid-$want_p$want_e.log"
start_hold "$pid" "$tlog"
# --phydm-watchdog because Jaguar1's EDCCA tracker is only built when
# tuning.phydm_watchdog is set; without it this cell measures a
# backend whose tracking path was never instantiated and calls that
# "no tracker". Jaguar3 ignores the flag.
start_hold "$pid" "$tlog" --phydm-watchdog
if ! wait_marker "$tlog" "^GATES set-primary$want_p-edcca$want_e "; then
fail "$pid track: probe never reported primary=$want_p edcca=$want_e"
stop_hold; continue
Expand Down
Loading