* [PATCH v2 0/6] some mac80211/cfg80211 patches
@ 2016-08-29 20:25 Luca Coelho
2016-08-29 20:25 ` [PATCH v2 1/6] cfg80211: clarify the requirements of .disconnect() Luca Coelho
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Luca Coelho @ 2016-08-29 20:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
From: Luca Coelho <luciano.coelho@intel.com>
Hi Johannes,
Here are a few of the mac80211 and cfg80211 patches that we have in
our internal tree.
Thanks for pointing out the missing patch. And please ignore the 5
patches I sent earlier today.
In v2:
* add a cover letter ;)
* add a patch that was missing for the MU-MIMO monitor implementation
Cheers,
Luca.
Aviya Erenfeld (2):
mac80211: refactor monitor representation in sdata
mac80211: add support for MU-MIMO air sniffer
Emmanuel Grumbach (1):
cfg80211: clarify the requirements of .disconnect()
Johannes Berg (3):
mac80211: add support for radiotap timestamp field
mac80211: send delBA on unexpected BlockAck data frames
mac80211: send delBA on unexpected BlockAck Request
include/net/cfg80211.h | 3 +-
include/net/ieee80211_radiotap.h | 21 ++++++++++++
include/net/mac80211.h | 12 +++++++
net/mac80211/agg-rx.c | 4 ++-
net/mac80211/cfg.c | 31 +++++++++++++++---
net/mac80211/driver-ops.c | 2 +-
net/mac80211/driver-ops.h | 3 +-
net/mac80211/ieee80211_i.h | 9 ++++--
net/mac80211/iface.c | 21 +++++++-----
net/mac80211/main.c | 3 ++
net/mac80211/rx.c | 70 ++++++++++++++++++++++++++++++++++++++--
net/mac80211/sta_info.h | 3 ++
net/mac80211/status.c | 2 +-
net/mac80211/tx.c | 2 +-
net/mac80211/util.c | 2 +-
15 files changed, 163 insertions(+), 25 deletions(-)
--
2.8.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/6] cfg80211: clarify the requirements of .disconnect()
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
@ 2016-08-29 20:25 ` Luca Coelho
2016-08-29 20:25 ` [PATCH v2 2/6] mac80211: refactor monitor representation in sdata Luca Coelho
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luca Coelho @ 2016-08-29 20:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
cfg80211 expects the .disconnect() handler to call
cfg80211_disconnect() when done. Make this requirement
more explicit.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
include/net/cfg80211.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9c23f4d3..d5e7f69 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2423,7 +2423,8 @@ struct cfg80211_qos_map {
* cases, the result of roaming is indicated with a call to
* cfg80211_roamed() or cfg80211_roamed_bss().
* (invoked with the wireless_dev mutex held)
- * @disconnect: Disconnect from the BSS/ESS.
+ * @disconnect: Disconnect from the BSS/ESS. Once done, call
+ * cfg80211_disconnected().
* (invoked with the wireless_dev mutex held)
*
* @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
--
2.8.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/6] mac80211: refactor monitor representation in sdata
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
2016-08-29 20:25 ` [PATCH v2 1/6] cfg80211: clarify the requirements of .disconnect() Luca Coelho
@ 2016-08-29 20:25 ` Luca Coelho
2016-08-29 20:25 ` [PATCH v2 3/6] mac80211: add support for MU-MIMO air sniffer Luca Coelho
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luca Coelho @ 2016-08-29 20:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
From: Aviya Erenfeld <aviya.erenfeld@intel.com>
Insert the u32 monitor flags variable in a new structure
that represents a monitor interface.
This will allow to add more configuration variables to
that structure which will happen in an upcoming change.
Signed-off-by: Aviya Erenfeld <aviya.erenfeld@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/mac80211/cfg.c | 8 ++++----
net/mac80211/driver-ops.c | 2 +-
net/mac80211/ieee80211_i.h | 6 +++++-
net/mac80211/iface.c | 16 ++++++++--------
net/mac80211/rx.c | 4 ++--
net/mac80211/status.c | 2 +-
net/mac80211/tx.c | 2 +-
net/mac80211/util.c | 2 +-
8 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 543b1d4..f2c8cd2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -39,7 +39,7 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
if (type == NL80211_IFTYPE_MONITOR && flags) {
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
- sdata->u.mntr_flags = *flags;
+ sdata->u.mntr.flags = *flags;
}
return wdev;
@@ -89,11 +89,11 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
* cooked_mntrs, monitor and all fif_* counters
* reconfigure hardware
*/
- if ((*flags & mask) != (sdata->u.mntr_flags & mask))
+ if ((*flags & mask) != (sdata->u.mntr.flags & mask))
return -EBUSY;
ieee80211_adjust_monitor_flags(sdata, -1);
- sdata->u.mntr_flags = *flags;
+ sdata->u.mntr.flags = *flags;
ieee80211_adjust_monitor_flags(sdata, 1);
ieee80211_configure_filter(local);
@@ -103,7 +103,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
* and ieee80211_do_open take care of "everything"
* mentioned in the comment above.
*/
- sdata->u.mntr_flags = *flags;
+ sdata->u.mntr.flags = *flags;
}
}
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index c258f10..c701b64 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -62,7 +62,7 @@ int drv_add_interface(struct ieee80211_local *local,
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
- !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
+ !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))))
return -EINVAL;
trace_drv_add_interface(local, sdata);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f56d342..9211cce 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -824,6 +824,10 @@ struct txq_info {
struct ieee80211_txq txq;
};
+struct ieee80211_if_mntr {
+ u32 flags;
+};
+
struct ieee80211_sub_if_data {
struct list_head list;
@@ -922,7 +926,7 @@ struct ieee80211_sub_if_data {
struct ieee80211_if_ibss ibss;
struct ieee80211_if_mesh mesh;
struct ieee80211_if_ocb ocb;
- u32 mntr_flags;
+ struct ieee80211_if_mntr mntr;
} u;
#ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b123a9e..c8509d9 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -188,7 +188,7 @@ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
continue;
if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
- !(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ !(iter->u.mntr.flags & MONITOR_FLAG_ACTIVE))
continue;
m = iter->vif.addr;
@@ -217,7 +217,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
return -EBUSY;
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
- !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
check_dup = false;
ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
@@ -357,7 +357,7 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
const int offset)
{
struct ieee80211_local *local = sdata->local;
- u32 flags = sdata->u.mntr_flags;
+ u32 flags = sdata->u.mntr.flags;
#define ADJUST(_f, _s) do { \
if (flags & MONITOR_FLAG_##_f) \
@@ -589,12 +589,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
}
break;
case NL80211_IFTYPE_MONITOR:
- if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
+ if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
local->cooked_mntrs++;
break;
}
- if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
+ if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
res = drv_add_interface(local, sdata);
if (res)
goto err_stop;
@@ -926,7 +926,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
/* no need to tell driver */
break;
case NL80211_IFTYPE_MONITOR:
- if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
+ if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
local->cooked_mntrs--;
break;
}
@@ -1012,7 +1012,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
ieee80211_recalc_idle(local);
mutex_unlock(&local->mtx);
- if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
break;
/* fall through */
@@ -1444,7 +1444,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
case NL80211_IFTYPE_MONITOR:
sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP;
sdata->dev->netdev_ops = &ieee80211_monitorif_ops;
- sdata->u.mntr_flags = MONITOR_FLAG_CONTROL |
+ sdata->u.mntr.flags = MONITOR_FLAG_CONTROL |
MONITOR_FLAG_OTHER_BSS;
break;
case NL80211_IFTYPE_WDS:
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9dce3b1..708c3b1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -567,7 +567,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
continue;
- if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)
+ if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
continue;
if (!ieee80211_sdata_running(sdata))
@@ -3147,7 +3147,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
continue;
if (sdata->vif.type != NL80211_IFTYPE_MONITOR ||
- !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
+ !(sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES))
continue;
if (prev_dev) {
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index a2a6826..fabd9ff 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -709,7 +709,7 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
if (!ieee80211_sdata_running(sdata))
continue;
- if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
+ if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) &&
!send_to_cooked)
continue;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1d0746d..efc38e7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1643,7 +1643,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
switch (sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
- if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
+ if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
vif = &sdata->vif;
break;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 42bf0b6..e777c2a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -598,7 +598,7 @@ static void __iterate_interfaces(struct ieee80211_local *local,
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
switch (sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
- if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
continue;
break;
case NL80211_IFTYPE_AP_VLAN:
--
2.8.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/6] mac80211: add support for MU-MIMO air sniffer
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
2016-08-29 20:25 ` [PATCH v2 1/6] cfg80211: clarify the requirements of .disconnect() Luca Coelho
2016-08-29 20:25 ` [PATCH v2 2/6] mac80211: refactor monitor representation in sdata Luca Coelho
@ 2016-08-29 20:25 ` Luca Coelho
2016-08-29 20:25 ` [PATCH v2 4/6] mac80211: add support for radiotap timestamp field Luca Coelho
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luca Coelho @ 2016-08-29 20:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
From: Aviya Erenfeld <aviya.erenfeld@intel.com>
add support to MU-MIMO air sniffer according groupID:
in monitor mode, use a given MU-MIMO groupID to monitor stations
that belongs to that group using MU-MIMO.
add support for following a station according to its MAC address
using VHT MU-MIMO sniffer:
the monitors wait until they get an action MU-MIMO notification
frame, then parses it in order to find the groupID that corresponds
to the given MAC address and monitors packets destined to that
groupID using VHT MU-MIMO.
Signed-off-by: Aviya Erenfeld <aviya.erenfeld@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/mac80211/cfg.c | 23 ++++++++++++++++++++++-
net/mac80211/driver-ops.h | 3 ++-
net/mac80211/ieee80211_i.h | 3 ++-
net/mac80211/iface.c | 5 +++++
net/mac80211/rx.c | 21 +++++++++++++++++++++
5 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f2c8cd2..5d4afea 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -73,8 +73,29 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
sdata->u.mgd.use_4addr = params->use_4addr;
}
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_sub_if_data *monitor_sdata;
+ u32 mu_mntr_cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
+
+ monitor_sdata = rtnl_dereference(local->monitor_sdata);
+ if (monitor_sdata &&
+ wiphy_ext_feature_isset(wiphy, mu_mntr_cap_flag)) {
+ memcpy(monitor_sdata->vif.bss_conf.mu_group.membership,
+ params->vht_mumimo_groups, WLAN_MEMBERSHIP_LEN);
+ memcpy(monitor_sdata->vif.bss_conf.mu_group.position,
+ params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
+ WLAN_USER_POSITION_LEN);
+ monitor_sdata->vif.mu_mimo_owner = true;
+ ieee80211_bss_info_change_notify(monitor_sdata,
+ BSS_CHANGED_MU_GROUPS);
+
+ ether_addr_copy(monitor_sdata->u.mntr.mu_follow_addr,
+ params->macaddr);
+ }
+
+ if (!flags)
+ return 0;
if (ieee80211_sdata_running(sdata)) {
u32 mask = MONITOR_FLAG_COOK_FRAMES |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 42a41ae..c39f93b 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -162,7 +162,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
return;
if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
- sdata->vif.type == NL80211_IFTYPE_MONITOR))
+ (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !sdata->vif.mu_mimo_owner)))
return;
if (!check_sdata_in_driver(sdata))
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9211cce..7576168 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -3,7 +3,7 @@
* Copyright 2005, Devicescape Software, Inc.
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2013-2014 Intel Mobile Communications GmbH
+ * Copyright 2013-2015 Intel Mobile Communications GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -826,6 +826,7 @@ struct txq_info {
struct ieee80211_if_mntr {
u32 flags;
+ u8 mu_follow_addr[ETH_ALEN] __aligned(2);
};
struct ieee80211_sub_if_data {
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c8509d9..b0abddc7 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -43,6 +43,8 @@
* by either the RTNL, the iflist_mtx or RCU.
*/
+static void ieee80211_iface_work(struct work_struct *work);
+
bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_chanctx_conf *chanctx_conf;
@@ -448,6 +450,9 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
return ret;
}
+ skb_queue_head_init(&sdata->skb_queue);
+ INIT_WORK(&sdata->work, ieee80211_iface_work);
+
return 0;
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 708c3b1..b7f051c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -485,6 +485,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
struct net_device *prev_dev = NULL;
int present_fcs_len = 0;
unsigned int rtap_vendor_space = 0;
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_sub_if_data *monitor_sdata =
+ rcu_dereference(local->monitor_sdata);
if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) {
struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data;
@@ -585,6 +588,24 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
ieee80211_rx_stats(sdata->dev, skb->len);
}
+ mgmt = (void *)skb->data;
+ if (monitor_sdata && ieee80211_is_action(mgmt->frame_control) &&
+ skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 +
+ VHT_MUMIMO_GROUPS_DATA_LEN &&
+ mgmt->u.action.category == WLAN_CATEGORY_VHT &&
+ mgmt->u.action.u.vht_group_notif.action_code ==
+ WLAN_VHT_ACTION_GROUPID_MGMT &&
+ is_valid_ether_addr(monitor_sdata->u.mntr.mu_follow_addr) &&
+ ether_addr_equal(mgmt->da, monitor_sdata->u.mntr.mu_follow_addr)) {
+ struct sk_buff *mu_skb = skb_copy(skb, GFP_ATOMIC);
+
+ if (mu_skb) {
+ mu_skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
+ skb_queue_tail(&monitor_sdata->skb_queue, mu_skb);
+ ieee80211_queue_work(&local->hw, &monitor_sdata->work);
+ }
+ }
+
if (prev_dev) {
skb->dev = prev_dev;
netif_receive_skb(skb);
--
2.8.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 4/6] mac80211: add support for radiotap timestamp field
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
` (2 preceding siblings ...)
2016-08-29 20:25 ` [PATCH v2 3/6] mac80211: add support for MU-MIMO air sniffer Luca Coelho
@ 2016-08-29 20:25 ` Luca Coelho
2016-08-29 20:25 ` [PATCH v2 5/6] mac80211: send delBA on unexpected BlockAck data frames Luca Coelho
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Luca Coelho @ 2016-08-29 20:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Use the existing device timestamp from the RX status information
to add support for the new radiotap timestamp field. Currently
only 32-bit counters are supported, but we also add the radiotap
mactime where applicable. This new field allows more flexibility
in where the timestamp is taken etc. The non-timestamp data in
the field is taken from a new field in the hw struct.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/ieee80211_radiotap.h | 21 +++++++++++++++++++++
include/net/mac80211.h | 12 ++++++++++++
net/mac80211/main.c | 3 +++
net/mac80211/rx.c | 30 ++++++++++++++++++++++++++++++
4 files changed, 66 insertions(+)
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index b0fd947..ba07b9d 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -190,6 +190,10 @@ struct ieee80211_radiotap_header {
* IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16
*
* Contains VHT information about this frame.
+ *
+ * IEEE80211_RADIOTAP_TIMESTAMP u64, u16, u8, u8 variable
+ *
+ * Contains timestamp information for this frame.
*/
enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_TSFT = 0,
@@ -214,6 +218,7 @@ enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_MCS = 19,
IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
IEEE80211_RADIOTAP_VHT = 21,
+ IEEE80211_RADIOTAP_TIMESTAMP = 22,
/* valid in every it_present bitmap, even vendor namespaces */
IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
@@ -321,6 +326,22 @@ enum ieee80211_radiotap_type {
#define IEEE80211_RADIOTAP_CODING_LDPC_USER2 0x04
#define IEEE80211_RADIOTAP_CODING_LDPC_USER3 0x08
+/* For IEEE80211_RADIOTAP_TIMESTAMP */
+#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MASK 0x000F
+#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MS 0x0000
+#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US 0x0001
+#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_NS 0x0003
+#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_MASK 0x00F0
+#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_BEGIN_MDPU 0x0000
+#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_MPDU 0x0010
+#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_PPDU 0x0020
+#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ 0x0030
+#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_UNKNOWN 0x00F0
+
+#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT 0x00
+#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT 0x01
+#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY 0x02
+
/* helpers */
static inline int ieee80211_get_radiotap_len(unsigned char *data)
{
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index cca510a..81870dc 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2141,6 +2141,14 @@ enum ieee80211_hw_flags {
* the default is _GI | _BANDWIDTH.
* Use the %IEEE80211_RADIOTAP_VHT_KNOWN_* values.
*
+ * @radiotap_timestamp: Information for the radiotap timestamp field; if the
+ * 'units_pos' member is set to a non-negative value it must be set to
+ * a combination of a IEEE80211_RADIOTAP_TIMESTAMP_UNIT_* and a
+ * IEEE80211_RADIOTAP_TIMESTAMP_SPOS_* value, and then the timestamp
+ * field will be added and populated from the &struct ieee80211_rx_status
+ * device_timestamp. If the 'accuracy' member is non-negative, it's put
+ * into the accuracy radiotap field and the accuracy known flag is set.
+ *
* @netdev_features: netdev features to be set in each netdev created
* from this HW. Note that not all features are usable with mac80211,
* other features will be rejected during HW registration.
@@ -2184,6 +2192,10 @@ struct ieee80211_hw {
u8 offchannel_tx_hw_queue;
u8 radiotap_mcs_details;
u16 radiotap_vht_details;
+ struct {
+ int units_pos;
+ s16 accuracy;
+ } radiotap_timestamp;
netdev_features_t netdev_features;
u8 uapsd_queues;
u8 uapsd_max_sp_len;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d00ea9b..ac053a9 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -660,6 +660,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
ieee80211_roc_setup(local);
+ local->hw.radiotap_timestamp.units_pos = -1;
+ local->hw.radiotap_timestamp.accuracy = -1;
+
return &local->hw;
err_free:
wiphy_free(wiphy);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b7f051c..268eeb7 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -180,6 +180,11 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
len += 12;
}
+ if (local->hw.radiotap_timestamp.units_pos >= 0) {
+ len = ALIGN(len, 8);
+ len += 12;
+ }
+
if (status->chains) {
/* antenna and antenna signal fields */
len += 2 * hweight8(status->chains);
@@ -447,6 +452,31 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos += 2;
}
+ if (local->hw.radiotap_timestamp.units_pos >= 0) {
+ u16 accuracy = 0;
+ u8 flags = IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT;
+
+ rthdr->it_present |=
+ cpu_to_le32(1 << IEEE80211_RADIOTAP_TIMESTAMP);
+
+ /* ensure 8 byte alignment */
+ while ((pos - (u8 *)rthdr) & 7)
+ pos++;
+
+ put_unaligned_le64(status->device_timestamp, pos);
+ pos += sizeof(u64);
+
+ if (local->hw.radiotap_timestamp.accuracy >= 0) {
+ accuracy = local->hw.radiotap_timestamp.accuracy;
+ flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY;
+ }
+ put_unaligned_le16(accuracy, pos);
+ pos += sizeof(u16);
+
+ *pos++ = local->hw.radiotap_timestamp.units_pos;
+ *pos++ = flags;
+ }
+
for_each_set_bit(chain, &chains, IEEE80211_MAX_CHAINS) {
*pos++ = status->chain_signal[chain];
*pos++ = chain;
--
2.8.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 5/6] mac80211: send delBA on unexpected BlockAck data frames
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
` (3 preceding siblings ...)
2016-08-29 20:25 ` [PATCH v2 4/6] mac80211: add support for radiotap timestamp field Luca Coelho
@ 2016-08-29 20:25 ` Luca Coelho
2016-08-29 20:25 ` [PATCH v2 6/6] mac80211: send delBA on unexpected BlockAck Request Luca Coelho
2016-09-12 9:47 ` [PATCH v2 0/6] some mac80211/cfg80211 patches Johannes Berg
6 siblings, 0 replies; 8+ messages in thread
From: Luca Coelho @ 2016-08-29 20:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
When we receive data frames with ACK policy BlockAck, send
delBA as requested by the 802.11 spec. Since this would be
happening for every frame inside an A-MPDU if it's really
received outside a session, limit it to a single attempt.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/agg-rx.c | 4 +++-
net/mac80211/rx.c | 9 ++++++++-
net/mac80211/sta_info.h | 3 +++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index a9aff60..4d05acc 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -406,8 +406,10 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
}
end:
- if (status == WLAN_STATUS_SUCCESS)
+ if (status == WLAN_STATUS_SUCCESS) {
__set_bit(tid, sta->ampdu_mlme.agg_session_valid);
+ __clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
+ }
mutex_unlock(&sta->ampdu_mlme.mtx);
end_no_lock:
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 268eeb7..27b58f3 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1123,8 +1123,15 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
- if (!tid_agg_rx)
+ if (!tid_agg_rx) {
+ if (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
+ !test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
+ !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
+ ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
+ WLAN_BACK_RECIPIENT,
+ WLAN_REASON_QSTA_REQUIRE_SETUP);
goto dont_reorder;
+ }
/* qos null data frames are excluded */
if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 0556be3..530231b 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -230,6 +230,8 @@ struct tid_ampdu_rx {
* @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the
* driver requested to close until the work for it runs
* @agg_session_valid: bitmap indicating which TID has a rx BA session open on
+ * @unexpected_agg: bitmap indicating which TID already sent a delBA due to
+ * unexpected aggregation related frames outside a session
* @work: work struct for starting/stopping aggregation
* @tid_tx: aggregation info for Tx per TID
* @tid_start_tx: sessions where start was requested
@@ -244,6 +246,7 @@ struct sta_ampdu_mlme {
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
+ unsigned long unexpected_agg[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
/* tx */
struct work_struct work;
struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];
--
2.8.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 6/6] mac80211: send delBA on unexpected BlockAck Request
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
` (4 preceding siblings ...)
2016-08-29 20:25 ` [PATCH v2 5/6] mac80211: send delBA on unexpected BlockAck data frames Luca Coelho
@ 2016-08-29 20:25 ` Luca Coelho
2016-09-12 9:47 ` [PATCH v2 0/6] some mac80211/cfg80211 patches Johannes Berg
6 siblings, 0 replies; 8+ messages in thread
From: Luca Coelho @ 2016-08-29 20:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
If we don't have a BA session, send delBA, as requested by the
IEEE 802.11 spec. Apply the same limit of sending such a delBA
only once as in the previous patch.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/rx.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 27b58f3..29f9669 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2593,6 +2593,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
tid = le16_to_cpu(bar_data.control) >> 12;
+ if (!test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
+ !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
+ ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
+ WLAN_BACK_RECIPIENT,
+ WLAN_REASON_QSTA_REQUIRE_SETUP);
+
tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]);
if (!tid_agg_rx)
return RX_DROP_MONITOR;
--
2.8.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/6] some mac80211/cfg80211 patches
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
` (5 preceding siblings ...)
2016-08-29 20:25 ` [PATCH v2 6/6] mac80211: send delBA on unexpected BlockAck Request Luca Coelho
@ 2016-09-12 9:47 ` Johannes Berg
6 siblings, 0 replies; 8+ messages in thread
From: Johannes Berg @ 2016-09-12 9:47 UTC (permalink / raw)
To: Luca Coelho; +Cc: linux-wireless
Applied all now. It seems I got held up somewhere in the middle before.
johannes
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-09-12 9:47 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-29 20:25 [PATCH v2 0/6] some mac80211/cfg80211 patches Luca Coelho
2016-08-29 20:25 ` [PATCH v2 1/6] cfg80211: clarify the requirements of .disconnect() Luca Coelho
2016-08-29 20:25 ` [PATCH v2 2/6] mac80211: refactor monitor representation in sdata Luca Coelho
2016-08-29 20:25 ` [PATCH v2 3/6] mac80211: add support for MU-MIMO air sniffer Luca Coelho
2016-08-29 20:25 ` [PATCH v2 4/6] mac80211: add support for radiotap timestamp field Luca Coelho
2016-08-29 20:25 ` [PATCH v2 5/6] mac80211: send delBA on unexpected BlockAck data frames Luca Coelho
2016-08-29 20:25 ` [PATCH v2 6/6] mac80211: send delBA on unexpected BlockAck Request Luca Coelho
2016-09-12 9:47 ` [PATCH v2 0/6] some mac80211/cfg80211 patches Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).