When short beaconing is enabled, correctly initialise the beacon timer using the short beacon interval. Additionally, utilise the correct short beaconing BSS configuration values when short beaconing is enabled for an S1G BSS within mac80211_hwsim. Signed-off-by: Lachlan Hodges <lachlan.hodges@xxxxxxxxxxxxxx> --- drivers/net/wireless/virtual/mac80211_hwsim.c | 109 ++++++++++++------ 1 file changed, 76 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index eefe8da3b14d..daeb7ff23384 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -655,6 +655,8 @@ static struct platform_driver mac80211_hwsim_driver = { struct mac80211_hwsim_link_data { u32 link_id; u64 beacon_int /* beacon interval in us */; + bool s1g_short_beaconing; /* whether this link is short beaconing */ + u64 s1g_short_beacon_int; /* S1G short beacon interval in us */ struct hrtimer beacon_timer; }; @@ -1226,15 +1228,18 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, { 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; + u32 bcn_int; conf = link_conf_dereference_protected(vif, data->link_data[0].link_id); - if (conf && !conf->enable_beacon) + if (!conf || !conf->enable_beacon) return; + /* MLD not supported here */ + bcn_int = conf->s1g_short_beaconing ? + data->link_data[0].s1g_short_beacon_int : + data->link_data[0].beacon_int; /* adjust after beaconing with new timestamp at old TBTT */ if (tsf > now) { data->tsf_offset += delta; @@ -2345,7 +2350,9 @@ mac80211_hwsim_beacon(struct hrtimer *timer) 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; + u64 bcn_int = link_data->s1g_short_beaconing ? + link_data->s1g_short_beacon_int : + link_data->beacon_int; if (!data->started) return HRTIMER_NORESTART; @@ -2449,11 +2456,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, int radio_idx, struct mac80211_hwsim_link_data *link_data = &data->link_data[idx]; - if (!data->started || !link_data->beacon_int) { + if (!data->started || (!link_data->beacon_int && + !link_data->s1g_short_beacon_int)) { hrtimer_cancel(&link_data->beacon_timer); } else if (!hrtimer_active(&link_data->beacon_timer)) { u64 tsf = mac80211_hwsim_get_tsf(hw, NULL); - u32 bcn_int = link_data->beacon_int; + u32 bcn_int = link_data->s1g_short_beaconing ? + link_data->s1g_short_beacon_int : + link_data->beacon_int; u64 until_tbtt = bcn_int - do_div(tsf, bcn_int); hrtimer_start(&link_data->beacon_timer, @@ -2520,6 +2530,55 @@ static void mac80211_hwsim_vif_info_changed(struct ieee80211_hw *hw, } } +static void +mac80211_hwsim_link_change_beacon(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + struct mac80211_hwsim_link_data *link_data, + struct mac80211_hwsim_data *data, + struct hwsim_vif_priv *vp) +{ + u64 tsf, until_tbtt; + u32 bcn_interval_us; + bool short_beaconing = vif->cfg.s1g && info->s1g_short_beaconing; + + vp->bcn_en = info->enable_beacon; + if (info->enable_beacon && data->started && + !hrtimer_active(&link_data->beacon_timer)) { + if (short_beaconing) { + link_data->s1g_short_beacon_int = + info->s1g_short_beacon_int * 1024; + bcn_interval_us = link_data->s1g_short_beacon_int; + link_data->s1g_short_beaconing = true; + } else { + link_data->beacon_int = info->beacon_int * 1024; + bcn_interval_us = link_data->beacon_int; + } + + tsf = mac80211_hwsim_get_tsf(hw, vif); + until_tbtt = bcn_interval_us - do_div(tsf, bcn_interval_us); + + hrtimer_start(&link_data->beacon_timer, + ns_to_ktime(until_tbtt * NSEC_PER_USEC), + HRTIMER_MODE_REL_SOFT); + } else if (!info->enable_beacon) { + unsigned int count = 0; + + ieee80211_iterate_active_interfaces_atomic( + data->hw, IEEE80211_IFACE_ITER_NORMAL, + mac80211_hwsim_bcn_en_iter, &count); + + wiphy_dbg(hw->wiphy, " beaconing vifs remaining: %u", count); + + if (count == 0) { + hrtimer_cancel(&link_data->beacon_timer); + link_data->beacon_int = 0; + link_data->s1g_short_beacon_int = 0; + link_data->s1g_short_beaconing = false; + } + } +} + static void mac80211_hwsim_link_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -2542,34 +2601,18 @@ static void mac80211_hwsim_link_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_ENABLED) { - wiphy_dbg(hw->wiphy, " BCN EN: %d (BI=%u)\n", - info->enable_beacon, info->beacon_int); - vp->bcn_en = info->enable_beacon; - if (data->started && - !hrtimer_active(&link_data->beacon_timer) && - info->enable_beacon) { - u64 tsf, until_tbtt; - u32 bcn_int; - link_data->beacon_int = info->beacon_int * 1024; - tsf = mac80211_hwsim_get_tsf(hw, vif); - bcn_int = link_data->beacon_int; - until_tbtt = bcn_int - do_div(tsf, bcn_int); - - hrtimer_start(&link_data->beacon_timer, - ns_to_ktime(until_tbtt * NSEC_PER_USEC), - HRTIMER_MODE_REL_SOFT); - } else if (!info->enable_beacon) { - unsigned int count = 0; - ieee80211_iterate_active_interfaces_atomic( - data->hw, IEEE80211_IFACE_ITER_NORMAL, - mac80211_hwsim_bcn_en_iter, &count); - wiphy_dbg(hw->wiphy, " beaconing vifs remaining: %u", - count); - if (count == 0) { - hrtimer_cancel(&link_data->beacon_timer); - link_data->beacon_int = 0; - } + if (info->s1g_short_beaconing) { + wiphy_dbg(hw->wiphy, + " SHORT BCN EN: %d (BI=%u, SBI=%u)\n", + info->enable_beacon, info->beacon_int, + info->s1g_short_beacon_int); + } else { + wiphy_dbg(hw->wiphy, " BCN EN: %d (BI=%u)\n", + info->enable_beacon, info->beacon_int); } + + mac80211_hwsim_link_change_beacon(hw, vif, info, link_data, + data, vp); } if (changed & BSS_CHANGED_ERP_CTS_PROT) { -- 2.43.0