From: Benjamin Berg To implement NAN synchronization in hwsim, the TSF needs to be adjusted regularly from the RX path. Add a spinlock so that this can be done in a safe manner. Signed-off-by: Benjamin Berg --- .../net/wireless/virtual/mac80211_hwsim_i.h | 1 + .../wireless/virtual/mac80211_hwsim_main.c | 34 ++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_i.h b/drivers/net/wireless/virtual/mac80211_hwsim_i.h index 0cc87205554e..ee566aff4785 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim_i.h +++ b/drivers/net/wireless/virtual/mac80211_hwsim_i.h @@ -101,6 +101,7 @@ struct mac80211_hwsim_data { u32 wmediumd; /* difference between this hw's clock and the real clock, in usecs */ + spinlock_t tsf_offset_lock; s64 tsf_offset; /* Stats */ diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c index 4e836289d58e..78f31921d8d7 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c @@ -1119,13 +1119,17 @@ static inline u64 mac80211_hwsim_get_sim_tsf(void) ktime_t mac80211_hwsim_tsf_to_boottime(struct mac80211_hwsim_data *data, u64 tsf) { - return us_to_ktime(tsf - data->tsf_offset); + scoped_guard(spinlock_bh, &data->tsf_offset_lock) { + return us_to_ktime(tsf - data->tsf_offset); + } } u64 mac80211_hwsim_boottime_to_tsf(struct mac80211_hwsim_data *data, ktime_t ts) { - return ktime_to_us(ts + data->tsf_offset); + scoped_guard(spinlock_bh, &data->tsf_offset_lock) { + return ktime_to_us(ts) + data->tsf_offset; + } } u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, @@ -1134,14 +1138,18 @@ u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, struct mac80211_hwsim_data *data = hw->priv; u64 sim_time = mac80211_hwsim_get_sim_tsf(); - return sim_time + data->tsf_offset; + scoped_guard(spinlock_bh, &data->tsf_offset_lock) { + return sim_time + data->tsf_offset; + } } static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) { u64 sim_time = mac80211_hwsim_get_sim_tsf(); - return cpu_to_le64(sim_time + data->tsf_offset); + scoped_guard(spinlock_bh, &data->tsf_offset_lock) { + return cpu_to_le64(sim_time + data->tsf_offset); + } } static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, @@ -1156,11 +1164,13 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, if (conf && !conf->enable_beacon) return; - /* adjust after beaconing with new timestamp at old TBTT */ - if (tsf > now) - data->tsf_offset += delta; - else - data->tsf_offset -= delta; + scoped_guard(spinlock_bh, &data->tsf_offset_lock) { + /* adjust after beaconing with new timestamp at old TBTT */ + if (tsf > now) + data->tsf_offset += delta; + else + data->tsf_offset -= delta; + } } static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, @@ -1440,6 +1450,8 @@ static void mac80211_hwsim_write_tsf(struct mac80211_hwsim_data *data, /* TODO: get MCS */ int bitrate = 100; + spin_lock_bh(&data->tsf_offset_lock); + txrate = ieee80211_get_tx_rate(data->hw, info); if (txrate) bitrate = txrate->bitrate; @@ -1465,6 +1477,8 @@ static void mac80211_hwsim_write_tsf(struct mac80211_hwsim_data *data, 10 * 8 * 10 / bitrate); } + + spin_unlock_bh(&data->tsf_offset_lock); } static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, @@ -5320,6 +5334,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, hw->wiphy->mbssid_max_interfaces = 8; hw->wiphy->ema_max_profile_periodicity = 3; + spin_lock_init(&data->tsf_offset_lock); + data->rx_rssi = DEFAULT_RX_RSSI; INIT_DELAYED_WORK(&data->roc_start, hw_roc_start); -- 2.51.1