Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH ath-next] wifi: ath9k_htc: fix beacon slot selection once TSF exceeds 2^42 us
@ 2026-10-22 10:56 Felix K.
  2026-10-23 11:14 ` Toke Høiland-Jørgensen
  2026-10-23 15:18 ` Toke Høiland-Jørgensen
  0 siblings, 2 replies; 5+ messages in thread
From: Felix K. @ 2026-10-22 10:56 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen; +Cc: linux-wireless, Felix K., stable

ath9k_htc_choose_bslot() derives the beacon slot from the TSF reported
in the SWBA event as

	tsftu = TSF_TO_TU(tsf >> 32, tsf);
	slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval;

TSF_TO_TU() truncates its result to 32 bits, so tsftu is
(tsf / 1024) mod 2^32 and wraps every 2^42 us (~50.9 days). 2^32 is not
a multiple of the beacon interval (2^32 mod 100 = 96 for the default
of 100 TU), so every wrap shifts the computed position within the
beacon interval by 4 TU. Depending on where in the interval the SWBA
event arrives, the wrong slot is chosen after one or more wraps. The
state only recovers when the TSF is reset.

Compute the offset within the beacon interval from the 64-bit TSF
instead. For TSF values below 2^42 us and an even beacon interval the
result is identical to the old calculation. TSF_TO_TU() in htc.h has no
other user and is removed.

This is the same issue as in ath9k_beacon_choose_slot(), which is fixed
separately. Compile tested only, I do not have ath9k_htc hardware.

Fixes: 832f6a18fc2a ("ath9k_htc: Add beacon slots")
Cc: stable@vger.kernel.org
Signed-off-by: Felix K. <fk@mutemail.de>
---
 drivers/net/wireless/ath/ath9k/htc.h            |  2 --
 drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 10 +++++-----
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 4d2b75d02..59e0b3cf7 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -39,8 +39,6 @@
 #define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
 
 #define ATH_DEFAULT_BMISS_LIMIT 10
-#define TSF_TO_TU(_h, _l) \
-	((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
 
 extern struct ieee80211_ops ath9k_htc_ops;
 extern int htc_modparam_nohwcrypt;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 81fa7cbad..b478af150 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -266,20 +266,20 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
 {
 	struct ath_common *common = ath9k_hw_common(priv->ah);
 	u64 tsf;
-	u32 tsftu;
+	u32 offset;
 	u16 intval;
 	int slot;
 
 	intval = priv->cur_beacon_conf.beacon_interval;
 
 	tsf = be64_to_cpu(swba->tsf);
-	tsftu = TSF_TO_TU(tsf >> 32, tsf);
-	slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval;
+	div_u64_rem(tsf, TU_TO_USEC(intval), &offset);
+	slot = (offset * ATH9K_HTC_MAX_BCN_VIF) / TU_TO_USEC(intval);
 	slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1;
 
 	ath_dbg(common, BEACON,
-		"Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n",
-		slot, tsf, tsftu, intval);
+		"Choose slot: %d, tsf: %llu, offset: %u, intval: %u\n",
+		slot, tsf, offset, intval);
 
 	return slot;
 }
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-23 15:18 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-22 10:56 [PATCH ath-next] wifi: ath9k_htc: fix beacon slot selection once TSF exceeds 2^42 us Felix K.
2026-10-23 11:14 ` Toke Høiland-Jørgensen
2026-10-23 13:51   ` Mehmet Fide
2026-10-23 15:07     ` Toke Høiland-Jørgensen
2026-10-23 15:18 ` Toke Høiland-Jørgensen

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