2012-03-01 23:40:14

by Javier Cardona

[permalink] [raw]
Subject: [PATCHv2 1/3] mac80211_hwsim: Add tsf to beacons, probe responses and radiotap header.

Generate a tsf from jiffies. Prepare the path for having different tsf
offsets on the each phy. This will be useful for testing mesh
synchronization algorithms.

Signed-off-by: Javier Cardona <[email protected]>
---
v2: Added timestamp to probe responses, as suggested by Johannes
Also implement tx_last_beacon, useful for testing (new patch 1/3)

drivers/net/wireless/mac80211_hwsim.c | 37 +++++++++++++++++++++++++++++---
1 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index ba16f05..f44b3f6 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -321,11 +321,13 @@ struct mac80211_hwsim_data {
struct dentry *debugfs_group;

int power_level;
+ int tsf_offset; /* in TUs */
};


struct hwsim_radiotap_hdr {
struct ieee80211_radiotap_header hdr;
+ u64 rt_tsft;
u8 rt_flags;
u8 rt_rate;
__le16 rt_channel;
@@ -367,6 +369,11 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}

+static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
+{
+ return cpu_to_le64(jiffies_to_msecs(jiffies)*1000/1024 +
+ data->tsf_offset);
+}

static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
struct sk_buff *tx_skb)
@@ -391,7 +398,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
(1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_TSFT) |
(1 << IEEE80211_RADIOTAP_CHANNEL));
+ hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
hdr->rt_flags = 0;
hdr->rt_rate = txrate->bitrate / 5;
hdr->rt_channel = cpu_to_le16(data->channel->center_freq);
@@ -610,7 +619,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
}

memset(&rx_status, 0, sizeof(rx_status));
- /* TODO: set mactime */
+ rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data));
+ rx_status.flag |= RX_FLAG_MACTIME_MPDU;
rx_status.freq = data->channel->center_freq;
rx_status.band = data->channel->band;
rx_status.rate_idx = info->control.rates[0].idx;
@@ -667,6 +677,19 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
bool ack;
struct ieee80211_tx_info *txi;
u32 _pid;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct mac80211_hwsim_data *data = hw->priv;
+ __le64 *tsfpos;
+ u16 fc = le16_to_cpu(hdr->frame_control);
+ u16 fctypes = fc & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
+
+ if (fctypes == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP) ||
+ fctypes == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) {
+ struct ieee80211_hdr_3addr *hdr3 =
+ (struct ieee80211_hdr_3addr *) skb->data;
+ tsfpos = (__le64 *) (hdr3 + 1);
+ put_unaligned(__mac80211_hwsim_get_tsf(data), tsfpos);
+ }

mac80211_hwsim_monitor_rx(hw, skb);

@@ -685,10 +708,8 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
/* NO wmediumd detected, perfect medium simulation */
ack = mac80211_hwsim_tx_frame_no_nl(hw, skb);

- if (ack && skb->len >= 16) {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ if (ack && skb->len >= 16)
mac80211_hwsim_monitor_ack(hw, hdr->addr2);
- }

txi = IEEE80211_SKB_CB(skb);

@@ -763,9 +784,12 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
struct ieee80211_vif *vif)
{
struct ieee80211_hw *hw = arg;
+ struct mac80211_hwsim_data *data = hw->priv;
struct sk_buff *skb;
struct ieee80211_tx_info *info;
u32 _pid;
+ struct ieee80211_hdr_3addr *hdr;
+ __le64 *tsfpos;

hwsim_check_magic(vif);

@@ -779,6 +803,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
return;
info = IEEE80211_SKB_CB(skb);

+ /* add the timestamp to the beacon */
+ hdr = (struct ieee80211_hdr_3addr *) skb->data;
+ tsfpos = (__le64 *) (hdr + 1);
+ put_unaligned(__mac80211_hwsim_get_tsf(data), tsfpos);
+
mac80211_hwsim_monitor_rx(hw, skb);

/* wmediumd mode check */
--
1.7.6



2012-03-02 07:50:36

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCHv2 3/3] mac80211_hwsim: Implement ieee80211_ops:tx_last_beacon

On Thu, 2012-03-01 at 15:40 -0800, Javier Cardona wrote:
> Without this you won't see probe responses in an IBSS/hwsim network,
> which is convenient for testing.
>
> Signed-off-by: Javier Cardona <[email protected]>
> ---
> drivers/net/wireless/mac80211_hwsim.c | 9 +++++++++
> 1 files changed, 9 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
> index deed95f..e4b6ca6 100644
> --- a/drivers/net/wireless/mac80211_hwsim.c
> +++ b/drivers/net/wireless/mac80211_hwsim.c
> @@ -47,6 +47,8 @@ static bool fake_hw_scan;
> module_param(fake_hw_scan, bool, 0444);
> MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler");
>
> +static struct ieee80211_hw *txed_last_beacon;

That's definitely not right.

> /**
> * enum hwsim_regtest - the type of regulatory tests we offer
> *
> @@ -821,6 +823,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
> hdr = (struct ieee80211_hdr_3addr *) skb->data;
> tsfpos = (__le64 *) (hdr + 1);
> put_unaligned(__mac80211_hwsim_get_tsf(data), tsfpos);
> + txed_last_beacon = hw;
>
> mac80211_hwsim_monitor_rx(hw, skb);
>
> @@ -1220,6 +1223,11 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw)
> mutex_unlock(&hwsim->mutex);
> }
>
> +static int mac80211_hwsim_tx_last_beacon(struct ieee80211_hw *hw)
> +{
> + return (hw == txed_last_beacon);
> +}

And this is mostly a fancy way of saying "return 1" -- there's no beacon
backoff protocol in here, so why not just hardcode "return 1"?

johannes


2012-03-01 23:40:15

by Javier Cardona

[permalink] [raw]
Subject: [PATCHv2 2/3] mac80211: Modify tsf via debugfs in mesh interfaces

Signed-off-by: Javier Cardona <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 16 ++++++++++++++++
net/mac80211/debugfs_netdev.c | 7 ++++++-
2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index f44b3f6..deed95f 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -375,6 +375,20 @@ static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
data->tsf_offset);
}

+static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+ return le64_to_cpu(__mac80211_hwsim_get_tsf(data));
+}
+
+static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u64 tsf)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+ data->tsf_offset = tsf - jiffies_to_msecs(jiffies)*1000/1024;
+}
+
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
struct sk_buff *tx_skb)
{
@@ -1228,6 +1242,8 @@ static struct ieee80211_ops mac80211_hwsim_ops =
.sw_scan_start = mac80211_hwsim_sw_scan,
.sw_scan_complete = mac80211_hwsim_sw_scan_complete,
.flush = mac80211_hwsim_flush,
+ .get_tsf = mac80211_hwsim_get_tsf,
+ .set_tsf = mac80211_hwsim_set_tsf,
};


diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 510ed1d..416b906 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -537,11 +537,15 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata)

#ifdef CONFIG_MAC80211_MESH

+static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
+{
+ DEBUGFS_ADD_MODE(tsf, 0600);
+}
+
static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
{
struct dentry *dir = debugfs_create_dir("mesh_stats",
sdata->debugfs.dir);
-
#define MESHSTATS_ADD(name)\
debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);

@@ -593,6 +597,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
switch (sdata->vif.type) {
case NL80211_IFTYPE_MESH_POINT:
#ifdef CONFIG_MAC80211_MESH
+ add_mesh_files(sdata);
add_mesh_stats(sdata);
add_mesh_config(sdata);
#endif
--
1.7.6


2012-03-01 23:40:16

by Javier Cardona

[permalink] [raw]
Subject: [PATCHv2 3/3] mac80211_hwsim: Implement ieee80211_ops:tx_last_beacon

Without this you won't see probe responses in an IBSS/hwsim network,
which is convenient for testing.

Signed-off-by: Javier Cardona <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index deed95f..e4b6ca6 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -47,6 +47,8 @@ static bool fake_hw_scan;
module_param(fake_hw_scan, bool, 0444);
MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler");

+static struct ieee80211_hw *txed_last_beacon;
+
/**
* enum hwsim_regtest - the type of regulatory tests we offer
*
@@ -821,6 +823,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
hdr = (struct ieee80211_hdr_3addr *) skb->data;
tsfpos = (__le64 *) (hdr + 1);
put_unaligned(__mac80211_hwsim_get_tsf(data), tsfpos);
+ txed_last_beacon = hw;

mac80211_hwsim_monitor_rx(hw, skb);

@@ -1220,6 +1223,11 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw)
mutex_unlock(&hwsim->mutex);
}

+static int mac80211_hwsim_tx_last_beacon(struct ieee80211_hw *hw)
+{
+ return (hw == txed_last_beacon);
+}
+
static struct ieee80211_ops mac80211_hwsim_ops =
{
.tx = mac80211_hwsim_tx,
@@ -1244,6 +1252,7 @@ static struct ieee80211_ops mac80211_hwsim_ops =
.flush = mac80211_hwsim_flush,
.get_tsf = mac80211_hwsim_get_tsf,
.set_tsf = mac80211_hwsim_set_tsf,
+ .tx_last_beacon = mac80211_hwsim_tx_last_beacon,
};


--
1.7.6


2012-03-02 07:49:34

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCHv2 1/3] mac80211_hwsim: Add tsf to beacons, probe responses and radiotap header.

On Thu, 2012-03-01 at 15:40 -0800, Javier Cardona wrote:
> Generate a tsf from jiffies. Prepare the path for having different tsf
> offsets on the each phy. This will be useful for testing mesh
> synchronization algorithms.

The fact that you used jiffies should have made me wonder earlier :)

> +static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
> +{
> + return cpu_to_le64(jiffies_to_msecs(jiffies)*1000/1024 +
> + data->tsf_offset);
> +}

This is not right? TSF is in microseconds, here you're like converting
msec to TU (I think). Also, jiffies doesn't even increase fast enough
for the timestamp, I'm pretty sure you need hrtimers.

johannes