From a8e828deb393e8a5ca84cd3d0df56b3c0be04607 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 26 Nov 2015 17:59:27 +0100 Subject: mac80211_hwsim: do not actively scan DFS channels We had another change to fix this in mac80211, but the hwsim "hardware" scan should also be fixed. Obviously this one isn't important since it's not real hardware, but we'd better be consistent. Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index c00a7daaa4bc..aaf1b3e860bf 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1871,7 +1871,8 @@ static void hw_scan_work(struct work_struct *work) req->channels[hwsim->scan_chan_idx]->center_freq); hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; - if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR || + if (hwsim->tmp_chan->flags & (IEEE80211_CHAN_NO_IR | + IEEE80211_CHAN_RADAR) || !req->n_ssids) { dwell = 120; } else { -- cgit v1.2.3 From 661ef475fdf5f24346ca33314964c71698ff3501 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 24 Nov 2015 18:29:45 +0100 Subject: mac80211_hwsim: delay hardware remain-on-channel start Typically drivers that implement hardware remain-on-channel will have to wait for scheduling constraints, so make hwsim also wait a little bit (only 20ms) before actually starting the operation. Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index aaf1b3e860bf..e922a4df3db3 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -495,6 +495,9 @@ struct mac80211_hwsim_data { const struct ieee80211_regdomain *regd; struct ieee80211_channel *tmp_chan; + struct ieee80211_channel *roc_chan; + u32 roc_duration; + struct delayed_work roc_start; struct delayed_work roc_done; struct delayed_work hw_scan; struct cfg80211_scan_request *hw_scan_request; @@ -1988,6 +1991,23 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw, mutex_unlock(&hwsim->mutex); } +static void hw_roc_start(struct work_struct *work) +{ + struct mac80211_hwsim_data *hwsim = + container_of(work, struct mac80211_hwsim_data, roc_start.work); + + mutex_lock(&hwsim->mutex); + + wiphy_debug(hwsim->hw->wiphy, "hwsim ROC begins\n"); + hwsim->tmp_chan = hwsim->roc_chan; + ieee80211_ready_on_channel(hwsim->hw); + + ieee80211_queue_delayed_work(hwsim->hw, &hwsim->roc_done, + msecs_to_jiffies(hwsim->roc_duration)); + + mutex_unlock(&hwsim->mutex); +} + static void hw_roc_done(struct work_struct *work) { struct mac80211_hwsim_data *hwsim = @@ -2015,16 +2035,14 @@ static int mac80211_hwsim_roc(struct ieee80211_hw *hw, return -EBUSY; } - hwsim->tmp_chan = chan; + hwsim->roc_chan = chan; + hwsim->roc_duration = duration; mutex_unlock(&hwsim->mutex); wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n", chan->center_freq, duration); + ieee80211_queue_delayed_work(hw, &hwsim->roc_start, HZ/50); - ieee80211_ready_on_channel(hw); - - ieee80211_queue_delayed_work(hw, &hwsim->roc_done, - msecs_to_jiffies(duration)); return 0; } @@ -2032,6 +2050,7 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw) { struct mac80211_hwsim_data *hwsim = hw->priv; + cancel_delayed_work_sync(&hwsim->roc_start); cancel_delayed_work_sync(&hwsim->roc_done); mutex_lock(&hwsim->mutex); @@ -2376,6 +2395,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb); } + INIT_DELAYED_WORK(&data->roc_start, hw_roc_start); INIT_DELAYED_WORK(&data->roc_done, hw_roc_done); INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work); -- cgit v1.2.3 From 732b5395efd05e79f546b59d6aa02653608bfe03 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 26 Nov 2015 20:50:12 +0200 Subject: mac80211_hwsim: Update timestamp in Probe Response frames Previously, this was done only for Beacon frames, but similar timestamp update is needed for Probe Response frames to make these more accurately match the real IEEE 802.11 behavior. Previously, all zeros timestamp was sent in Probe Response frames. Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e922a4df3db3..593314e94d9d 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1250,6 +1250,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, { struct mac80211_hwsim_data *data = hw->priv; struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_channel *channel; bool ack; @@ -1295,6 +1296,22 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, ARRAY_SIZE(txi->control.rates)); txi->rate_driver_data[0] = channel; + + if (skb->len >= 24 + 8 && + ieee80211_is_probe_resp(hdr->frame_control)) { + /* fake header transmission time */ + struct ieee80211_mgmt *mgmt; + struct ieee80211_rate *txrate; + u64 ts; + + mgmt = (struct ieee80211_mgmt *)skb->data; + txrate = ieee80211_get_tx_rate(hw, txi); + ts = mac80211_hwsim_get_tsf_raw(); + mgmt->u.probe_resp.timestamp = + cpu_to_le64(ts + data->tsf_offset + + 24 * 8 * 10 / txrate->bitrate); + } + mac80211_hwsim_monitor_rx(hw, skb, channel); /* wmediumd mode check */ -- cgit v1.2.3 From 00eeccc4a9a84afe819062df13cdb47159919a7c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 26 Nov 2015 20:51:04 +0200 Subject: mac80211_hwsim: Advertise support for VHT IBSS VHT can be used with IBSS without needing any additional changes in mac80211_hwsim, so start claiming support for this to increase test coverage. Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 593314e94d9d..00d752523fc7 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2449,6 +2449,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, NL80211_FEATURE_STATIC_SMPS | NL80211_FEATURE_DYNAMIC_SMPS | NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS); /* ask mac80211 to reserve space for magic */ hw->vif_data_size = sizeof(struct hwsim_vif_priv); -- cgit v1.2.3 From 959eb2fd70df86a089e9e31be654462235952a24 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 6 Nov 2015 11:57:23 +0100 Subject: mac80211_hwsim: stop using pointers as cookies Instead of using pointers, use sequentially assigned cookies. This is easier to understand while debugging and also avoids problems when the pointer is reused for the next allocation. Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 00d752523fc7..194264c1ee1f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -517,6 +517,7 @@ struct mac80211_hwsim_data { bool ps_poll_pending; struct dentry *debugfs; + uintptr_t pending_cookie; struct sk_buff_head pending; /* packets pending */ /* * Only radios in the same group can communicate together (the @@ -963,6 +964,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, unsigned int hwsim_flags = 0; int i; struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; + uintptr_t cookie; if (data->ps != PS_DISABLED) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); @@ -1021,7 +1023,10 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, goto nla_put_failure; /* We create a cookie to identify this skb */ - if (nla_put_u64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb)) + data->pending_cookie++; + cookie = data->pending_cookie; + info->rate_driver_data[0] = (void *)cookie; + if (nla_put_u64(skb, HWSIM_ATTR_COOKIE, cookie)) goto nla_put_failure; genlmsg_end(skb, msg_head); @@ -2749,7 +2754,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, struct mac80211_hwsim_data *data2; struct ieee80211_tx_info *txi; struct hwsim_tx_rate *tx_attempts; - unsigned long ret_skb_ptr; + u64 ret_skb_cookie; struct sk_buff *skb, *tmp; const u8 *src; unsigned int hwsim_flags; @@ -2767,7 +2772,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, src = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]); - ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); + ret_skb_cookie = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); data2 = get_hwsim_data_ref_from_addr(src); if (!data2) @@ -2775,7 +2780,12 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, /* look for the skb matching the cookie passed back from user */ skb_queue_walk_safe(&data2->pending, skb, tmp) { - if ((unsigned long)skb == ret_skb_ptr) { + u64 skb_cookie; + + txi = IEEE80211_SKB_CB(skb); + skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0]; + + if (skb_cookie == ret_skb_cookie) { skb_unlink(skb, &data2->pending); found = true; break; -- cgit v1.2.3 From 89f44d8c25bb21f167d7d124c6b83dd494f948af Mon Sep 17 00:00:00 2001 From: Amit Khatri Date: Mon, 30 Nov 2015 12:46:52 +0530 Subject: mac80211_hwsim: check txrate for NULL If the rate control algorithm messed up then the txrate pointer here could be NULL - WARN and drop the packet from monitoring. Signed-off-by: Amit Khatri Signed-off-by: Rahul Jain [rewrite commit message, add warning] Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 194264c1ee1f..297b192b9e13 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -814,6 +814,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb); struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); + if (WARN_ON(!txrate)) + return; + if (!netif_running(hwsim_mon)) return; -- cgit v1.2.3 From 641cf2a5ba0345c01f4eb1ca2980372415c2a5e1 Mon Sep 17 00:00:00 2001 From: Adam Welle Date: Tue, 1 Dec 2015 17:13:52 -0500 Subject: mac80211_hwsim: check ATTR_FREQ for wmediumd (netlink) packets If a packet is received from netlink with the frequency value set it is checked against the current radio's frequency and discarded if different. The frequency is also checked against data2->tmp_chan to support the "hw" off-channel/scan case. Signed-off-by: Adam Welle [allow both simultaneously, add locking] Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 297b192b9e13..c32889a1e39c 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2879,10 +2879,25 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, /* A frame is received from user space */ memset(&rx_status, 0, sizeof(rx_status)); - /* TODO: Check ATTR_FREQ if it exists, and maybe throw away off-channel - * packets? - */ - rx_status.freq = data2->channel->center_freq; + if (info->attrs[HWSIM_ATTR_FREQ]) { + /* throw away off-channel packets, but allow both the temporary + * ("hw" scan/remain-on-channel) and regular channel, since the + * internal datapath also allows this + */ + mutex_lock(&data2->mutex); + rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]); + + if (rx_status.freq != data2->channel->center_freq && + (!data2->tmp_chan || + rx_status.freq != data2->tmp_chan->center_freq)) { + mutex_unlock(&data2->mutex); + goto out; + } + mutex_unlock(&data2->mutex); + } else { + rx_status.freq = data2->channel->center_freq; + } + rx_status.band = data2->channel->band; rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); -- cgit v1.2.3