You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 4e896fd
Browse filesBrowse the repository at this point in the historyBrowse files
kestrel: hardware ACK responder on the 8852C (#489)
## The problem
On the 8852C, `SetAckResponder` refused: the firmware ignores the
addr_cam H2C altogether. After it, neither the address CAM entry nor the
BSSID CAM entry it carries is written, and nothing changed that: a
byte-for-byte replay of the vendor Windows driver's association H2Cs
(CMAC table, DMAC table, join_info, addr_cam), a join_info alone, and a
64-byte addr_cam. The same replay commits on the 8852B.
## The change
- On the 8852C the arm writes the station entry from the host
(`HalKestrel::write_addr_cam_sta`), the way the vendor's
`mac_upd_addr_cam` does when the firmware is not running: VALID cleared
first (a retarget rewrites a live entry), then the body, then VALID. No
H2C is sent, and the clear is the host clear alone. The 8852B path is
unchanged.
- The address CAM stride is per die (`addr_cam_entry_addr`), as the
vendor's `get_addr_cam_size` lays it out: 0x40 on the 8852B, 0x20 on the
8852C, 128 entries on both. `HalKestrel` used 0x40 on both before; it
only mattered on the 8852C.
- The responder's slot is per die (`ack_slot()`): 127 on the 8852B, as
before, and 63 on the 8852C. `RegisterPeerSta` / `RegisterBeamformee`
keep refusing it, and now also refuse an ADDR_CAM index past the
128-entry CAM.
- The station entry encoding moves to `KestrelAddrCam.h`, shared by the
8852B's addr_cam H2C (the payload is byte-identical to before) and the
8852C's host write. A new headless selftest, `kestrel_addr_cam`, pins it
against hardware read-backs: an entry the 8852B firmware committed, and
one the host wrote on an 8852C.
- The response-abort gate clear is mandatory on this die: its EDCCA
reads its own floor as busy, and with the gates armed every ACK was
dropped (0/2060, 0/2019).
- The host write reports a failed register transfer (it stops before
setting VALID again), and the arm on the 8852C is confirmed by reading
the whole entry back, every dword the hardware backs (dword 5 reads
`0xdeadbeef` on this die whatever is written), not only VALID and the
address.
- `ack_responder_ok` is true on the 8852B only (`== C8852B`) and false
on the 8852C: a dead session reads its entry back like a good one, so
the flag could not tell a caller the loop closes. `SetAckResponder`
still arms the 8852C (below).
- rxdemo's disarm message, `AdapterCaps.h` and
`docs/kestrel-ack-responder.md` are updated.
## Measured
TX50UH (RTL8832CU) as responder, TX20U Nano (RTL8852BU) soliciting and
counting the ACKs it receives, ch161, MCS1, one attempt per frame, 10 s
per cell, 3 runs per row. This matrix was taken with the entry at
hardware entry 126 (the 0x40-stride layout); the re-measurement at entry
63 follows it.
| row | ACKs | per run |
|---|---|---|
| armed at Init (rxdemo) | 13831/14041 | 99.3 / 96.6 / 99.5 |
| armed at InitWrite (txdemo) | 9439/9639 (two live runs) | 98.9 / dead
session / 97.0 |
| retargeted (second MAC) | 14239/14408 | 98.9 / 99.0 / 98.6 |
| old address after the retarget | 0/5993 | 0 / 0 / 0 |
| never armed | 0/6062 | 0 / 0 / 0 |
Arm A, retarget to B, clear, re-arm A in one session: correct in the
live run (A 98.3%, then A 0% / B 99.0%, both 0% after the clear, A 99.0%
after the re-arm); the other two runs were dead sessions. Injection
delivery to a witness is unchanged armed vs unarmed. The long RX
descriptor shows every frame addressed to the responder matching the
host-written entry (macid 63).
At hardware entry 63 (8 s per cell): live disarm with the solicitor
running across it in one session, 3812/3837 then 0/1616 and 3846/3848
then 0/1623 (a third cell was a dead session); 15 armed sessions back to
back, 9 answering 97.5-99.9% and 6 dead.
8852B regression on this code (0x40 stride, unchanged): 3 sessions
99.8-99.9%, live disarm across the solicitor 3842/3848 then 0/1773.
Earlier, at the first revision: 99.5-99.8% armed and retargeted, 0 after
a live disarm, the arm/retarget/clear/re-arm cycle correct, still on
slot 127.
Full MSVC build and `ctest` pass (79 tests on Windows).
## What this does not solve
Some 8852C bring-ups answer no ACK at all: the responder arms, the entry
reads back, the adapter airs its own frames, and it answers nothing for
the whole session. How often varies, and no cause is established: 3 of
12 and 6 of 15 sessions here, and on the maintainer's bench 8 of 21 at
entry 126 and 1 of 16 at entry 63. Dead sessions come interleaved with
good ones, a VBUS cold cycle before every session lowered the rate but
did not remove it, and the thermal meter stayed flat, so it is not read
as thermal or uptime-related.
In failed sessions the MAC configuration registers are identical to a
good session's, and the response abort counters stay at 0 (the response
is never attempted). What does differ is that the MAC classifies the
soliciting frames as its own BSS's traffic (`R_AX_WMAC_NAV_UP_INFO`
records intra-BSS NAV updates, `R_AX_PS_RXINFO` flags port-0 data).
Ruled out by measurement: the response NAV checks, the BSSID CAM, the
injector, the host's per-frame RX cost, and arm timing. The doc lists
what was measured. I don't have the cause yet.
One bench, one pair of dongles, near field.
0 commit comments