# DF-4723 — ath_tdma_settimers: 32-bit `(nexttbtt<<3)` truncation in the DBA/SWBA math vs full-range TU nexttbtt — beacon-timer corruption after ~6.2 days of TSF (acknowledged-unaudited wrap family)

**File:** `sys/dev/netif/ath/ath/if_ath_tdma.c` · **Severity:** Low · **Bucket:** base:dev (DoS) · **Confidence:** certain

## Root cause (path:line)

The file itself documents the un-audited wrap family (comment at
`if_ath_tdma.c:345-353`: "please audit it to ensure that when the TU values
programmed into the timers wrap at (2^31)-1 TSF, all the various terms wrap
consistently"). They do not:

- `nextslottu` is the **full 32-bit TU** value derived from the received
  beacon's TSF: `TSF_TO_TU(nextslot>>32, nextslot)` = `TSF >> 10` truncated
  to u32 (`if_ath_tdma.c:444`) — a monotonically growing value that reaches
  2^29 TU after **~6.2 days** of continuous TSF runtime (2^29 TU × 1024 µs).
  It is passed unclamped to `ath_tdma_settimers(sc, nextslottu, ...)`
  (`if_ath_tdma.c:576`).
- Inside `ath_tdma_settimers()` (`if_ath_tdma.c:137-189`):

```c
	bt.bt_nexttbtt = nexttbtt;                                    /* 143 */
	bt.bt_nextdba = (nexttbtt<<3) - sc->sc_tdmadbaprep;           /* 144 */
	bt.bt_nextswba = (nexttbtt<<3) - sc->sc_tdmaswbaprep;         /* 145 */
	bt.bt_nextatim = nexttbtt+1;                                  /* 146 */
```

`nexttbtt << 3` is **32-bit** unsigned arithmetic: it silently truncates for
`nexttbtt ≥ 2^29`, i.e. exactly when the TSF-derived TU value crosses
2^29 — wrapping the DBA/SWBA alert targets to small values (i.e. the past).

- Meanwhile the HAL truncates at a **different** point:
  `ar5416_beacon.c:48-50` writes `AR_NEXT_TBTT = TU_TO_USEC(bt_nexttbtt)`
  (= `<<10`, wraps at 2^22 TU) but `AR_NEXT_DBA/SWBA =
  ONE_EIGHTH_TU_TO_USEC(bt_nextdba/nextswba)` (built from the already-wrapped
  `<<3` values). The three timers therefore wrap **inconsistently**:
  nexttbtt stays coherent up to 2^22 TU while dba/swba corrupt from 2^29 TU.

Per the in-file comment (`if_ath_tdma.c:563-569`): "Negative jumps larger
than the beacon interval seem to cause the timers to stop and generally
cause instability" — i.e. after ~6.2 days of continuous TDMA operation the
station's beacon alert timers are programmed with wrapped garbage: SWBA/DBA
stop firing or fire continuously (interrupt storm), the TDMA link collapses
until reconfiguration (`ath_tdma_config` resets TSF via
`HAL_BEACON_RESET_TSF`, `if_ath_tdma.c:303-304`, which is why long-lived
TDMA sessions are required to hit it).

Related sub-issue in the same function family: `(nexttbtt<<3) - prep`
underflows (no saturation) whenever `nexttbtt` is small but `prep` is large,
and `bt.bt_nextatim = nexttbtt+1` wraps at 2^32-1.

## Impact

Correctness/availability (DoS of the TDMA link after ~6.2 days continuous
operation; possible SWBA interrupt storm). Requires admin-configured TDMA on
long-lived ATH infrastructure. Certain at the arithmetic level; the file's own
TODO confirms it was never audited upstream.

## Verification

Requires ~6.2 days of radio TSF runtime — not reproducible in the QEMU guest;
arithmetic verified by inspection (shift widths, types, HAL consumers).

## Recommended fix

Compute the DBA/SWBA targets in `u_int64_t` and truncate once, so all three
timers share one wrap point (and clamp the TSF-derived `nextslottu` to the
hardware timer domain before programming). See fix.diff.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
