return ktime_to_us(ktime_get_boottime());
}
+static ktime_t mac80211_hwsim_tsf_to_boottime(struct mac80211_hwsim_data *data,
+ u64 tsf)
+{
+ return us_to_ktime(tsf - data->tsf_offset);
+}
+
u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
{
struct mac80211_hwsim_data *data = hw->priv;
u64 now = mac80211_hwsim_get_tsf(hw, vif);
- /* MLD not supported here */
- u32 bcn_int = data->link_data[0].beacon_int;
u64 delta = abs(tsf - now);
struct ieee80211_bss_conf *conf;
return;
/* adjust after beaconing with new timestamp at old TBTT */
- if (tsf > now) {
+ if (tsf > now)
data->tsf_offset += delta;
- data->bcn_delta = do_div(delta, bcn_int);
- } else {
+ else
data->tsf_offset -= delta;
- data->bcn_delta = -(s64)do_div(delta, bcn_int);
- }
}
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
container_of(link_data, struct mac80211_hwsim_data,
link_data[link_data->link_id]);
struct ieee80211_hw *hw = data->hw;
- u64 bcn_int = link_data->beacon_int;
+ u32 remainder;
+ u64 tsf_now;
+ u64 tbtt;
if (!data->started)
return HRTIMER_NORESTART;
hw, IEEE80211_IFACE_ITER_NORMAL,
mac80211_hwsim_beacon_tx, link_data);
- /* beacon at new TBTT + beacon interval */
- if (data->bcn_delta) {
- bcn_int -= data->bcn_delta;
- data->bcn_delta = 0;
- }
- hrtimer_forward_now(&link_data->beacon_timer,
- ns_to_ktime(bcn_int * NSEC_PER_USEC));
+ /* TSF is the same for all VIFs, parameter is unused */
+ tsf_now = mac80211_hwsim_get_tsf(hw, NULL);
+
+ /* Wrap value to be after the next TBTT */
+ tbtt = tsf_now + link_data->beacon_int;
+
+ /* Round TBTT down to the correct time */
+ div_u64_rem(tbtt, link_data->beacon_int, &remainder);
+ tbtt = tbtt - remainder;
+
+ hrtimer_set_expires(&link_data->beacon_timer,
+ mac80211_hwsim_tsf_to_boottime(data, tbtt));
+
return HRTIMER_RESTART;
}