@@ -593,10 +593,27 @@ u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
*/
u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
{
- u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ u32 tsf_lower, tsf_upper;
+
+ /*
+ * While reading TSF upper and then lower part, the clock is still
+ * counting so the lower part can rollover just after reading the
+ * upper part. In this case, we expect the lower part to be quite
+ * small (let's say less than 100us) and we would just need to read
+ * the upper part again to get the correct value.
+ *
+ * Tested on AR2425 (AR5001)
+ */
+
+ tsf_upper = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+
+ if (tsf_lower < 100)
+ tsf_upper = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+
ATH5K_TRACE(ah->ah_sc);
- return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
+ return (((u64)tsf_upper << 32) | tsf_lower);
}
/**