diff options
author | Javier Cardona <javier@cozybit.com> | 2012-03-05 20:20:37 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-06 15:16:17 -0500 |
commit | 2f40b9404903dba89d70d706ee71263f9babd109 (patch) | |
tree | 29f71a6f98c327376a458210b8a4af2c2853995a /drivers/net/wireless/mac80211_hwsim.c | |
parent | 6b62bf326393deede630731a933713de9d574128 (diff) |
mac80211_hwsim: Add tsf to beacons, probe responses and radiotap header.
Generate a tsf from internal kernel clock. Prepare the path for having
different tsf offsets on each phy. This will be useful for testing
mesh synchronization algorithms.
Signed-off-by: Javier Cardona <javier@cozybit.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mac80211_hwsim.c')
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ba16f05df0fc..14a3cac19a30 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include <linux/debugfs.h> | 28 | #include <linux/debugfs.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/ktime.h> | ||
30 | #include <net/genetlink.h> | 31 | #include <net/genetlink.h> |
31 | #include "mac80211_hwsim.h" | 32 | #include "mac80211_hwsim.h" |
32 | 33 | ||
@@ -321,11 +322,15 @@ struct mac80211_hwsim_data { | |||
321 | struct dentry *debugfs_group; | 322 | struct dentry *debugfs_group; |
322 | 323 | ||
323 | int power_level; | 324 | int power_level; |
325 | |||
326 | /* difference between this hw's clock and the real clock, in usecs */ | ||
327 | u64 tsf_offset; | ||
324 | }; | 328 | }; |
325 | 329 | ||
326 | 330 | ||
327 | struct hwsim_radiotap_hdr { | 331 | struct hwsim_radiotap_hdr { |
328 | struct ieee80211_radiotap_header hdr; | 332 | struct ieee80211_radiotap_header hdr; |
333 | __le64 rt_tsft; | ||
329 | u8 rt_flags; | 334 | u8 rt_flags; |
330 | u8 rt_rate; | 335 | u8 rt_rate; |
331 | __le16 rt_channel; | 336 | __le16 rt_channel; |
@@ -367,6 +372,12 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, | |||
367 | return NETDEV_TX_OK; | 372 | return NETDEV_TX_OK; |
368 | } | 373 | } |
369 | 374 | ||
375 | static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) | ||
376 | { | ||
377 | struct timeval tv = ktime_to_timeval(ktime_get_real()); | ||
378 | u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; | ||
379 | return cpu_to_le64(now + data->tsf_offset); | ||
380 | } | ||
370 | 381 | ||
371 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | 382 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, |
372 | struct sk_buff *tx_skb) | 383 | struct sk_buff *tx_skb) |
@@ -391,7 +402,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | |||
391 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); | 402 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); |
392 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 403 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
393 | (1 << IEEE80211_RADIOTAP_RATE) | | 404 | (1 << IEEE80211_RADIOTAP_RATE) | |
405 | (1 << IEEE80211_RADIOTAP_TSFT) | | ||
394 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 406 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
407 | hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); | ||
395 | hdr->rt_flags = 0; | 408 | hdr->rt_flags = 0; |
396 | hdr->rt_rate = txrate->bitrate / 5; | 409 | hdr->rt_rate = txrate->bitrate / 5; |
397 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); | 410 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); |
@@ -610,7 +623,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
610 | } | 623 | } |
611 | 624 | ||
612 | memset(&rx_status, 0, sizeof(rx_status)); | 625 | memset(&rx_status, 0, sizeof(rx_status)); |
613 | /* TODO: set mactime */ | 626 | rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data)); |
627 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; | ||
614 | rx_status.freq = data->channel->center_freq; | 628 | rx_status.freq = data->channel->center_freq; |
615 | rx_status.band = data->channel->band; | 629 | rx_status.band = data->channel->band; |
616 | rx_status.rate_idx = info->control.rates[0].idx; | 630 | rx_status.rate_idx = info->control.rates[0].idx; |
@@ -667,6 +681,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
667 | bool ack; | 681 | bool ack; |
668 | struct ieee80211_tx_info *txi; | 682 | struct ieee80211_tx_info *txi; |
669 | u32 _pid; | 683 | u32 _pid; |
684 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; | ||
685 | struct mac80211_hwsim_data *data = hw->priv; | ||
686 | |||
687 | if (ieee80211_is_beacon(mgmt->frame_control) || | ||
688 | ieee80211_is_probe_resp(mgmt->frame_control)) | ||
689 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
670 | 690 | ||
671 | mac80211_hwsim_monitor_rx(hw, skb); | 691 | mac80211_hwsim_monitor_rx(hw, skb); |
672 | 692 | ||
@@ -763,9 +783,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
763 | struct ieee80211_vif *vif) | 783 | struct ieee80211_vif *vif) |
764 | { | 784 | { |
765 | struct ieee80211_hw *hw = arg; | 785 | struct ieee80211_hw *hw = arg; |
786 | struct mac80211_hwsim_data *data = hw->priv; | ||
766 | struct sk_buff *skb; | 787 | struct sk_buff *skb; |
767 | struct ieee80211_tx_info *info; | 788 | struct ieee80211_tx_info *info; |
768 | u32 _pid; | 789 | u32 _pid; |
790 | struct ieee80211_mgmt *mgmt; | ||
769 | 791 | ||
770 | hwsim_check_magic(vif); | 792 | hwsim_check_magic(vif); |
771 | 793 | ||
@@ -779,6 +801,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
779 | return; | 801 | return; |
780 | info = IEEE80211_SKB_CB(skb); | 802 | info = IEEE80211_SKB_CB(skb); |
781 | 803 | ||
804 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
805 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
806 | |||
782 | mac80211_hwsim_monitor_rx(hw, skb); | 807 | mac80211_hwsim_monitor_rx(hw, skb); |
783 | 808 | ||
784 | /* wmediumd mode check */ | 809 | /* wmediumd mode check */ |