diff options
author | Thomas Pedersen <thomas@cozybit.com> | 2013-01-02 17:55:18 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-04 08:01:55 -0500 |
commit | c51f878379b1d0677619798b1d9358d053bdbdb1 (patch) | |
tree | 2fdfb9e013fc18094ee4b414bb5f91fdd5f2f7de /drivers | |
parent | 01e59e467ecf976c782eecd4dc99644802cc60e2 (diff) |
mac80211_hwsim: fix beacon timing
A beacon period starts at TSF time 0. Spoof this by
rounding the starting beacon time to a multiple of the
beacon interval, and keep TBTT aligned on TSF adjustment.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index c54c5d17a037..b6e2caa024a7 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -362,6 +362,7 @@ struct mac80211_hwsim_data { | |||
362 | 362 | ||
363 | /* difference between this hw's clock and the real clock, in usecs */ | 363 | /* difference between this hw's clock and the real clock, in usecs */ |
364 | s64 tsf_offset; | 364 | s64 tsf_offset; |
365 | s64 bcn_delta; | ||
365 | }; | 366 | }; |
366 | 367 | ||
367 | 368 | ||
@@ -428,9 +429,12 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, | |||
428 | { | 429 | { |
429 | struct mac80211_hwsim_data *data = hw->priv; | 430 | struct mac80211_hwsim_data *data = hw->priv; |
430 | u64 now = mac80211_hwsim_get_tsf(hw, vif); | 431 | u64 now = mac80211_hwsim_get_tsf(hw, vif); |
432 | u32 bcn_int = data->beacon_int; | ||
431 | s64 delta = tsf - now; | 433 | s64 delta = tsf - now; |
432 | 434 | ||
433 | data->tsf_offset += delta; | 435 | data->tsf_offset += delta; |
436 | /* adjust after beaconing with new timestamp at old TBTT */ | ||
437 | data->bcn_delta = do_div(delta, bcn_int); | ||
434 | } | 438 | } |
435 | 439 | ||
436 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | 440 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, |
@@ -1018,6 +1022,12 @@ mac80211_hwsim_beacon(struct hrtimer *timer) | |||
1018 | hw, IEEE80211_IFACE_ITER_NORMAL, | 1022 | hw, IEEE80211_IFACE_ITER_NORMAL, |
1019 | mac80211_hwsim_beacon_tx, hw); | 1023 | mac80211_hwsim_beacon_tx, hw); |
1020 | 1024 | ||
1025 | /* beacon at new TBTT + beacon interval */ | ||
1026 | if (data->bcn_delta) { | ||
1027 | bcn_int -= data->bcn_delta; | ||
1028 | data->bcn_delta = 0; | ||
1029 | } | ||
1030 | |||
1021 | next_bcn = ktime_add(hrtimer_get_expires(timer), | 1031 | next_bcn = ktime_add(hrtimer_get_expires(timer), |
1022 | ns_to_ktime(bcn_int * 1000)); | 1032 | ns_to_ktime(bcn_int * 1000)); |
1023 | tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS); | 1033 | tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS); |
@@ -1062,8 +1072,12 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
1062 | if (!data->started || !data->beacon_int) | 1072 | if (!data->started || !data->beacon_int) |
1063 | tasklet_hrtimer_cancel(&data->beacon_timer); | 1073 | tasklet_hrtimer_cancel(&data->beacon_timer); |
1064 | else if (!hrtimer_is_queued(&data->beacon_timer.timer)) { | 1074 | else if (!hrtimer_is_queued(&data->beacon_timer.timer)) { |
1075 | u64 tsf = mac80211_hwsim_get_tsf(hw, NULL); | ||
1076 | u32 bcn_int = data->beacon_int; | ||
1077 | u64 until_tbtt = bcn_int - do_div(tsf, bcn_int); | ||
1078 | |||
1065 | tasklet_hrtimer_start(&data->beacon_timer, | 1079 | tasklet_hrtimer_start(&data->beacon_timer, |
1066 | ns_to_ktime(data->beacon_int * 1000), | 1080 | ns_to_ktime(until_tbtt * 1000), |
1067 | HRTIMER_MODE_REL); | 1081 | HRTIMER_MODE_REL); |
1068 | } | 1082 | } |
1069 | 1083 | ||
@@ -1123,11 +1137,15 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
1123 | if (data->started && | 1137 | if (data->started && |
1124 | !hrtimer_is_queued(&data->beacon_timer.timer) && | 1138 | !hrtimer_is_queued(&data->beacon_timer.timer) && |
1125 | info->enable_beacon) { | 1139 | info->enable_beacon) { |
1140 | u64 tsf, until_tbtt; | ||
1141 | u32 bcn_int; | ||
1126 | if (WARN_ON(!data->beacon_int)) | 1142 | if (WARN_ON(!data->beacon_int)) |
1127 | data->beacon_int = 1000 * 1024; | 1143 | data->beacon_int = 1000 * 1024; |
1144 | tsf = mac80211_hwsim_get_tsf(hw, vif); | ||
1145 | bcn_int = data->beacon_int; | ||
1146 | until_tbtt = bcn_int - do_div(tsf, bcn_int); | ||
1128 | tasklet_hrtimer_start(&data->beacon_timer, | 1147 | tasklet_hrtimer_start(&data->beacon_timer, |
1129 | ns_to_ktime(data->beacon_int * | 1148 | ns_to_ktime(until_tbtt * 1000), |
1130 | 1000), | ||
1131 | HRTIMER_MODE_REL); | 1149 | HRTIMER_MODE_REL); |
1132 | } else if (!info->enable_beacon) | 1150 | } else if (!info->enable_beacon) |
1133 | tasklet_hrtimer_cancel(&data->beacon_timer); | 1151 | tasklet_hrtimer_cancel(&data->beacon_timer); |