--- a/sys/dev/netif/ath/ath/if_ath_tdma.c +++ b/sys/dev/netif/ath/ath/if_ath_tdma.c @@ -138,13 +138,25 @@ static void ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt, u_int32_t bintval) { struct ath_hal *ah = sc->sc_ah; HAL_BEACON_TIMERS bt; + u_int64_t dba, swba; bt.bt_intval = bintval | HAL_BEACON_ENA; bt.bt_nexttbtt = nexttbtt; - bt.bt_nextdba = (nexttbtt<<3) - sc->sc_tdmadbaprep; - bt.bt_nextswba = (nexttbtt<<3) - sc->sc_tdmaswbaprep; + /* + * DF-4723: nexttbtt is the full 32-bit TU value derived from the + * TSF; doing the TU -> 1/8 TU conversion in 32-bit truncated the + * DBA/SWBA targets once TSF crossed 2^29 TU (~6.2 days), wrapping + * the alert timers while bt_nexttbtt itself stayed coherent. + * Compute in 64-bit and truncate once so all three timers share + * one wrap point. + */ + dba = ((u_int64_t)nexttbtt << 3) - sc->sc_tdmadbaprep; + swba = ((u_int64_t)nexttbtt << 3) - sc->sc_tdmaswbaprep; + bt.bt_nextdba = (u_int32_t)dba; + bt.bt_nextswba = (u_int32_t)swba; bt.bt_nextatim = nexttbtt+1; /* Enables TBTT, DBA, SWBA timers by default */ bt.bt_flags = 0;