aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Pedersen <thomas@cozybit.com>2013-01-02 17:55:18 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-04 08:01:55 -0500
commitc51f878379b1d0677619798b1d9358d053bdbdb1 (patch)
tree2fdfb9e013fc18094ee4b414bb5f91fdd5f2f7de /drivers
parent01e59e467ecf976c782eecd4dc99644802cc60e2 (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.c24
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
436static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, 440static 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);