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
94 changes: 52 additions & 42 deletions src/RadioManagementModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,65 +302,75 @@ void RadioManagementModule::phy_SwChnlAndSetBwMode8812() {
* temperatures. Capture both dumps within a few seconds for clean
* parity. */
if (std::getenv("DEVOURER_DUMP_CANARY")) {
static const uint16_t bb_canary[] = {
/* PHY/AGC anchors */
/* Per-chip canary set. Each Jaguar variant has a different active
* RF/path footprint:
* - 8821AU is 1T1R AC: only path-A exists physically. Path-B BB-AGC
* mirror (0xe20-0xe40) and RF[B] reads return BB-init defaults
* or sentinel zero — including them just clutters the diff.
* - 8812AU is 2T2R: paths A + B are both active.
* - 8814AU is 4T4R: paths A + B + C + D BB-table state is active.
* RF[C]/RF[D] are write-only by HW design (kaeru cite "RTL8814AU
* RF read mechanism — paths C/D write-only by HW design") so we
* skip RF reads for paths C and D.
* The MAC anchor set is chip-independent (same regs across the
* family). */

/* Shared anchors — PHY anchors + MAC: same for every Jaguar chip. */
static const uint16_t bb_anchors[] = {
0x808, 0x80c, 0x82c, 0x830, 0x834, 0x838, 0x84c, 0x860, 0x8ac,
0x8b0, 0x8c4,
/* Page-C path A: TX-AGC + AGC core */
0x8b0, 0x8c4};
static const uint16_t bb_pathA[] = {
/* Page-C path A: TX-AGC + AGC core + IQK/DPK output regs */
0xc00, 0xc1c, 0xc20, 0xc24, 0xc28, 0xc2c, 0xc30, 0xc34, 0xc38,
0xc3c, 0xc40, 0xc50, 0xc54, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70,
/* IQK / DPK output regs (path A): rOFDM0_X*TxIQImbalance,
* IQC matrix coefficients, IQK readback registers. */
0xc10, 0xc14, 0xc90, 0xc94,
/* Page-C path B: TX-AGC mirror of 0xc20-0xc40 (path-A AGC table
* is mirrored to path-B at 0xe20-0xe40 by PHY_SetTxPowerIndex_8812A
* for 2T2R chips; divergence here would surface a path-B-specific
* port bug we'd otherwise miss). */
0xc10, 0xc14, 0xc90, 0xc94};
static const uint16_t bb_pathB[] = {
/* Page-C path B: TX-AGC mirror of path-A + IQK/DPK output regs */
0xe1c, 0xe20, 0xe24, 0xe28, 0xe2c, 0xe30, 0xe34, 0xe38, 0xe3c,
0xe40, 0xe50, 0xe54,
/* IQK / DPK output regs (path B). */
0xe10, 0xe14, 0xe90, 0xe94};
0xe40, 0xe50, 0xe54, 0xe10, 0xe14, 0xe90, 0xe94};
static const uint16_t bb_pathC[] = {
/* 8814A path-C BB-table (0x18xx range, see hal/Hal8814PhyReg.h) */
0x1820, 0x1824, 0x1828, 0x182c, 0x1830, 0x1834, 0x1838, 0x183c,
0x1840, 0x181c, 0x1850};
static const uint16_t bb_pathD[] = {
/* 8814A path-D BB-table (0x1Axx range, see hal/Hal8814PhyReg.h) */
0x1a20, 0x1a24, 0x1a28, 0x1a2c, 0x1a30, 0x1a34, 0x1a38, 0x1a3c,
0x1a40, 0x1a1c, 0x1a50};
static const uint16_t mac_canary[] = {0x40, 0xcf, 0xf0, 0x100,
0x102, 0x420, 0x4c8, 0x508,
0x522, 0x550, 0x560, 0x610,
0x614};
static const uint32_t rf_canary[] = {0x00, 0x05, 0x18, 0x42, 0x65, 0x8f};

/* Chip-dependent path mask. */
const auto ictype = _eepromManager->version_id.ICType;
const bool has_pathB = (ictype != CHIP_8821);
const bool has_pathCD = (ictype == CHIP_8814A);

_logger->info("=== DEVOURER_DUMP_CANARY (post channel-set ch={}) ===",
unsigned(_currentChannel));
for (uint16_t a : bb_canary)
for (uint16_t a : bb_anchors)
_logger->info("BB 0x{:03x} = 0x{:08X}", a, _device.rtw_read32(a));
for (uint16_t a : bb_pathA)
_logger->info("BB 0x{:03x} = 0x{:08X}", a, _device.rtw_read32(a));
if (has_pathB)
for (uint16_t a : bb_pathB)
_logger->info("BB 0x{:03x} = 0x{:08X}", a, _device.rtw_read32(a));
if (has_pathCD) {
for (uint16_t a : bb_pathC)
_logger->info("BB 0x{:04x} = 0x{:08X}", a, _device.rtw_read32(a));
for (uint16_t a : bb_pathD)
_logger->info("BB 0x{:04x} = 0x{:08X}", a, _device.rtw_read32(a));
}
for (uint16_t a : mac_canary)
_logger->info("MAC 0x{:03x} = 0x{:08X}", a, _device.rtw_read32(a));
for (uint32_t a : rf_canary)
_logger->info("RF[A] 0x{:02x} = 0x{:05X}", a,
phy_query_rf_reg(RfPath::RF_PATH_A, a, 0xfffffu));
for (uint32_t a : rf_canary)
_logger->info("RF[B] 0x{:02x} = 0x{:05X}", a,
phy_query_rf_reg(RfPath::RF_PATH_B, a, 0xfffffu));

/* 8814AU extension: dump path-C/D BB-AGC + IGI + BB-swing. Paths C/D
* exist at BB-register-table level (0x18xx for path C, 0x1Axx for
* path D, see hal/Hal8814PhyReg.h). NB: the corresponding RF
* registers for paths C/D are write-only by HW design on 8814AU
* (see kaeru cite "RTL8814AU RF read mechanism — paths C/D
* write-only by HW design") — read attempts return undefined
* data, so we skip RF[C]/RF[D]. The BB-table state IS readable
* and is the canary surface for path-C/D init drift. */
if (_eepromManager->version_id.ICType == CHIP_8814A) {
static const uint16_t bb_canary_8814_pathCD[] = {
/* Path-C TX-AGC table */
0x1820, 0x1824, 0x1828, 0x182c, 0x1830, 0x1834, 0x1838, 0x183c,
0x1840,
/* Path-C BB-swing + IGI */
0x181c, 0x1850,
/* Path-D TX-AGC table */
0x1a20, 0x1a24, 0x1a28, 0x1a2c, 0x1a30, 0x1a34, 0x1a38, 0x1a3c,
0x1a40,
/* Path-D BB-swing + IGI */
0x1a1c, 0x1a50};
for (uint16_t a : bb_canary_8814_pathCD)
_logger->info("BB 0x{:04x} = 0x{:08X}", a, _device.rtw_read32(a));
}
if (has_pathB)
for (uint32_t a : rf_canary)
_logger->info("RF[B] 0x{:02x} = 0x{:05X}", a,
phy_query_rf_reg(RfPath::RF_PATH_B, a, 0xfffffu));
_logger->info("=== END DEVOURER_DUMP_CANARY ===");
}

Expand Down
78 changes: 56 additions & 22 deletions tools/canary_kernel_dump.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,32 @@ set -euo pipefail

if [[ $# -lt 2 ]]; then
echo "Usage: $0 <iface> <channel> [chip]" >&2
echo " chip: 8812 (default) | 8814" >&2
echo " chip: 8812 (default) | 8821 | 8814" >&2
exit 1
fi

IFACE="$1"
CHANNEL="$2"
CHIP="${3:-8812}"

case "$CHIP" in
8812|8821|8814) ;;
*)
echo "unknown chip '$CHIP' — must be 8812, 8821 or 8814" >&2
exit 1
;;
esac

# Per-chip path mask — mirrors the chip-aware dump in
# RadioManagementModule::phy_SwChnlAndSetBwMode8812. 8821 is 1T1R so
# path-B BB-AGC mirror + RF[B] reads return sentinel/default; skip
# them. 8814 has additional path-C/D BB-table state (RF[C]/RF[D] are
# HW write-only so RF is still A+B only).
HAS_PATHB=1
HAS_PATHCD=0
if [[ "$CHIP" = "8821" ]]; then HAS_PATHB=0; fi
if [[ "$CHIP" = "8814" ]]; then HAS_PATHCD=1; fi

if ! ip -o link show "$IFACE" >/dev/null 2>&1; then
echo "iface '$IFACE' not found — did you modprobe 88XXau?" >&2
exit 1
Expand All @@ -69,42 +87,58 @@ rfread() {

echo "=== DEVOURER_DUMP_CANARY (post channel-set ch=$CHANNEL) ==="

# BB canary set — same list as `RadioManagementModule::phy_SwChnlAndSetBwMode8812`
# emits when DEVOURER_DUMP_CANARY=1 is set. Keep the two lists in sync.
# Order matches `RadioManagementModule::phy_SwChnlAndSetBwMode8812`'s
# DEVOURER_DUMP_CANARY block exactly — keep the two in sync so the
# kernel + devourer captures line-diff cleanly.

# Shared anchors — PHY/AGC anchors common to every Jaguar chip.
for ADDR in 0x808 0x80c 0x82c 0x830 0x834 0x838 0x84c 0x860 0x8ac \
0x8b0 0x8c4 \
0xc00 0xc1c 0xc20 0xc24 0xc28 0xc2c 0xc30 \
0x8b0 0x8c4; do
printf "BB %s = %s\n" "$ADDR" "$(readreg $ADDR)"
done

# Path-A BB: TX-AGC + AGC core + IQK/DPK output regs.
for ADDR in 0xc00 0xc1c 0xc20 0xc24 0xc28 0xc2c 0xc30 \
0xc34 0xc38 0xc3c 0xc40 0xc50 0xc54 0xc60 0xc64 0xc68 \
0xc6c 0xc70 \
0xc10 0xc14 0xc90 0xc94 \
0xe1c 0xe20 0xe24 0xe28 0xe2c 0xe30 0xe34 0xe38 0xe3c \
0xe40 0xe50 0xe54 \
0xe10 0xe14 0xe90 0xe94; do
0xc10 0xc14 0xc90 0xc94; do
printf "BB %s = %s\n" "$ADDR" "$(readreg $ADDR)"
done

# Path-B BB: TX-AGC mirror + IQK/DPK output. Skipped on 1T1R 8821.
if [[ "$HAS_PATHB" = "1" ]]; then
for ADDR in 0xe1c 0xe20 0xe24 0xe28 0xe2c 0xe30 0xe34 0xe38 0xe3c \
0xe40 0xe50 0xe54 \
0xe10 0xe14 0xe90 0xe94; do
printf "BB %s = %s\n" "$ADDR" "$(readreg $ADDR)"
done
fi

# Path-C/D BB-AGC + BB-swing + IGI. 8814AU only.
if [[ "$HAS_PATHCD" = "1" ]]; then
for ADDR in 0x1820 0x1824 0x1828 0x182c 0x1830 0x1834 0x1838 0x183c \
0x1840 0x181c 0x1850 \
0x1a20 0x1a24 0x1a28 0x1a2c 0x1a30 0x1a34 0x1a38 0x1a3c \
0x1a40 0x1a1c 0x1a50; do
printf "BB %s = %s\n" "$ADDR" "$(readreg $ADDR)"
done
fi

# MAC anchors — chip-independent.
for ADDR in 0x040 0x0cf 0x0f0 0x100 0x102 0x420 0x4c8 0x508 \
0x522 0x550 0x560 0x610 0x614; do
printf "MAC %s = %s\n" "$ADDR" "$(readreg $ADDR)"
done

for PATH_IDX in 0 1; do
# RF: path A always; path B skipped on 1T1R; paths C/D never (write-only
# by HW design on 8814).
PATHS="0"
if [[ "$HAS_PATHB" = "1" ]]; then PATHS="0 1"; fi
for PATH_IDX in $PATHS; do
PATH_LBL=$([ "$PATH_IDX" = "0" ] && echo "A" || echo "B")
for RF in 0x00 0x05 0x18 0x42 0x65 0x8f; do
printf "RF[%s] %s = %s\n" "$PATH_LBL" "$RF" "$(rfread $PATH_IDX $RF)"
done
done

# 8814AU extension: path-C/D BB-AGC + IGI + BB-swing. RF[C]/RF[D]
# are write-only by HW design on 8814AU (read attempts return undefined
# data), so we only dump BB-table state for paths C/D.
if [[ "$CHIP" = "8814" ]]; then
for ADDR in 0x1820 0x1824 0x1828 0x182c 0x1830 0x1834 0x1838 0x183c \
0x1840 0x181c 0x1850 \
0x1a20 0x1a24 0x1a28 0x1a2c 0x1a30 0x1a34 0x1a38 0x1a3c \
0x1a40 0x1a1c 0x1a50; do
printf "BB %s = %s\n" "$ADDR" "$(readreg $ADDR)"
done
fi

echo "=== END DEVOURER_DUMP_CANARY ==="
Loading