* [PATCH] ath6kl: Fix error in writing create_qos debugfs
From: Vasanthakumar Thiagarajan @ 2011-11-04 13:04 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
100 bytes are allocated to store the parameters which are needed
to create a priority stream. These 100 bytes are not sufficiant and
throws error when running the following command.
echo "6 2 3 1 1 9999999 9999999 9999999 7777777 0 6 45000 200 56789000
56789000 5678900 0 0 9999999 20000 0" > create_qos
179 bytes are needed when the following vlaues are given so that
a maximum possible value in that data type can be given in decimal.
echo "255 255 255 255 255 4294967295 4294967295 4294967295 4294967295
4294967295 255 65535 65535 4294967295 4294967295 4294967295 4294967295
4294967295 4294967295 4294967295 4294967295" > create_qos
Following takes 187 bytes when given in hex
echo "0xff 0xff 0xff 0xff 0xff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff
0xff 0xffff 0xffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff
0xffffffff 0xffffffff" > create_qos
Increase the size to 200 bytes so that it can hold upto the maximum
value possible for that data type.
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/debug.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 70ea137..370664a 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1252,7 +1252,7 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
struct ath6kl *ar = file->private_data;
struct ath6kl_vif *vif;
- char buf[100];
+ char buf[200];
ssize_t len;
char *sptr, *token;
struct wmi_create_pstream_cmd pstream;
--
1.7.0.4
^ permalink raw reply related
* Re: b43 scans wifi networks with old firmware only.
From: Rafał Miłecki @ 2011-11-04 10:27 UTC (permalink / raw)
To: Greg KH, Larry Finger; +Cc: roman-vl, linux-wireless
In-Reply-To: <4EB333E1.6000508@lwfinger.net>
W dniu 4 listopada 2011 01:37 użytkownik Larry Finger
<Larry.Finger@lwfinger.net> napisał:
> On 11/03/2011 05:37 PM, Rafał Miłecki wrote:
>>
>> 2011/11/3 Larry Finger<Larry.Finger@lwfinger.net>:
>>>
>>> On 11/03/2011 06:21 AM, Roman V.Leon. wrote:
>>>>
>>>> Hello Gents.
>>>> I have problem with b43 driver 5.100.138, it's not scanning networks for
>>>> unknown reason. I have broadcom wifi card PCIID is 14e4:4315, linux kern
>>>> ver. is 3.0. When i'm trying to launch iwlist scan, i'm getting "no scan
>>>> results".
>>>>
>>>> for example:
>>>> sudo ifconfig wlan0 up
>>>> sudo iwlist wlan0 scan
>>>> No scan results.
>>>>
>>>> With the older driver 5.10.56.2808, i see normal scan results. If you
>>>> need
>>>> any more information, i will send.
>>>
>>> The condition you report is known. Broadcom changed the TX/RX header
>>> structure with firmware versions greater than 600, as shown by a 'dmesg |
>>> grep firmware'. Those changes are not implemented in b43 until kernel
>>> 3.2.
>>>
>>> These numbers are not b43 driver numbers, nor are they firmware numbers
>>> reported by b43. They are the versions of Broadcom drivers.
>>>
>>> If you look at
>>> http://wireless.kernel.org/en/users/Drivers/b43#firmwareinstallation, you
>>> will see that firmware should be extracted from Broadcom driver 5.100.138
>>> "if you are using kernel 3.2 or newer". For older kernels you should
>>> extract
>>> firmware from the 5.10.56.27.3 of the Broadcom proprietary driver. Of
>>> course, 5.10.56.2808 will also work.
>>>
>>> You could also get those changes by employing a bleeding-edge version of
>>> compat-wireless. In that case, firmware from 5.100.138 would work.
>>
>> Should we/can we send patch for at least 3.0.x and 3.1.x kernels
>> adding error on loading too new firmware?
>
> I think adding an error would have been appropriate. We certainly cannot
> prevent versionitis; however, getting a patch into those kernels that is not
> in mainline might be a problem.
Greg: the problem with b43 happens when kernels 3.1- users install
firmware supported by kernels 3.2+.
Is this possible to grab some separated patch for that older kernels?
The ideal way to do this was:
1) Commit error enabling patch with Cc: stable
2) Add support for new firmwares
3) Drop error
Unfortunately I didn't think about that, now it's too late.
--
Rafał
^ permalink raw reply
* [PATCH 12/12] cfg80211/mac80211: allow management TX to not wait for ACK
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 11/12] mac80211: send unexpected 4addr event
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 10/12] cfg80211: add event for unexpected 4addr frames
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 09/12] mac80211: report OBSS beacons
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 08/12] cfg80211: allow registering to beacons
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 07/12] mac80211: support client probe
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 06/12] nl80211: add API to probe a client
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 05/12] nl80211: advertise device AP SME
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 04/12] mac80211: support spurious class3 event
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 03/12] nl80211: allow subscribing to unexpected class3 frames
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 02/12] mac80211: add support for control port protocol in AP mode
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 01/12] mac80211: add helper to free TX skb
From: Johannes Berg @ 2011-11-04 10:18 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <20111104101809.711636760@sipsolutions.net>
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
* [PATCH 00/12] monitor-less AP mode part 1
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
* [PATCH] ath6kl: Fix tx packet drop in AP mode with bridge
From: Vasanthakumar Thiagarajan @ 2011-11-04 10:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
skb is dropped in ath6kl_data_tx() when the headroom in skb
is insufficient. We hit this condition for every skb in AP mode
which is used with bridge, so all tx packets are getting dropped
when tried to send traffic to wireless client from bridge. Fix
this by reallocating the headroom instead of dropping the skb
when it has lesser headroom than needed.
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/txrx.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 06e4912..251abf8 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -266,8 +266,14 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
if (test_bit(WMI_ENABLED, &ar->flag)) {
if (skb_headroom(skb) < dev->needed_headroom) {
- WARN_ON(1);
- goto fail_tx;
+ struct sk_buff *tmp_skb = skb;
+
+ skb = skb_realloc_headroom(skb, dev->needed_headroom);
+ kfree_skb(tmp_skb);
+ if (skb == NULL) {
+ vif->net_stats.tx_dropped++;
+ return 0;
+ }
}
if (ath6kl_wmi_dix_2_dot3(ar->wmi, skb)) {
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v2] cfg80211: merge in beacon ies of hidden bss.
From: Johannes Berg @ 2011-11-04 10:07 UTC (permalink / raw)
To: Dmitry Tarnyagin; +Cc: linux-wireless
In-Reply-To: <CAMG6FYgvkjYENbE9ud16HthVF4aeSDqM5McnKDr77XxOD542eA@mail.gmail.com>
Hi,
> > Since we need to fix cmp_ie() anyway, how about we change it there as
> > well. I'm going to post a patch.
> I assume there is some (unclear for me) idea behind the order of operation
> in the cmp_ie comparator. Natural order of scan output?
Well, the sort order here matters only for the tree search and is
clearly broken for that. I just sent a patch to fix that.
johannes
^ permalink raw reply
* [PATCH] cfg80211: fix cmp_ies
From: Johannes Berg @ 2011-11-04 10:01 UTC (permalink / raw)
To: John Linville; +Cc: Dmitry Tarnyagin, linux-wireless
From: Johannes Berg <johannes.berg@intel.com>
When comparing two items by IE, the sort order
wasn't stable, which could lead to issues in the
rbtree. Make it stable by making a missing IE
sort before a present IE.
Also sort by length first if it differs and then
by contents.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/wireless/scan.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
--- a/net/wireless/scan.c 2011-11-03 13:48:30.000000000 +0100
+++ b/net/wireless/scan.c 2011-11-04 09:38:25.000000000 +0100
@@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, siz
{
const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
- int r;
+ /* equal if both missing */
if (!ie1 && !ie2)
return 0;
- if (!ie1 || !ie2)
+ /* sort missing IE before (left of) present IE */
+ if (!ie1)
return -1;
+ if (!ie2)
+ return 1;
- r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
- if (r == 0 && ie1[1] != ie2[1])
+ /* sort by length first, then by contents */
+ if (ie1[1] != ie2[1])
return ie2[1] - ie1[1];
- return r;
+ return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
}
static bool is_bss(struct cfg80211_bss *a,
^ permalink raw reply
* Re: [ath9k-devel] [RFC v2 2/2] ath9k: integrate initial DFS module
From: Zefir Kurtisi @ 2011-11-04 9:47 UTC (permalink / raw)
To: Christian Lamparter, ath9k-devel, linux-wireless, rodrigue
In-Reply-To: <20111104030046.25361.qmail@stuge.se>
On 11/04/2011 04:00 AM, Peter Stuge wrote:
> Zefir Kurtisi wrote:
>> Just clarify whether you do not like the CONFIG_ prefix or the fact
>> that it can't be enabled.
>
> It's IMO always stupid to add dead code. No exceptions for
> $random_authority_which_has_no_jurisdiction_for_billions_of_users.
>
>
> //Peter
Hi Peter,
ok, got it.
But I don't call it dead code when its sole purpose is to be tested by developers (i.e. useless for the common user) and can be easily enabled by those. This is only a tiny fraction of the DFS functionality at the lowest layer that need additional support at the upper (mac, hostapd) that is missing so far. Therefore I opted to make it available for devs until all pieces are in (no authority issue, just sanity), but will change it in v3.
Thanks for your feedback
Zefir
^ permalink raw reply
* Re: A new driver is going to be released
From: Johannes Berg @ 2011-11-04 9:20 UTC (permalink / raw)
To: Dmitry Tarnyagin; +Cc: Dan Williams, Larry Finger, linux-wireless
In-Reply-To: <CAMG6FYjGDhts2K3gYSeh0HACkFgSxxXZYdRCHrYp=2W3LceoyQ@mail.gmail.com>
On Fri, 2011-11-04 at 10:10 +0100, Dmitry Tarnyagin wrote:
> Hi Johannes,
>
> >> Correct. But I would move it to drivers/net/wireless during submission.
> >
> > A word of caution: don't attempt that in its current state.
> >
> Thank you for caution. CONFIG_CW1200_USE_STE_EXTENSIONS,
> CONFIG_WAKELOCK and HAS_PUT_TASK_STRUCT will be removed
> of course, API will be aligned with 3.1. But I'm a bit curious what else could
> prevent from submission to drivers/net/wireless? I do not see obvious problems
> with code. Could you please give a short advise what should be fixed then if you
> see problems?
Well there is a ton of stuff like compat code too. Also, for example the
worker thread is pretty strange -- kthread_create() is essentially
deprecated, and having a thread to handle interrupts is weird to start
with.
johannes
^ permalink raw reply
* Re: A new driver is going to be released
From: Kalle Valo @ 2011-11-04 9:18 UTC (permalink / raw)
To: Vitaly Wool; +Cc: Dmitry Tarnyagin, linux-wireless
In-Reply-To: <CAMJBoFMiRh6CD_WTrWq9DOWPBYj92eDZBjNkWDA99qWAQ5mhGA@mail.gmail.com>
Vitaly Wool <vitalywool@gmail.com> writes:
> On Fri, Nov 4, 2011 at 9:06 AM, Kalle Valo <kvalo@adurom.com> wrote:
>>> (more or less latest code is available here:
>>> http://www.igloocommunity.org/gitweb/?p=kernel/igloo-kernel.git;a=shortlog;h=refs/heads/linux-3.0-ux500
>>> as well).
>>
>> I can't access it. I get "404 - Reading tree failed" when I try to
>> access the tree through gitweb:
>>
>> http://www.igloocommunity.org/gitweb/?p=kernel/igloo-kernel.git;a=tree;h=%5Crefs/heads/linux-3.0-ux500;hb=%5Crefs/heads/linux-3.0-ux500
>
> I have a feeling that your mailer screws up the links because I can
> access the tree using the one above but not the one that you get.
That was it, there was one extra '\'. Should have figured out that
myself, thanks.
--
Kalle Valo
^ permalink raw reply
* Re: A new driver is going to be released
From: Vitaly Wool @ 2011-11-04 9:13 UTC (permalink / raw)
To: Kalle Valo; +Cc: Dmitry Tarnyagin, linux-wireless
In-Reply-To: <87vcr09urr.fsf@purkki.adurom.net>
Hi Kalle,
On Fri, Nov 4, 2011 at 9:06 AM, Kalle Valo <kvalo@adurom.com> wrote:
>> (more or less latest code is available here:
>> http://www.igloocommunity.org/gitweb/?p=kernel/igloo-kernel.git;a=shortlog;h=refs/heads/linux-3.0-ux500
>> as well).
>
> I can't access it. I get "404 - Reading tree failed" when I try to
> access the tree through gitweb:
>
> http://www.igloocommunity.org/gitweb/?p=kernel/igloo-kernel.git;a=tree;h=%5Crefs/heads/linux-3.0-ux500;hb=%5Crefs/heads/linux-3.0-ux500
I have a feeling that your mailer screws up the links because I can
access the tree using the one above but not the one that you get.
Thanks,
Vitaly
^ permalink raw reply
* Re: A new driver is going to be released
From: Dmitry Tarnyagin @ 2011-11-04 9:10 UTC (permalink / raw)
To: Johannes Berg; +Cc: Dan Williams, Larry Finger, linux-wireless
In-Reply-To: <1320394336.3969.0.camel@jlt3.sipsolutions.net>
Hi Johannes,
>> Correct. But I would move it to drivers/net/wireless during submission.
>
> A word of caution: don't attempt that in its current state.
>
Thank you for caution. CONFIG_CW1200_USE_STE_EXTENSIONS,
CONFIG_WAKELOCK and HAS_PUT_TASK_STRUCT will be removed
of course, API will be aligned with 3.1. But I'm a bit curious what else could
prevent from submission to drivers/net/wireless? I do not see obvious problems
with code. Could you please give a short advise what should be fixed then if you
see problems?
Thank you and with best regards,
Dmitry
^ permalink raw reply
* Re: [PATCH v2] cfg80211: merge in beacon ies of hidden bss.
From: Dmitry Tarnyagin @ 2011-11-04 8:59 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1320395185.3969.4.camel@jlt3.sipsolutions.net>
Hi Johannes,
>> + /* Absence of SSID or zero-sized SSID is used as
>> + * an indication of the hidden bss. */
>> + if (!ie2 || !ie2[1])
>> + return 0;
>
> I don't think that's right -- I never saw anything w/o an SSID IE except
> for mesh networks I think. Also this has different semantics from the
> regular rb-tree search which will return -1 if not present (which is
> actually a bug).
Ok, agree.
> Since we need to fix cmp_ie() anyway, how about we change it there as
> well. I'm going to post a patch.
>
I assume there is some (unclear for me) idea behind the order of operation
in the cmp_ie comparator. Natural order of scan output?
>> + /* TODO: The code is not trying to update existing probe
>> + * response bss entries when beacon ies are
>> + * getting changed. */
>
> This is nicer, though I'd prefer the TODO was addressed as well since
> now we'll forever show stale data, this seems a bit bad.
>
We'll discuss it and maybe will redesign bss cache a bit, but not in a scope
of this patch. I do not like stale data in IEs as well - from end-user
prospective
WPS likely will not work.
With best regards,
Dmitry
^ permalink raw reply
* Re: [PATCH v2] cfg80211: merge in beacon ies of hidden bss.
From: Johannes Berg @ 2011-11-04 8:26 UTC (permalink / raw)
To: Dmitry Tarnyagin; +Cc: linux-wireless
In-Reply-To: <CAMG6FYg__nsSLa93AmzcMgckg8HG3FjD3LxpyDfA77WTsVm0oA@mail.gmail.com>
On Thu, 2011-11-03 at 22:59 +0100, Dmitry Tarnyagin wrote:
> + /* Absence of SSID or zero-sized SSID is used as
> + * an indication of the hidden bss. */
> + if (!ie2 || !ie2[1])
> + return 0;
I don't think that's right -- I never saw anything w/o an SSID IE except
for mesh networks I think. Also this has different semantics from the
regular rb-tree search which will return -1 if not present (which is
actually a bug).
> + /* Key comparator must use same algorithm in any rb-tree
> + * search function (order is important), otherwise ordering
> + * of items in the tree is broken and search gives incorrect
> + * results. This code uses same order as cmp_ies() does.
> + *
> + * The only difference is that this code searchs for zeroed
> + * SSID ie (another indication of the hidden bss). */
> + ielen = min(ie1[1], ie2[1]);
> + for (i = 0; i < ielen; i++)
> + if (ie2[i + 2])
> + return -1;
> + return ie2[1] - ie1[1];
Since we need to fix cmp_ie() anyway, how about we change it there as
well. I'm going to post a patch.
> @@ -587,6 +681,21 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
>
> kref_put(&res->ref, bss_release);
> } else {
> + struct cfg80211_internal_bss *hidden;
> +
> + /* First check if the beacon is a probe response from
> + * a hidden bss. If so, copy beacon ies (with nullified
> + * ssid) into the probe response bss entry (with real ssid).
> + * It is required basically for PSM implementation
> + * (probe responses do not contain tim ie) */
> +
> + /* TODO: The code is not trying to update existing probe
> + * response bss entries when beacon ies are
> + * getting changed. */
> + hidden = rb_find_hidden_bss(dev, res);
> + if (hidden)
> + copy_hidden_ies(res, hidden);
> +
This is nicer, though I'd prefer the TODO was addressed as well since
now we'll forever show stale data, this seems a bit bad.
johannes
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox