diff options
author | Javier Cardona <javier@cozybit.com> | 2012-03-31 14:31:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-04-10 15:20:29 -0400 |
commit | f483ad25c397bc2b33542fe245ea99c22c8a750c (patch) | |
tree | 135e297b21667ec5d240380fb78e17e2037db940 /drivers/net/wireless/mac80211_hwsim.c | |
parent | 88c868c43ba38ac3bab07bab4c45b4bc44c94357 (diff) |
mac80211_hwsim: Fill timestamp beacon at the time it is transmitted
Generate more acurate tsf values in hwsim by setting the tsf value on
trasmitted beacons immediately before they are moved to the rx path.
Also, adjust the beacon timestamp to be the time at which the first byte
of the timestamp is transmitted.
With these changes the observed tsf offset between two hwsim/mesh peers
is 0 (unless the offset is modified via debugfs)
Signed-off-by: Javier Cardona <javier@cozybit.com>
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 | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 8737f4e52cbc..a257df727821 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -632,6 +632,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
632 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 632 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
633 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 633 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
634 | struct ieee80211_rx_status rx_status; | 634 | struct ieee80211_rx_status rx_status; |
635 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); | ||
635 | 636 | ||
636 | if (data->idle) { | 637 | if (data->idle) { |
637 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); | 638 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); |
@@ -666,6 +667,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
666 | spin_lock(&hwsim_radio_lock); | 667 | spin_lock(&hwsim_radio_lock); |
667 | list_for_each_entry(data2, &hwsim_radios, list) { | 668 | list_for_each_entry(data2, &hwsim_radios, list) { |
668 | struct sk_buff *nskb; | 669 | struct sk_buff *nskb; |
670 | struct ieee80211_mgmt *mgmt; | ||
669 | 671 | ||
670 | if (data == data2) | 672 | if (data == data2) |
671 | continue; | 673 | continue; |
@@ -683,8 +685,17 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
683 | 685 | ||
684 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) | 686 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) |
685 | ack = true; | 687 | ack = true; |
688 | |||
689 | /* set bcn timestamp relative to receiver mactime */ | ||
686 | rx_status.mactime = | 690 | rx_status.mactime = |
687 | le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); | 691 | le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); |
692 | mgmt = (struct ieee80211_mgmt *) nskb->data; | ||
693 | if (ieee80211_is_beacon(mgmt->frame_control) || | ||
694 | ieee80211_is_probe_resp(mgmt->frame_control)) | ||
695 | mgmt->u.beacon.timestamp = cpu_to_le64( | ||
696 | rx_status.mactime + | ||
697 | 24 * 8 * 10 / txrate->bitrate); | ||
698 | |||
688 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); | 699 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); |
689 | ieee80211_rx_irqsafe(data2->hw, nskb); | 700 | ieee80211_rx_irqsafe(data2->hw, nskb); |
690 | } | 701 | } |
@@ -698,12 +709,6 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
698 | bool ack; | 709 | bool ack; |
699 | struct ieee80211_tx_info *txi; | 710 | struct ieee80211_tx_info *txi; |
700 | u32 _pid; | 711 | u32 _pid; |
701 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; | ||
702 | struct mac80211_hwsim_data *data = hw->priv; | ||
703 | |||
704 | if (ieee80211_is_beacon(mgmt->frame_control) || | ||
705 | ieee80211_is_probe_resp(mgmt->frame_control)) | ||
706 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
707 | 712 | ||
708 | mac80211_hwsim_monitor_rx(hw, skb); | 713 | mac80211_hwsim_monitor_rx(hw, skb); |
709 | 714 | ||
@@ -800,11 +805,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
800 | struct ieee80211_vif *vif) | 805 | struct ieee80211_vif *vif) |
801 | { | 806 | { |
802 | struct ieee80211_hw *hw = arg; | 807 | struct ieee80211_hw *hw = arg; |
803 | struct mac80211_hwsim_data *data = hw->priv; | ||
804 | struct sk_buff *skb; | 808 | struct sk_buff *skb; |
805 | struct ieee80211_tx_info *info; | 809 | struct ieee80211_tx_info *info; |
806 | u32 _pid; | 810 | u32 _pid; |
807 | struct ieee80211_mgmt *mgmt; | ||
808 | 811 | ||
809 | hwsim_check_magic(vif); | 812 | hwsim_check_magic(vif); |
810 | 813 | ||
@@ -818,9 +821,6 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
818 | return; | 821 | return; |
819 | info = IEEE80211_SKB_CB(skb); | 822 | info = IEEE80211_SKB_CB(skb); |
820 | 823 | ||
821 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
822 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
823 | |||
824 | mac80211_hwsim_monitor_rx(hw, skb); | 824 | mac80211_hwsim_monitor_rx(hw, skb); |
825 | 825 | ||
826 | /* wmediumd mode check */ | 826 | /* wmediumd mode check */ |
@@ -1444,7 +1444,7 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group, | |||
1444 | hwsim_fops_group_read, hwsim_fops_group_write, | 1444 | hwsim_fops_group_read, hwsim_fops_group_write, |
1445 | "%llx\n"); | 1445 | "%llx\n"); |
1446 | 1446 | ||
1447 | struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr( | 1447 | static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr( |
1448 | struct mac_address *addr) | 1448 | struct mac_address *addr) |
1449 | { | 1449 | { |
1450 | struct mac80211_hwsim_data *data; | 1450 | struct mac80211_hwsim_data *data; |