mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH wireless-next] wifi: b43: fix missing beacons by starting at the next TBTT
@ 2026-11-02 23:59 Marco Martins
  0 siblings, 0 replies; only message in thread
From: Marco Martins @ 2026-11-02 23:59 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Michael Büsch, b43-dev, linux-kernel

b43_set_beacon_int() programs the first TBTT one beacon interval after
zero, as if the TSF started there. The hardware compares it with the
low 32 bits of the TSF. Up to 2^31 us past it, it moves it on by whole
intervals and beacons. Further past, it leaves it and sends no beacons:
on a BCM5352 (core rev 9, firmware 666) the TBTT stayed at 0x19000 for
over six minutes while the low 32 bits of the TSF ran from 0xd1d508fa
to 0xe7f71356.

Without beacons there are no DTIMs, so the frames held in the multicast
ring for stations in power save are never sent. The ring fills and b43
stops the queue of the frame that filled it, best effort for most
broadcasts: stations still associate, but get no DHCP lease.

The TSF is not reset when beaconing starts, so an AP that starts with
the low 32 bits of the TSF in the upper half of their range does not
beacon. With one interface, starting the radio resets the TSF, so this
needs beaconing to start again while the radio stays up, or a TSF taken
from other stations in IBSS or mesh mode. The first was tested: hostapd
stopped and started again on an interface it had found up, which it
leaves up, with the TSF set to 50 minutes in between by b43_tsf_write().
The TBTT stayed at 0x19000 and no TBTT interrupt came for over 20
seconds; with this patch the TBTT was just ahead of the TSF and the
interrupts went on. IBSS and mesh were not tested.

This was found with an out-of-tree patch that runs a station and an AP
on one b43 radio, as a repeater: the station interface keeps the radio
up and synchronises the TSF to its AP, and an AP restarted beside it did
not beacon whenever it started in that half. With this patch it did, in
the same half.

Where the hardware does move the TBTT on, the beacons go out at
multiples of the interval in the low 32 bits only, which are not the
TBTTs once the TSF has passed 2^32 us: 2^32 us is 4 TU more than a
multiple of 100 TU, so they are 4 TU off for every 2^32 us the TSF had
run when beaconing started.

Program the next TBTT from the TSF instead, as ath5k does.

The bug was found, and this patch and its description written, with an
AI coding assistant (Claude Code, model Claude Opus 5.5), asked to find
why phones got no DHCP lease from the repeater after its AP restarted.
It read b43 and mac80211, added debug hooks to b43 that dump the TSF,
the TBTT registers and the DMA rings, and ran the tests on the device.

Fixes: a82d992261f7 ("b43: Beaconing fixes")
Signed-off-by: Marco Martins <marcomartins86@gmail.com>
---
Tested on an ASUS WL-320gE (BCM5352) running OpenWrt 25.12 (backports
6.18, built for MIPS without warnings) with the out-of-tree station and
AP patch: as a repeater, and as a plain AP with one interface.

Not done: no build or run of wireless-next or mainline itself, only of
the same function in backports 6.18; IBSS and mesh not tested; the
single-interface test set the TSF with a debug hook instead of waiting
50 minutes; beaconing resuming when the low 32 bits of the TSF wrap
around was not observed.

 drivers/net/wireless/broadcom/b43/main.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
index 3825b6a..5fa3cd9 100644
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -1852,10 +1852,22 @@ static void b43_update_templates(struct b43_wl *wl)
 
 static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
 {
+	u64 tsf;
+	u32 rem;
+
 	b43_time_lock(dev);
 	if (dev->dev->core_rev >= 3) {
+		/* Start at the next TBTT, the next multiple of the beacon
+		 * interval on the TSF. The TSF need not be near zero, and the
+		 * hardware sends no beacons for a start more than 2^31 us
+		 * behind it.
+		 */
+		b43_tsf_read(dev, &tsf);
+		tsf >>= 10;
+		div_u64_rem(tsf, beacon_int, &rem);
+		tsf += beacon_int - rem;
 		b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));
-		b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));
+		b43_write32(dev, B43_MMIO_TSF_CFP_START, lower_32_bits(tsf << 10));
 	} else {
 		b43_write16(dev, 0x606, (beacon_int >> 6));
 		b43_write16(dev, 0x610, beacon_int);

base-commit: 991a73f4909f1348ffb4b38765cdb522a775e4c2
-- 
2.53.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-03  0:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02 23:59 [PATCH wireless-next] wifi: b43: fix missing beacons by starting at the next TBTT Marco Martins

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®