* [PATCH 00/12] monitor-less AP mode part 1
@ 2011-11-04 10:18 Johannes Berg
2011-11-04 10:18 ` [PATCH 01/12] mac80211: add helper to free TX skb Johannes Berg
` (11 more replies)
0 siblings, 12 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
This is the first batch of patches. With these, it will work, but
not get EAPOL TX status. The socket option for that is still pending
review on netdev, but these patches can stand alone, and hostapd can
even work with just these w/o EAPOL TX status, just not completely
compliant.
johannes
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/12] mac80211: add helper to free TX skb
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 02/12] mac80211: add support for control port protocol in AP mode Johannes Berg
` (10 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Drivers that need to drop a frame before it
can be transmitted will usually simply free
that frame. This is currently fine, but in
the future it'll be needed to tell mac80211
about this case, so add a new routine that
frees a TX skb.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/mac80211.h | 10 ++++++++++
net/mac80211/status.c | 6 ++++++
2 files changed, 16 insertions(+)
--- a/include/net/mac80211.h 2011-11-03 10:54:17.000000000 +0100
+++ b/include/net/mac80211.h 2011-11-03 11:52:48.000000000 +0100
@@ -1304,6 +1304,16 @@ ieee80211_get_alt_retry_rate(const struc
}
/**
+ * ieee80211_free_txskb - free TX skb
+ * @hw: the hardware
+ * @skb: the skb
+ *
+ * Free a transmit skb. Use this funtion when some failure
+ * to transmit happened and thus status cannot be reported.
+ */
+void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
+
+/**
* DOC: Hardware crypto acceleration
*
* mac80211 is capable of taking advantage of many hardware
--- a/net/mac80211/status.c 2011-11-03 10:54:17.000000000 +0100
+++ b/net/mac80211/status.c 2011-11-03 11:52:48.000000000 +0100
@@ -609,3 +609,9 @@ void ieee80211_report_low_ack(struct iee
num_packets, GFP_ATOMIC);
}
EXPORT_SYMBOL(ieee80211_report_low_ack);
+
+void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ dev_kfree_skb_any(skb);
+}
+EXPORT_SYMBOL(ieee80211_free_txskb);
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 02/12] mac80211: add support for control port protocol in AP mode
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
2011-11-04 10:18 ` [PATCH 01/12] mac80211: add helper to free TX skb Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 03/12] nl80211: allow subscribing to unexpected class3 frames Johannes Berg
` (9 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
This will allow us to support dynamic WEP with 802.1X
properly in mac80211 by not encrypting outgoing and
accepting unencrypted incoming frames.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/cfg.c | 21 ++++++++++++++++++++-
net/mac80211/iface.c | 13 ++++++++++++-
2 files changed, 32 insertions(+), 2 deletions(-)
--- a/net/mac80211/cfg.c 2011-11-03 11:52:40.000000000 +0100
+++ b/net/mac80211/cfg.c 2011-11-03 11:52:48.000000000 +0100
@@ -594,6 +594,8 @@ static int ieee80211_add_beacon(struct w
{
struct ieee80211_sub_if_data *sdata;
struct beacon_data *old;
+ struct ieee80211_sub_if_data *vlan;
+ int ret;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -601,7 +603,24 @@ static int ieee80211_add_beacon(struct w
if (old)
return -EALREADY;
- return ieee80211_config_beacon(sdata, params);
+ ret = ieee80211_config_beacon(sdata, params);
+ if (ret)
+ return ret;
+
+ /*
+ * Apply control port protocol, this allows us to
+ * not encrypt dynamic WEP control frames.
+ */
+ sdata->control_port_protocol = params->crypto.control_port_ethertype;
+ sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
+ vlan->control_port_protocol =
+ params->crypto.control_port_ethertype;
+ vlan->control_port_no_encrypt =
+ params->crypto.control_port_no_encrypt;
+ }
+
+ return 0;
}
static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
--- a/net/mac80211/iface.c 2011-11-03 11:52:47.000000000 +0100
+++ b/net/mac80211/iface.c 2011-11-03 11:52:48.000000000 +0100
@@ -188,11 +188,22 @@ static int ieee80211_do_open(struct net_
if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
return -ENOLINK;
break;
- case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_AP_VLAN: {
+ struct ieee80211_sub_if_data *master;
+
if (!sdata->bss)
return -ENOLINK;
+
list_add(&sdata->u.vlan.list, &sdata->bss->vlans);
+
+ master = container_of(sdata->bss,
+ struct ieee80211_sub_if_data, u.ap);
+ sdata->control_port_protocol =
+ master->control_port_protocol;
+ sdata->control_port_no_encrypt =
+ master->control_port_no_encrypt;
break;
+ }
case NL80211_IFTYPE_AP:
sdata->bss = &sdata->u.ap;
break;
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 03/12] nl80211: allow subscribing to unexpected class3 frames
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
2011-11-04 10:18 ` [PATCH 01/12] mac80211: add helper to free TX skb Johannes Berg
2011-11-04 10:18 ` [PATCH 02/12] mac80211: add support for control port protocol in AP mode Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 04/12] mac80211: support spurious class3 event Johannes Berg
` (8 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
To implement AP mode without monitor interfaces we
need to be able to send a deauth to stations that
send frames without being associated. Enable this
by adding a new nl80211 event for such frames that
an application can subscribe to.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/linux/nl80211.h | 12 ++++++++
include/net/cfg80211.h | 17 ++++++++++++
net/wireless/mlme.c | 16 +++++++++++
net/wireless/nl80211.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.h | 3 ++
5 files changed, 114 insertions(+)
--- a/include/linux/nl80211.h 2011-11-03 13:48:25.000000000 +0100
+++ b/include/linux/nl80211.h 2011-11-03 14:16:36.000000000 +0100
@@ -509,6 +509,16 @@
* @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
* @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
*
+ * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
+ * (or GO) interface (i.e. hostapd) to ask for unexpected frames to
+ * implement sending deauth to stations that send unexpected class 3
+ * frames. Also used as the event sent by the kernel when such a frame
+ * is received.
+ * For the event, the %NL80211_ATTR_MAC attribute carries the TA and
+ * other attributes like the interface index are present.
+ * If used as the command it must have an interface index and you can
+ * only unsubscribe from the event by closing the socket.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -638,6 +648,8 @@ enum nl80211_commands {
NL80211_CMD_TDLS_OPER,
NL80211_CMD_TDLS_MGMT,
+ NL80211_CMD_UNEXPECTED_FRAME,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- a/include/net/cfg80211.h 2011-11-03 14:02:27.000000000 +0100
+++ b/include/net/cfg80211.h 2011-11-03 14:16:48.000000000 +0100
@@ -2179,6 +2179,8 @@ struct wireless_dev {
int beacon_interval;
+ u32 ap_unexpected_nlpid;
+
#ifdef CONFIG_CFG80211_WEXT
/* wext data */
struct {
@@ -3189,6 +3191,21 @@ void cfg80211_gtk_rekey_notify(struct ne
void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
const u8 *bssid, bool preauth, gfp_t gfp);
+/**
+ * cfg80211_rx_spurious_frame - inform userspace about a spurious frame
+ * @dev: The device the frame matched to
+ * @addr: the transmitter address
+ * @gfp: context flags
+ *
+ * This function is used in AP mode (only!) to inform userspace that
+ * a spurious class 3 frame was received, to be able to deauth the
+ * sender.
+ * Returns %true if the frame was passed to userspace (or this failed
+ * for a reason other than not having a subscription.)
+ */
+bool cfg80211_rx_spurious_frame(struct net_device *dev,
+ const u8 *addr, gfp_t gfp);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
--- a/net/wireless/mlme.c 2011-11-03 13:48:30.000000000 +0100
+++ b/net/wireless/mlme.c 2011-11-03 14:16:34.000000000 +0100
@@ -879,6 +879,9 @@ void cfg80211_mlme_unregister_socket(str
}
spin_unlock_bh(&wdev->mgmt_registrations_lock);
+
+ if (nlpid == wdev->ap_unexpected_nlpid)
+ wdev->ap_unexpected_nlpid = 0;
}
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
@@ -1107,3 +1110,16 @@ void cfg80211_pmksa_candidate_notify(str
nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
}
EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
+
+bool cfg80211_rx_spurious_frame(struct net_device *dev,
+ const u8 *addr, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
+ wdev->iftype != NL80211_IFTYPE_P2P_GO))
+ return false;
+
+ return nl80211_unexpected_frame(dev, addr, gfp);
+}
+EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
--- a/net/wireless/nl80211.c 2011-11-03 14:02:27.000000000 +0100
+++ b/net/wireless/nl80211.c 2011-11-03 14:16:36.000000000 +0100
@@ -5826,6 +5826,23 @@ static int nl80211_set_rekey_data(struct
return err;
}
+static int nl80211_register_unexpected_frame(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (wdev->iftype != NL80211_IFTYPE_AP &&
+ wdev->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EINVAL;
+
+ if (wdev->ap_unexpected_nlpid)
+ return -EBUSY;
+
+ wdev->ap_unexpected_nlpid = info->snd_pid;
+ return 0;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -6381,6 +6398,14 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_UNEXPECTED_FRAME,
+ .doit = nl80211_register_unexpected_frame,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -7165,6 +7190,47 @@ void nl80211_send_sta_del_event(struct c
nlmsg_free(msg);
}
+bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+ int err;
+ u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid);
+
+ if (!nlpid)
+ return false;
+
+ msg = nlmsg_new(100, gfp);
+ if (!msg)
+ return true;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UNEXPECTED_FRAME);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return true;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+
+ err = genlmsg_end(msg, hdr);
+ if (err < 0) {
+ nlmsg_free(msg);
+ return true;
+ }
+
+ genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
+ return true;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+ return true;
+}
+
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid,
int freq, const u8 *buf, size_t len, gfp_t gfp)
--- a/net/wireless/nl80211.h 2011-11-03 13:48:30.000000000 +0100
+++ b/net/wireless/nl80211.h 2011-11-03 14:16:34.000000000 +0100
@@ -117,4 +117,7 @@ void nl80211_pmksa_candidate_notify(stru
struct net_device *netdev, int index,
const u8 *bssid, bool preauth, gfp_t gfp);
+bool nl80211_unexpected_frame(struct net_device *dev,
+ const u8 *addr, gfp_t gfp);
+
#endif /* __NET_WIRELESS_NL80211_H */
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 04/12] mac80211: support spurious class3 event
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (2 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 03/12] nl80211: allow subscribing to unexpected class3 frames Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 05/12] nl80211: advertise device AP SME Johannes Berg
` (7 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Add support for the spurious class3 frame event
to mac80211 to enable AP w/o monitor mode.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/rx.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/net/mac80211/rx.c 2011-11-03 11:52:41.000000000 +0100
+++ b/net/mac80211/rx.c 2011-11-03 11:52:50.000000000 +0100
@@ -854,6 +854,13 @@ ieee80211_rx_h_check(struct ieee80211_rx
rx->sdata->control_port_protocol)
return RX_CONTINUE;
}
+
+ if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
+ cfg80211_rx_spurious_frame(rx->sdata->dev,
+ hdr->addr2,
+ GFP_ATOMIC))
+ return RX_DROP_UNUSABLE;
+
return RX_DROP_MONITOR;
}
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 05/12] nl80211: advertise device AP SME
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (3 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 04/12] mac80211: support spurious class3 event Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-07 8:29 ` Arik Nemtsov
2011-11-07 11:39 ` [PATCH v3 " Johannes Berg
2011-11-04 10:18 ` [PATCH 06/12] nl80211: add API to probe a client Johannes Berg
` (6 subsequent siblings)
11 siblings, 2 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Add the ability to advertise that the device
contains the AP SME and what features it can
support.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: fix attribute name (thanks Eliad)
drivers/net/wireless/ath/ath6kl/init.c | 4 +++-
include/linux/nl80211.h | 20 ++++++++++++++++++++
include/net/cfg80211.h | 6 ++++++
net/wireless/core.c | 4 ++++
net/wireless/nl80211.c | 4 ++++
5 files changed, 37 insertions(+), 1 deletion(-)
--- a/include/linux/nl80211.h 2011-11-03 11:52:49.000000000 +0100
+++ b/include/linux/nl80211.h 2011-11-03 11:52:51.000000000 +0100
@@ -1122,6 +1122,11 @@ enum nl80211_commands {
* %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
* used for asking the driver to perform a TDLS operation.
*
+ * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices
+ * that have AP support to indicate that they have the AP SME integrated
+ * with support for the features listed in this attribute, see
+ * &enum nl80211_ap_sme_features.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1350,6 +1355,8 @@ enum nl80211_attrs {
NL80211_ATTR_TDLS_SUPPORT,
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+ NL80211_ATTR_DEVICE_AP_SME,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -2663,4 +2670,17 @@ enum nl80211_tdls_operation {
NL80211_TDLS_DISABLE_LINK,
};
+/**
+ * enum nl80211_ap_sme_features - device-integrated AP features
+ * @NL80211_AP_SME_WSC: The driver is capable of indicating received probe
+ * request frames to userspace via management frame subscription events
+ * if the payload includes the WSC IE. The driver is capable of adding
+ * the WSC IE as configured from userspace into beacons, probe responses
+ * and (re)association reponse frame and allows userspace to update them
+ * during the lifetime of the BSS.
+ */
+enum nl80211_ap_sme_features {
+ NL80211_AP_SME_WSC = 1 << 0,
+};
+
#endif /* __LINUX_NL80211_H */
--- a/include/net/cfg80211.h 2011-11-03 11:52:49.000000000 +0100
+++ b/include/net/cfg80211.h 2011-11-03 11:52:51.000000000 +0100
@@ -1675,6 +1675,7 @@ struct cfg80211_ops {
* teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT
* command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be
* used for asking the driver/firmware to perform a TDLS operation.
+ * @WIPHY_FLAG_HAVE_AP_SME: device integrates AP SME
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1693,6 +1694,7 @@ enum wiphy_flags {
WIPHY_FLAG_AP_UAPSD = BIT(14),
WIPHY_FLAG_SUPPORTS_TDLS = BIT(15),
WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16),
+ WIPHY_FLAG_HAVE_AP_SME = BIT(17),
};
/**
@@ -1903,6 +1905,8 @@ struct wiphy_wowlan_support {
* may request, if implemented.
*
* @wowlan: WoWLAN support information
+ *
+ * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -1926,6 +1930,8 @@ struct wiphy {
u32 flags;
+ u32 ap_sme_capa;
+
enum cfg80211_signal_type signal_type;
int bss_priv_size;
--- a/net/wireless/core.c 2011-11-03 10:54:14.000000000 +0100
+++ b/net/wireless/core.c 2011-11-03 11:52:51.000000000 +0100
@@ -492,6 +492,10 @@ int wiphy_register(struct wiphy *wiphy)
!(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
return -EINVAL;
+ if (WARN_ON(wiphy->ap_sme_capa &&
+ !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
+ return -EINVAL;
+
if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
return -EINVAL;
--- a/net/wireless/nl80211.c 2011-11-03 11:52:49.000000000 +0100
+++ b/net/wireless/nl80211.c 2011-11-03 11:52:51.000000000 +0100
@@ -1007,6 +1007,10 @@ static int nl80211_send_wiphy(struct sk_
if (nl80211_put_iface_combinations(&dev->wiphy, msg))
goto nla_put_failure;
+ if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME)
+ NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME,
+ dev->wiphy.ap_sme_capa);
+
return genlmsg_end(msg, hdr);
nla_put_failure:
--- a/drivers/net/wireless/ath/ath6kl/init.c 2011-11-03 10:54:14.000000000 +0100
+++ b/drivers/net/wireless/ath/ath6kl/init.c 2011-11-03 11:52:51.000000000 +0100
@@ -1548,7 +1548,9 @@ static int ath6kl_init(struct net_device
ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
- ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+ ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
+ WIPHY_FLAG_HAVE_AP_SME;
+ ar->wdev->wiphy->ap_sme_capa = NL80211_AP_SME_WSC;
status = ath6kl_target_config_wlan_params(ar);
if (!status)
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 06/12] nl80211: add API to probe a client
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (4 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 05/12] nl80211: advertise device AP SME Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 07/12] mac80211: support client probe Johannes Berg
` (5 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
When the AP SME in hostapd is used it wants to
probe the clients when they have been idle for
some time. Add explicit API to support this.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: - indicate both ack/non-ack status for cookie validity
include/linux/nl80211.h | 10 ++++
include/net/cfg80211.h | 17 +++++++
net/wireless/nl80211.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 131 insertions(+)
--- a/include/linux/nl80211.h 2011-11-03 11:52:51.000000000 +0100
+++ b/include/linux/nl80211.h 2011-11-03 11:52:51.000000000 +0100
@@ -520,6 +520,14 @@
* If used as the command, must have an interface index, and you can
* only unsubscribe from the event by closing the socket.
*
+ * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface
+ * by sending a null data frame to it and reporting when the frame is
+ * acknowleged. This is used to allow timing out inactive clients. Uses
+ * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a
+ * direct reply with an %NL80211_ATTR_COOKIE that is later used to match
+ * up the event with the request. The event includes the same data and
+ * has %NL80211_ATTR_ACK set if the frame was ACKed.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -651,6 +659,8 @@ enum nl80211_commands {
NL80211_CMD_UNEXPECTED_FRAME,
+ NL80211_CMD_PROBE_CLIENT,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- a/include/net/cfg80211.h 2011-11-03 11:52:51.000000000 +0100
+++ b/include/net/cfg80211.h 2011-11-03 11:52:51.000000000 +0100
@@ -1428,6 +1428,9 @@ struct cfg80211_gtk_rekey_data {
*
* @tdls_mgmt: Transmit a TDLS management frame.
* @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup).
+ *
+ * @probe_client: probe an associated client, must return a cookie that it
+ * later passes to cfg80211_probe_status().
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -1617,6 +1620,9 @@ struct cfg80211_ops {
u16 status_code, const u8 *buf, size_t len);
int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
u8 *peer, enum nl80211_tdls_operation oper);
+
+ int (*probe_client)(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *peer, u64 *cookie);
};
/*
@@ -3214,6 +3220,17 @@ void cfg80211_pmksa_candidate_notify(str
bool cfg80211_rx_spurious_frame(struct net_device *dev,
const u8 *addr, gfp_t gfp);
+/**
+ * cfg80211_probe_status - notify userspace about probe status
+ * @dev: the device the probe was sent on
+ * @addr: the address of the peer
+ * @cookie: the cookie filled in @probe_client previously
+ * @acked: indicates whether probe was acked or not
+ * @gfp: allocation flags
+ */
+void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
+ u64 cookie, bool acked, gfp_t gfp);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
--- a/net/wireless/nl80211.c 2011-11-03 11:52:51.000000000 +0100
+++ b/net/wireless/nl80211.c 2011-11-03 11:52:51.000000000 +0100
@@ -890,6 +890,7 @@ static int nl80211_send_wiphy(struct sk_
}
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
CMD(sched_scan_start, START_SCHED_SCAN);
+ CMD(probe_client, PROBE_CLIENT);
#undef CMD
@@ -5847,6 +5848,59 @@ static int nl80211_register_unexpected_f
return 0;
}
+static int nl80211_probe_client(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct sk_buff *msg;
+ void *hdr;
+ const u8 *addr;
+ u64 cookie;
+ int err;
+
+ if (wdev->iftype != NL80211_IFTYPE_AP &&
+ wdev->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ if (!rdev->ops->probe_client)
+ return -EOPNOTSUPP;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+ NL80211_CMD_PROBE_CLIENT);
+
+ if (IS_ERR(hdr)) {
+ err = PTR_ERR(hdr);
+ goto free_msg;
+ }
+
+ addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+ err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie);
+ if (err)
+ goto free_msg;
+
+ NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+
+ genlmsg_end(msg, hdr);
+
+ return genlmsg_reply(msg, info);
+
+ nla_put_failure:
+ err = -ENOBUFS;
+ free_msg:
+ nlmsg_free(msg);
+ return err;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -6410,6 +6464,14 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_PROBE_CLIENT,
+ .doit = nl80211_probe_client,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -7472,6 +7534,48 @@ nl80211_send_cqm_pktloss_notify(struct c
nlmsg_free(msg);
}
+void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
+ u64 cookie, bool acked, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+ int err;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+ NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+ if (acked)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_ACK);
+
+ err = genlmsg_end(msg, hdr);
+ if (err < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_probe_status);
+
static int nl80211_netlink_notify(struct notifier_block * nb,
unsigned long state,
void *_notify)
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 07/12] mac80211: support client probe
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (5 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 06/12] nl80211: add API to probe a client Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 08/12] cfg80211: allow registering to beacons Johannes Berg
` (4 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Support probing clients with null data frames
in AP mode.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: update to use cfg80211_probe_status
net/mac80211/cfg.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/status.c | 45 +++++++++++++++++++--------------
2 files changed, 95 insertions(+), 18 deletions(-)
--- a/net/mac80211/cfg.c 2011-11-03 11:52:48.000000000 +0100
+++ b/net/mac80211/cfg.c 2011-11-03 11:52:52.000000000 +0100
@@ -2507,6 +2507,73 @@ static int ieee80211_tdls_oper(struct wi
return 0;
}
+static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *peer, u64 *cookie)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_qos_hdr *nullfunc;
+ struct sk_buff *skb;
+ int size = sizeof(*nullfunc);
+ __le16 fc;
+ bool qos;
+ struct ieee80211_tx_info *info;
+ struct sta_info *sta;
+
+ rcu_read_lock();
+ sta = sta_info_get(sdata, peer);
+ if (sta)
+ qos = test_sta_flag(sta, WLAN_STA_WME);
+ rcu_read_unlock();
+
+ if (!sta)
+ return -ENOLINK;
+
+ if (qos) {
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_QOS_NULLFUNC |
+ IEEE80211_FCTL_FROMDS);
+ } else {
+ size -= 2;
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_FROMDS);
+ }
+
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + size);
+ if (!skb)
+ return -ENOMEM;
+
+ skb->dev = dev;
+
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+
+ nullfunc = (void *) skb_put(skb, size);
+ nullfunc->frame_control = fc;
+ nullfunc->duration_id = 0;
+ memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
+ memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
+ memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
+ nullfunc->seq_ctrl = 0;
+
+ info = IEEE80211_SKB_CB(skb);
+
+ info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
+ IEEE80211_TX_INTFL_NL80211_FRAME_TX;
+
+ skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+ skb->priority = 7;
+ if (qos)
+ nullfunc->qos_ctrl = cpu_to_le16(7);
+
+ local_bh_disable();
+ ieee80211_xmit(sdata, skb);
+ local_bh_enable();
+
+ *cookie = (unsigned long) skb;
+ return 0;
+}
+
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -2572,4 +2639,5 @@ struct cfg80211_ops mac80211_config_ops
.set_rekey_data = ieee80211_set_rekey_data,
.tdls_oper = ieee80211_tdls_oper,
.tdls_mgmt = ieee80211_tdls_mgmt,
+ .probe_client = ieee80211_probe_client,
};
--- a/net/mac80211/status.c 2011-11-03 11:52:48.000000000 +0100
+++ b/net/mac80211/status.c 2011-11-03 11:52:52.000000000 +0100
@@ -516,27 +516,36 @@ void ieee80211_tx_status(struct ieee8021
}
if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
- struct ieee80211_work *wk;
u64 cookie = (unsigned long)skb;
- rcu_read_lock();
- list_for_each_entry_rcu(wk, &local->work_list, list) {
- if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
- continue;
- if (wk->offchan_tx.frame != skb)
- continue;
- wk->offchan_tx.status = true;
- break;
- }
- rcu_read_unlock();
- if (local->hw_roc_skb_for_status == skb) {
- cookie = local->hw_roc_cookie ^ 2;
- local->hw_roc_skb_for_status = NULL;
- }
+ if (ieee80211_is_nullfunc(hdr->frame_control) ||
+ ieee80211_is_qos_nullfunc(hdr->frame_control)) {
+ bool acked = info->flags & IEEE80211_TX_STAT_ACK;
+ cfg80211_probe_status(skb->dev, hdr->addr1,
+ cookie, acked, GFP_ATOMIC);
+ } else {
+ struct ieee80211_work *wk;
- cfg80211_mgmt_tx_status(
- skb->dev, cookie, skb->data, skb->len,
- !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
+ rcu_read_lock();
+ list_for_each_entry_rcu(wk, &local->work_list, list) {
+ if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
+ continue;
+ if (wk->offchan_tx.frame != skb)
+ continue;
+ wk->offchan_tx.status = true;
+ break;
+ }
+ rcu_read_unlock();
+ if (local->hw_roc_skb_for_status == skb) {
+ cookie = local->hw_roc_cookie ^ 2;
+ local->hw_roc_skb_for_status = NULL;
+ }
+
+ cfg80211_mgmt_tx_status(
+ skb->dev, cookie, skb->data, skb->len,
+ !!(info->flags & IEEE80211_TX_STAT_ACK),
+ GFP_ATOMIC);
+ }
}
/* this was a transmitted frame, but now we want to reuse it */
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 08/12] cfg80211: allow registering to beacons
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (6 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 07/12] mac80211: support client probe Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 09/12] mac80211: report OBSS beacons Johannes Berg
` (3 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Add the ability to register to received beacon frames
to allow implementing OLBC logic in userspace. The
registration is per wiphy since there's no point in
receiving the same frame multiple times.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/linux/nl80211.h | 7 ++++
include/net/cfg80211.h | 20 +++++++++++++
net/wireless/core.h | 2 +
net/wireless/nl80211.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 98 insertions(+), 1 deletion(-)
--- a/net/wireless/core.h 2011-11-03 13:48:30.000000000 +0100
+++ b/net/wireless/core.h 2011-11-03 14:02:32.000000000 +0100
@@ -54,6 +54,8 @@ struct cfg80211_registered_device {
int opencount; /* also protected by devlist_mtx */
wait_queue_head_t dev_wait;
+ u32 ap_beacons_nlpid;
+
/* BSSes/scanning */
spinlock_t bss_lock;
struct list_head bss_list;
--- a/include/linux/nl80211.h 2011-11-03 14:02:28.000000000 +0100
+++ b/include/linux/nl80211.h 2011-11-03 14:02:32.000000000 +0100
@@ -528,6 +528,11 @@
* up the event with the request. The event includes the same data and
* has %NL80211_ATTR_ACK set if the frame was ACKed.
*
+ * @NL80211_CMD_REGISTER_BEACONS: Register this socket to receive beacons from
+ * other BSSes when any interfaces are in AP mode. This helps implement
+ * OLBC handling in hostapd. Beacons are reported in %NL80211_CMD_FRAME
+ * messages. Note that per PHY only one application may register.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -661,6 +666,8 @@ enum nl80211_commands {
NL80211_CMD_PROBE_CLIENT,
+ NL80211_CMD_REGISTER_BEACONS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- a/net/wireless/nl80211.c 2011-11-03 14:02:28.000000000 +0100
+++ b/net/wireless/nl80211.c 2011-11-03 14:02:32.000000000 +0100
@@ -891,6 +891,10 @@ static int nl80211_send_wiphy(struct sk_
if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
CMD(sched_scan_start, START_SCHED_SCAN);
CMD(probe_client, PROBE_CLIENT);
+ if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
+ i++;
+ NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS);
+ }
#undef CMD
@@ -5901,6 +5905,21 @@ static int nl80211_probe_client(struct s
return err;
}
+static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
+ return -EOPNOTSUPP;
+
+ if (rdev->ap_beacons_nlpid)
+ return -EBUSY;
+
+ rdev->ap_beacons_nlpid = info->snd_pid;
+
+ return 0;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -6472,6 +6491,14 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_REGISTER_BEACONS,
+ .doit = nl80211_register_beacons,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -7576,6 +7603,44 @@ void cfg80211_probe_status(struct net_de
}
EXPORT_SYMBOL(cfg80211_probe_status);
+void cfg80211_report_obss_beacon(struct wiphy *wiphy,
+ const u8 *frame, size_t len,
+ int freq, gfp_t gfp)
+{
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+ u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid);
+
+ if (!nlpid)
+ return;
+
+ msg = nlmsg_new(len + 100, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ if (freq)
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
+ NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_report_obss_beacon);
+
static int nl80211_netlink_notify(struct notifier_block * nb,
unsigned long state,
void *_notify)
@@ -7589,9 +7654,12 @@ static int nl80211_netlink_notify(struct
rcu_read_lock();
- list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list)
+ list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
list_for_each_entry_rcu(wdev, &rdev->netdev_list, list)
cfg80211_mlme_unregister_socket(wdev, notify->pid);
+ if (rdev->ap_beacons_nlpid == notify->pid)
+ rdev->ap_beacons_nlpid = 0;
+ }
rcu_read_unlock();
--- a/include/net/cfg80211.h 2011-11-03 14:02:28.000000000 +0100
+++ b/include/net/cfg80211.h 2011-11-03 14:02:32.000000000 +0100
@@ -1682,6 +1682,9 @@ struct cfg80211_ops {
* command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be
* used for asking the driver/firmware to perform a TDLS operation.
* @WIPHY_FLAG_HAVE_AP_SME: device integrates AP SME
+ * @WIPHY_FLAG_REPORTS_OBSS: the device will report beacons from other BSSes
+ * when there are virtual interfaces in AP mode by calling
+ * cfg80211_report_obss_beacon().
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1701,6 +1704,7 @@ enum wiphy_flags {
WIPHY_FLAG_SUPPORTS_TDLS = BIT(15),
WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16),
WIPHY_FLAG_HAVE_AP_SME = BIT(17),
+ WIPHY_FLAG_REPORTS_OBSS = BIT(18),
};
/**
@@ -3231,6 +3235,22 @@ bool cfg80211_rx_spurious_frame(struct n
void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
u64 cookie, bool acked, gfp_t gfp);
+/**
+ * cfg80211_report_obss_beacon - report beacon from other APs
+ * @wiphy: The wiphy that received the beacon
+ * @frame: the frame
+ * @len: length of the frame
+ * @freq: frequency the frame was received on
+ * @gfp: allocation flags
+ *
+ * Use this function to report to userspace when a beacon was
+ * received. It is not useful to call this when there is no
+ * netdev that is in AP/GO mode.
+ */
+void cfg80211_report_obss_beacon(struct wiphy *wiphy,
+ const u8 *frame, size_t len,
+ int freq, gfp_t gfp);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 09/12] mac80211: report OBSS beacons
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (7 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 08/12] cfg80211: allow registering to beacons Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 10/12] cfg80211: add event for unexpected 4addr frames Johannes Berg
` (2 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
If there's an interface in AP mode, OBSS beacons
are needed by hostapd/wpa_s to implement logic to
enable/disable protection etc. Report the frames
and set the capability flag.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/ieee80211_i.h | 3 +++
net/mac80211/main.c | 3 ++-
net/mac80211/rx.c | 12 ++++++++++++
3 files changed, 17 insertions(+), 1 deletion(-)
--- a/net/mac80211/ieee80211_i.h 2011-11-03 14:02:28.000000000 +0100
+++ b/net/mac80211/ieee80211_i.h 2011-11-03 14:02:35.000000000 +0100
@@ -184,12 +184,15 @@ enum ieee80211_packet_rx_flags {
* enum ieee80211_rx_flags - RX data flags
*
* @IEEE80211_RX_CMNTR: received on cooked monitor already
+ * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported
+ * to cfg80211_report_obss_beacon().
*
* These flags are used across handling multiple interfaces
* for a single frame.
*/
enum ieee80211_rx_flags {
IEEE80211_RX_CMNTR = BIT(0),
+ IEEE80211_RX_BEACON_REPORTED = BIT(1),
};
struct ieee80211_rx_data {
--- a/net/mac80211/main.c 2011-11-03 13:48:28.000000000 +0100
+++ b/net/mac80211/main.c 2011-11-03 14:02:35.000000000 +0100
@@ -595,7 +595,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(
wiphy->flags |= WIPHY_FLAG_NETNS_OK |
WIPHY_FLAG_4ADDR_AP |
- WIPHY_FLAG_4ADDR_STATION;
+ WIPHY_FLAG_4ADDR_STATION |
+ WIPHY_FLAG_REPORTS_OBSS;
if (!ops->set_key)
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
--- a/net/mac80211/rx.c 2011-11-03 14:02:28.000000000 +0100
+++ b/net/mac80211/rx.c 2011-11-03 14:02:35.000000000 +0100
@@ -2177,6 +2177,18 @@ ieee80211_rx_h_mgmt_check(struct ieee802
if (!ieee80211_is_mgmt(mgmt->frame_control))
return RX_DROP_MONITOR;
+ if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
+ ieee80211_is_beacon(mgmt->frame_control) &&
+ !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
+ struct ieee80211_rx_status *status;
+
+ status = IEEE80211_SKB_RXCB(rx->skb);
+ cfg80211_report_obss_beacon(rx->local->hw.wiphy,
+ rx->skb->data, rx->skb->len,
+ status->freq, GFP_ATOMIC);
+ rx->flags |= IEEE80211_RX_BEACON_REPORTED;
+ }
+
if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_DROP_MONITOR;
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 10/12] cfg80211: add event for unexpected 4addr frames
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (8 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 09/12] mac80211: report OBSS beacons Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 11/12] mac80211: send unexpected 4addr event Johannes Berg
2011-11-04 10:18 ` [PATCH 12/12] cfg80211/mac80211: allow management TX to not wait for ACK Johannes Berg
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
The frames are used by AP/STA WDS mode, and hostapd
needs to know when such a frame was received to set
up the VLAN appropriately to allow using it.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/linux/nl80211.h | 10 +++++++++-
include/net/cfg80211.h | 16 ++++++++++++++++
net/wireless/mlme.c | 14 ++++++++++++++
net/wireless/nl80211.c | 19 +++++++++++++++++--
net/wireless/nl80211.h | 2 ++
5 files changed, 58 insertions(+), 3 deletions(-)
--- a/include/linux/nl80211.h 2011-11-03 14:17:00.000000000 +0100
+++ b/include/linux/nl80211.h 2011-11-03 14:17:00.000000000 +0100
@@ -517,7 +517,13 @@
* For the event, the %NL80211_ATTR_MAC attribute carries the TA and
* other attributes like the interface index are present.
* If used as the command it must have an interface index and you can
- * only unsubscribe from the event by closing the socket.
+ * only unsubscribe from the event by closing the socket. Subscription
+ * is also for %NL80211_CMD_UNEXPECTED_4ADDR_FRAME events.
+ *
+ * @NL80211_CMD_UNEXPECTED_4ADDR_FRAME: Sent as an event indicating that the
+ * associated station identified by %NL80211_ATTR_MAC sent a 4addr frame
+ * and wasn't already in a 4-addr VLAN. The event will be sent similarly
+ * to the %NL80211_CMD_UNEXPECTED_FRAME event, to the same listener.
*
* @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface
* by sending a null data frame to it and reporting when the frame is
@@ -667,6 +673,8 @@ enum nl80211_commands {
NL80211_CMD_REGISTER_BEACONS,
+ NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- a/net/wireless/mlme.c 2011-11-03 14:16:34.000000000 +0100
+++ b/net/wireless/mlme.c 2011-11-03 14:21:06.000000000 +0100
@@ -1123,3 +1123,17 @@ bool cfg80211_rx_spurious_frame(struct n
return nl80211_unexpected_frame(dev, addr, gfp);
}
EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
+
+bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
+ const u8 *addr, gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
+ wdev->iftype != NL80211_IFTYPE_P2P_GO &&
+ wdev->iftype != NL80211_IFTYPE_AP_VLAN))
+ return false;
+
+ return nl80211_unexpected_4addr_frame(dev, addr, gfp);
+}
+EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
--- a/net/wireless/nl80211.c 2011-11-03 14:17:00.000000000 +0100
+++ b/net/wireless/nl80211.c 2011-11-03 14:17:41.000000000 +0100
@@ -7283,7 +7283,8 @@ void nl80211_send_sta_del_event(struct c
nlmsg_free(msg);
}
-bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp)
+static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
+ const u8 *addr, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -7299,7 +7300,7 @@ bool nl80211_unexpected_frame(struct net
if (!msg)
return true;
- hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UNEXPECTED_FRAME);
+ hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
if (!hdr) {
nlmsg_free(msg);
return true;
@@ -7324,6 +7325,20 @@ bool nl80211_unexpected_frame(struct net
return true;
}
+bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp)
+{
+ return __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
+ addr, gfp);
+}
+
+bool nl80211_unexpected_4addr_frame(struct net_device *dev,
+ const u8 *addr, gfp_t gfp)
+{
+ return __nl80211_unexpected_frame(dev,
+ NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
+ addr, gfp);
+}
+
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid,
int freq, const u8 *buf, size_t len, gfp_t gfp)
--- a/net/wireless/nl80211.h 2011-11-03 14:16:34.000000000 +0100
+++ b/net/wireless/nl80211.h 2011-11-03 14:17:00.000000000 +0100
@@ -119,5 +119,7 @@ void nl80211_pmksa_candidate_notify(stru
bool nl80211_unexpected_frame(struct net_device *dev,
const u8 *addr, gfp_t gfp);
+bool nl80211_unexpected_4addr_frame(struct net_device *dev,
+ const u8 *addr, gfp_t gfp);
#endif /* __NET_WIRELESS_NL80211_H */
--- a/include/net/cfg80211.h 2011-11-03 14:17:00.000000000 +0100
+++ b/include/net/cfg80211.h 2011-11-03 14:17:00.000000000 +0100
@@ -3223,6 +3223,22 @@ bool cfg80211_rx_spurious_frame(struct n
const u8 *addr, gfp_t gfp);
/**
+ * cfg80211_rx_unexpected_4addr_frame - inform about unexpected WDS frame
+ * @dev: The device the frame matched to
+ * @addr: the transmitter address
+ * @gfp: context flags
+ *
+ * This function is used in AP mode (only!) to inform userspace that
+ * an associated station sent a 4addr frame but that wasn't expected.
+ * It is allowed and desirable to send this event only once for each
+ * station to avoid event flooding.
+ * Returns %true if the frame was passed to userspace (or this failed
+ * for a reason other than not having a subscription.)
+ */
+bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
+ const u8 *addr, gfp_t gfp);
+
+/**
* cfg80211_probe_status - notify userspace about probe status
* @dev: the device the probe was sent on
* @addr: the address of the peer
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 11/12] mac80211: send unexpected 4addr event
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (9 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 10/12] cfg80211: add event for unexpected 4addr frames Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
2011-11-04 10:18 ` [PATCH 12/12] cfg80211/mac80211: allow management TX to not wait for ACK Johannes Berg
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
Implement the cfg80211 notification but only send
one event per associated station to avoid having
tons of events if the station thinks it should be
allowed to use 4addr frames but it isn't.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/rx.c | 24 +++++++++++++++++-------
net/mac80211/sta_info.h | 8 ++++++++
2 files changed, 25 insertions(+), 7 deletions(-)
--- a/net/mac80211/rx.c 2011-11-03 14:17:00.000000000 +0100
+++ b/net/mac80211/rx.c 2011-11-03 14:25:14.000000000 +0100
@@ -1330,15 +1330,20 @@ ieee80211_rx_h_sta_process(struct ieee80
/*
* If we receive a 4-addr nullfunc frame from a STA
- * that was not moved to a 4-addr STA vlan yet, drop
- * the frame to the monitor interface, to make sure
- * that hostapd sees it
+ * that was not moved to a 4-addr STA vlan yet send
+ * the event to userspace and for older hostapd drop
+ * the frame to the monitor interface.
*/
if (ieee80211_has_a4(hdr->frame_control) &&
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
(rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
- !rx->sdata->u.vlan.sta)))
+ !rx->sdata->u.vlan.sta))) {
+ if (!test_and_set_sta_flag(sta, WLAN_STA_4ADDR_EVENT))
+ cfg80211_rx_unexpected_4addr_frame(
+ rx->sdata->dev, sta->sta.addr,
+ GFP_ATOMIC);
return RX_DROP_MONITOR;
+ }
/*
* Update counter and free packet here to avoid
* counting this as a dropped packed.
@@ -2017,12 +2022,17 @@ ieee80211_rx_h_data(struct ieee80211_rx_
return RX_DROP_MONITOR;
/*
- * Allow the cooked monitor interface of an AP to see 4-addr frames so
- * that a 4-addr station can be detected and moved into a separate VLAN
+ * Send unexpected-4addr-frame event to hostapd. For older versions,
+ * also drop the frame to cooked monitor interfaces.
*/
if (ieee80211_has_a4(hdr->frame_control) &&
- sdata->vif.type == NL80211_IFTYPE_AP)
+ sdata->vif.type == NL80211_IFTYPE_AP) {
+ if (rx->sta &&
+ !test_and_set_sta_flag(rx->sta, WLAN_STA_4ADDR_EVENT))
+ cfg80211_rx_unexpected_4addr_frame(
+ rx->sdata->dev, rx->sta->sta.addr, GFP_ATOMIC);
return RX_DROP_MONITOR;
+ }
err = __ieee80211_data_to_8023(rx, &port_control);
if (unlikely(err))
--- a/net/mac80211/sta_info.h 2011-11-03 13:48:28.000000000 +0100
+++ b/net/mac80211/sta_info.h 2011-11-03 14:20:15.000000000 +0100
@@ -52,6 +52,7 @@
* unblocks the station.
* @WLAN_STA_SP: Station is in a service period, so don't try to
* reply to other uAPSD trigger frames or PS-Poll.
+ * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
*/
enum ieee80211_sta_info_flags {
WLAN_STA_AUTH,
@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_TDLS_PEER_AUTH,
WLAN_STA_UAPSD,
WLAN_STA_SP,
+ WLAN_STA_4ADDR_EVENT,
};
#define STA_TID_NUM 16
@@ -390,6 +392,12 @@ static inline int test_and_clear_sta_fla
return test_and_clear_bit(flag, &sta->_flags);
}
+static inline int test_and_set_sta_flag(struct sta_info *sta,
+ enum ieee80211_sta_info_flags flag)
+{
+ return test_and_set_bit(flag, &sta->_flags);
+}
+
void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
struct tid_ampdu_tx *tid_tx);
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 12/12] cfg80211/mac80211: allow management TX to not wait for ACK
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
` (10 preceding siblings ...)
2011-11-04 10:18 ` [PATCH 11/12] mac80211: send unexpected 4addr event Johannes Berg
@ 2011-11-04 10:18 ` Johannes Berg
11 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
For probe responses it can be useful to not wait for ACK to
avoid retransmissions if the station that sent the probe is
already on the next channel, so allow userspace to request
not caring about the ACK with a new nl80211 flag.
Since mac80211 needs to be updated for the new function
prototype anyway implement it right away -- it's just a
few lines of code.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: accidentally sent as v2 instead of v1
v3: update commit log (Arend) and fix bug (Eliad)
drivers/net/wireless/ath/ath6kl/cfg80211.c | 3 +-
include/linux/nl80211.h | 7 ++++
include/net/cfg80211.h | 2 -
net/mac80211/cfg.c | 11 +++++--
net/wireless/core.h | 2 -
net/wireless/mlme.c | 5 ++-
net/wireless/nl80211.c | 43 +++++++++++++++++------------
7 files changed, 48 insertions(+), 25 deletions(-)
--- a/include/linux/nl80211.h 2011-11-03 14:02:32.000000000 +0100
+++ b/include/linux/nl80211.h 2011-11-03 14:02:44.000000000 +0100
@@ -1144,6 +1144,11 @@ enum nl80211_commands {
* with support for the features listed in this attribute, see
* &enum nl80211_ap_sme_features.
*
+ * @NL80211_ATTR_DONT_WAIT_FOR_ACK: Used with %NL80211_CMD_FRAME, this tells
+ * the driver to not wait for an acknowledgement. Note that due to this,
+ * it will also not give a status callback nor return a cookie. This is
+ * mostly useful for probe responses to save airtime.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1374,6 +1379,8 @@ enum nl80211_attrs {
NL80211_ATTR_DEVICE_AP_SME,
+ NL80211_ATTR_DONT_WAIT_FOR_ACK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
--- a/net/wireless/core.h 2011-11-03 14:02:32.000000000 +0100
+++ b/net/wireless/core.h 2011-11-03 14:02:44.000000000 +0100
@@ -378,7 +378,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg8021
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, bool no_cck,
- u64 *cookie);
+ bool dont_wait_for_ack, u64 *cookie);
/* SME */
int __cfg80211_connect(struct cfg80211_registered_device *rdev,
--- a/net/wireless/mlme.c 2011-11-03 14:02:28.000000000 +0100
+++ b/net/wireless/mlme.c 2011-11-03 14:02:44.000000000 +0100
@@ -904,7 +904,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg8021
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, bool no_cck,
- u64 *cookie)
+ bool dont_wait_for_ack, u64 *cookie)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
const struct ieee80211_mgmt *mgmt;
@@ -995,7 +995,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg8021
/* Transmit the Action frame as requested by user space */
return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
channel_type, channel_type_valid,
- wait, buf, len, no_cck, cookie);
+ wait, buf, len, no_cck, dont_wait_for_ack,
+ cookie);
}
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
--- a/net/wireless/nl80211.c 2011-11-03 14:02:32.000000000 +0100
+++ b/net/wireless/nl80211.c 2011-11-03 14:02:44.000000000 +0100
@@ -196,6 +196,7 @@ static const struct nla_policy nl80211_p
[NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
[NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
+ [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
};
/* policy for the key attributes */
@@ -5276,10 +5277,11 @@ static int nl80211_tx_mgmt(struct sk_buf
int err;
void *hdr;
u64 cookie;
- struct sk_buff *msg;
+ struct sk_buff *msg = NULL;
unsigned int wait = 0;
- bool offchan;
- bool no_cck;
+ bool offchan, no_cck, dont_wait_for_ack;
+
+ dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
if (!info->attrs[NL80211_ATTR_FRAME] ||
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
@@ -5323,29 +5325,36 @@ static int nl80211_tx_mgmt(struct sk_buf
if (chan == NULL)
return -EINVAL;
- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg)
- return -ENOMEM;
-
- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
- NL80211_CMD_FRAME);
-
- if (IS_ERR(hdr)) {
- err = PTR_ERR(hdr);
- goto free_msg;
+ if (!dont_wait_for_ack) {
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+ NL80211_CMD_FRAME);
+
+ if (IS_ERR(hdr)) {
+ err = PTR_ERR(hdr);
+ goto free_msg;
+ }
}
+
err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type,
channel_type_valid, wait,
nla_data(info->attrs[NL80211_ATTR_FRAME]),
nla_len(info->attrs[NL80211_ATTR_FRAME]),
- no_cck, &cookie);
+ no_cck, dont_wait_for_ack, &cookie);
if (err)
goto free_msg;
- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+ if (msg) {
+ NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
- genlmsg_end(msg, hdr);
- return genlmsg_reply(msg, info);
+ genlmsg_end(msg, hdr);
+ return genlmsg_reply(msg, info);
+ }
+
+ return 0;
nla_put_failure:
err = -ENOBUFS;
--- a/include/net/cfg80211.h 2011-11-03 14:02:32.000000000 +0100
+++ b/include/net/cfg80211.h 2011-11-03 14:02:44.000000000 +0100
@@ -1584,7 +1584,7 @@ struct cfg80211_ops {
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, bool no_cck,
- u64 *cookie);
+ bool dont_wait_for_ack, u64 *cookie);
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
struct net_device *dev,
u64 cookie);
--- a/net/mac80211/cfg.c 2011-11-03 14:02:28.000000000 +0100
+++ b/net/mac80211/cfg.c 2011-11-03 14:02:44.000000000 +0100
@@ -1936,7 +1936,7 @@ static int ieee80211_mgmt_tx(struct wiph
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
const u8 *buf, size_t len, bool no_cck,
- u64 *cookie)
+ bool dont_wait_for_ack, u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
@@ -1944,10 +1944,15 @@ static int ieee80211_mgmt_tx(struct wiph
struct sta_info *sta;
struct ieee80211_work *wk;
const struct ieee80211_mgmt *mgmt = (void *)buf;
- u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
- IEEE80211_TX_CTL_REQ_TX_STATUS;
+ u32 flags;
bool is_offchan = false;
+ if (dont_wait_for_ack)
+ flags = IEEE80211_TX_CTL_NO_ACK;
+ else
+ flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
+
/* Check that we are on the requested channel for transmission */
if (chan != local->tmp_channel &&
chan != local->oper_channel)
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c 2011-11-03 13:48:08.000000000 +0100
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c 2011-11-03 14:02:44.000000000 +0100
@@ -1732,7 +1732,8 @@ static int ath6kl_mgmt_tx(struct wiphy *
struct ieee80211_channel *chan, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, bool no_cck, u64 *cookie)
+ const u8 *buf, size_t len, bool no_cck,
+ bool dont_wait_for_ack, u64 *cookie)
{
struct ath6kl *ar = ath6kl_priv(dev);
u32 id;
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 05/12] nl80211: advertise device AP SME
2011-11-04 10:18 ` [PATCH 05/12] nl80211: advertise device AP SME Johannes Berg
@ 2011-11-07 8:29 ` Arik Nemtsov
2011-11-07 8:49 ` Johannes Berg
2011-11-07 11:39 ` [PATCH v3 " Johannes Berg
1 sibling, 1 reply; 16+ messages in thread
From: Arik Nemtsov @ 2011-11-07 8:29 UTC (permalink / raw)
To: Johannes Berg; +Cc: John Linville, linux-wireless
On Fri, Nov 4, 2011 at 12:18, Johannes Berg <johannes@sipsolutions.net> wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> Add the ability to advertise that the device
> contains the AP SME and what features it can
> support.
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[...]
>
> +/**
> + * enum nl80211_ap_sme_features - device-integrated AP features
> + * @NL80211_AP_SME_WSC: The driver is capable of indicating received probe
> + * request frames to userspace via management frame subscription events
> + * if the payload includes the WSC IE. The driver is capable of adding
> + * the WSC IE as configured from userspace into beacons, probe responses
> + * and (re)association reponse frame and allows userspace to update them
> + * during the lifetime of the BSS.
> + */
> +enum nl80211_ap_sme_features {
> + NL80211_AP_SME_WSC = 1 << 0,
> +};
Perhaps we should break up this feature into two? With the upcoming
probe-resp patches a wl12xx card will be able to indicate
probe-requests with WSC IE up, but won't be able to add a userspace
provided WSC IE into beacons.
Also I'm wondering what this is used for. For instance this contains
no indication about WPS1 and p2p. Pretty sure ath6kl handles these in
a similar fashion (at least for the put-IE-from-userspace-in-beacon
part).
And as a final nit-pick, I think WPS2 is more appropriate, as this is
also the name of the option in the hostapd code and config file.
Arik
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 05/12] nl80211: advertise device AP SME
2011-11-07 8:29 ` Arik Nemtsov
@ 2011-11-07 8:49 ` Johannes Berg
0 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-07 8:49 UTC (permalink / raw)
To: Arik Nemtsov; +Cc: John Linville, linux-wireless
On Mon, 2011-11-07 at 10:29 +0200, Arik Nemtsov wrote:
> > +/**
> > + * enum nl80211_ap_sme_features - device-integrated AP features
> > + * @NL80211_AP_SME_WSC: The driver is capable of indicating received probe
> > + * request frames to userspace via management frame subscription events
> > + * if the payload includes the WSC IE. The driver is capable of adding
> > + * the WSC IE as configured from userspace into beacons, probe responses
> > + * and (re)association reponse frame and allows userspace to update them
> > + * during the lifetime of the BSS.
> > + */
> > +enum nl80211_ap_sme_features {
> > + NL80211_AP_SME_WSC = 1 << 0,
> > +};
>
> Perhaps we should break up this feature into two? With the upcoming
> probe-resp patches a wl12xx card will be able to indicate
> probe-requests with WSC IE up, but won't be able to add a userspace
> provided WSC IE into beacons.
Break up how? wl12xx obviously wouldn't say it has AP SME included.
Also, I think here it is actually still doing this by reporting probe
requests up, but it's somewhat different.
> Also I'm wondering what this is used for. For instance this contains
> no indication about WPS1 and p2p. Pretty sure ath6kl handles these in
> a similar fashion (at least for the put-IE-from-userspace-in-beacon
> part).
Yeah. This was more or less a placeholder, I guess we need more info
from the ath6kl people.
> And as a final nit-pick, I think WPS2 is more appropriate, as this is
> also the name of the option in the hostapd code and config file.
Good point. Let's discuss the bits & the behaviour a bit more, although
I hate having to postpone the patchset for it :-)
I think the thing here is that we approach a middle ground from two
different sides. With mac80211, we typically handle everything on the
host, so things like replying to probe requests is an offload. With
AP_SME, we initially expect everything to be handled on the device and
approach middle ground by not replying to WPS probe requests. I thought
it makes sense to put these into different attributes rather than use
the same probe response offload attribute you have for wl12xx, but I'll
admit that the semantics are pretty similar.
However, I could see much more features come into play here, for example
FT would probably not be a feature an AP_SME device has, but for
mac80211 based drivers it's obviously just implemented in hostapd. So
such a feature might also need a bit in this new bitfield.
johannes
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 05/12] nl80211: advertise device AP SME
2011-11-04 10:18 ` [PATCH 05/12] nl80211: advertise device AP SME Johannes Berg
2011-11-07 8:29 ` Arik Nemtsov
@ 2011-11-07 11:39 ` Johannes Berg
1 sibling, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2011-11-07 11:39 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Arik Nemtsov
From: Johannes Berg <johannes.berg@intel.com>
Add the ability to advertise that the device
contains the AP SME and what features it can
support. There are currently no features in
the bitmap -- probe response offload will be
advertised by a few patches Arik is working
on now (who took over from Guy Eilam) and a
device with AP SME will typically implement
and require response offload.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: fix attribute name (thanks Eliad)
v3: remove WSC bit
drivers/net/wireless/ath/ath6kl/init.c | 3 ++-
include/linux/nl80211.h | 15 +++++++++++++++
include/net/cfg80211.h | 6 ++++++
net/wireless/core.c | 4 ++++
net/wireless/nl80211.c | 4 ++++
5 files changed, 31 insertions(+), 1 deletion(-)
--- a/include/linux/nl80211.h 2011-11-04 11:21:17.000000000 +0100
+++ b/include/linux/nl80211.h 2011-11-07 12:35:59.000000000 +0100
@@ -1121,6 +1121,11 @@ enum nl80211_commands {
* %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
* used for asking the driver to perform a TDLS operation.
*
+ * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices
+ * that have AP support to indicate that they have the AP SME integrated
+ * with support for the features listed in this attribute, see
+ * &enum nl80211_ap_sme_features.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1349,6 +1354,8 @@ enum nl80211_attrs {
NL80211_ATTR_TDLS_SUPPORT,
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+ NL80211_ATTR_DEVICE_AP_SME,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -2662,4 +2669,12 @@ enum nl80211_tdls_operation {
NL80211_TDLS_DISABLE_LINK,
};
+/*
+ * enum nl80211_ap_sme_features - device-integrated AP features
+ * Reserved for future use, no bits are defined in
+ * NL80211_ATTR_DEVICE_AP_SME yet.
+enum nl80211_ap_sme_features {
+};
+ */
+
#endif /* __LINUX_NL80211_H */
--- a/include/net/cfg80211.h 2011-11-04 11:21:17.000000000 +0100
+++ b/include/net/cfg80211.h 2011-11-07 12:31:55.000000000 +0100
@@ -1675,6 +1675,7 @@ struct cfg80211_ops {
* teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT
* command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be
* used for asking the driver/firmware to perform a TDLS operation.
+ * @WIPHY_FLAG_HAVE_AP_SME: device integrates AP SME
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1693,6 +1694,7 @@ enum wiphy_flags {
WIPHY_FLAG_AP_UAPSD = BIT(14),
WIPHY_FLAG_SUPPORTS_TDLS = BIT(15),
WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16),
+ WIPHY_FLAG_HAVE_AP_SME = BIT(17),
};
/**
@@ -1903,6 +1905,8 @@ struct wiphy_wowlan_support {
* may request, if implemented.
*
* @wowlan: WoWLAN support information
+ *
+ * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -1926,6 +1930,8 @@ struct wiphy {
u32 flags;
+ u32 ap_sme_capa;
+
enum cfg80211_signal_type signal_type;
int bss_priv_size;
--- a/net/wireless/core.c 2011-11-03 14:41:41.000000000 +0100
+++ b/net/wireless/core.c 2011-11-04 11:21:17.000000000 +0100
@@ -492,6 +492,10 @@ int wiphy_register(struct wiphy *wiphy)
!(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
return -EINVAL;
+ if (WARN_ON(wiphy->ap_sme_capa &&
+ !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
+ return -EINVAL;
+
if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
return -EINVAL;
--- a/net/wireless/nl80211.c 2011-11-04 11:21:17.000000000 +0100
+++ b/net/wireless/nl80211.c 2011-11-07 12:31:55.000000000 +0100
@@ -1007,6 +1007,10 @@ static int nl80211_send_wiphy(struct sk_
if (nl80211_put_iface_combinations(&dev->wiphy, msg))
goto nla_put_failure;
+ if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME)
+ NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME,
+ dev->wiphy.ap_sme_capa);
+
return genlmsg_end(msg, hdr);
nla_put_failure:
--- a/drivers/net/wireless/ath/ath6kl/init.c 2011-11-03 14:41:41.000000000 +0100
+++ b/drivers/net/wireless/ath/ath6kl/init.c 2011-11-07 12:34:45.000000000 +0100
@@ -1548,7 +1548,8 @@ static int ath6kl_init(struct net_device
ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
- ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+ ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
+ WIPHY_FLAG_HAVE_AP_SME;
status = ath6kl_target_config_wlan_params(ar);
if (!status)
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2011-11-07 11:39 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-04 10:18 [PATCH 00/12] monitor-less AP mode part 1 Johannes Berg
2011-11-04 10:18 ` [PATCH 01/12] mac80211: add helper to free TX skb Johannes Berg
2011-11-04 10:18 ` [PATCH 02/12] mac80211: add support for control port protocol in AP mode Johannes Berg
2011-11-04 10:18 ` [PATCH 03/12] nl80211: allow subscribing to unexpected class3 frames Johannes Berg
2011-11-04 10:18 ` [PATCH 04/12] mac80211: support spurious class3 event Johannes Berg
2011-11-04 10:18 ` [PATCH 05/12] nl80211: advertise device AP SME Johannes Berg
2011-11-07 8:29 ` Arik Nemtsov
2011-11-07 8:49 ` Johannes Berg
2011-11-07 11:39 ` [PATCH v3 " Johannes Berg
2011-11-04 10:18 ` [PATCH 06/12] nl80211: add API to probe a client Johannes Berg
2011-11-04 10:18 ` [PATCH 07/12] mac80211: support client probe Johannes Berg
2011-11-04 10:18 ` [PATCH 08/12] cfg80211: allow registering to beacons Johannes Berg
2011-11-04 10:18 ` [PATCH 09/12] mac80211: report OBSS beacons Johannes Berg
2011-11-04 10:18 ` [PATCH 10/12] cfg80211: add event for unexpected 4addr frames Johannes Berg
2011-11-04 10:18 ` [PATCH 11/12] mac80211: send unexpected 4addr event Johannes Berg
2011-11-04 10:18 ` [PATCH 12/12] cfg80211/mac80211: allow management TX to not wait for ACK 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).