linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: Memory leak in iwlwifi or false positive?
From: reinette chatre @ 2009-07-02 22:25 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: linux-wireless@vger.kernel.org, linux-kernel
In-Reply-To: <1246570323.24044.16.camel@pc1117.cambridge.arm.com>

Hi Catalin,

On Thu, 2009-07-02 at 14:32 -0700, Catalin Marinas wrote:
> Hi,
> 
> I'm trying to get kmemleak more robust and with the latest patches (not

I just compiled my 2.6.31 kernel with kmemleak but did not yet look into
how it works ... I do see a lot of messages though. 

> pushed yet) it seems to no longer show so many random leaks. However, I
> get a lot of leaks reported in the iwlwifi code, about 4800 and they do
> not disappear from any subsequent memory scanning (as is usually the
> case with false positives). There are a lot of kmalloc's of < 512 bytes
> and /proc/slabinfo seems to be in line with this:
> 
> kmalloc-512         5440   5481
> 
> This happens shortly after booting. Note that if an object is freed,
> kmemleak no longer tracks it and therefore no reporting. But in this
> case it looks like the iwlwifi code really allocated ~4800 blocks. Is it
> normal for this code to keep so many blocks allocated? If yes, it is
> probably kmemleak missing some root object in the references tree.

Yes - this sounds about right. You tested with 5100 hardware which by
default initializes 20 TX queues. For each of these queues it maintains
a 256 buffer array of commands with 356 bytes used for each command.

The 20 * 256 gives me 5120 ... would that explain the ~4800?

Reinette



^ permalink raw reply

* [PATCH] mac80211: minstrel: avoid accessing negative indices in rix_to_ndx()
From: Luciano Coelho @ 2009-07-02 21:52 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, johannes, kalle.valo, vidhya.govindan, nbd

If rix is not found in mi->r[], i will become -1 after the loop.  This value
is eventually used to access arrays, so we were accessing arrays with a
negative index, which is obviously not what we want to do.  This patch fixes
this potential problem.

Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
 net/mac80211/rc80211_minstrel.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index b218b98..e2dd248 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -66,7 +66,7 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
 	for (i = rix; i >= 0; i--)
 		if (mi->r[i].rix == rix)
 			break;
-	WARN_ON(mi->r[i].rix != rix);
+	WARN_ON(i < 0 || mi->r[i].rix != rix);
 	return i;
 }
 
@@ -181,6 +181,9 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 			break;
 
 		ndx = rix_to_ndx(mi, ar[i].idx);
+		if (ndx < 0)
+			continue;
+
 		mi->r[ndx].attempts += ar[i].count;
 
 		if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH v2] nl80211: limit to one pairwise cipher for associate()
From: Johannes Berg @ 2009-07-02 19:36 UTC (permalink / raw)
  To: John Linville; +Cc: Vasanth Thiagarajan, Jouni Malinen, linux-wireless
In-Reply-To: <1246563276.16770.48.camel@johannes.local>

In this case, only one cipher makes sense, unlike for
connect() where it may be possible to have the card or
driver select.

No changes to mac80211 due to the way the structs are
laid out -- but the loop in net/mac80211/cfg.c will
degrade to just zero or one passes.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Sorry, based on wrong patch.

 net/wireless/nl80211.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-02 21:34:53.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-02 21:34:53.000000000 +0200
@@ -3118,7 +3118,8 @@ unlock_rtnl:
 }
 
 static int nl80211_crypto_settings(struct genl_info *info,
-				   struct cfg80211_crypto_settings *settings)
+				   struct cfg80211_crypto_settings *settings,
+				   int cipher_limit)
 {
 	settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
 
@@ -3133,7 +3134,7 @@ static int nl80211_crypto_settings(struc
 		if (len % sizeof(u32))
 			return -EINVAL;
 
-		if (settings->n_ciphers_pairwise > NL80211_MAX_NR_CIPHER_SUITES)
+		if (settings->n_ciphers_pairwise > cipher_limit)
 			return -EINVAL;
 
 		memcpy(settings->ciphers_pairwise, data, len);
@@ -3246,7 +3247,7 @@ static int nl80211_associate(struct sk_b
 		}
 	}
 
-	err = nl80211_crypto_settings(info, &crypto);
+	err = nl80211_crypto_settings(info, &crypto, 1);
 	if (!err)
 		err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, ssid,
 					  ssid_len, ie, ie_len, use_mfp,
@@ -3651,7 +3652,8 @@ static int nl80211_connect(struct sk_buf
 
 	connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
 
-	err = nl80211_crypto_settings(info, &connect.crypto);
+	err = nl80211_crypto_settings(info, &connect.crypto,
+				      NL80211_MAX_NR_CIPHER_SUITES);
 	if (err)
 		return err;
 	rtnl_lock();



^ permalink raw reply

* Re: [PATCH] orinoco: fix printk format specifier for size_t arguments
From: Johannes Berg @ 2009-07-02 19:36 UTC (permalink / raw)
  To: David Kilroy; +Cc: linux-wireless
In-Reply-To: <1246562805-9785-1-git-send-email-kilroyd@googlemail.com>

[-- Attachment #1: Type: text/plain, Size: 719 bytes --]

On Thu, 2009-07-02 at 20:26 +0100, David Kilroy wrote:
> This addresses the following compile warnings on 64-bit platforms.
> 
> drivers/net/wireless/orinoco/scan.c: In function 'orinoco_add_hostscan_results':
> drivers/net/wireless/orinoco/scan.c:194: warning: format '%d' expects type 'int', but argument 3 has type 'size_t'
> drivers/net/wireless/orinoco/scan.c:211: warning: format '%d' expects type 'int', but argument 3 has type 'size_t'
> drivers/net/wireless/orinoco/scan.c:211: warning: format '%d' expects type 'int', but argument 4 has type 'size_t'
> 
> Signed-off-by: David Kilroy <kilroyd@googlemail.com>
> ---
> 
> Thanks to Johannes for pointing this out.

Thanks for the fix!

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* [PATCH] nl80211: limit to one pairwise cipher for associate()
From: Johannes Berg @ 2009-07-02 19:34 UTC (permalink / raw)
  To: John Linville; +Cc: Vasanth Thiagarajan, Jouni Malinen, linux-wireless

In this case, only one cipher makes sense, unlike for
connect() where it may be possible to have the card or
driver select.

No changes to mac80211 due to the way the structs are
laid out -- but the loop in net/mac80211/cfg.c will
degrade to just zero or one passes.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/nl80211.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-02 21:30:54.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-02 21:31:55.000000000 +0200
@@ -3119,7 +3119,8 @@ unlock_rtnl:
 }
 
 static int nl80211_crypto_settings(struct genl_info *info,
-				   struct cfg80211_crypto_settings *settings)
+				   struct cfg80211_crypto_settings *settings,
+				   int cipher_limit)
 {
 	settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
 
@@ -3134,7 +3135,7 @@ static int nl80211_crypto_settings(struc
 		if (len % sizeof(u32))
 			return -EINVAL;
 
-		if (settings->n_ciphers_pairwise > NL80211_MAX_NR_CIPHER_SUITES)
+		if (settings->n_ciphers_pairwise > cipher_limit)
 			return -EINVAL;
 
 		memcpy(settings->ciphers_pairwise, data, len);
@@ -3250,7 +3251,7 @@ static int nl80211_associate(struct sk_b
 	if (info->attrs[NL80211_ATTR_PREV_BSSID])
 		prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
 
-	err = nl80211_crypto_settings(info, &crypto);
+	err = nl80211_crypto_settings(info, &crypto, 1);
 	if (!err)
 		err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
 					  ssid, ssid_len, ie, ie_len, use_mfp,
@@ -3655,7 +3656,8 @@ static int nl80211_connect(struct sk_buf
 
 	connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
 
-	err = nl80211_crypto_settings(info, &connect.crypto);
+	err = nl80211_crypto_settings(info, &connect.crypto,
+				      NL80211_MAX_NR_CIPHER_SUITES);
 	if (err)
 		return err;
 	rtnl_lock();



^ permalink raw reply

* [PATCH] orinoco: fix printk format specifier for size_t arguments
From: David Kilroy @ 2009-07-02 19:26 UTC (permalink / raw)
  To: linux-wireless; +Cc: David Kilroy

This addresses the following compile warnings on 64-bit platforms.

drivers/net/wireless/orinoco/scan.c: In function 'orinoco_add_hostscan_results':
drivers/net/wireless/orinoco/scan.c:194: warning: format '%d' expects type 'int', but argument 3 has type 'size_t'
drivers/net/wireless/orinoco/scan.c:211: warning: format '%d' expects type 'int', but argument 3 has type 'size_t'
drivers/net/wireless/orinoco/scan.c:211: warning: format '%d' expects type 'int', but argument 4 has type 'size_t'

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---

Thanks to Johannes for pointing this out.

This was introduced in patch 21 of the cfg80211 switch series "orinoco:
convert scanning to cfg80211"

---
 drivers/net/wireless/orinoco/scan.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 522eb98..d2f10e9 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -190,7 +190,7 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
 			/* Sanity check for atom_len */
 			if (atom_len < sizeof(struct prism2_scan_apinfo)) {
 				printk(KERN_ERR "%s: Invalid atom_len in scan "
-				       "data: %d\n", priv->ndev->name,
+				       "data: %zu\n", priv->ndev->name,
 				       atom_len);
 				abort = true;
 				goto scan_abort;
@@ -206,8 +206,8 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
 
 	/* Check that we got an whole number of atoms */
 	if ((len - offset) % atom_len) {
-		printk(KERN_ERR "%s: Unexpected scan data length %d, "
-		       "atom_len %d, offset %d\n", priv->ndev->name, len,
+		printk(KERN_ERR "%s: Unexpected scan data length %zu, "
+		       "atom_len %zu, offset %d\n", priv->ndev->name, len,
 		       atom_len, offset);
 		abort = true;
 		goto scan_abort;
-- 
1.6.0.6


^ permalink raw reply related

* Re: [PATCH] Add prism 2/3 usb adaptor firmware for use with staging/wlan-ng driver.
From: Karl Relton @ 2009-07-02 16:59 UTC (permalink / raw)
  To: David Woodhouse; +Cc: Luis R. Rodriguez, linux-wireless
In-Reply-To: <1246477614.3681.2103.camel@macbook.infradead.org>

On Wed, 2009-07-01 at 20:46 +0100, David Woodhouse wrote:
> On Wed, 2009-07-01 at 17:16 +0100, Karl Relton wrote:
> > On Tue, 2009-06-30 at 14:58 -0700, Luis R. Rodriguez wrote:
> > > On Tue, Jun 30, 2009 at 2:09 PM, Karl
> > > Relton<karllinuxtest.relton@ntlworld.com> wrote:
> > > > On Tue, 2009-06-30 at 12:17 -0700, Luis R. Rodriguez wrote:
> > > >> On Tue, Jun 30, 2009 at 12:05 PM, Karl
> > > >> Relton<karllinuxtest.relton@ntlworld.com> wrote:
> > > >> > Signed-Off-By: Karl Relton
> > > >> > Signed-Off-By: Mark S. Mathews
> > > >>
> > > >> The commit log is empty. Where is this driver? Is it in staging at
> > > >> least? If so does this get users of the driver a usable firmware? What
> > > >> is the future of the driver BTW?
> > > >>
> > > >
> > > > Oops - put text in wrong part of patch documentation. I can move this up
> > > > to the 'commit log' part.
> > > >
> > > > The driver is under 'staging' - maintained by Greg Koah-Hartman
> > > >
> > > > The firmware blob in 'srec' format for prism 2/3 usb adaptors.
> > > > The driver will read the srec file using a standard request_firmware()
> > > > call, and will convert it into the appropriate binary format and upload to
> > > > the adaptor. Note the processing is left to the driver (rather than
> > > > pre-compiling) because the driver needs to insert runtime data obtained from
> > > > the adaptor into the blob. The appropriate insertion locations are conveyed
> > > > by the srec format.
> > > 
> > > Why all the srec->binary conversion? Doesn't this waste space on
> > > people's firmware directories?
> > > 
> > Yes, technically it does. The srec file is ~185KB, a binary image would
> > be ~64KB.
> > 
> > The reason it was left is that the driver has to do some runtime
> > plugging of data into the image, so pre-compilation would have meant
> > inventing both a compiler tool and an intermediate format for the driver
> > to read and process. Putting all the srec processing in the driver was
> > more expedient (just meant porting existing userspace code into driver
> > space).
> 
> The kernel has support for a binary form of srec files (well, of ihex
> files, which are fairly much the same thing).
> 
> See include/linux/ihex.h and firmware/ihex2fw.c.
>  

Hi David

Thanks for this info.

Assuming the necessary work was done to suitably pre-process srec to a
binary, would the firmware image (with its currently somewhat ambiguous
license statement) be allowed into linux-firmware anyway, or would it
simply not pass the criteria you need to apply?

Karl


^ permalink raw reply

* [PATCH] cfg80211: refuse authenticating to same BSSID twice
From: Johannes Berg @ 2009-07-02 16:26 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

It is possible that there are different BSS structs with
the same BSSID, but we cannot authenticate with multiple
of them them because we need the BSSID to be unique for
deauthenticating/disassociating.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/mlme.c |   22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

--- wireless-testing.orig/net/wireless/mlme.c	2009-07-02 18:18:51.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2009-07-02 18:24:03.000000000 +0200
@@ -278,6 +278,21 @@ int cfg80211_mlme_auth(struct cfg80211_r
 	struct cfg80211_internal_bss *bss;
 	int i, err, slot = -1, nfree = 0;
 
+	if (wdev->current_bss &&
+	    memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
+		return -EALREADY;
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid,
+		    				ETH_ALEN) == 0)
+			return -EALREADY;
+		if (wdev->auth_bsses[i] &&
+		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
+		    				ETH_ALEN) == 0)
+			return -EALREADY;
+	}
+
 	memset(&req, 0, sizeof(req));
 
 	req.ie = ie;
@@ -291,13 +306,6 @@ int cfg80211_mlme_auth(struct cfg80211_r
 	bss = bss_from_pub(req.bss);
 
 	for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (bss == wdev->auth_bsses[i]) {
-			err = -EALREADY;
-			goto out;
-		}
-	}
-
-	for (i = 0; i < MAX_AUTH_BSSES; i++) {
 		if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
 			slot = i;
 			nfree++;



^ permalink raw reply

* Re: kernel .30 BROKE ATH5K with my AR5212 atheros.
From: Bob Copeland @ 2009-07-02 15:36 UTC (permalink / raw)
  To: Jasin Colegrove; +Cc: linux-wireless
In-Reply-To: <6c354a1a0906301550g70fbd9ddkecd09fc0e98dd1ef@mail.gmail.com>

On Tue, Jun 30, 2009 at 6:50 PM, Jasin
Colegrove<j.wholesalesupply@gmail.com> wrote:
> I AM NOT A SUBSCRIBER. Please reply to me directly at this e-mail
> address j.wholesalesupply@gmail.com

No need to shout -- also common etiquette on Linux kernel lists is
to "reply-all" anyway :)

> Then I decided to see if it the card was working, So I tried to iwlist
> wlan0 scan, it returned the expected results.

> I would be glad to offer up as much
> information as I can, but I don't have the slightest on how to debug
> this issue?

So to summarize:

2.6.29 works, 2.6.30 doesn't, ath9k works, ath5k doesn't, userspace
setup is unchanged.  ath5k can get scan results (which means RX is
working at least some of the time) but dhcp does not.

You said you are comfortable with the command line, in that case the
easiest way to debug the change is to just bisect the ath5k changes
using git.  There were only 50 or so patches since 2.6.29 so you will
likely only need to compile the kernel 5 or 6 times.  You can do
something like:

$ git bisect start v2.6.30 v2.6.29 -- drivers/net/wireless/ath5k

> Any help on that issue is much appreciated. Where can I
> file the appropriate bug and what information do I need to post from a
> technical standpoint.

http://bugzilla.kernel.org/ is where you would file it, the information
you've already given here is a good start.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* [PATCH] cfg80211: keep track of BSSes
From: Johannes Berg @ 2009-07-02 15:20 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

In order to avoid problems with BSS structs going away
while they're in use, I've long wanted to make cfg80211
keep track of them. Without the SME, that wasn't doable
but now that we have the SME we can do this too. It can
keep track of up to four separate authentications and
one association, regardless of whether it's controlled
by the cfg80211 SME or the userspace SME.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h  |   86 ++---------
 net/mac80211/cfg.c      |   22 +-
 net/mac80211/mlme.c     |    6 
 net/wireless/core.c     |    5 
 net/wireless/core.h     |   41 +++++
 net/wireless/ibss.c     |   12 -
 net/wireless/mlme.c     |  361 +++++++++++++++++++++++++++++++++++++++++++++---
 net/wireless/nl80211.c  |  144 +++++++++----------
 net/wireless/scan.c     |   31 ----
 net/wireless/sme.c      |  156 ++++++++++++--------
 net/wireless/wext-sme.c |    4 
 11 files changed, 591 insertions(+), 277 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-07-02 17:13:49.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-07-02 17:17:11.000000000 +0200
@@ -584,7 +584,6 @@ enum cfg80211_signal_type {
  *	is no guarantee that these are well-formed!)
  * @len_information_elements: total length of the information elements
  * @signal: signal strength value (type depends on the wiphy's signal_type)
- * @hold: BSS should not expire
  * @free_priv: function pointer to free private data
  * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
  */
@@ -642,33 +641,17 @@ struct cfg80211_crypto_settings {
  *
  * This structure provides information needed to complete IEEE 802.11
  * authentication.
- * NOTE: This structure will likely change when more code from mac80211 is
- * moved into cfg80211 so that non-mac80211 drivers can benefit from it, too.
- * Before using this in a driver that does not use mac80211, it would be better
- * to check the status of that work and better yet, volunteer to work on it.
- *
- * @chan: The channel to use or %NULL if not specified (auto-select based on
- *	scan results)
- * @peer_addr: The address of the peer STA (AP BSSID in infrastructure case);
- *	this field is required to be present; if the driver wants to help with
- *	BSS selection, it should use (yet to be added) MLME event to allow user
- *	space SME to be notified of roaming candidate, so that the SME can then
- *	use the authentication request with the recommended BSSID and whatever
- *	other data may be needed for authentication/association
- * @ssid: SSID or %NULL if not yet available
- * @ssid_len: Length of ssid in octets
+ *
+ * @bss: The BSS to authenticate with.
  * @auth_type: Authentication type (algorithm)
  * @ie: Extra IEs to add to Authentication frame or %NULL
  * @ie_len: Length of ie buffer in octets
  */
 struct cfg80211_auth_request {
-	struct ieee80211_channel *chan;
-	u8 *peer_addr;
-	const u8 *ssid;
-	size_t ssid_len;
-	enum nl80211_auth_type auth_type;
+	struct cfg80211_bss *bss;
 	const u8 *ie;
 	size_t ie_len;
+	enum nl80211_auth_type auth_type;
 };
 
 /**
@@ -676,32 +659,18 @@ struct cfg80211_auth_request {
  *
  * This structure provides information needed to complete IEEE 802.11
  * (re)association.
- * NOTE: This structure will likely change when more code from mac80211 is
- * moved into cfg80211 so that non-mac80211 drivers can benefit from it, too.
- * Before using this in a driver that does not use mac80211, it would be better
- * to check the status of that work and better yet, volunteer to work on it.
- *
- * @chan: The channel to use or %NULL if not specified (auto-select based on
- *	scan results)
- * @peer_addr: The address of the peer STA (AP BSSID); this field is required
- *	to be present and the STA must be in State 2 (authenticated) with the
- *	peer STA
- * @ssid: SSID
- * @ssid_len: Length of ssid in octets
+ * @bss: The BSS to associate with.
  * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
  * @ie_len: Length of ie buffer in octets
  * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
  * @crypto: crypto settings
  */
 struct cfg80211_assoc_request {
-	struct ieee80211_channel *chan;
-	u8 *peer_addr;
-	const u8 *ssid;
-	size_t ssid_len;
+	struct cfg80211_bss *bss;
 	const u8 *ie;
 	size_t ie_len;
-	bool use_mfp;
 	struct cfg80211_crypto_settings crypto;
+	bool use_mfp;
 };
 
 /**
@@ -710,16 +679,16 @@ struct cfg80211_assoc_request {
  * This structure provides information needed to complete IEEE 802.11
  * deauthentication.
  *
- * @peer_addr: The address of the peer STA (AP BSSID); this field is required
- *	to be present and the STA must be authenticated with the peer STA
+ * @bss: the BSS to deauthenticate from
  * @ie: Extra IEs to add to Deauthentication frame or %NULL
  * @ie_len: Length of ie buffer in octets
+ * @reason_code: The reason code for the deauthentication
  */
 struct cfg80211_deauth_request {
-	u8 *peer_addr;
-	u16 reason_code;
+	struct cfg80211_bss *bss;
 	const u8 *ie;
 	size_t ie_len;
+	u16 reason_code;
 };
 
 /**
@@ -728,16 +697,16 @@ struct cfg80211_deauth_request {
  * This structure provides information needed to complete IEEE 802.11
  * disassocation.
  *
- * @peer_addr: The address of the peer STA (AP BSSID); this field is required
- *	to be present and the STA must be associated with the peer STA
+ * @bss: the BSS to disassociate from
  * @ie: Extra IEs to add to Disassociation frame or %NULL
  * @ie_len: Length of ie buffer in octets
+ * @reason_code: The reason code for the disassociation
  */
 struct cfg80211_disassoc_request {
-	u8 *peer_addr;
-	u16 reason_code;
+	struct cfg80211_bss *bss;
 	const u8 *ie;
 	size_t ie_len;
+	u16 reason_code;
 };
 
 /**
@@ -1252,6 +1221,9 @@ extern void wiphy_free(struct wiphy *wip
 
 /* internal struct */
 struct cfg80211_conn;
+struct cfg80211_internal_bss;
+
+#define MAX_AUTH_BSSES		4
 
 /**
  * struct wireless_dev - wireless per-netdev state
@@ -1281,7 +1253,6 @@ struct wireless_dev {
 	struct net_device *netdev;
 
 	/* currently used for IBSS and SME - might be rearranged later */
-	struct cfg80211_bss *current_bss;
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 ssid_len;
 	enum {
@@ -1291,6 +1262,10 @@ struct wireless_dev {
 	} sme_state;
 	struct cfg80211_conn *conn;
 
+	struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
+	struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
+	struct cfg80211_internal_bss *current_bss; /* associated / joined */
+
 #ifdef CONFIG_WIRELESS_EXT
 	/* wext data */
 	struct {
@@ -1813,23 +1788,6 @@ void cfg80211_send_deauth(struct net_dev
 void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
 
 /**
- * cfg80211_hold_bss - exclude bss from expiration
- * @bss: bss which should not expire
- *
- * In a case when the BSS is not updated but it shouldn't expire this
- * function can be used to mark the BSS to be excluded from expiration.
- */
-void cfg80211_hold_bss(struct cfg80211_bss *bss);
-
-/**
- * cfg80211_unhold_bss - remove expiration exception from the BSS
- * @bss: bss which can expire again
- *
- * This function marks the BSS to be expirable again.
- */
-void cfg80211_unhold_bss(struct cfg80211_bss *bss);
-
-/**
  * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
  * @dev: network device
  * @addr: The source MAC address of the frame
--- wireless-testing.orig/net/wireless/core.h	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-07-02 17:17:11.000000000 +0200
@@ -110,12 +110,30 @@ struct cfg80211_internal_bss {
 	struct rb_node rbn;
 	unsigned long ts;
 	struct kref ref;
-	bool hold, ies_allocated;
+	atomic_t hold;
+	bool ies_allocated;
 
 	/* must be last because of priv member */
 	struct cfg80211_bss pub;
 };
 
+static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub)
+{
+	return container_of(pub, struct cfg80211_internal_bss, pub);
+}
+
+static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
+{
+	atomic_inc(&bss->hold);
+}
+
+static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
+{
+	int r = atomic_dec_return(&bss->hold);
+	WARN_ON(r < 0);
+}
+
+
 struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx);
 int get_wiphy_idx(struct wiphy *wiphy);
 
@@ -176,6 +194,26 @@ void cfg80211_clear_ibss(struct net_devi
 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, bool nowext);
 
+/* MLME */
+int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev, struct ieee80211_channel *chan,
+		       enum nl80211_auth_type auth_type, const u8 *bssid,
+		       const u8 *ssid, int ssid_len,
+		       const u8 *ie, int ie_len);
+int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, struct ieee80211_channel *chan,
+			const u8 *bssid, const u8 *ssid, int ssid_len,
+			const u8 *ie, int ie_len, bool use_mfp,
+			struct cfg80211_crypto_settings *crypt);
+int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev, const u8 *bssid,
+			 const u8 *ie, int ie_len, u16 reason);
+int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
+			   struct net_device *dev, const u8 *bssid,
+			   const u8 *ie, int ie_len, u16 reason);
+void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
+			struct net_device *dev);
+
 /* SME */
 int cfg80211_connect(struct cfg80211_registered_device *rdev,
 		     struct net_device *dev,
@@ -193,5 +231,6 @@ void __cfg80211_disconnected(struct net_
 			     size_t ie_len, u16 reason, bool from_ap);
 void cfg80211_sme_scan_done(struct net_device *dev);
 void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_sme_disassoc(struct net_device *dev, int idx);
 
 #endif /* __NET_WIRELESS_CORE_H */
--- wireless-testing.orig/net/wireless/mlme.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2009-07-02 17:17:11.000000000 +0200
@@ -14,8 +14,32 @@
 
 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	u8 *bssid = mgmt->bssid;
+	int i;
+	u16 status = le16_to_cpu(mgmt->u.auth.status_code);
+	bool done = false;
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
+							ETH_ALEN) == 0) {
+			if (status == WLAN_STATUS_SUCCESS) {
+				wdev->auth_bsses[i] = wdev->authtry_bsses[i];
+			} else {
+				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+			}
+			wdev->authtry_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+
+	WARN_ON(!done);
 
 	nl80211_send_rx_auth(rdev, dev, buf, len, gfp);
 	cfg80211_sme_rx_auth(dev, buf, len);
@@ -30,7 +54,8 @@ void cfg80211_send_rx_assoc(struct net_d
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 	u8 *ie = mgmt->u.assoc_resp.variable;
-	int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+	int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+	bool done;
 
 	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 
@@ -38,6 +63,20 @@ void cfg80211_send_rx_assoc(struct net_d
 
 	cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
 				status_code, gfp);
+
+	if (status_code == WLAN_STATUS_SUCCESS) {
+		for (i = 0; wdev->current_bss && i < MAX_AUTH_BSSES; i++) {
+			if (wdev->auth_bsses[i] == wdev->current_bss) {
+				cfg80211_unhold_bss(wdev->auth_bsses[i]);
+				cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
+				wdev->auth_bsses[i] = NULL;
+				done = true;
+				break;
+			}
+		}
+
+		WARN_ON(!done);
+	}
 }
 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
 
@@ -47,9 +86,45 @@ void cfg80211_send_deauth(struct net_dev
 	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	const u8 *bssid = mgmt->bssid;
+	int i;
+	bool done = false;
 
 	nl80211_send_deauth(rdev, dev, buf, len, gfp);
 
+	if (wdev->current_bss &&
+	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
+		done = true;
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
+		wdev->current_bss = NULL;
+	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i] &&
+		    memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->auth_bsses[i]);
+			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
+			wdev->auth_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+			wdev->authtry_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+/*
+ * mac80211 currently triggers this warning,
+ * so disable for now (it's harmless, just
+ * means that we got a spurious event)
+
+	WARN_ON(!done);
+
+ */
+
 	if (wdev->sme_state == CFG80211_SME_CONNECTED) {
 		u16 reason_code;
 		bool from_ap;
@@ -59,8 +134,6 @@ void cfg80211_send_deauth(struct net_dev
 		from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
 		__cfg80211_disconnected(dev, gfp, NULL, 0,
 					reason_code, from_ap);
-
-		wdev->sme_state = CFG80211_SME_IDLE;
 	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
 		cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
 					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
@@ -74,21 +147,38 @@ void cfg80211_send_disassoc(struct net_d
 	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	const u8 *bssid = mgmt->bssid;
+	int i;
+	u16 reason_code;
+	bool from_ap;
+	bool done = false;
 
 	nl80211_send_disassoc(rdev, dev, buf, len, gfp);
 
-	if (wdev->sme_state == CFG80211_SME_CONNECTED) {
-		u16 reason_code;
-		bool from_ap;
-
-		reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
-
-		from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
-		__cfg80211_disconnected(dev, gfp, NULL, 0,
-					reason_code, from_ap);
+	if (!wdev->sme_state == CFG80211_SME_CONNECTED)
+		return;
 
-		wdev->sme_state = CFG80211_SME_IDLE;
-	}
+	if (wdev->current_bss &&
+	    memcmp(wdev->current_bss, bssid, ETH_ALEN) == 0) {
+		for (i = 0; i < MAX_AUTH_BSSES; i++) {
+			if (wdev->authtry_bsses[i] || wdev->auth_bsses[i])
+				continue;
+			wdev->auth_bsses[i] = wdev->current_bss;
+			wdev->current_bss = NULL;
+			done = true;
+			cfg80211_sme_disassoc(dev, i);
+			break;
+		}
+		WARN_ON(!done);
+	} else
+		WARN_ON(1);
+
+
+	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
+
+	from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
+	__cfg80211_disconnected(dev, gfp, NULL, 0,
+				reason_code, from_ap);
 }
 EXPORT_SYMBOL(cfg80211_send_disassoc);
 
@@ -97,11 +187,27 @@ void cfg80211_send_auth_timeout(struct n
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	int i;
+	bool done = false;
+
 	nl80211_send_auth_timeout(rdev, dev, addr, gfp);
 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
 		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
 					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
-	wdev->sme_state = CFG80211_SME_IDLE;
+
+	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(wdev->authtry_bsses[i]->pub.bssid,
+			   addr, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+			wdev->authtry_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+
+	WARN_ON(!done);
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 
@@ -110,11 +216,27 @@ void cfg80211_send_assoc_timeout(struct 
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	int i;
+	bool done = false;
+
 	nl80211_send_assoc_timeout(rdev, dev, addr, gfp);
 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
 		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
 					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
-	wdev->sme_state = CFG80211_SME_IDLE;
+
+	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i] &&
+		    memcmp(wdev->auth_bsses[i]->pub.bssid,
+			   addr, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->auth_bsses[i]);
+			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
+			wdev->auth_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+
+	WARN_ON(!done);
 }
 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
 
@@ -143,3 +265,208 @@ void cfg80211_michael_mic_failure(struct
 	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
 }
 EXPORT_SYMBOL(cfg80211_michael_mic_failure);
+
+/* some MLME handling for userspace SME */
+int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev, struct ieee80211_channel *chan,
+		       enum nl80211_auth_type auth_type, const u8 *bssid,
+		       const u8 *ssid, int ssid_len,
+		       const u8 *ie, int ie_len)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_auth_request req;
+	struct cfg80211_internal_bss *bss;
+	int i, err, slot = -1, nfree = 0;
+
+	memset(&req, 0, sizeof(req));
+
+	req.ie = ie;
+	req.ie_len = ie_len;
+	req.auth_type = auth_type;
+	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
+				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+	if (!req.bss)
+		return -ENOENT;
+
+	bss = bss_from_pub(req.bss);
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (bss == wdev->auth_bsses[i]) {
+			err = -EALREADY;
+			goto out;
+		}
+	}
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
+			slot = i;
+			nfree++;
+		}
+	}
+
+	/* we need one free slot for disassoc and one for this auth */
+	if (nfree < 2) {
+		err = -ENOSPC;
+		goto out;
+	}
+
+	wdev->authtry_bsses[slot] = bss;
+	cfg80211_hold_bss(bss);
+
+	err = rdev->ops->auth(&rdev->wiphy, dev, &req);
+	if (err) {
+		wdev->authtry_bsses[slot] = NULL;
+		cfg80211_unhold_bss(bss);
+	}
+
+ out:
+	if (err)
+		cfg80211_put_bss(req.bss);
+	return err;
+}
+
+int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, struct ieee80211_channel *chan,
+			const u8 *bssid, const u8 *ssid, int ssid_len,
+			const u8 *ie, int ie_len, bool use_mfp,
+			struct cfg80211_crypto_settings *crypt)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_assoc_request req;
+	struct cfg80211_internal_bss *bss;
+	int i, err, slot = -1;
+
+	memset(&req, 0, sizeof(req));
+
+	if (wdev->current_bss)
+		return -EALREADY;
+
+	req.ie = ie;
+	req.ie_len = ie_len;
+	memcpy(&req.crypto, crypt, sizeof(req.crypto));
+	req.use_mfp = use_mfp;
+	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
+				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+	if (!req.bss)
+		return -ENOENT;
+
+	bss = bss_from_pub(req.bss);
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (bss == wdev->auth_bsses[i]) {
+			slot = i;
+			break;
+		}
+	}
+
+	if (slot < 0) {
+		err = -ENOTCONN;
+		goto out;
+	}
+
+	err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
+ out:
+	/* still a reference in wdev->auth_bsses[slot] */
+	cfg80211_put_bss(req.bss);
+	return err;
+}
+
+int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev, const u8 *bssid,
+			 const u8 *ie, int ie_len, u16 reason)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_deauth_request req;
+	int i;
+
+	memset(&req, 0, sizeof(req));
+	req.reason_code = reason;
+	req.ie = ie;
+	req.ie_len = ie_len;
+	if (wdev->current_bss &&
+	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
+		req.bss = &wdev->current_bss->pub;
+	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i] &&
+		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
+			req.bss = &wdev->auth_bsses[i]->pub;
+			break;
+		}
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
+			req.bss = &wdev->authtry_bsses[i]->pub;
+			break;
+		}
+	}
+
+	if (!req.bss)
+		return -ENOTCONN;
+
+	return rdev->ops->deauth(&rdev->wiphy, dev, &req);
+}
+
+int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
+			   struct net_device *dev, const u8 *bssid,
+			   const u8 *ie, int ie_len, u16 reason)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_disassoc_request req;
+
+	memset(&req, 0, sizeof(req));
+	req.reason_code = reason;
+	req.ie = ie;
+	req.ie_len = ie_len;
+	if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
+		req.bss = &wdev->current_bss->pub;
+	else
+		return -ENOTCONN;
+
+	return rdev->ops->disassoc(&rdev->wiphy, dev, &req);
+}
+
+void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
+			struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_deauth_request req;
+	int i;
+
+	if (!rdev->ops->deauth)
+		return;
+
+	memset(&req, 0, sizeof(req));
+	req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
+	req.ie = NULL;
+	req.ie_len = 0;
+
+	if (wdev->current_bss) {
+		req.bss = &wdev->current_bss->pub;
+		rdev->ops->deauth(&rdev->wiphy, dev, &req);
+		if (wdev->current_bss) {
+			cfg80211_unhold_bss(wdev->current_bss);
+			cfg80211_put_bss(&wdev->current_bss->pub);
+			wdev->current_bss = NULL;
+		}
+	}
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i]) {
+			req.bss = &wdev->auth_bsses[i]->pub;
+			rdev->ops->deauth(&rdev->wiphy, dev, &req);
+			if (wdev->auth_bsses[i]) {
+				cfg80211_unhold_bss(wdev->auth_bsses[i]);
+				cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
+				wdev->auth_bsses[i] = NULL;
+			}
+		}
+		if (wdev->authtry_bsses[i]) {
+			req.bss = &wdev->authtry_bsses[i]->pub;
+			rdev->ops->deauth(&rdev->wiphy, dev, &req);
+			if (wdev->authtry_bsses[i]) {
+				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+				wdev->authtry_bsses[i] = NULL;
+			}
+		}
+	}
+}
--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-02 17:17:11.000000000 +0200
@@ -3043,9 +3043,10 @@ static int nl80211_authenticate(struct s
 {
 	struct cfg80211_registered_device *drv;
 	struct net_device *dev;
-	struct cfg80211_auth_request req;
-	struct wiphy *wiphy;
-	int err;
+	struct ieee80211_channel *chan;
+	const u8 *bssid, *ssid, *ie = NULL;
+	int err, ssid_len, ie_len = 0;
+	enum nl80211_auth_type auth_type;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
@@ -3056,6 +3057,12 @@ static int nl80211_authenticate(struct s
 	if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
 		return -EINVAL;
 
+	if (!info->attrs[NL80211_ATTR_SSID])
+		return -EINVAL;
+
+	if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
+		return -EINVAL;
+
 	rtnl_lock();
 
 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -3077,38 +3084,30 @@ static int nl80211_authenticate(struct s
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
-
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
-
-	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-		req.chan = ieee80211_get_channel(
-			wiphy,
-			nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
-		if (!req.chan) {
-			err = -EINVAL;
-			goto out;
-		}
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	chan = ieee80211_get_channel(&drv->wiphy,
+		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+	if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
+		err = -EINVAL;
+		goto out;
 	}
 
-	if (info->attrs[NL80211_ATTR_SSID]) {
-		req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
-		req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
-	}
+	ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+	ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
-	if (!nl80211_valid_auth_type(req.auth_type)) {
+	auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+	if (!nl80211_valid_auth_type(auth_type)) {
 		err = -EINVAL;
 		goto out;
 	}
 
-	err = drv->ops->auth(&drv->wiphy, dev, &req);
+	err = cfg80211_mlme_auth(drv, dev, chan, auth_type, bssid,
+				 ssid, ssid_len, ie, ie_len);
 
 out:
 	cfg80211_put_dev(drv);
@@ -3182,26 +3181,29 @@ static int nl80211_crypto_settings(struc
 
 static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
-	struct cfg80211_assoc_request req;
-	struct wiphy *wiphy;
-	int err;
+	struct cfg80211_crypto_settings crypto;
+	struct ieee80211_channel *chan;
+	const u8 *bssid, *ssid, *ie = NULL;
+	int err, ssid_len, ie_len = 0;
+	bool use_mfp = false;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
 
 	if (!info->attrs[NL80211_ATTR_MAC] ||
-	    !info->attrs[NL80211_ATTR_SSID])
+	    !info->attrs[NL80211_ATTR_SSID] ||
+	    !info->attrs[NL80211_ATTR_WIPHY_FREQ])
 		return -EINVAL;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_drv_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->assoc) {
+	if (!rdev->ops->assoc) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3216,46 +3218,42 @@ static int nl80211_associate(struct sk_b
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
-
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-		req.chan = ieee80211_get_channel(
-			wiphy,
-			nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
-		if (!req.chan) {
-			err = -EINVAL;
-			goto out;
-		}
+	chan = ieee80211_get_channel(&rdev->wiphy,
+		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+	if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
+		err = -EINVAL;
+		goto out;
 	}
 
-	req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
-	req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+	ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+	ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
 	if (info->attrs[NL80211_ATTR_USE_MFP]) {
 		enum nl80211_mfp use_mfp =
 			nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
 		if (use_mfp == NL80211_MFP_REQUIRED)
-			req.use_mfp = true;
+			use_mfp = true;
 		else if (use_mfp != NL80211_MFP_NO) {
 			err = -EINVAL;
 			goto out;
 		}
 	}
 
-	err = nl80211_crypto_settings(info, &req.crypto);
+	err = nl80211_crypto_settings(info, &crypto);
 	if (!err)
-		err = drv->ops->assoc(&drv->wiphy, dev, &req);
+		err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, ssid,
+					  ssid_len, ie, ie_len, use_mfp,
+					  &crypto);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_put_dev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3266,9 +3264,9 @@ static int nl80211_deauthenticate(struct
 {
 	struct cfg80211_registered_device *drv;
 	struct net_device *dev;
-	struct cfg80211_deauth_request req;
-	struct wiphy *wiphy;
-	int err;
+	const u8 *ie = NULL, *bssid;
+	int err, ie_len = 0;
+	u16 reason_code;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
@@ -3300,24 +3298,21 @@ static int nl80211_deauthenticate(struct
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
-
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
-	if (req.reason_code == 0) {
+	reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+	if (reason_code == 0) {
 		/* Reason Code 0 is reserved */
 		err = -EINVAL;
 		goto out;
 	}
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	err = drv->ops->deauth(&drv->wiphy, dev, &req);
+	err = cfg80211_mlme_deauth(drv, dev, bssid, ie, ie_len, reason_code);
 
 out:
 	cfg80211_put_dev(drv);
@@ -3331,9 +3326,9 @@ static int nl80211_disassociate(struct s
 {
 	struct cfg80211_registered_device *drv;
 	struct net_device *dev;
-	struct cfg80211_disassoc_request req;
-	struct wiphy *wiphy;
-	int err;
+	const u8 *ie = NULL, *bssid;
+	int err, ie_len = 0;
+	u16 reason_code;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
@@ -3365,24 +3360,21 @@ static int nl80211_disassociate(struct s
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
-
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
-	if (req.reason_code == 0) {
+	reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+	if (reason_code == 0) {
 		/* Reason Code 0 is reserved */
 		err = -EINVAL;
 		goto out;
 	}
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	err = drv->ops->disassoc(&drv->wiphy, dev, &req);
+	err = cfg80211_mlme_disassoc(drv, dev, bssid, ie, ie_len, reason_code);
 
 out:
 	cfg80211_put_dev(drv);
--- wireless-testing.orig/net/wireless/scan.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/scan.c	2009-07-02 17:17:11.000000000 +0200
@@ -70,6 +70,8 @@ static void bss_release(struct kref *ref
 	if (bss->ies_allocated)
 		kfree(bss->pub.information_elements);
 
+	BUG_ON(atomic_read(&bss->hold));
+
 	kfree(bss);
 }
 
@@ -92,8 +94,9 @@ void cfg80211_bss_expire(struct cfg80211
 	bool expired = false;
 
 	list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
-		if (bss->hold ||
-		    !time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
+		if (atomic_read(&bss->hold))
+			continue;
+		if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
 			continue;
 		list_del(&bss->list);
 		rb_erase(&bss->rbn, &dev->bss_tree);
@@ -553,30 +556,6 @@ void cfg80211_unlink_bss(struct wiphy *w
 }
 EXPORT_SYMBOL(cfg80211_unlink_bss);
 
-void cfg80211_hold_bss(struct cfg80211_bss *pub)
-{
-	struct cfg80211_internal_bss *bss;
-
-	if (!pub)
-		return;
-
-	bss = container_of(pub, struct cfg80211_internal_bss, pub);
-	bss->hold = true;
-}
-EXPORT_SYMBOL(cfg80211_hold_bss);
-
-void cfg80211_unhold_bss(struct cfg80211_bss *pub)
-{
-	struct cfg80211_internal_bss *bss;
-
-	if (!pub)
-		return;
-
-	bss = container_of(pub, struct cfg80211_internal_bss, pub);
-	bss->hold = false;
-}
-EXPORT_SYMBOL(cfg80211_unhold_bss);
-
 #ifdef CONFIG_WIRELESS_EXT
 int cfg80211_wext_siwscan(struct net_device *dev,
 			  struct iw_request_info *info,
--- wireless-testing.orig/net/wireless/ibss.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/ibss.c	2009-07-02 17:17:11.000000000 +0200
@@ -33,11 +33,11 @@ void cfg80211_ibss_joined(struct net_dev
 
 	if (wdev->current_bss) {
 		cfg80211_unhold_bss(wdev->current_bss);
-		cfg80211_put_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
 	}
 
-	cfg80211_hold_bss(bss);
-	wdev->current_bss = bss;
+	cfg80211_hold_bss(bss_from_pub(bss));
+	wdev->current_bss = bss_from_pub(bss);
 
 	nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
 #ifdef CONFIG_WIRELESS_EXT
@@ -78,7 +78,7 @@ void cfg80211_clear_ibss(struct net_devi
 
 	if (wdev->current_bss) {
 		cfg80211_unhold_bss(wdev->current_bss);
-		cfg80211_put_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
 	}
 
 	wdev->current_bss = NULL;
@@ -212,7 +212,7 @@ int cfg80211_ibss_wext_giwfreq(struct ne
 		return -EINVAL;
 
 	if (wdev->current_bss)
-		chan = wdev->current_bss->channel;
+		chan = wdev->current_bss->pub.channel;
 	else if (wdev->wext.ibss.channel)
 		chan = wdev->wext.ibss.channel;
 
@@ -352,7 +352,7 @@ int cfg80211_ibss_wext_giwap(struct net_
 	ap_addr->sa_family = ARPHRD_ETHER;
 
 	if (wdev->current_bss)
-		memcpy(ap_addr->sa_data, wdev->current_bss->bssid, ETH_ALEN);
+		memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN);
 	else
 		memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
 	return 0;
--- wireless-testing.orig/net/wireless/sme.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/sme.c	2009-07-02 17:17:11.000000000 +0200
@@ -103,44 +103,37 @@ static int cfg80211_conn_scan(struct wir
 static int cfg80211_conn_do_work(struct wireless_dev *wdev)
 {
 	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
-	union {
-		struct cfg80211_auth_request auth_req;
-		struct cfg80211_assoc_request assoc_req;
-	} u;
-
-	memset(&u, 0, sizeof(u));
+	struct cfg80211_connect_params *params;
+	int err;
 
 	if (!wdev->conn)
 		return 0;
 
+	params = &wdev->conn->params;
+
 	switch (wdev->conn->state) {
 	case CFG80211_CONN_SCAN_AGAIN:
 		return cfg80211_conn_scan(wdev);
 	case CFG80211_CONN_AUTHENTICATE_NEXT:
-		u.auth_req.chan = wdev->conn->params.channel;
-		u.auth_req.peer_addr = wdev->conn->params.bssid;
-		u.auth_req.ssid = wdev->conn->params.ssid;
-		u.auth_req.ssid_len = wdev->conn->params.ssid_len;
-		u.auth_req.auth_type = wdev->conn->params.auth_type;
-		u.auth_req.ie = NULL;
-		u.auth_req.ie_len = 0;
-		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
 		BUG_ON(!drv->ops->auth);
-		return drv->ops->auth(wdev->wiphy, wdev->netdev, &u.auth_req);
+		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
+		return cfg80211_mlme_auth(drv, wdev->netdev,
+					  params->channel, params->auth_type,
+					  params->bssid,
+					  params->ssid, params->ssid_len,
+					  NULL, 0);
 	case CFG80211_CONN_ASSOCIATE_NEXT:
-		u.assoc_req.chan = wdev->conn->params.channel;
-		u.assoc_req.peer_addr = wdev->conn->params.bssid;
-		u.assoc_req.ssid = wdev->conn->params.ssid;
-		u.assoc_req.ssid_len = wdev->conn->params.ssid_len;
-		u.assoc_req.ie = wdev->conn->params.ie;
-		u.assoc_req.ie_len = wdev->conn->params.ie_len;
-		u.assoc_req.use_mfp = false;
-		memcpy(&u.assoc_req.crypto, &wdev->conn->params.crypto,
-			sizeof(u.assoc_req.crypto));
-		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
 		BUG_ON(!drv->ops->assoc);
-		return drv->ops->assoc(wdev->wiphy, wdev->netdev,
-					&u.assoc_req);
+		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
+		err = cfg80211_mlme_assoc(drv, wdev->netdev,
+					  params->channel, params->bssid,
+					  params->ssid, params->ssid_len,
+					  params->ie, params->ie_len,
+					  false, &params->crypto);
+		if (err)
+			cfg80211_mlme_deauth(drv, wdev->netdev, params->bssid,
+					     NULL, 0, WLAN_REASON_DEAUTH_LEAVING);
+		return err;
 	default:
 		return 0;
 	}
@@ -186,7 +179,6 @@ static bool cfg80211_get_conn_bss(struct
 			       wdev->conn->params.ssid_len,
 			       WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
 			       capa);
-
 	if (!bss)
 		return false;
 
@@ -264,9 +256,11 @@ void cfg80211_sme_rx_auth(struct net_dev
 		}
 		wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
 		schedule_work(&rdev->conn_work);
-	} else if (status_code != WLAN_STATUS_SUCCESS)
+	} else if (status_code != WLAN_STATUS_SUCCESS) {
 		wdev->sme_state = CFG80211_SME_IDLE;
-	else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
+		kfree(wdev->conn);
+		wdev->conn = NULL;
+	} else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
 		 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
 		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
 		schedule_work(&rdev->conn_work);
@@ -330,10 +324,13 @@ static void __cfg80211_connect_result(st
 
 	if (wdev->current_bss) {
 		cfg80211_unhold_bss(wdev->current_bss);
-		cfg80211_put_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
 		wdev->current_bss = NULL;
 	}
 
+	if (wdev->conn)
+		wdev->conn->state = CFG80211_CONN_IDLE;
+
 	if (status == WLAN_STATUS_SUCCESS) {
 		bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
 				       wdev->ssid, wdev->ssid_len,
@@ -343,16 +340,15 @@ static void __cfg80211_connect_result(st
 		if (WARN_ON(!bss))
 			return;
 
-		cfg80211_hold_bss(bss);
-		wdev->current_bss = bss;
+		cfg80211_hold_bss(bss_from_pub(bss));
+		wdev->current_bss = bss_from_pub(bss);
 
 		wdev->sme_state = CFG80211_SME_CONNECTED;
 	} else {
 		wdev->sme_state = CFG80211_SME_IDLE;
+		kfree(wdev->conn);
+		wdev->conn = NULL;
 	}
-
-	if (wdev->conn)
-		wdev->conn->state = CFG80211_CONN_IDLE;
 }
 
 void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -387,7 +383,7 @@ void cfg80211_roamed(struct net_device *
 	}
 
 	cfg80211_unhold_bss(wdev->current_bss);
-	cfg80211_put_bss(wdev->current_bss);
+	cfg80211_put_bss(&wdev->current_bss->pub);
 	wdev->current_bss = NULL;
 
 	bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
@@ -397,8 +393,8 @@ void cfg80211_roamed(struct net_device *
 	if (WARN_ON(!bss))
 		return;
 
-	cfg80211_hold_bss(bss);
-	wdev->current_bss = bss;
+	cfg80211_hold_bss(bss_from_pub(bss));
+	wdev->current_bss = bss_from_pub(bss);
 
 	nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), dev, bssid,
 			    req_ie, req_ie_len, resp_ie, resp_ie_len, gfp);
@@ -440,7 +436,7 @@ void __cfg80211_disconnected(struct net_
 
 	if (wdev->current_bss) {
 		cfg80211_unhold_bss(wdev->current_bss);
-		cfg80211_put_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
 	}
 
 	wdev->current_bss = NULL;
@@ -449,6 +445,8 @@ void __cfg80211_disconnected(struct net_
 	if (wdev->conn) {
 		kfree(wdev->conn->ie);
 		wdev->conn->ie = NULL;
+		kfree(wdev->conn);
+		wdev->conn = NULL;
 	}
 
 	nl80211_send_disconnected(wiphy_to_dev(wdev->wiphy), dev,
@@ -482,12 +480,12 @@ int cfg80211_connect(struct cfg80211_reg
 		if (!rdev->ops->auth || !rdev->ops->assoc)
 			return -EOPNOTSUPP;
 
-		if (!wdev->conn) {
-			wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
-			if (!wdev->conn)
-				return -ENOMEM;
-		} else
-			memset(wdev->conn, 0, sizeof(*wdev->conn));
+		if (WARN_ON(wdev->conn))
+			return -EINPROGRESS;
+
+		wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
+		if (!wdev->conn)
+			return -ENOMEM;
 
 		/*
 		 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
@@ -502,8 +500,11 @@ int cfg80211_connect(struct cfg80211_reg
 			wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
 						GFP_KERNEL);
 			wdev->conn->params.ie = wdev->conn->ie;
-			if (!wdev->conn->ie)
+			if (!wdev->conn->ie) {
+				kfree(wdev->conn);
+				wdev->conn = NULL;
 				return -ENOMEM;
+			}
 		}
 
 		if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
@@ -543,8 +544,11 @@ int cfg80211_connect(struct cfg80211_reg
 				wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
 			}
 		}
-		if (err)
+		if (err) {
+			kfree(wdev->conn);
+			wdev->conn = NULL;
 			wdev->sme_state = CFG80211_SME_IDLE;
+		}
 
 		return err;
 	} else {
@@ -572,31 +576,27 @@ int cfg80211_disconnect(struct cfg80211_
 		return -EINVAL;
 
 	if (!rdev->ops->disconnect) {
-		struct cfg80211_deauth_request deauth;
-		u8 bssid[ETH_ALEN];
+		if (!rdev->ops->deauth)
+			return -EOPNOTSUPP;
 
-		/* internal bug. */
-		if (WARN_ON(!wdev->conn))
-			return -EINVAL;
+		/* was it connected by userspace SME? */
+		if (!wdev->conn) {
+			cfg80211_mlme_down(rdev, dev);
+			return 0;
+		}
 
 		if (wdev->sme_state == CFG80211_SME_CONNECTING &&
 		    (wdev->conn->state == CFG80211_CONN_SCANNING ||
 		     wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
 			wdev->sme_state = CFG80211_SME_IDLE;
+			kfree(wdev->conn);
+			wdev->conn = NULL;
 			return 0;
 		}
 
-		if (!rdev->ops->deauth)
-			return -EOPNOTSUPP;
-
-		memset(&deauth, 0, sizeof(deauth));
-
 		/* wdev->conn->params.bssid must be set if > SCANNING */
-		memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN);
-		deauth.peer_addr = bssid;
-		deauth.reason_code = reason;
-
-		err = rdev->ops->deauth(&rdev->wiphy, dev, &deauth);
+		err = cfg80211_mlme_deauth(rdev, dev, wdev->conn->params.bssid,
+					   NULL, 0, reason);
 		if (err)
 			return err;
 	} else {
@@ -614,3 +614,33 @@ int cfg80211_disconnect(struct cfg80211_
 
 	return 0;
 }
+
+void cfg80211_sme_disassoc(struct net_device *dev, int idx)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	u8 bssid[ETH_ALEN];
+
+	if (!wdev->conn)
+		return;
+
+	if (wdev->conn->state == CFG80211_CONN_IDLE)
+		return;
+
+	/*
+	 * Ok, so the association was made by this SME -- we don't
+	 * want it any more so deauthenticate too.
+	 */
+
+	if (!wdev->auth_bsses[idx])
+		return;
+
+	memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
+	if (cfg80211_mlme_deauth(rdev, dev, bssid,
+				 NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) {
+		/* whatever -- assume gone anyway */
+		cfg80211_unhold_bss(wdev->auth_bsses[idx]);
+		cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
+		wdev->auth_bsses[idx] = NULL;
+	}
+}
--- wireless-testing.orig/net/wireless/wext-sme.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/wext-sme.c	2009-07-02 17:17:11.000000000 +0200
@@ -93,7 +93,7 @@ int cfg80211_mgd_wext_giwfreq(struct net
 		return -EINVAL;
 
 	if (wdev->current_bss)
-		chan = wdev->current_bss->channel;
+		chan = wdev->current_bss->pub.channel;
 	else if (wdev->wext.connect.channel)
 		chan = wdev->wext.connect.channel;
 
@@ -244,7 +244,7 @@ int cfg80211_mgd_wext_giwap(struct net_d
 	ap_addr->sa_family = ARPHRD_ETHER;
 
 	if (wdev->current_bss)
-		memcpy(ap_addr->sa_data, wdev->current_bss->bssid, ETH_ALEN);
+		memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN);
 	else if (wdev->wext.connect.bssid)
 		memcpy(ap_addr->sa_data, wdev->wext.connect.bssid, ETH_ALEN);
 	else
--- wireless-testing.orig/net/mac80211/cfg.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-07-02 17:17:11.000000000 +0200
@@ -1173,6 +1173,7 @@ static int ieee80211_auth(struct wiphy *
 			  struct cfg80211_auth_request *req)
 {
 	struct ieee80211_sub_if_data *sdata;
+	const u8 *ssid;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
@@ -1193,15 +1194,16 @@ static int ieee80211_auth(struct wiphy *
 		return -EOPNOTSUPP;
 	}
 
-	memcpy(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN);
+	memcpy(sdata->u.mgd.bssid, req->bss->bssid, ETH_ALEN);
 
-	sdata->local->oper_channel = req->chan;
+	sdata->local->oper_channel = req->bss->channel;
 	ieee80211_hw_config(sdata->local, 0);
 
-	if (!req->ssid)
+	ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
+	if (!ssid)
 		return -EINVAL;
-	memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
-	sdata->u.mgd.ssid_len = req->ssid_len;
+	sdata->u.mgd.ssid_len = *(ssid + 1);
+	memcpy(sdata->u.mgd.ssid, ssid + 2, sdata->u.mgd.ssid_len);
 
 	kfree(sdata->u.mgd.sme_auth_ie);
 	sdata->u.mgd.sme_auth_ie = NULL;
@@ -1227,7 +1229,7 @@ static int ieee80211_assoc(struct wiphy 
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-	if (memcmp(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN) != 0 ||
+	if (memcmp(sdata->u.mgd.bssid, req->bss->bssid, ETH_ALEN) != 0 ||
 	    !(sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED))
 		return -ENOLINK; /* not authenticated */
 
@@ -1239,15 +1241,9 @@ static int ieee80211_assoc(struct wiphy 
 		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
 			sdata->u.mgd.flags |= IEEE80211_STA_DISABLE_11N;
 
-	sdata->local->oper_channel = req->chan;
+	sdata->local->oper_channel = req->bss->channel;
 	ieee80211_hw_config(sdata->local, 0);
 
-	if (!req->ssid)
-		return -EINVAL;
-
-	memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
-	sdata->u.mgd.ssid_len = req->ssid_len;
-
 	ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
 	if (ret && ret != -EALREADY)
 		return ret;
--- wireless-testing.orig/net/mac80211/mlme.c	2009-07-02 17:16:57.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-07-02 17:17:11.000000000 +0200
@@ -876,8 +876,6 @@ static void ieee80211_set_associated(str
 		bss_info_changed |= ieee80211_handle_bss_capability(sdata,
 			bss->cbss.capability, bss->has_erp_value, bss->erp_value);
 
-		cfg80211_hold_bss(&bss->cbss);
-
 		ieee80211_rx_bss_put(local, bss);
 	}
 
@@ -1031,10 +1029,8 @@ static void ieee80211_set_disassoc(struc
 				   conf->channel->center_freq,
 				   ifmgd->ssid, ifmgd->ssid_len);
 
-	if (bss) {
-		cfg80211_unhold_bss(&bss->cbss);
+	if (bss)
 		ieee80211_rx_bss_put(local, bss);
-	}
 
 	if (self_disconnected) {
 		if (deauth)
--- wireless-testing.orig/net/wireless/core.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-02 17:17:11.000000000 +0200
@@ -583,15 +583,12 @@ static int cfg80211_netdev_notifier_call
 #endif
 			cfg80211_disconnect(rdev, dev,
 					    WLAN_REASON_DEAUTH_LEAVING, true);
+			cfg80211_mlme_down(rdev, dev);
 			break;
 		default:
 			break;
 		}
 		break;
-	case NETDEV_DOWN:
-		kfree(wdev->conn);
-		wdev->conn = NULL;
-		break;
 	case NETDEV_UP:
 #ifdef CONFIG_WIRELESS_EXT
 		switch (wdev->iftype) {



^ permalink raw reply

* [PATCH] cfg80211: assimilate and export ieee80211_bss_get_ie
From: Johannes Berg @ 2009-07-02 15:18 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

This function from mac80211 seems generally useful, and
I will need it in cfg80211 soon.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h |    9 +++++++++
 net/mac80211/mlme.c    |   25 +++----------------------
 net/wireless/util.c    |   21 +++++++++++++++++++++
 3 files changed, 33 insertions(+), 22 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-07-02 17:13:49.000000000 +0200
@@ -605,6 +605,15 @@ struct cfg80211_bss {
 };
 
 /**
+ * ieee80211_bss_get_ie - find IE with given ID
+ * @bss: the bss to search
+ * @ie: the IE ID
+ * Returns %NULL if not found.
+ */
+const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
+
+
+/**
  * struct cfg80211_crypto_settings - Crypto settings
  * @wpa_versions: indicates which, if any, WPA versions are enabled
  *	(from enum nl80211_wpa_versions)
--- wireless-testing.orig/net/mac80211/mlme.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-07-02 17:16:57.000000000 +0200
@@ -46,26 +46,6 @@ static int ecw2cw(int ecw)
 	return (1 << ecw) - 1;
 }
 
-static u8 *ieee80211_bss_get_ie(struct ieee80211_bss *bss, u8 ie)
-{
-	u8 *end, *pos;
-
-	pos = bss->cbss.information_elements;
-	if (pos == NULL)
-		return NULL;
-	end = pos + bss->cbss.len_information_elements;
-
-	while (pos + 1 < end) {
-		if (pos + 2 + pos[1] > end)
-			break;
-		if (pos[0] == ie)
-			return pos;
-		pos += 2 + pos[1];
-	}
-
-	return NULL;
-}
-
 static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
 				      struct ieee80211_supported_band *sband,
 				      u32 *rates)
@@ -181,7 +161,8 @@ static void ieee80211_send_assoc(struct 
 	struct ieee80211_local *local = sdata->local;
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
-	u8 *pos, *ies, *ht_ie;
+	u8 *pos;
+	const u8 *ies, *ht_ie;
 	int i, len, count, rates_len, supp_rates_len;
 	u16 capab;
 	struct ieee80211_bss *bss;
@@ -345,7 +326,7 @@ static void ieee80211_send_assoc(struct 
 	 */
 	if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
 	    sband->ht_cap.ht_supported &&
-	    (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) &&
+	    (ht_ie = ieee80211_bss_get_ie(&bss->cbss, WLAN_EID_HT_INFORMATION)) &&
 	    ht_ie[1] >= sizeof(struct ieee80211_ht_info) &&
 	    (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) {
 		struct ieee80211_ht_info *ht_info =
--- wireless-testing.orig/net/wireless/util.c	2009-07-02 17:13:46.000000000 +0200
+++ wireless-testing/net/wireless/util.c	2009-07-02 17:13:49.000000000 +0200
@@ -502,3 +502,24 @@ unsigned int cfg80211_classify8021d(stru
 	return dscp >> 5;
 }
 EXPORT_SYMBOL(cfg80211_classify8021d);
+
+const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie)
+{
+	u8 *end, *pos;
+
+	pos = bss->information_elements;
+	if (pos == NULL)
+		return NULL;
+	end = pos + bss->len_information_elements;
+
+	while (pos + 1 < end) {
+		if (pos + 2 + pos[1] > end)
+			break;
+		if (pos[0] == ie)
+			return pos;
+		pos += 2 + pos[1];
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(ieee80211_bss_get_ie);



^ permalink raw reply

* Re: [PATCH hostap/wpa_supplicant] Allow wpa_supplicant to use libnl-2.0
From: Jon Loeliger @ 2009-07-02 15:09 UTC (permalink / raw)
  To: Dan Williams; +Cc: jouni.malinen, linux-wireless@vger.kernel.org
In-Reply-To: <1246537755.16543.1.camel@localhost.localdomain>

On Thu, 2009-07-02 at 08:29 -0400, Dan Williams wrote:
> On Wed, 2009-07-01 at 15:59 -0500, Jon Loeliger wrote:
> > Introduce CONFIG_LIBNL20 .config parameter and propogate
> > that as a CFLAG in the Makefile.
> > 
> > Add forward-compatibility code to allow the existing code
> > to also use libnl-2.0.
> > 
> > Signed-off-by: Jon Loeliger <jdl@bigfootnetworks.com>
> 
> You might actually want to post this to the hostap/wpa_supplicant
> mailing list instead.  While developers involved in both projects are
> subscribed to both lists, linux-wireless isn't the right place for
> patches against hostap and wpa_supplicant.
> 
> http://lists.shmoo.com/mailman/listinfo/hostap
> 
> Dan

Argh.  Done.  Thanks.

jdl



^ permalink raw reply

* Re: 4311 not detected at all
From: Larry Finger @ 2009-07-02 14:21 UTC (permalink / raw)
  To: Fabio A. Correa; +Cc: wireless
In-Reply-To: <ec2083b20907020617q689f9672h383bb853ba6019d0@mail.gmail.com>

Fabio A. Correa wrote:
> Hello All,
> 
> I recompiled the Linux kernel with ssb, phy and b43 as modules. I made
> sure those modules were loaded after login, and now the b43 driver
> properly detects the card. It seems the phy driver is not needed.
> 
> Now I have the problem that the card does not scan, and it does not
> associate to any AP.

AFAIK, the phy driver is for wired devices. Have you installed the
firmware? Please look at the output of the command

dmesg | egrep "ssb|b43|wlan0"

The other kernel modules that are needed are mac80211 and friends;
however, the Kconfig rules should ensure that mac80211 is built before
you can actually build b43.

BTW, your mailer is misconfigured. the "To:" header field is wrong,
which prevents an automatic "reply to".

^ permalink raw reply

* [PATCH] cfg80211: reset auth algorithm
From: Johannes Berg @ 2009-07-02 13:49 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

When the interface is brought down, we need to
reset the auth algorithm because wpa_supplicant
doesn't reset it, and then we fail to use shared
key auth when required later.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/core.c |    1 +
 1 file changed, 1 insertion(+)

--- wireless-testing.orig/net/wireless/core.c	2009-07-02 15:47:06.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-02 15:47:52.000000000 +0200
@@ -579,6 +579,7 @@ static int cfg80211_netdev_notifier_call
 			kfree(wdev->wext.ie);
 			wdev->wext.ie = NULL;
 			wdev->wext.ie_len = 0;
+			wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
 #endif
 			cfg80211_disconnect(rdev, dev,
 					    WLAN_REASON_DEAUTH_LEAVING, true);



^ permalink raw reply

* [PATCH 2.6.31] cfg80211: fix refcount leak
From: Johannes Berg @ 2009-07-02 13:46 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

The code in cfg80211's cfg80211_bss_update erroneously
grabs a reference to the BSS, which means that it will
never be freed.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: stable@kernel.org [2.6.29, 2.6.30]
---
 net/wireless/scan.c |    1 -
 1 file changed, 1 deletion(-)

--- wireless-testing.orig/net/wireless/scan.c	2009-07-02 15:32:12.000000000 +0200
+++ wireless-testing/net/wireless/scan.c	2009-07-02 15:39:23.000000000 +0200
@@ -376,7 +376,6 @@ cfg80211_bss_update(struct cfg80211_regi
 	found = rb_find_bss(dev, res);
 
 	if (found) {
-		kref_get(&found->ref);
 		found->pub.beacon_interval = res->pub.beacon_interval;
 		found->pub.tsf = res->pub.tsf;
 		found->pub.signal = res->pub.signal;



^ permalink raw reply

* Re: 4311 not detected at all
From: Fabio A. Correa @ 2009-07-02 13:17 UTC (permalink / raw)

In-Reply-To: <ec2083b20906171932g401fab8fk15531459e1dc4d41@mail.gmail.com>

Hello All,

I recompiled the Linux kernel with ssb, phy and b43 as modules. I made
sure those modules were loaded after login, and now the b43 driver
properly detects the card. It seems the phy driver is not needed.

Now I have the problem that the card does not scan, and it does not
associate to any AP.

-- 
Fabio Andrés Correa Durán
http://facorread.150m.com

^ permalink raw reply

* Re: Build error in 2.6.31-rc1-wl
From: John W. Linville @ 2009-07-02 12:47 UTC (permalink / raw)
  To: Larry Finger; +Cc: Johannes Berg, wireless
In-Reply-To: <4A4BCA87.8020805@lwfinger.net>

On Wed, Jul 01, 2009 at 03:43:51PM -0500, Larry Finger wrote:
> When building the above kernel based on a fress pull of
> wireless-testing, I get the following build error:
> 
>   CC      net/core/skbuff.o
> net/core/skbuff.c: In function ‘__copy_skb_header’:
> net/core/skbuff.c:563: error: ‘struct sk_buff’ has no member named
> ‘do_not_encrypt’
> net/core/skbuff.c:563: error: ‘const struct sk_buff’ has no member
> named ‘do_not_encrypt’
> make[2]: *** [net/core/skbuff.o] Error 1
> 
> The code that errors is
> 
>         new->vlan_tci           = old->vlan_tci;
> #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
>         new->do_not_encrypt     = old->do_not_encrypt;
> #endif
> 
>         skb_copy_secmark(new, old);
> }

Some patch damage when moving to 2.6.31-rc1.  Johannes sent me a
fix-up yesterday, so I have folded it back into the damaged patch
and pushed it out.

Thanks,

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.
			¡Viva Honduras Libre!

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Dan Williams @ 2009-07-02 12:44 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Marcel Holtmann, Greg KH, Luis R. Rodriguez, John W. Linville,
	Dave, Karl Relton, dwmw2, linux-wireless
In-Reply-To: <200907021307.17719.bzolnier@gmail.com>

On Thu, 2009-07-02 at 13:07 +0200, Bartlomiej Zolnierkiewicz wrote:
> Hi,
> 
> On Thursday 02 July 2009 00:18:49 Marcel Holtmann wrote:
> > Hi Greg,
> > 
> > > > > >> > That's really all I
> > > > > >> > care about, I don't want another WEXT-based driver accepted; I want all
> > > > > >> > the new ones using cfg80211.
> > > > > >>
> > > > > >> Now there is a discussion we should have had in Berlin...is it time
> > > > > >> to insist on cfg80211-based configuration for all new drivers?
> > > > > >
> > > > > > there is really nothing much to discuss on this topic. The plan is to
> > > > > > deprecate WEXT, that simple. So if the driver has no cfg80211 support,
> > > > > > then it will not be included. Period.
> > > > > >
> > > > > > Send such drivers off to staging and let them have their 6 month.  Then
> > > > > > we either remove them again or they got ported to cfg80211.
> > > > > 
> > > > > 6 months only in staging ? Is this a rule now for staging?
> > > > 
> > > > that is what Greg mentioned to me. If there is no activity for 6 month
> > > > and the driver is not getting anywhere, he going to drop it.
> > > 
> > > That is "within reason".  If a driver is still needed there, I'l
> > > probably keep it, and will take each one on a case-by-case basis.
> > 
> > what do you mean "within reason". If the driver is just sitting there
> > and no effort in making in upstream ready it is doing clearly more harm
> > than any good. And I am not talking about removing some kernel version
> > details or typedefs or coding style. Drivers with missing cfg80211 need
> 
> Well, most of those drivers need a major cleanup before porting..	
> 
> > active porting. And it is not that hard. See the orinoco one for an
> > example.
> 
> Could you please provide some more pointers here, I don't see any such
> changes in linux-next yet and I'm very interested in seeing a practical
> example of such conversion (thanks!).

http://osdir.com/ml/linux-wireless/2009-06/msg01141.html

It's not in -next, it's in wireless-testing, which gets dumped to next
periodically.  Wireless stuff happens first in wireless-testing, of
course.

> > If we see developers committed to fixing it that is a different story,
> > but a lot of drivers in staging are getting no attention all. So they
> > are fully pointless and are not doing any good for Linux. We need to
> > send the vendors a clear message that code drops of their crappy Windows
> > code are not desired.
> 
> How's about sending a clear _positive_ message for a change?
> 
> Where one can find an up to date documentation for {mac,cfg,nl}80211 (not
> just some random DocBook generated excerpts, I mean the real thing here,
> with references to kernel versions when API changes were introduced, some
> practical examples and exemplary drivers) and more importantly when one
> can find the _porting_ guide for the older stacks?

Johannes has done an much-better-than-average job of documenting
cfg80211 and nl80211, which is more than I can say for many other
subsystems.

Dan


^ permalink raw reply

* Re: [PATCH hostap/wpa_supplicant] Allow wpa_supplicant to use libnl-2.0
From: Dan Williams @ 2009-07-02 12:29 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: jouni.malinen, linux-wireless@vger.kernel.org
In-Reply-To: <1246481949.11632.36.camel@jdl-desktop>

On Wed, 2009-07-01 at 15:59 -0500, Jon Loeliger wrote:
> Introduce CONFIG_LIBNL20 .config parameter and propogate
> that as a CFLAG in the Makefile.
> 
> Add forward-compatibility code to allow the existing code
> to also use libnl-2.0.
> 
> Signed-off-by: Jon Loeliger <jdl@bigfootnetworks.com>

You might actually want to post this to the hostap/wpa_supplicant
mailing list instead.  While developers involved in both projects are
subscribed to both lists, linux-wireless isn't the right place for
patches against hostap and wpa_supplicant.

http://lists.shmoo.com/mailman/listinfo/hostap

Dan

> ---
> 
> This patch applies to:
>     git://w1.fi/srv/git/hostap-06.git
>     fa4e296f542af01da135d997358d6d45a32dd59e
> 
> Also, I suspect that this define:
> 
>     +#define nl_handle nl_sock
> 
> may need to be added to the hostapd side as well, but
> I'm not using that and haven't investigated or tested that.
> 
> jdl
> 
> 
>  src/drivers/driver_nl80211.c |   17 +++++++++++++++++
>  wpa_supplicant/Makefile      |    4 ++++
>  2 files changed, 21 insertions(+), 0 deletions(-)
> 
> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
> index a7b351a..66288f6 100644
> --- a/src/drivers/driver_nl80211.c
> +++ b/src/drivers/driver_nl80211.c
> @@ -47,6 +47,15 @@
>  #endif
>  
> 
> +#ifdef CONFIG_LIBNL20
> +/* libnl 2.0 compatibility code */
> +
> +#define nl_handle nl_sock
> +#define nl_handle_alloc_cb nl_socket_alloc_cb
> +#define nl_handle_destroy nl_socket_free
> +#endif /* CONFIG_LIBNL20 */
> +
> +
>  struct wpa_driver_nl80211_data {
>  	void *ctx;
>  	int wext_event_sock;
> @@ -1441,12 +1450,20 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
>  		goto err3;
>  	}
>  
> +#ifdef CONFIG_LIBNL20
> +	if (genl_ctrl_alloc_cache(drv->nl_handle, &drv->nl_cache) < 0) {
> +	    wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
> +			   "netlink cache");
> +		goto err3;
> +	}
> +#else
>  	drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);
>  	if (drv->nl_cache == NULL) {
>  		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
>  			   "netlink cache");
>  		goto err3;
>  	}
> +#endif
>  
>  	drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");
>  	if (drv->nl80211 == NULL) {
> diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
> index 45d6ada..fa43a0c 100644
> --- a/wpa_supplicant/Makefile
> +++ b/wpa_supplicant/Makefile
> @@ -135,6 +135,10 @@ ifdef CONFIG_DRIVER_NL80211
>  CFLAGS += -DCONFIG_DRIVER_NL80211
>  OBJS_d += ../src/drivers/driver_nl80211.o
>  LIBS += -lnl
> +ifdef CONFIG_LIBNL20
> +LIBS += -lnl-genl
> +CFLAGS += -DCONFIG_LIBNL20
> +endif
>  ifdef CONFIG_CLIENT_MLME
>  OBJS_d += ../src/drivers/radiotap.o
>  endif


^ permalink raw reply

* Re: [PATCH 8/8 v3.1] mac80211: re-add HT disabling
From: Johannes Berg @ 2009-07-02 11:56 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: Vasanthakumar Thiagarajan, Vasanth Thiagarajan,
	linux-wireless@vger.kernel.org, Jouni Malinen
In-Reply-To: <20090702114316.GA12652@jm.kir.nu>

[-- Attachment #1: Type: text/plain, Size: 568 bytes --]

On Thu, 2009-07-02 at 14:43 +0300, Jouni Malinen wrote:
> On Thu, Jul 02, 2009 at 11:53:17AM +0200, Johannes Berg wrote:
> 
> > So we have to support multiple for connect() to allow the card/driver to
> > choose, but a single one for associate()?
> 
> Sounds reasonable.. Many drivers might not be able to handle multiple
> options for connect(), though, so even with that, it may be reasonable
> to just pass in a single option.

That's something the driver would have to refuse then, I guess.

I'll send a patch to limit it to 1 for assoc()

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [PATCH 8/8 v3.1] mac80211: re-add HT disabling
From: Jouni Malinen @ 2009-07-02 11:43 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Vasanthakumar Thiagarajan, Vasanth Thiagarajan,
	linux-wireless@vger.kernel.org, Jouni Malinen
In-Reply-To: <1246528397.16770.31.camel@johannes.local>

On Thu, Jul 02, 2009 at 11:53:17AM +0200, Johannes Berg wrote:

> So we have to support multiple for connect() to allow the card/driver to
> choose, but a single one for associate()?

Sounds reasonable.. Many drivers might not be able to handle multiple
options for connect(), though, so even with that, it may be reasonable
to just pass in a single option. Anyway, it would be nice if the
multiple options case could be supported.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Bartlomiej Zolnierkiewicz @ 2009-07-02 11:07 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Greg KH, Luis R. Rodriguez, John W. Linville, Dan Williams, Dave,
	Karl Relton, dwmw2, linux-wireless
In-Reply-To: <1246486729.12994.176.camel@localhost.localdomain>


Hi,

On Thursday 02 July 2009 00:18:49 Marcel Holtmann wrote:
> Hi Greg,
> 
> > > > >> > That's really all I
> > > > >> > care about, I don't want another WEXT-based driver accepted; I want all
> > > > >> > the new ones using cfg80211.
> > > > >>
> > > > >> Now there is a discussion we should have had in Berlin...is it time
> > > > >> to insist on cfg80211-based configuration for all new drivers?
> > > > >
> > > > > there is really nothing much to discuss on this topic. The plan is to
> > > > > deprecate WEXT, that simple. So if the driver has no cfg80211 support,
> > > > > then it will not be included. Period.
> > > > >
> > > > > Send such drivers off to staging and let them have their 6 month.  Then
> > > > > we either remove them again or they got ported to cfg80211.
> > > > 
> > > > 6 months only in staging ? Is this a rule now for staging?
> > > 
> > > that is what Greg mentioned to me. If there is no activity for 6 month
> > > and the driver is not getting anywhere, he going to drop it.
> > 
> > That is "within reason".  If a driver is still needed there, I'l
> > probably keep it, and will take each one on a case-by-case basis.
> 
> what do you mean "within reason". If the driver is just sitting there
> and no effort in making in upstream ready it is doing clearly more harm
> than any good. And I am not talking about removing some kernel version
> details or typedefs or coding style. Drivers with missing cfg80211 need

Well, most of those drivers need a major cleanup before porting..	

> active porting. And it is not that hard. See the orinoco one for an
> example.

Could you please provide some more pointers here, I don't see any such
changes in linux-next yet and I'm very interested in seeing a practical
example of such conversion (thanks!).

> If we see developers committed to fixing it that is a different story,
> but a lot of drivers in staging are getting no attention all. So they
> are fully pointless and are not doing any good for Linux. We need to
> send the vendors a clear message that code drops of their crappy Windows
> code are not desired.

How's about sending a clear _positive_ message for a change?

Where one can find an up to date documentation for {mac,cfg,nl}80211 (not
just some random DocBook generated excerpts, I mean the real thing here,
with references to kernel versions when API changes were introduced, some
practical examples and exemplary drivers) and more importantly when one
can find the _porting_ guide for the older stacks?

Thanks,
Bart

^ permalink raw reply

* Re: [PATCH 8/8 v3.1] mac80211: re-add HT disabling
From: Johannes Berg @ 2009-07-02  9:53 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: Vasanthakumar Thiagarajan, Vasanth Thiagarajan,
	linux-wireless@vger.kernel.org, Jouni Malinen
In-Reply-To: <20090702095134.GA11235@jm.kir.nu>

[-- Attachment #1: Type: text/plain, Size: 1116 bytes --]

On Thu, 2009-07-02 at 12:51 +0300, Jouni Malinen wrote:
> On Wed, Jul 01, 2009 at 12:42:39PM +0200, Johannes Berg wrote:
> > On Wed, 2009-07-01 at 15:43 +0530, Vasanthakumar Thiagarajan wrote:
> > > On Wed, Jul 01, 2009 at 01:09:16PM +0530, Johannes Berg wrote:
> > > > @@ -1236,6 +1236,14 @@ static int ieee80211_assoc(struct wiphy
> > > > +       for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
> > > > +               if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
> 
> > > for..loop does not seem to be necessary here as it is very unlikely that
> > > an assoc req will have more than one cipher suite.
> 
> > True, but so far we've defined the API that way. Should we redefine the
> > API? I keep forgetting what is valid where. Jouni?
> 
> The (re)association request is only allowed to list one pairwise cipher
> suite (see IEEE 802.11, 8.4.3). Various other use cases for RSN IE
> support multiple cipher suites, but this one does not.

So we have to support multiple for connect() to allow the card/driver to
choose, but a single one for associate()?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [PATCH 8/8 v3.1] mac80211: re-add HT disabling
From: Jouni Malinen @ 2009-07-02  9:51 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Vasanthakumar Thiagarajan, Vasanth Thiagarajan,
	linux-wireless@vger.kernel.org, Jouni Malinen
In-Reply-To: <1246444959.4131.15.camel@johannes.local>

On Wed, Jul 01, 2009 at 12:42:39PM +0200, Johannes Berg wrote:
> On Wed, 2009-07-01 at 15:43 +0530, Vasanthakumar Thiagarajan wrote:
> > On Wed, Jul 01, 2009 at 01:09:16PM +0530, Johannes Berg wrote:
> > > @@ -1236,6 +1236,14 @@ static int ieee80211_assoc(struct wiphy
> > > +       for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
> > > +               if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||

> > for..loop does not seem to be necessary here as it is very unlikely that
> > an assoc req will have more than one cipher suite.

> True, but so far we've defined the API that way. Should we redefine the
> API? I keep forgetting what is valid where. Jouni?

The (re)association request is only allowed to list one pairwise cipher
suite (see IEEE 802.11, 8.4.3). Various other use cases for RSN IE
support multiple cipher suites, but this one does not.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Christoph Hellwig @ 2009-07-02  9:19 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Luis R. Rodriguez, Greg KH, John W. Linville, Dan Williams, Dave,
	Karl Relton, dwmw2, linux-wireless
In-Reply-To: <1246486104.12994.169.camel@localhost.localdomain>

On Wed, Jul 01, 2009 at 03:08:24PM -0700, Marcel Holtmann wrote:
> that is what Greg mentioned to me. If there is no activity for 6 month
> and the driver is not getting anywhere, he going to drop it.

If that were true and not just an excuse the whole initial batch and a
couple of later drivers would be gone now.


^ permalink raw reply


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).