Summary
Follow-up to the passive noise-floor in #201 (GetRxQuality().noise_floor_dbm = rssi_dbm - snr_db). I attempted the vendor active / frame-free absolute noise floor (odm_inband_noise_monitor_ac) on Jaguar1 (8812AU), measured it, and it is NOT safe to ship as a live-pollable metric — it intermittently wedges the RX path. Filing so someone can pick up a wedge-free variant and/or the J2/J3 ports.
What was ported (Jaguar1 8812/8821/8814 — the debug-port I/Q path)
Vendor reference/rtl88x2bu/hal/phydm/phydm_noisemonitor.c:254 odm_inband_noise_monitor_ac. Per sample:
save IGI (0x0C50[6:0])
loop until 5 valid samples (invalid cap 10):
0x0C50[6:0] = 0x1C # fix IGI
0x08B4[6] = 1 # stop CK320 & CK88
0x08FC = 0x200 # debug port -> RX I/Q buffer (path A)
v = read 0x0FA0 # rxi=v[19:10], rxq=v[9:0], pd_flag=v[31]
if !pd_flag or rxi!=0x200: pwdb = pwdb_conv(sign(rxi)^2+sign(rxq)^2, 20,18)
0x08B4[6] = 0 # restart clocks
BB reset: 0x0002[0] 0->1
PMAC reset: 0x0B03[0] 0->1
CCK reset: if 0x080B[4]: 0x080B[4] 0->1
accept pwdb in [-27,0)
noise_dbm = sum/5 + 12 + 0x1C - 110 - 3
restore IGI
Ported the two phydm_math_lib helpers (odm_sign_conversion, odm_pwdb_conversion) verbatim.
Measured (8812AU, monitor mode)
- It works + returns a sane number: −91…−96 dBm idle floor on 5 GHz ch36 (thermal −101 dBm + ~7 dB NF — realistic). I/Q values vary per read. So the debug-port sampling DOES function in devourer's monitor-mode bring-up.
- Cost:
read_us ≈ 40–76 ms per measurement (dominated by the ~15 USB control round-trips, not baseband downtime).
- The blocker — intermittent RX wedge: polling it once/second alongside a live
StartRxLoop, 2 of 6 runs delivered 0 frames (canonical-SA hits: 4800, 0, 3900, 4100, 0, 4000). The clock-stop (0x08B4[6]) + BB/PMAC/CCK resets collide with the concurrent bulk-IN RX DMA and hang the RX engine ~33% of the time. The vendor runs this with DIG paused but without a userspace bulk-RX loop competing for the same USB/BB — devourer always has RX live.
Disposition
What would make it shippable (help wanted)
- A wedge-free variant: pause/drain the RX URB queue around the ~60 ms measurement (a
StopRxLoop/StartRxLoop bracket, or a dedicated quiescent window), so it's only ever run RX-idle — matches Fluke's first-boot CAL run (LOS, ~2 min, no live link) rather than a live poll.
- Or a path that doesn't stop CK320/CK88 (the likely wedge cause) — unclear if a valid I/Q sample is obtainable without it.
- The J2/J3 ports (
phydm_idle_noise_measure_ac for 8822B/8821C; the reference/rtl88x2cu variant for 8822C/E) — distinct registers, unattempted; J3 has no background DIG so its path differs most.
Refs: #201 (passive noise floor, shipped), #199 (dis_cca, same measure-first-null discipline).
Summary
Follow-up to the passive noise-floor in #201 (
GetRxQuality().noise_floor_dbm = rssi_dbm - snr_db). I attempted the vendor active / frame-free absolute noise floor (odm_inband_noise_monitor_ac) on Jaguar1 (8812AU), measured it, and it is NOT safe to ship as a live-pollable metric — it intermittently wedges the RX path. Filing so someone can pick up a wedge-free variant and/or the J2/J3 ports.What was ported (Jaguar1 8812/8821/8814 — the debug-port I/Q path)
Vendor
reference/rtl88x2bu/hal/phydm/phydm_noisemonitor.c:254odm_inband_noise_monitor_ac. Per sample:Ported the two
phydm_math_libhelpers (odm_sign_conversion,odm_pwdb_conversion) verbatim.Measured (8812AU, monitor mode)
read_us ≈ 40–76 msper measurement (dominated by the ~15 USB control round-trips, not baseband downtime).StartRxLoop, 2 of 6 runs delivered 0 frames (canonical-SA hits: 4800, 0, 3900, 4100, 0, 4000). The clock-stop (0x08B4[6]) + BB/PMAC/CCK resets collide with the concurrent bulk-IN RX DMA and hang the RX engine ~33% of the time. The vendor runs this with DIG paused but without a userspace bulk-RX loop competing for the same USB/BB — devourer always has RX live.Disposition
nf rises as SNR drops under a raised floor) with zero RX disruption, so the active floor's only edge (frame-free / no wanted frame) doesn't justify a 33% RX-wedge risk on a live link.What would make it shippable (help wanted)
StopRxLoop/StartRxLoopbracket, or a dedicated quiescent window), so it's only ever run RX-idle — matches Fluke's first-boot CAL run (LOS, ~2 min, no live link) rather than a live poll.phydm_idle_noise_measure_acfor 8822B/8821C; thereference/rtl88x2cuvariant for 8822C/E) — distinct registers, unattempted; J3 has no background DIG so its path differs most.Refs: #201 (passive noise floor, shipped), #199 (dis_cca, same measure-first-null discipline).