linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] cfg80211 fixes, cleanups, improvements
@ 2009-07-07  1:56 Johannes Berg
  2009-07-07  1:56 ` [PATCH 1/9] cfg80211: fix netdev down problem Johannes Berg
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

This has a whole bunch of cfg80211 fixes, most
notably work to actually do locking in cfg80211
properly! Sorry, my head was too small to grasp
all of that in cfg80211 at once, so I deferred
locking for the connect() API to this series.

johannes


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/9] cfg80211: fix netdev down problem
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 2/9] cfg80211: dont use union for wext Johannes Berg
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

We shouldn't be looking at the ssid_len for non-IBSS,
and for IBSS we should also return an error on trying
to leave an IBSS while not in or joining an IBSS.

This fixes an issue where we wouldn't disconnect() on
an interface being taken down since there's no SSID
configured this way.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/core.c |    3 ---
 net/wireless/ibss.c |    4 ++++
 2 files changed, 4 insertions(+), 3 deletions(-)

--- wireless-testing.orig/net/wireless/core.c	2009-07-07 03:29:39.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-07 03:37:03.000000000 +0200
@@ -567,9 +567,6 @@ static int cfg80211_netdev_notifier_call
 #endif
 		break;
 	case NETDEV_GOING_DOWN:
-		if (!wdev->ssid_len)
-			break;
-
 		switch (wdev->iftype) {
 		case NL80211_IFTYPE_ADHOC:
 			cfg80211_leave_ibss(rdev, dev, true);
--- wireless-testing.orig/net/wireless/ibss.c	2009-07-07 03:29:39.000000000 +0200
+++ wireless-testing/net/wireless/ibss.c	2009-07-07 03:37:03.000000000 +0200
@@ -92,8 +92,12 @@ void cfg80211_clear_ibss(struct net_devi
 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, bool nowext)
 {
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
+	if (!wdev->ssid_len)
+		return -ENOLINK;
+
 	err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
 
 	if (err)

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/9] cfg80211: dont use union for wext
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
  2009-07-07  1:56 ` [PATCH 1/9] cfg80211: fix netdev down problem Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 3/9] cfg80211: mlme API must be able to sleep Johannes Berg
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Otherwise it becomes very hard to reset the structs
correctly since wext can be configured while the
interface is down.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-07-07 03:36:58.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-07-07 03:37:04.000000000 +0200
@@ -1270,10 +1270,8 @@ struct wireless_dev {
 #ifdef CONFIG_WIRELESS_EXT
 	/* wext data */
 	struct {
-		union {
-			struct cfg80211_ibss_params ibss;
-			struct cfg80211_connect_params connect;
-		};
+		struct cfg80211_ibss_params ibss;
+		struct cfg80211_connect_params connect;
 		u8 *ie;
 		size_t ie_len;
 		u8 bssid[ETH_ALEN];

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/9] cfg80211: mlme API must be able to sleep
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
  2009-07-07  1:56 ` [PATCH 1/9] cfg80211: fix netdev down problem Johannes Berg
  2009-07-07  1:56 ` [PATCH 2/9] cfg80211: dont use union for wext Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 4/9] cfg80211: warn again on spurious deauth Johannes Berg
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

After the mac80211 mlme cleanup, we can require that
the MLME functions in cfg80211 can sleep. This will
simplify future work in cfg80211 a lot.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h |   30 +++++++++++++---------------
 net/mac80211/mlme.c    |   26 ++++++++----------------
 net/wireless/mlme.c    |   51 +++++++++++++++++++++++++++++++------------------
 3 files changed, 56 insertions(+), 51 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-07-07 03:37:04.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-07-07 03:37:04.000000000 +0200
@@ -1721,70 +1721,68 @@ void cfg80211_unlink_bss(struct wiphy *w
  * @dev: network device
  * @buf: authentication frame (header + body)
  * @len: length of the frame data
- * @gfp: allocation flags
  *
  * This function is called whenever an authentication has been processed in
  * station mode. The driver is required to call either this function or
  * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
- * call.
+ * call. This function may sleep.
  */
-void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
+void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
 
 /**
  * cfg80211_send_auth_timeout - notification of timed out authentication
  * @dev: network device
  * @addr: The MAC address of the device with which the authentication timed out
- * @gfp: allocation flags
+ *
+ * This function may sleep.
  */
-void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp);
+void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
 
 /**
  * cfg80211_send_rx_assoc - notification of processed association
  * @dev: network device
  * @buf: (re)association response frame (header + body)
  * @len: length of the frame data
- * @gfp: allocation flags
  *
  * This function is called whenever a (re)association response has been
  * processed in station mode. The driver is required to call either this
  * function or cfg80211_send_assoc_timeout() to indicate the result of
- * cfg80211_ops::assoc() call.
+ * cfg80211_ops::assoc() call. This function may sleep.
  */
-void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
+void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
 
 /**
  * cfg80211_send_assoc_timeout - notification of timed out association
  * @dev: network device
  * @addr: The MAC address of the device with which the association timed out
- * @gfp: allocation flags
+ *
+ * This function may sleep.
  */
-void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp);
+void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
 
 /**
  * cfg80211_send_deauth - notification of processed deauthentication
  * @dev: network device
  * @buf: deauthentication frame (header + body)
  * @len: length of the frame data
- * @gfp: allocation flags
  *
  * This function is called whenever deauthentication has been processed in
  * station mode. This includes both received deauthentication frames and
- * locally generated ones.
+ * locally generated ones. This function may sleep.
  */
-void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
 
 /**
  * cfg80211_send_disassoc - notification of processed disassociation
  * @dev: network device
  * @buf: disassociation response frame (header + body)
  * @len: length of the frame data
- * @gfp: allocation flags
  *
  * This function is called whenever disassociation has been processed in
  * station mode. This includes both received disassociation frames and locally
- * generated ones.
+ * generated ones. This function may sleep.
  */
-void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);
 
 /**
  * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
--- wireless-testing.orig/net/wireless/mlme.c	2009-07-07 03:36:58.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2009-07-07 03:37:04.000000000 +0200
@@ -12,7 +12,7 @@
 #include "core.h"
 #include "nl80211.h"
 
-void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
+void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -23,6 +23,8 @@ void cfg80211_send_rx_auth(struct net_de
 	u16 status = le16_to_cpu(mgmt->u.auth.status_code);
 	bool done = false;
 
+	might_sleep();
+
 	for (i = 0; i < MAX_AUTH_BSSES; i++) {
 		if (wdev->authtry_bsses[i] &&
 		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
@@ -41,12 +43,12 @@ void cfg80211_send_rx_auth(struct net_de
 
 	WARN_ON(!done);
 
-	nl80211_send_rx_auth(rdev, dev, buf, len, gfp);
+	nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
 	cfg80211_sme_rx_auth(dev, buf, len);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_auth);
 
-void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
+void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 {
 	u16 status_code;
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -57,12 +59,14 @@ void cfg80211_send_rx_assoc(struct net_d
 	int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
 	bool done;
 
+	might_sleep();
+
 	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 
-	nl80211_send_rx_assoc(rdev, dev, buf, len, gfp);
+	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
 
 	cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
-				status_code, gfp);
+				status_code, GFP_KERNEL);
 
 	if (status_code == WLAN_STATUS_SUCCESS) {
 		for (i = 0; wdev->current_bss && i < MAX_AUTH_BSSES; i++) {
@@ -80,7 +84,7 @@ void cfg80211_send_rx_assoc(struct net_d
 }
 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
 
-void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -90,7 +94,9 @@ void cfg80211_send_deauth(struct net_dev
 	int i;
 	bool done = false;
 
-	nl80211_send_deauth(rdev, dev, buf, len, gfp);
+	might_sleep();
+
+	nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
 
 	if (wdev->current_bss &&
 	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
@@ -132,16 +138,17 @@ void cfg80211_send_deauth(struct net_dev
 		reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 
 		from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
-		__cfg80211_disconnected(dev, gfp, NULL, 0,
+		__cfg80211_disconnected(dev, GFP_KERNEL, NULL, 0,
 					reason_code, from_ap);
 	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
 		cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
-					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					GFP_KERNEL);
 	}
 }
 EXPORT_SYMBOL(cfg80211_send_deauth);
 
-void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -153,7 +160,9 @@ void cfg80211_send_disassoc(struct net_d
 	bool from_ap;
 	bool done = false;
 
-	nl80211_send_disassoc(rdev, dev, buf, len, gfp);
+	might_sleep();
+
+	nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
 
 	if (!wdev->sme_state == CFG80211_SME_CONNECTED)
 		return;
@@ -177,12 +186,12 @@ void cfg80211_send_disassoc(struct net_d
 	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,
+	__cfg80211_disconnected(dev, GFP_KERNEL, NULL, 0,
 				reason_code, from_ap);
 }
 EXPORT_SYMBOL(cfg80211_send_disassoc);
 
-void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
+void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -190,10 +199,13 @@ void cfg80211_send_auth_timeout(struct n
 	int i;
 	bool done = false;
 
-	nl80211_send_auth_timeout(rdev, dev, addr, gfp);
+	might_sleep();
+
+	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
 		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
-					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					GFP_KERNEL);
 
 	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
 		if (wdev->authtry_bsses[i] &&
@@ -211,7 +223,7 @@ void cfg80211_send_auth_timeout(struct n
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 
-void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
+void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -219,10 +231,13 @@ void cfg80211_send_assoc_timeout(struct 
 	int i;
 	bool done = false;
 
-	nl80211_send_assoc_timeout(rdev, dev, addr, gfp);
+	might_sleep();
+
+	nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
 		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
-					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					GFP_KERNEL);
 
 	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
 		if (wdev->auth_bsses[i] &&
--- wireless-testing.orig/net/mac80211/mlme.c	2009-07-07 03:37:03.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-07-07 03:37:04.000000000 +0200
@@ -412,11 +412,9 @@ static void ieee80211_send_deauth_disass
 	mgmt->u.deauth.reason_code = cpu_to_le16(reason);
 
 	if (stype == IEEE80211_STYPE_DEAUTH)
-		cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len,
-				     GFP_KERNEL);
+		cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
 	else
-		cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len,
-				       GFP_KERNEL);
+		cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
 	ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
 }
 
@@ -1839,12 +1837,10 @@ static void ieee80211_sta_rx_queued_mgmt
 			/* no action */
 			break;
 		case RX_MGMT_CFG80211_DEAUTH:
-			cfg80211_send_deauth(sdata->dev, (u8 *) mgmt,
-					     skb->len, GFP_KERNEL);
+			cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
 			break;
 		case RX_MGMT_CFG80211_DISASSOC:
-			cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt,
-					       skb->len, GFP_KERNEL);
+			cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
 			break;
 		default:
 			WARN(1, "unexpected: %d", rma);
@@ -1893,12 +1889,10 @@ static void ieee80211_sta_rx_queued_mgmt
 		/* no action */
 		break;
 	case RX_MGMT_CFG80211_AUTH:
-		cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len,
-				      GFP_KERNEL);
+		cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len);
 		break;
 	case RX_MGMT_CFG80211_ASSOC:
-		cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len,
-				       GFP_KERNEL);
+		cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len);
 		break;
 	default:
 		WARN(1, "unexpected: %d", rma);
@@ -2026,13 +2020,11 @@ static void ieee80211_sta_work(struct wo
 		switch (wk->tries) {
 		case RX_MGMT_CFG80211_AUTH_TO:
 			cfg80211_send_auth_timeout(sdata->dev,
-						   wk->bss->cbss.bssid,
-						   GFP_KERNEL);
+						   wk->bss->cbss.bssid);
 			break;
 		case RX_MGMT_CFG80211_ASSOC_TO:
-			cfg80211_send_auth_timeout(sdata->dev,
-						   wk->bss->cbss.bssid,
-						   GFP_KERNEL);
+			cfg80211_send_assoc_timeout(sdata->dev,
+						    wk->bss->cbss.bssid);
 			break;
 		default:
 			WARN(1, "unexpected: %d", wk->tries);

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 4/9] cfg80211: warn again on spurious deauth
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
                   ` (2 preceding siblings ...)
  2009-07-07  1:56 ` [PATCH 3/9] cfg80211: mlme API must be able to sleep Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 5/9] cfg80211: properly name driver locking Johannes Berg
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

The original code in mac80211 could send a deauth
frame under certain circumstances even if nothing
had ever requested an authentication. This has been
fixed with the rework there, so cfg80211 can now
warn again about spurious events to catch possible
future drivers or mac80211 regressions.

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

--- wireless-testing.orig/net/wireless/mlme.c	2009-07-07 03:37:04.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2009-07-07 03:37:05.000000000 +0200
@@ -122,15 +122,9 @@ void cfg80211_send_deauth(struct net_dev
 			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;

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 5/9] cfg80211: properly name driver locking
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
                   ` (3 preceding siblings ...)
  2009-07-07  1:56 ` [PATCH 4/9] cfg80211: warn again on spurious deauth Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 6/9] cfg80211: fix MFP bug, sparse warnings Johannes Berg
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Currently we call that cfg80211_put_dev(), but that is
misleading. With the new convention of using 'rdev' for
registered_device variables, also call that function
cfg80211_unlock_rdev().

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/core.c    |    6 ---
 net/wireless/core.h    |    8 +++--
 net/wireless/nl80211.c |   74 ++++++++++++++++++++++++-------------------------
 net/wireless/scan.c    |    6 +--
 4 files changed, 45 insertions(+), 49 deletions(-)

--- wireless-testing.orig/net/wireless/core.c	2009-07-07 03:37:03.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-07 03:37:05.000000000 +0200
@@ -171,12 +171,6 @@ cfg80211_get_dev_from_ifindex(int ifinde
 	return drv;
 }
 
-void cfg80211_put_dev(struct cfg80211_registered_device *drv)
-{
-	BUG_ON(IS_ERR(drv));
-	mutex_unlock(&drv->mtx);
-}
-
 /* requires cfg80211_mutex to be held */
 int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 			char *newname)
--- wireless-testing.orig/net/wireless/core.h	2009-07-07 03:36:58.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-07-07 03:37:05.000000000 +0200
@@ -146,7 +146,7 @@ __cfg80211_drv_from_info(struct genl_inf
  * If successful, it returns non-NULL and also locks
  * the driver's mutex!
  *
- * This means that you need to call cfg80211_put_dev()
+ * This means that you need to call cfg80211_unlock_rdev()
  * before being allowed to acquire &cfg80211_mutex!
  *
  * This is necessary because we need to lock the global
@@ -170,7 +170,11 @@ struct wiphy *wiphy_idx_to_wiphy(int wip
 extern struct cfg80211_registered_device *
 cfg80211_get_dev_from_ifindex(int ifindex);
 
-extern void cfg80211_put_dev(struct cfg80211_registered_device *drv);
+static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *drv)
+{
+	BUG_ON(IS_ERR(drv) || !drv);
+	mutex_unlock(&drv->mtx);
+}
 
 /* free object */
 extern void cfg80211_dev_free(struct cfg80211_registered_device *drv);
--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-07 03:36:58.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-07 03:37:05.000000000 +0200
@@ -411,14 +411,14 @@ static int nl80211_get_wiphy(struct sk_b
 	if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
 		goto out_free;
 
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 
 	return genlmsg_unicast(msg, info->snd_pid);
 
  out_free:
 	nlmsg_free(msg);
  out_err:
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 	return -ENOBUFS;
 }
 
@@ -737,7 +737,7 @@ static int nl80211_get_interface(struct 
 		goto out_free;
 
 	dev_put(netdev);
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 
 	return genlmsg_unicast(msg, info->snd_pid);
 
@@ -745,7 +745,7 @@ static int nl80211_get_interface(struct 
 	nlmsg_free(msg);
  out_err:
 	dev_put(netdev);
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 	return -ENOBUFS;
 }
 
@@ -853,7 +853,7 @@ static int nl80211_set_interface(struct 
 
  unlock:
 	dev_put(dev);
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -906,7 +906,7 @@ static int nl80211_new_interface(struct 
 		type, err ? NULL : &flags, &params);
 
  unlock:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -934,7 +934,7 @@ static int nl80211_del_interface(struct 
 	err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -1037,7 +1037,7 @@ static int nl80211_get_key(struct sk_buf
 	err = -ENOBUFS;
 	nlmsg_free(msg);
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1097,7 +1097,7 @@ static int nl80211_set_key(struct sk_buf
 #endif
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 
  unlock_rtnl:
@@ -1163,7 +1163,7 @@ static int nl80211_new_key(struct sk_buf
 	err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1211,7 +1211,7 @@ static int nl80211_del_key(struct sk_buf
 #endif
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 
  unlock_rtnl:
@@ -1306,7 +1306,7 @@ static int nl80211_addset_beacon(struct 
 	err = call(&drv->wiphy, dev, &params);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1338,7 +1338,7 @@ static int nl80211_del_beacon(struct sk_
 	err = drv->ops->del_beacon(&drv->wiphy, dev);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1572,7 +1572,7 @@ static int nl80211_dump_station(struct s
 	cb->args[1] = sta_idx;
 	err = skb->len;
  out_err:
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
  out_rtnl:
 	rtnl_unlock();
 
@@ -1624,7 +1624,7 @@ static int nl80211_get_station(struct sk
  out_free:
 	nlmsg_free(msg);
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1760,7 +1760,7 @@ static int nl80211_set_station(struct sk
  out:
 	if (params.vlan)
 		dev_put(params.vlan);
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1865,7 +1865,7 @@ static int nl80211_new_station(struct sk
  out:
 	if (params.vlan)
 		dev_put(params.vlan);
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1904,7 +1904,7 @@ static int nl80211_del_station(struct sk
 	err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2035,7 +2035,7 @@ static int nl80211_dump_mpath(struct sk_
 	cb->args[1] = path_idx;
 	err = skb->len;
  out_err:
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
  out_rtnl:
 	rtnl_unlock();
 
@@ -2093,7 +2093,7 @@ static int nl80211_get_mpath(struct sk_b
  out_free:
 	nlmsg_free(msg);
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2142,7 +2142,7 @@ static int nl80211_set_mpath(struct sk_b
 	err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2190,7 +2190,7 @@ static int nl80211_new_mpath(struct sk_b
 	err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2222,7 +2222,7 @@ static int nl80211_del_mpath(struct sk_b
 	err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2278,7 +2278,7 @@ static int nl80211_set_bss(struct sk_buf
 	err = drv->ops->change_bss(&drv->wiphy, dev, &params);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2444,7 +2444,7 @@ static int nl80211_get_mesh_params(struc
 	err = -EMSGSIZE;
  out:
 	/* Cleanup */
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2550,7 +2550,7 @@ static int nl80211_set_mesh_params(struc
 
  out:
 	/* cleanup */
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2890,7 +2890,7 @@ static int nl80211_trigger_scan(struct s
 		kfree(request);
 	}
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -3007,7 +3007,7 @@ static int nl80211_dump_scan(struct sk_b
 
 	cb->args[1] = idx;
 	err = skb->len;
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
  out_put_netdev:
 	dev_put(netdev);
 
@@ -3112,7 +3112,7 @@ static int nl80211_authenticate(struct s
 				 ssid, ssid_len, ie, ie_len);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3259,7 +3259,7 @@ static int nl80211_associate(struct sk_b
 					  &crypto);
 
 out:
-	cfg80211_put_dev(rdev);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3321,7 +3321,7 @@ static int nl80211_deauthenticate(struct
 	err = cfg80211_mlme_deauth(drv, dev, bssid, ie, ie_len, reason_code);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3383,7 +3383,7 @@ static int nl80211_disassociate(struct s
 	err = cfg80211_mlme_disassoc(drv, dev, bssid, ie, ie_len, reason_code);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3464,7 +3464,7 @@ static int nl80211_join_ibss(struct sk_b
 	err = cfg80211_join_ibss(drv, dev, &ibss);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3501,7 +3501,7 @@ static int nl80211_leave_ibss(struct sk_
 	err = cfg80211_leave_ibss(drv, dev, false);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3538,7 +3538,7 @@ static int nl80211_testmode_do(struct sk
 		rdev->testmode_info = NULL;
 	}
 
-	cfg80211_put_dev(rdev);
+	cfg80211_unlock_rdev(rdev);
 
  unlock_rtnl:
 	rtnl_unlock();
@@ -3707,7 +3707,7 @@ static int nl80211_connect(struct sk_buf
 	err = cfg80211_connect(drv, dev, &connect);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3748,7 +3748,7 @@ static int nl80211_disconnect(struct sk_
 	err = cfg80211_disconnect(drv, dev, reason, true);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(drv);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
--- wireless-testing.orig/net/wireless/scan.c	2009-07-07 03:29:39.000000000 +0200
+++ wireless-testing/net/wireless/scan.c	2009-07-07 03:37:05.000000000 +0200
@@ -28,8 +28,6 @@ void cfg80211_scan_done(struct cfg80211_
 	if (!dev)
 		goto out;
 
-	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
-
 	/*
 	 * This must be before sending the other events!
 	 * Otherwise, wpa_supplicant gets completely confused with
@@ -636,7 +634,7 @@ int cfg80211_wext_siwscan(struct net_dev
 	} else
 		nl80211_send_scan_start(rdev, dev);
  out:
-	cfg80211_put_dev(rdev);
+	cfg80211_unlock_rdev(rdev);
 	return err;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
@@ -945,7 +943,7 @@ int cfg80211_wext_giwscan(struct net_dev
 	}
 
  out:
-	cfg80211_put_dev(rdev);
+	cfg80211_unlock_rdev(rdev);
 	return res;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 6/9] cfg80211: fix MFP bug, sparse warnings
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
                   ` (4 preceding siblings ...)
  2009-07-07  1:56 ` [PATCH 5/9] cfg80211: properly name driver locking Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 7/9] cfg80211: fix locking Johannes Berg
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

sparse warns about a number of things, and one of them
(use_mfp shadowed variable) actually is a bug, fix all
of them.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/nl80211.c     |    6 +++---
 net/wireless/wext-compat.c |    6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-07 03:37:05.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-07 03:37:05.000000000 +0200
@@ -3239,11 +3239,11 @@ static int nl80211_associate(struct sk_b
 	}
 
 	if (info->attrs[NL80211_ATTR_USE_MFP]) {
-		enum nl80211_mfp use_mfp =
+		enum nl80211_mfp mfp =
 			nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
-		if (use_mfp == NL80211_MFP_REQUIRED)
+		if (mfp == NL80211_MFP_REQUIRED)
 			use_mfp = true;
-		else if (use_mfp != NL80211_MFP_NO) {
+		else if (mfp != NL80211_MFP_NO) {
 			err = -EINVAL;
 			goto out;
 		}
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-07-07 03:29:39.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-07-07 03:37:05.000000000 +0200
@@ -855,7 +855,7 @@ static int cfg80211_set_wpa_version(stru
 	return 0;
 }
 
-int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
+static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
 {
 	wdev->wext.connect.crypto.cipher_group = 0;
 
@@ -880,7 +880,7 @@ int cfg80211_set_cipher_group(struct wir
 	return 0;
 }
 
-int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher)
+static int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher)
 {
 	int nr_ciphers = 0;
 	u32 *ciphers_pairwise = wdev->wext.connect.crypto.ciphers_pairwise;
@@ -918,7 +918,7 @@ int cfg80211_set_cipher_pairwise(struct 
 }
 
 
-int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
+static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
 {
 	int nr_akm_suites = 0;
 

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 7/9] cfg80211: fix locking
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
                   ` (5 preceding siblings ...)
  2009-07-07  1:56 ` [PATCH 6/9] cfg80211: fix MFP bug, sparse warnings Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 8/9] cfg80211: clean up naming once and for all Johannes Berg
  2009-07-07  1:56 ` [PATCH 9/9] cfg80211: disallow configuring unsupported interfaces Johannes Berg
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Over time, a lot of locking issues have crept into
the smarts of cfg80211, so e.g. scan completion can
race against a new scan, IBSS join can race against
leaving an IBSS, etc.

Introduce a new per-interface lock that protects
most of the per-interface data that we need to keep
track of, and sprinkle assertions about that lock
everywhere. Some things now need to be offloaded to
work structs so that we don't require being able to
sleep in functions the drivers call. The exception
to that are the MLME callbacks (rx_auth etc.) that
currently only mac80211 calls because it was easier
to do that there instead of in cfg80211, and future
drivers implementing those calls will, if they ever
exist, probably need to use a similar scheme like
mac80211 anyway...

In order to be able to handle _deauth and _disassoc
properly, introduce a cookie passed to it that will
determine locking requirements.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |   24 +++-
 net/mac80211/cfg.c         |   12 +-
 net/mac80211/ieee80211_i.h |    6 -
 net/mac80211/mlme.c        |   25 ++--
 net/wireless/core.c        |   92 +++++++++++++++-
 net/wireless/core.h        |  100 +++++++++++++++++
 net/wireless/ibss.c        |  133 ++++++++++++++++++-----
 net/wireless/mlme.c        |  214 ++++++++++++++++++++++++++++++--------
 net/wireless/nl80211.c     |    8 -
 net/wireless/nl80211.h     |    2 
 net/wireless/scan.c        |   30 ++++-
 net/wireless/sme.c         |  252 +++++++++++++++++++++++++++++++++++----------
 net/wireless/wext-sme.c    |  125 +++++++++++++++-------
 13 files changed, 823 insertions(+), 200 deletions(-)

--- wireless-testing.orig/net/wireless/core.c	2009-07-07 03:37:05.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-07 03:37:06.000000000 +0200
@@ -257,6 +257,71 @@ static void cfg80211_rfkill_sync_work(st
 	cfg80211_rfkill_set_block(drv, rfkill_blocked(drv->rfkill));
 }
 
+static void cfg80211_process_events(struct wireless_dev *wdev)
+{
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	while (!list_empty(&wdev->event_list)) {
+		ev = list_first_entry(&wdev->event_list,
+				      struct cfg80211_event, list);
+		list_del(&ev->list);
+		spin_unlock_irqrestore(&wdev->event_lock, flags);
+
+		wdev_lock(wdev);
+		switch (ev->type) {
+		case EVENT_CONNECT_RESULT:
+			__cfg80211_connect_result(
+				wdev->netdev, ev->cr.bssid,
+				ev->cr.req_ie, ev->cr.req_ie_len,
+				ev->cr.resp_ie, ev->cr.resp_ie_len,
+				ev->cr.status,
+				ev->cr.status == WLAN_STATUS_SUCCESS);
+			break;
+		case EVENT_ROAMED:
+			__cfg80211_roamed(wdev, ev->rm.bssid,
+					  ev->rm.req_ie, ev->rm.req_ie_len,
+					  ev->rm.resp_ie, ev->rm.resp_ie_len);
+			break;
+		case EVENT_DISCONNECTED:
+			__cfg80211_disconnected(wdev->netdev,
+						ev->dc.ie, ev->dc.ie_len,
+						ev->dc.reason, true);
+			break;
+		case EVENT_IBSS_JOINED:
+			__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
+			break;
+		}
+		wdev_unlock(wdev);
+
+		kfree(ev);
+
+		spin_lock_irqsave(&wdev->event_lock, flags);
+	}
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+}
+
+static void cfg80211_event_work(struct work_struct *work)
+{
+	struct cfg80211_registered_device *rdev;
+	struct wireless_dev *wdev;
+
+	rdev = container_of(work, struct cfg80211_registered_device,
+			    event_work);
+
+	rtnl_lock();
+	cfg80211_lock_rdev(rdev);
+	mutex_lock(&rdev->devlist_mtx);
+
+	list_for_each_entry(wdev, &rdev->netdev_list, list)
+		cfg80211_process_events(wdev);
+
+	mutex_unlock(&rdev->devlist_mtx);
+	cfg80211_unlock_rdev(rdev);
+	rtnl_unlock();
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
@@ -299,6 +364,7 @@ struct wiphy *wiphy_new(const struct cfg
 	INIT_LIST_HEAD(&drv->netdev_list);
 	spin_lock_init(&drv->bss_lock);
 	INIT_LIST_HEAD(&drv->bss_list);
+	INIT_WORK(&drv->scan_done_wk, __cfg80211_scan_done);
 
 	device_initialize(&drv->wiphy.dev);
 	drv->wiphy.dev.class = &ieee80211_class;
@@ -316,6 +382,7 @@ struct wiphy *wiphy_new(const struct cfg
 
 	INIT_WORK(&drv->rfkill_sync, cfg80211_rfkill_sync_work);
 	INIT_WORK(&drv->conn_work, cfg80211_conn_work);
+	INIT_WORK(&drv->event_work, cfg80211_event_work);
 
 	/*
 	 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
@@ -477,6 +544,9 @@ void wiphy_unregister(struct wiphy *wiph
 	mutex_unlock(&drv->mtx);
 
 	cancel_work_sync(&drv->conn_work);
+	cancel_work_sync(&drv->scan_done_wk);
+	kfree(drv->scan_req);
+	flush_work(&drv->event_work);
 
 	cfg80211_debugfs_drv_del(drv);
 
@@ -535,6 +605,9 @@ static int cfg80211_netdev_notifier_call
 
 	switch (state) {
 	case NETDEV_REGISTER:
+		mutex_init(&wdev->mtx);
+		INIT_LIST_HEAD(&wdev->event_list);
+		spin_lock_init(&wdev->event_lock);
 		mutex_lock(&rdev->devlist_mtx);
 		list_add(&wdev->list, &rdev->netdev_list);
 		if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
@@ -566,15 +639,17 @@ static int cfg80211_netdev_notifier_call
 			cfg80211_leave_ibss(rdev, dev, true);
 			break;
 		case NL80211_IFTYPE_STATION:
+			wdev_lock(wdev);
 #ifdef CONFIG_WIRELESS_EXT
 			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);
+			__cfg80211_disconnect(rdev, dev,
+					      WLAN_REASON_DEAUTH_LEAVING, true);
 			cfg80211_mlme_down(rdev, dev);
+			wdev_unlock(wdev);
 			break;
 		default:
 			break;
@@ -582,20 +657,24 @@ static int cfg80211_netdev_notifier_call
 		break;
 	case NETDEV_UP:
 #ifdef CONFIG_WIRELESS_EXT
+		cfg80211_lock_rdev(rdev);
+		wdev_lock(wdev);
 		switch (wdev->iftype) {
 		case NL80211_IFTYPE_ADHOC:
 			if (wdev->wext.ibss.ssid_len)
-				cfg80211_join_ibss(rdev, dev,
-						   &wdev->wext.ibss);
+				__cfg80211_join_ibss(rdev, dev,
+						     &wdev->wext.ibss);
 			break;
 		case NL80211_IFTYPE_STATION:
 			if (wdev->wext.connect.ssid_len)
-				cfg80211_connect(rdev, dev,
-						 &wdev->wext.connect);
+				__cfg80211_connect(rdev, dev,
+						   &wdev->wext.connect);
 			break;
 		default:
 			break;
 		}
+		wdev_unlock(wdev);
+		cfg80211_unlock_rdev(rdev);
 #endif
 		break;
 	case NETDEV_UNREGISTER:
@@ -605,6 +684,7 @@ static int cfg80211_netdev_notifier_call
 			list_del_init(&wdev->list);
 		}
 		mutex_unlock(&rdev->devlist_mtx);
+		mutex_destroy(&wdev->mtx);
 		break;
 	case NETDEV_PRE_UP:
 		if (rfkill_blocked(rdev->rfkill))
--- wireless-testing.orig/net/wireless/core.h	2009-07-07 03:37:05.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-07-07 03:37:06.000000000 +0200
@@ -57,12 +57,14 @@ struct cfg80211_registered_device {
 	u32 bss_generation;
 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
 	unsigned long suspend_at;
+	struct work_struct scan_done_wk;
 
 #ifdef CONFIG_NL80211_TESTMODE
 	struct genl_info *testmode_info;
 #endif
 
 	struct work_struct conn_work;
+	struct work_struct event_work;
 
 #ifdef CONFIG_CFG80211_DEBUGFS
 	/* Debugfs entries */
@@ -170,12 +172,73 @@ struct wiphy *wiphy_idx_to_wiphy(int wip
 extern struct cfg80211_registered_device *
 cfg80211_get_dev_from_ifindex(int ifindex);
 
+static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *drv)
+{
+	mutex_lock(&drv->mtx);
+}
+
 static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *drv)
 {
 	BUG_ON(IS_ERR(drv) || !drv);
 	mutex_unlock(&drv->mtx);
 }
 
+static inline void wdev_lock(struct wireless_dev *wdev)
+	__acquires(wdev)
+{
+	mutex_lock(&wdev->mtx);
+	__acquire(wdev->mtx);
+}
+
+static inline void wdev_unlock(struct wireless_dev *wdev)
+	__releases(wdev)
+{
+	__release(wdev->mtx);
+	mutex_unlock(&wdev->mtx);
+}
+
+#define ASSERT_RDEV_LOCK(rdev) WARN_ON(!mutex_is_locked(&(rdev)->mtx));
+#define ASSERT_WDEV_LOCK(wdev) WARN_ON(!mutex_is_locked(&(wdev)->mtx));
+
+enum cfg80211_event_type {
+	EVENT_CONNECT_RESULT,
+	EVENT_ROAMED,
+	EVENT_DISCONNECTED,
+	EVENT_IBSS_JOINED,
+};
+
+struct cfg80211_event {
+	struct list_head list;
+	enum cfg80211_event_type type;
+
+	union {
+		struct {
+			u8 bssid[ETH_ALEN];
+			const u8 *req_ie;
+			const u8 *resp_ie;
+			size_t req_ie_len;
+			size_t resp_ie_len;
+			u16 status;
+		} cr;
+		struct {
+			u8 bssid[ETH_ALEN];
+			const u8 *req_ie;
+			const u8 *resp_ie;
+			size_t req_ie_len;
+			size_t resp_ie_len;
+		} rm;
+		struct {
+			const u8 *ie;
+			size_t ie_len;
+			u16 reason;
+		} dc;
+		struct {
+			u8 bssid[ETH_ALEN];
+		} ij;
+	};
+};
+
+
 /* free object */
 extern void cfg80211_dev_free(struct cfg80211_registered_device *drv);
 
@@ -191,25 +254,46 @@ void cfg80211_bss_age(struct cfg80211_re
                       unsigned long age_secs);
 
 /* IBSS */
+int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev,
+			 struct cfg80211_ibss_params *params);
 int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 		       struct net_device *dev,
 		       struct cfg80211_ibss_params *params);
 void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, bool nowext);
+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
 
 /* 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_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 *prev_bssid,
+			  const u8 *ssid, int ssid_len,
+			  const u8 *ie, int ie_len, bool use_mfp,
+			  struct cfg80211_crypto_settings *crypt);
 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, struct ieee80211_channel *chan,
 			const u8 *bssid, const u8 *prev_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_deauth(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev, const u8 *bssid,
 			 const u8 *ie, int ie_len, u16 reason);
@@ -218,24 +302,38 @@ int cfg80211_mlme_disassoc(struct cfg802
 			   const u8 *ie, int ie_len, u16 reason);
 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 			struct net_device *dev);
+void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			       const u8 *req_ie, size_t req_ie_len,
+			       const u8 *resp_ie, size_t resp_ie_len,
+			       u16 status, bool wextev);
 
 /* SME */
+int __cfg80211_connect(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev,
+		       struct cfg80211_connect_params *connect);
 int cfg80211_connect(struct cfg80211_registered_device *rdev,
 		     struct net_device *dev,
 		     struct cfg80211_connect_params *connect);
+int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev, u16 reason,
+			  bool wextev);
 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, u16 reason,
 			bool wextev);
+void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
+		       const u8 *req_ie, size_t req_ie_len,
+		       const u8 *resp_ie, size_t resp_ie_len);
 
 void cfg80211_conn_work(struct work_struct *work);
 
 /* internal helpers */
 int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
 				   const u8 *mac_addr);
-void __cfg80211_disconnected(struct net_device *dev, gfp_t gfp, u8 *ie,
+void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
 			     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);
+void __cfg80211_scan_done(struct work_struct *wk);
 
 #endif /* __NET_WIRELESS_CORE_H */
--- wireless-testing.orig/net/wireless/mlme.c	2009-07-07 03:37:05.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2009-07-07 03:37:06.000000000 +0200
@@ -23,7 +23,7 @@ void cfg80211_send_rx_auth(struct net_de
 	u16 status = le16_to_cpu(mgmt->u.auth.status_code);
 	bool done = false;
 
-	might_sleep();
+	wdev_lock(wdev);
 
 	for (i = 0; i < MAX_AUTH_BSSES; i++) {
 		if (wdev->authtry_bsses[i] &&
@@ -45,6 +45,8 @@ void cfg80211_send_rx_auth(struct net_de
 
 	nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
 	cfg80211_sme_rx_auth(dev, buf, len);
+
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_auth);
 
@@ -59,14 +61,15 @@ void cfg80211_send_rx_assoc(struct net_d
 	int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
 	bool done;
 
-	might_sleep();
+	wdev_lock(wdev);
 
 	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 
 	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
 
-	cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
-				status_code, GFP_KERNEL);
+	__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
+				  status_code,
+				  status_code == WLAN_STATUS_SUCCESS);
 
 	if (status_code == WLAN_STATUS_SUCCESS) {
 		for (i = 0; wdev->current_bss && i < MAX_AUTH_BSSES; i++) {
@@ -81,10 +84,13 @@ void cfg80211_send_rx_assoc(struct net_d
 
 		WARN_ON(!done);
 	}
+
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
 
-void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
+static void __cfg80211_send_deauth(struct net_device *dev,
+				   const u8 *buf, size_t len)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -94,7 +100,7 @@ void cfg80211_send_deauth(struct net_dev
 	int i;
 	bool done = false;
 
-	might_sleep();
+	ASSERT_WDEV_LOCK(wdev);
 
 	nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
 
@@ -132,17 +138,35 @@ void cfg80211_send_deauth(struct net_dev
 		reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 
 		from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
-		__cfg80211_disconnected(dev, GFP_KERNEL, NULL, 0,
-					reason_code, from_ap);
+		__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
 	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
-		cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
-					WLAN_STATUS_UNSPECIFIED_FAILURE,
-					GFP_KERNEL);
+		__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  false);
+	}
+}
+
+
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len,
+			  void *cookie)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	BUG_ON(cookie && wdev != cookie);
+
+	if (cookie) {
+		/* called within callback */
+		__cfg80211_send_deauth(dev, buf, len);
+	} else {
+		wdev_lock(wdev);
+		__cfg80211_send_deauth(dev, buf, len);
+		wdev_unlock(wdev);
 	}
 }
 EXPORT_SYMBOL(cfg80211_send_deauth);
 
-void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
+static void __cfg80211_send_disassoc(struct net_device *dev,
+				     const u8 *buf, size_t len)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -154,12 +178,12 @@ void cfg80211_send_disassoc(struct net_d
 	bool from_ap;
 	bool done = false;
 
-	might_sleep();
+	wdev_lock(wdev);
 
 	nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
 
 	if (!wdev->sme_state == CFG80211_SME_CONNECTED)
-		return;
+		goto out;
 
 	if (wdev->current_bss &&
 	    memcmp(wdev->current_bss, bssid, ETH_ALEN) == 0) {
@@ -180,8 +204,26 @@ void cfg80211_send_disassoc(struct net_d
 	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_KERNEL, NULL, 0,
-				reason_code, from_ap);
+	__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
+ out:
+	wdev_unlock(wdev);
+}
+
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len,
+			    void *cookie)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	BUG_ON(cookie && wdev != cookie);
+
+	if (cookie) {
+		/* called within callback */
+		__cfg80211_send_disassoc(dev, buf, len);
+	} else {
+		wdev_lock(wdev);
+		__cfg80211_send_disassoc(dev, buf, len);
+		wdev_unlock(wdev);
+	}
 }
 EXPORT_SYMBOL(cfg80211_send_disassoc);
 
@@ -193,13 +235,13 @@ void cfg80211_send_auth_timeout(struct n
 	int i;
 	bool done = false;
 
-	might_sleep();
+	wdev_lock(wdev);
 
 	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
-		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
-					WLAN_STATUS_UNSPECIFIED_FAILURE,
-					GFP_KERNEL);
+		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  false);
 
 	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
 		if (wdev->authtry_bsses[i] &&
@@ -214,6 +256,8 @@ void cfg80211_send_auth_timeout(struct n
 	}
 
 	WARN_ON(!done);
+
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 
@@ -225,13 +269,13 @@ void cfg80211_send_assoc_timeout(struct 
 	int i;
 	bool done = false;
 
-	might_sleep();
+	wdev_lock(wdev);
 
 	nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
-		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
-					WLAN_STATUS_UNSPECIFIED_FAILURE,
-					GFP_KERNEL);
+		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  false);
 
 	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
 		if (wdev->auth_bsses[i] &&
@@ -246,6 +290,8 @@ void cfg80211_send_assoc_timeout(struct 
 	}
 
 	WARN_ON(!done);
+
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
 
@@ -276,17 +322,21 @@ void cfg80211_michael_mic_failure(struct
 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)
+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;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (wdev->current_bss &&
 	    memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
 		return -EALREADY;
@@ -342,18 +392,37 @@ int cfg80211_mlme_auth(struct cfg80211_r
 	return err;
 }
 
-int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
-			struct net_device *dev, struct ieee80211_channel *chan,
-			const u8 *bssid, const u8 *prev_bssid,
-			const u8 *ssid, int ssid_len,
-			const u8 *ie, int ie_len, bool use_mfp,
-			struct cfg80211_crypto_settings *crypt)
+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 err;
+
+	wdev_lock(dev->ieee80211_ptr);
+	err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
+				   ssid, ssid_len, ie, ie_len);
+	wdev_unlock(dev->ieee80211_ptr);
+
+	return err;
+}
+
+int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev,
+			  struct ieee80211_channel *chan,
+			  const u8 *bssid, const u8 *prev_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;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	memset(&req, 0, sizeof(req));
 
 	if (wdev->current_bss)
@@ -390,14 +459,35 @@ int cfg80211_mlme_assoc(struct cfg80211_
 	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)
+int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			struct net_device *dev,
+			struct ieee80211_channel *chan,
+			const u8 *bssid, const u8 *prev_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;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
+				    ssid, ssid_len, ie, ie_len, use_mfp, crypt);
+	wdev_unlock(wdev);
+
+	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;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	memset(&req, 0, sizeof(req));
 	req.reason_code = reason;
 	req.ie = ie;
@@ -421,16 +511,32 @@ int cfg80211_mlme_deauth(struct cfg80211
 	if (!req.bss)
 		return -ENOTCONN;
 
-	return rdev->ops->deauth(&rdev->wiphy, dev, &req);
+	return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 }
 
-int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
-			   struct net_device *dev, const u8 *bssid,
-			   const u8 *ie, int ie_len, u16 reason)
+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;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason);
+	wdev_unlock(wdev);
+
+	return err;
+}
+
+static 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;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	memset(&req, 0, sizeof(req));
 	req.reason_code = reason;
 	req.ie = ie;
@@ -440,7 +546,21 @@ int cfg80211_mlme_disassoc(struct cfg802
 	else
 		return -ENOTCONN;
 
-	return rdev->ops->disassoc(&rdev->wiphy, dev, &req);
+	return rdev->ops->disassoc(&rdev->wiphy, dev, &req, wdev);
+}
+
+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;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason);
+	wdev_unlock(wdev);
+
+	return err;
 }
 
 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
@@ -450,6 +570,8 @@ void cfg80211_mlme_down(struct cfg80211_
 	struct cfg80211_deauth_request req;
 	int i;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (!rdev->ops->deauth)
 		return;
 
@@ -460,7 +582,7 @@ void cfg80211_mlme_down(struct cfg80211_
 
 	if (wdev->current_bss) {
 		req.bss = &wdev->current_bss->pub;
-		rdev->ops->deauth(&rdev->wiphy, dev, &req);
+		rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 		if (wdev->current_bss) {
 			cfg80211_unhold_bss(wdev->current_bss);
 			cfg80211_put_bss(&wdev->current_bss->pub);
@@ -471,7 +593,7 @@ void cfg80211_mlme_down(struct cfg80211_
 	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);
+			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 			if (wdev->auth_bsses[i]) {
 				cfg80211_unhold_bss(wdev->auth_bsses[i]);
 				cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
@@ -480,7 +602,7 @@ void cfg80211_mlme_down(struct cfg80211_
 		}
 		if (wdev->authtry_bsses[i]) {
 			req.bss = &wdev->authtry_bsses[i]->pub;
-			rdev->ops->deauth(&rdev->wiphy, dev, &req);
+			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 			if (wdev->authtry_bsses[i]) {
 				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
 				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
--- wireless-testing.orig/net/wireless/sme.c	2009-07-07 03:36:58.000000000 +0200
+++ wireless-testing/net/wireless/sme.c	2009-07-07 03:37:06.000000000 +0200
@@ -38,6 +38,8 @@ static int cfg80211_conn_scan(struct wir
 	int n_channels, err;
 
 	ASSERT_RTNL();
+	ASSERT_RDEV_LOCK(drv);
+	ASSERT_WDEV_LOCK(wdev);
 
 	if (drv->scan_req)
 		return -EBUSY;
@@ -106,6 +108,8 @@ static int cfg80211_conn_do_work(struct 
 	struct cfg80211_connect_params *params;
 	int err;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (!wdev->conn)
 		return 0;
 
@@ -117,11 +121,11 @@ static int cfg80211_conn_do_work(struct 
 	case CFG80211_CONN_AUTHENTICATE_NEXT:
 		BUG_ON(!drv->ops->auth);
 		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);
+		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:
 		BUG_ON(!drv->ops->assoc);
 		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -131,14 +135,16 @@ static int cfg80211_conn_do_work(struct 
 		 * that some APs don't like that -- so we'd need to retry
 		 * the association.
 		 */
-		err = cfg80211_mlme_assoc(drv, wdev->netdev,
-					  params->channel, params->bssid, NULL,
-					  params->ssid, params->ssid_len,
-					  params->ie, params->ie_len,
-					  false, &params->crypto);
+		err = __cfg80211_mlme_assoc(drv, wdev->netdev,
+					    params->channel, params->bssid,
+					    NULL,
+					    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);
+			__cfg80211_mlme_deauth(drv, wdev->netdev, params->bssid,
+					       NULL, 0,
+					       WLAN_REASON_DEAUTH_LEAVING);
 		return err;
 	default:
 		return 0;
@@ -152,22 +158,31 @@ void cfg80211_conn_work(struct work_stru
 	struct wireless_dev *wdev;
 
 	rtnl_lock();
+	cfg80211_lock_rdev(drv);
 	mutex_lock(&drv->devlist_mtx);
 
 	list_for_each_entry(wdev, &drv->netdev_list, list) {
-		if (!netif_running(wdev->netdev))
+		wdev_lock(wdev);
+		if (!netif_running(wdev->netdev)) {
+			wdev_unlock(wdev);
 			continue;
-		if (wdev->sme_state != CFG80211_SME_CONNECTING)
+		}
+		if (wdev->sme_state != CFG80211_SME_CONNECTING) {
+			wdev_unlock(wdev);
 			continue;
+		}
 		if (cfg80211_conn_do_work(wdev))
-			cfg80211_connect_result(wdev->netdev,
-						wdev->conn->params.bssid,
-						NULL, 0, NULL, 0,
-						WLAN_STATUS_UNSPECIFIED_FAILURE,
-						GFP_ATOMIC);
+			__cfg80211_connect_result(
+					wdev->netdev,
+					wdev->conn->params.bssid,
+					NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					false);
+		wdev_unlock(wdev);
 	}
 
 	mutex_unlock(&drv->devlist_mtx);
+	cfg80211_unlock_rdev(drv);
 	rtnl_unlock();
 }
 
@@ -177,6 +192,8 @@ static bool cfg80211_get_conn_bss(struct
 	struct cfg80211_bss *bss;
 	u16 capa = WLAN_CAPABILITY_ESS;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (wdev->conn->params.privacy)
 		capa |= WLAN_CAPABILITY_PRIVACY;
 
@@ -198,11 +215,13 @@ static bool cfg80211_get_conn_bss(struct
 	return true;
 }
 
-void cfg80211_sme_scan_done(struct net_device *dev)
+static void __cfg80211_sme_scan_done(struct net_device *dev)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (wdev->sme_state != CFG80211_SME_CONNECTING)
 		return;
 
@@ -218,15 +237,26 @@ void cfg80211_sme_scan_done(struct net_d
 		if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
 			schedule_work(&drv->conn_work);
 		else
-			cfg80211_connect_result(dev, wdev->conn->params.bssid,
-						NULL, 0, NULL, 0,
-						WLAN_STATUS_UNSPECIFIED_FAILURE,
-						GFP_ATOMIC);
-		return;
+			__cfg80211_connect_result(
+					wdev->netdev,
+					wdev->conn->params.bssid,
+					NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					false);
 	}
 }
 
-void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
+void cfg80211_sme_scan_done(struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	wdev_lock(wdev);
+	__cfg80211_sme_scan_done(dev);
+	wdev_unlock(wdev);
+}
+
+void cfg80211_sme_rx_auth(struct net_device *dev,
+			  const u8 *buf, size_t len)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -234,6 +264,8 @@ void cfg80211_sme_rx_auth(struct net_dev
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 	u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	/* should only RX auth frames when connecting */
 	if (wdev->sme_state != CFG80211_SME_CONNECTING)
 		return;
@@ -273,10 +305,10 @@ void cfg80211_sme_rx_auth(struct net_dev
 	}
 }
 
-static void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
-				      const u8 *req_ie, size_t req_ie_len,
-				      const u8 *resp_ie, size_t resp_ie_len,
-				      u16 status, bool wextev, gfp_t gfp)
+void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			       const u8 *req_ie, size_t req_ie_len,
+			       const u8 *resp_ie, size_t resp_ie_len,
+			       u16 status, bool wextev)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_bss *bss;
@@ -284,18 +316,20 @@ static void __cfg80211_connect_result(st
 	union iwreq_data wrqu;
 #endif
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
 		return;
 
 	if (wdev->sme_state == CFG80211_SME_CONNECTED)
 		nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), dev,
 				    bssid, req_ie, req_ie_len,
-				    resp_ie, resp_ie_len, gfp);
+				    resp_ie, resp_ie_len, GFP_KERNEL);
 	else
 		nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
 					    bssid, req_ie, req_ie_len,
 					    resp_ie, resp_ie_len,
-					    status, gfp);
+					    status, GFP_KERNEL);
 
 #ifdef CONFIG_WIRELESS_EXT
 	if (wextev) {
@@ -362,21 +396,43 @@ void cfg80211_connect_result(struct net_
 			     const u8 *resp_ie, size_t resp_ie_len,
 			     u16 status, gfp_t gfp)
 {
-	bool wextev = status == WLAN_STATUS_SUCCESS;
-	__cfg80211_connect_result(dev, bssid, req_ie, req_ie_len, resp_ie, resp_ie_len, status, wextev, gfp);
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_CONNECT_RESULT;
+	memcpy(ev->cr.bssid, bssid, ETH_ALEN);
+	ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
+	ev->cr.req_ie_len = req_ie_len;
+	memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
+	ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
+	ev->cr.resp_ie_len = resp_ie_len;
+	memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
+	ev->cr.status = status;
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
 }
 EXPORT_SYMBOL(cfg80211_connect_result);
 
-void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
-		     const u8 *req_ie, size_t req_ie_len,
-		     const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
+void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
+		       const u8 *req_ie, size_t req_ie_len,
+		       const u8 *resp_ie, size_t resp_ie_len)
 {
-	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_bss *bss;
 #ifdef CONFIG_WIRELESS_EXT
 	union iwreq_data wrqu;
 #endif
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
 		return;
 
@@ -402,31 +458,62 @@ void cfg80211_roamed(struct net_device *
 	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);
+	nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), wdev->netdev, bssid,
+			    req_ie, req_ie_len, resp_ie, resp_ie_len,
+			    GFP_KERNEL);
 
 #ifdef CONFIG_WIRELESS_EXT
 	if (req_ie) {
 		memset(&wrqu, 0, sizeof(wrqu));
 		wrqu.data.length = req_ie_len;
-		wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, req_ie);
+		wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
+				    &wrqu, req_ie);
 	}
 
 	if (resp_ie) {
 		memset(&wrqu, 0, sizeof(wrqu));
 		wrqu.data.length = resp_ie_len;
-		wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
+		wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
+				    &wrqu, resp_ie);
 	}
 
 	memset(&wrqu, 0, sizeof(wrqu));
 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
-	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+	wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
 #endif
 }
+
+void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
+		     const u8 *req_ie, size_t req_ie_len,
+		     const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_ROAMED;
+	memcpy(ev->rm.bssid, bssid, ETH_ALEN);
+	ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
+	ev->rm.req_ie_len = req_ie_len;
+	memcpy((void *)ev->rm.req_ie, req_ie, req_ie_len);
+	ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
+	ev->rm.resp_ie_len = resp_ie_len;
+	memcpy((void *)ev->rm.resp_ie, resp_ie, resp_ie_len);
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
+}
 EXPORT_SYMBOL(cfg80211_roamed);
 
-void __cfg80211_disconnected(struct net_device *dev, gfp_t gfp, u8 *ie,
+void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
 			     size_t ie_len, u16 reason, bool from_ap)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -434,6 +521,8 @@ void __cfg80211_disconnected(struct net_
 	union iwreq_data wrqu;
 #endif
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
 		return;
 
@@ -456,7 +545,7 @@ void __cfg80211_disconnected(struct net_
 	}
 
 	nl80211_send_disconnected(wiphy_to_dev(wdev->wiphy), dev,
-				  reason, ie, ie_len, from_ap, gfp);
+				  reason, ie, ie_len, from_ap);
 
 #ifdef CONFIG_WIRELESS_EXT
 	memset(&wrqu, 0, sizeof(wrqu));
@@ -468,16 +557,36 @@ void __cfg80211_disconnected(struct net_
 void cfg80211_disconnected(struct net_device *dev, u16 reason,
 			   u8 *ie, size_t ie_len, gfp_t gfp)
 {
-	__cfg80211_disconnected(dev, gfp, ie, ie_len, reason, true);
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	ev = kzalloc(sizeof(*ev) + ie_len, gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_DISCONNECTED;
+	ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
+	ev->dc.ie_len = ie_len;
+	memcpy((void *)ev->dc.ie, ie, ie_len);
+	ev->dc.reason = reason;
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
 }
 EXPORT_SYMBOL(cfg80211_disconnected);
 
-int cfg80211_connect(struct cfg80211_registered_device *rdev,
-		     struct net_device *dev,
-		     struct cfg80211_connect_params *connect)
+int __cfg80211_connect(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev,
+		       struct cfg80211_connect_params *connect)
 {
-	int err;
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	ASSERT_WDEV_LOCK(wdev);
 
 	if (wdev->sme_state != CFG80211_SME_IDLE)
 		return -EALREADY;
@@ -572,12 +681,27 @@ int cfg80211_connect(struct cfg80211_reg
 	}
 }
 
-int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
-			struct net_device *dev, u16 reason, bool wextev)
+int cfg80211_connect(struct cfg80211_registered_device *rdev,
+		     struct net_device *dev,
+		     struct cfg80211_connect_params *connect)
+{
+	int err;
+
+	wdev_lock(dev->ieee80211_ptr);
+	err = __cfg80211_connect(rdev, dev, connect);
+	wdev_unlock(dev->ieee80211_ptr);
+
+	return err;
+}
+
+int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev, u16 reason, bool wextev)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (wdev->sme_state == CFG80211_SME_IDLE)
 		return -EINVAL;
 
@@ -601,8 +725,9 @@ int cfg80211_disconnect(struct cfg80211_
 		}
 
 		/* wdev->conn->params.bssid must be set if > SCANNING */
-		err = cfg80211_mlme_deauth(rdev, dev, wdev->conn->params.bssid,
-					   NULL, 0, reason);
+		err = __cfg80211_mlme_deauth(rdev, dev,
+					     wdev->conn->params.bssid,
+					     NULL, 0, reason);
 		if (err)
 			return err;
 	} else {
@@ -612,21 +737,36 @@ int cfg80211_disconnect(struct cfg80211_
 	}
 
 	if (wdev->sme_state == CFG80211_SME_CONNECTED)
-		__cfg80211_disconnected(dev, GFP_KERNEL, NULL, 0, 0, false);
+		__cfg80211_disconnected(dev, NULL, 0, 0, false);
 	else if (wdev->sme_state == CFG80211_SME_CONNECTING)
 		__cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
 					  WLAN_STATUS_UNSPECIFIED_FAILURE,
-					  wextev, GFP_KERNEL);
+					  wextev);
 
 	return 0;
 }
 
+int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			struct net_device *dev,
+			u16 reason, bool wextev)
+{
+	int err;
+
+	wdev_lock(dev->ieee80211_ptr);
+	err = __cfg80211_disconnect(rdev, dev, reason, wextev);
+	wdev_unlock(dev->ieee80211_ptr);
+
+	return err;
+}
+
 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];
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (!wdev->conn)
 		return;
 
--- wireless-testing.orig/include/net/cfg80211.h	2009-07-07 03:37:04.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-07-07 03:37:06.000000000 +0200
@@ -555,6 +555,7 @@ struct cfg80211_scan_request {
 	/* internal */
 	struct wiphy *wiphy;
 	int ifidx;
+	bool aborted;
 };
 
 /**
@@ -998,9 +999,11 @@ struct cfg80211_ops {
 	int	(*assoc)(struct wiphy *wiphy, struct net_device *dev,
 			 struct cfg80211_assoc_request *req);
 	int	(*deauth)(struct wiphy *wiphy, struct net_device *dev,
-			  struct cfg80211_deauth_request *req);
+			  struct cfg80211_deauth_request *req,
+			  void *cookie);
 	int	(*disassoc)(struct wiphy *wiphy, struct net_device *dev,
-			    struct cfg80211_disassoc_request *req);
+			    struct cfg80211_disassoc_request *req,
+			    void *cookie);
 
 	int	(*connect)(struct wiphy *wiphy, struct net_device *dev,
 			   struct cfg80211_connect_params *sme);
@@ -1249,10 +1252,12 @@ struct wireless_dev {
 	struct wiphy *wiphy;
 	enum nl80211_iftype iftype;
 
-	/* private to the generic wireless code */
+	/* the remainder of this struct should be private to cfg80211 */
 	struct list_head list;
 	struct net_device *netdev;
 
+	struct mutex mtx;
+
 	/* currently used for IBSS and SME - might be rearranged later */
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 ssid_len;
@@ -1263,6 +1268,9 @@ struct wireless_dev {
 	} sme_state;
 	struct cfg80211_conn *conn;
 
+	struct list_head event_list;
+	spinlock_t event_lock;
+
 	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 */
@@ -1765,24 +1773,30 @@ void cfg80211_send_assoc_timeout(struct 
  * @dev: network device
  * @buf: deauthentication frame (header + body)
  * @len: length of the frame data
+ * @cookie: cookie from ->deauth if called within that callback,
+ *	%NULL otherwise
  *
  * This function is called whenever deauthentication has been processed in
  * station mode. This includes both received deauthentication frames and
  * locally generated ones. This function may sleep.
  */
-void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len,
+			  void *cookie);
 
 /**
  * cfg80211_send_disassoc - notification of processed disassociation
  * @dev: network device
  * @buf: disassociation response frame (header + body)
  * @len: length of the frame data
+ * @cookie: cookie from ->disassoc if called within that callback,
+ *	%NULL otherwise
  *
  * This function is called whenever disassociation has been processed in
  * station mode. This includes both received disassociation frames and locally
  * generated ones. This function may sleep.
  */
-void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len,
+			    void *cookie);
 
 /**
  * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
--- wireless-testing.orig/net/wireless/scan.c	2009-07-07 03:37:05.000000000 +0200
+++ wireless-testing/net/wireless/scan.c	2009-07-07 03:37:06.000000000 +0200
@@ -17,13 +17,21 @@
 
 #define IEEE80211_SCAN_RESULT_EXPIRE	(10 * HZ)
 
-void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
+void __cfg80211_scan_done(struct work_struct *wk)
 {
+	struct cfg80211_registered_device *rdev;
+	struct cfg80211_scan_request *request;
 	struct net_device *dev;
 #ifdef CONFIG_WIRELESS_EXT
 	union iwreq_data wrqu;
 #endif
 
+	rdev = container_of(wk, struct cfg80211_registered_device,
+			    scan_done_wk);
+
+	mutex_lock(&rdev->mtx);
+	request = rdev->scan_req;
+
 	dev = dev_get_by_index(&init_net, request->ifidx);
 	if (!dev)
 		goto out;
@@ -35,7 +43,7 @@ void cfg80211_scan_done(struct cfg80211_
 	 */
 	cfg80211_sme_scan_done(dev);
 
-	if (aborted)
+	if (request->aborted)
 		nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
 	else
 		nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
@@ -43,7 +51,7 @@ void cfg80211_scan_done(struct cfg80211_
 	wiphy_to_dev(request->wiphy)->scan_req = NULL;
 
 #ifdef CONFIG_WIRELESS_EXT
-	if (!aborted) {
+	if (!request->aborted) {
 		memset(&wrqu, 0, sizeof(wrqu));
 
 		wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
@@ -53,8 +61,24 @@ void cfg80211_scan_done(struct cfg80211_
 	dev_put(dev);
 
  out:
+	cfg80211_unlock_rdev(rdev);
 	kfree(request);
 }
+
+void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
+{
+	struct net_device *dev = dev_get_by_index(&init_net, request->ifidx);
+	if (WARN_ON(!dev)) {
+		kfree(request);
+		return;
+	}
+
+	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
+
+	request->aborted = aborted;
+	schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk);
+	dev_put(dev);
+}
 EXPORT_SYMBOL(cfg80211_scan_done);
 
 static void bss_release(struct kref *ref)
--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-07 03:37:05.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-07 03:37:06.000000000 +0200
@@ -4029,6 +4029,8 @@ static int nl80211_add_scan_req(struct s
 	struct nlattr *nest;
 	int i;
 
+	ASSERT_RDEV_LOCK(rdev);
+
 	if (WARN_ON(!req))
 		return 0;
 
@@ -4391,12 +4393,12 @@ void nl80211_send_roamed(struct cfg80211
 
 void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
 			       struct net_device *netdev, u16 reason,
-			       u8 *ie, size_t ie_len, bool from_ap, gfp_t gfp)
+			       const u8 *ie, size_t ie_len, bool from_ap)
 {
 	struct sk_buff *msg;
 	void *hdr;
 
-	msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
 	if (!msg)
 		return;
 
@@ -4420,7 +4422,7 @@ void nl80211_send_disconnected(struct cf
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
 	return;
 
  nla_put_failure:
--- wireless-testing.orig/net/wireless/ibss.c	2009-07-07 03:37:03.000000000 +0200
+++ wireless-testing/net/wireless/ibss.c	2009-07-07 03:37:06.000000000 +0200
@@ -10,7 +10,7 @@
 #include "nl80211.h"
 
 
-void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_bss *bss;
@@ -39,22 +39,45 @@ void cfg80211_ibss_joined(struct net_dev
 	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);
+	nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
+				GFP_KERNEL);
 #ifdef CONFIG_WIRELESS_EXT
 	memset(&wrqu, 0, sizeof(wrqu));
 	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 #endif
 }
+
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	ev = kzalloc(sizeof(*ev), gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_IBSS_JOINED;
+	memcpy(ev->cr.bssid, bssid, ETH_ALEN);
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
+}
 EXPORT_SYMBOL(cfg80211_ibss_joined);
 
-int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
-		       struct net_device *dev,
-		       struct cfg80211_ibss_params *params)
+int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev,
+			 struct cfg80211_ibss_params *params)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (wdev->ssid_len)
 		return -EALREADY;
 
@@ -72,10 +95,26 @@ int cfg80211_join_ibss(struct cfg80211_r
 	return 0;
 }
 
-void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev,
+		       struct cfg80211_ibss_params *params)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_join_ibss(rdev, dev, params);
+	wdev_unlock(wdev);
+
+	return err;
+}
+
+static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (wdev->current_bss) {
 		cfg80211_unhold_bss(wdev->current_bss);
 		cfg80211_put_bss(&wdev->current_bss->pub);
@@ -89,12 +128,23 @@ void cfg80211_clear_ibss(struct net_devi
 #endif
 }
 
-int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
-			struct net_device *dev, bool nowext)
+void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	wdev_lock(wdev);
+	__cfg80211_clear_ibss(dev, nowext);
+	wdev_unlock(wdev);
+}
+
+static int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+				 struct net_device *dev, bool nowext)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (!wdev->ssid_len)
 		return -ENOLINK;
 
@@ -103,11 +153,24 @@ int cfg80211_leave_ibss(struct cfg80211_
 	if (err)
 		return err;
 
-	cfg80211_clear_ibss(dev, nowext);
+	__cfg80211_clear_ibss(dev, nowext);
 
 	return 0;
 }
 
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, bool nowext)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_leave_ibss(rdev, dev, nowext);
+	wdev_unlock(wdev);
+
+	return err;
+}
+
 #ifdef CONFIG_WIRELESS_EXT
 static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 				   struct wireless_dev *wdev)
@@ -184,12 +247,15 @@ int cfg80211_ibss_wext_siwfreq(struct ne
 	if (wdev->wext.ibss.channel == chan)
 		return 0;
 
-	if (wdev->ssid_len) {
-		err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
-					  dev, true);
-		if (err)
-			return err;
-	}
+	wdev_lock(wdev);
+	err = 0;
+	if (wdev->ssid_len)
+		err = __cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+					    dev, true);
+	wdev_unlock(wdev);
+
+	if (err)
+		return err;
 
 	if (chan) {
 		wdev->wext.ibss.channel = chan;
@@ -215,10 +281,12 @@ int cfg80211_ibss_wext_giwfreq(struct ne
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
 		return -EINVAL;
 
+	wdev_lock(wdev);
 	if (wdev->current_bss)
 		chan = wdev->current_bss->pub.channel;
 	else if (wdev->wext.ibss.channel)
 		chan = wdev->wext.ibss.channel;
+	wdev_unlock(wdev);
 
 	if (chan) {
 		freq->m = chan->center_freq;
@@ -247,12 +315,15 @@ int cfg80211_ibss_wext_siwessid(struct n
 	if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
 		return -EOPNOTSUPP;
 
-	if (wdev->ssid_len) {
-		err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
-					  dev, true);
-		if (err)
-			return err;
-	}
+	wdev_lock(wdev);
+	err = 0;
+	if (wdev->ssid_len)
+		err = __cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+					    dev, true);
+	wdev_unlock(wdev);
+
+	if (err)
+		return err;
 
 	/* iwconfig uses nul termination in SSID.. */
 	if (len > 0 && ssid[len - 1] == '\0')
@@ -279,6 +350,7 @@ int cfg80211_ibss_wext_giwessid(struct n
 
 	data->flags = 0;
 
+	wdev_lock(wdev);
 	if (wdev->ssid_len) {
 		data->flags = 1;
 		data->length = wdev->ssid_len;
@@ -288,6 +360,7 @@ int cfg80211_ibss_wext_giwessid(struct n
 		data->length = wdev->wext.ibss.ssid_len;
 		memcpy(ssid, wdev->wext.ibss.ssid, data->length);
 	}
+	wdev_unlock(wdev);
 
 	return 0;
 }
@@ -325,12 +398,15 @@ int cfg80211_ibss_wext_siwap(struct net_
 	    compare_ether_addr(bssid, wdev->wext.ibss.bssid) == 0)
 		return 0;
 
-	if (wdev->ssid_len) {
-		err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
-					  dev, true);
-		if (err)
-			return err;
-	}
+	wdev_lock(wdev);
+	err = 0;
+	if (wdev->ssid_len)
+		err = __cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+					    dev, true);
+	wdev_unlock(wdev);
+
+	if (err)
+		return err;
 
 	if (bssid) {
 		memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
@@ -355,10 +431,13 @@ int cfg80211_ibss_wext_giwap(struct net_
 
 	ap_addr->sa_family = ARPHRD_ETHER;
 
+	wdev_lock(wdev);
 	if (wdev->current_bss)
 		memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN);
 	else
 		memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
+	wdev_unlock(wdev);
+
 	return 0;
 }
 /* temporary symbol - mark GPL - in the future the handler won't be */
--- wireless-testing.orig/net/wireless/wext-sme.c	2009-07-07 03:29:39.000000000 +0200
+++ wireless-testing/net/wireless/wext-sme.c	2009-07-07 03:37:06.000000000 +0200
@@ -15,6 +15,9 @@ static int cfg80211_mgd_wext_connect(str
 {
 	int err;
 
+	ASSERT_RDEV_LOCK(rdev);
+	ASSERT_WDEV_LOCK(wdev);
+
 	if (!netif_running(wdev->netdev))
 		return 0;
 
@@ -24,8 +27,8 @@ static int cfg80211_mgd_wext_connect(str
 
 	err = 0;
 	if (wdev->wext.connect.ssid_len != 0)
-		err = cfg80211_connect(rdev, wdev->netdev,
-					&wdev->wext.connect);
+		err = __cfg80211_connect(rdev, wdev->netdev,
+					 &wdev->wext.connect);
 
 	return err;
 }
@@ -50,33 +53,43 @@ int cfg80211_mgd_wext_siwfreq(struct net
 	if (chan && (chan->flags & IEEE80211_CHAN_DISABLED))
 		return -EINVAL;
 
-	if (wdev->wext.connect.channel == chan)
-		return 0;
+	cfg80211_lock_rdev(rdev);
+	wdev_lock(wdev);
+
+	if (wdev->wext.connect.channel == chan) {
+		err = 0;
+		goto out;
+	}
 
 	if (wdev->sme_state != CFG80211_SME_IDLE) {
 		bool event = true;
 		/* if SSID set, we'll try right again, avoid event */
 		if (wdev->wext.connect.ssid_len)
 			event = false;
-		err = cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
-					  dev, WLAN_REASON_DEAUTH_LEAVING,
-					  event);
+		err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
+					    dev, WLAN_REASON_DEAUTH_LEAVING,
+					    event);
 		if (err)
-			return err;
+			goto out;
 	}
 
+
 	wdev->wext.connect.channel = chan;
 
 	/* SSID is not set, we just want to switch channel */
 	if (wdev->wext.connect.ssid_len && chan) {
-		if (!rdev->ops->set_channel)
-			return -EOPNOTSUPP;
-
-		return rdev->ops->set_channel(wdev->wiphy, chan,
-					      NL80211_CHAN_NO_HT);
+		err = -EOPNOTSUPP;
+		if (rdev->ops->set_channel)
+			err = rdev->ops->set_channel(wdev->wiphy, chan,
+						     NL80211_CHAN_NO_HT);
+		goto out;
 	}
 
-	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+	err = cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+ out:
+	wdev_unlock(wdev);
+	cfg80211_unlock_rdev(rdev);
+	return err;
 }
 /* temporary symbol - mark GPL - in the future the handler won't be */
 EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwfreq);
@@ -92,10 +105,12 @@ int cfg80211_mgd_wext_giwfreq(struct net
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
 		return -EINVAL;
 
+	wdev_lock(wdev);
 	if (wdev->current_bss)
 		chan = wdev->current_bss->pub.channel;
 	else if (wdev->wext.connect.channel)
 		chan = wdev->wext.connect.channel;
+	wdev_unlock(wdev);
 
 	if (chan) {
 		freq->m = chan->center_freq;
@@ -128,21 +143,26 @@ int cfg80211_mgd_wext_siwessid(struct ne
 	if (len > 0 && ssid[len - 1] == '\0')
 		len--;
 
+	cfg80211_lock_rdev(wiphy_to_dev(wdev->wiphy));
+	wdev_lock(wdev);
+
+	err = 0;
+
 	if (wdev->wext.connect.ssid && len &&
 	    len == wdev->wext.connect.ssid_len &&
 	    memcmp(wdev->wext.connect.ssid, ssid, len))
-		return 0;
+		goto out;
 
 	if (wdev->sme_state != CFG80211_SME_IDLE) {
 		bool event = true;
 		/* if SSID set now, we'll try to connect, avoid event */
 		if (len)
 			event = false;
-		err = cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
-					  dev, WLAN_REASON_DEAUTH_LEAVING,
-					  event);
+		err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
+					    dev, WLAN_REASON_DEAUTH_LEAVING,
+					    event);
 		if (err)
-			return err;
+			goto out;
 	}
 
 	wdev->wext.connect.ssid = wdev->wext.ssid;
@@ -151,7 +171,11 @@ int cfg80211_mgd_wext_siwessid(struct ne
 
 	wdev->wext.connect.crypto.control_port = false;
 
-	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+	err = cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+ out:
+	wdev_unlock(wdev);
+	cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy));
+	return err;
 }
 /* temporary symbol - mark GPL - in the future the handler won't be */
 EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwessid);
@@ -168,6 +192,7 @@ int cfg80211_mgd_wext_giwessid(struct ne
 
 	data->flags = 0;
 
+	wdev_lock(wdev);
 	if (wdev->ssid_len) {
 		data->flags = 1;
 		data->length = wdev->ssid_len;
@@ -178,6 +203,7 @@ int cfg80211_mgd_wext_giwessid(struct ne
 		memcpy(ssid, wdev->wext.connect.ssid, data->length);
 	} else
 		data->flags = 0;
+	wdev_unlock(wdev);
 
 	return 0;
 }
@@ -203,21 +229,25 @@ int cfg80211_mgd_wext_siwap(struct net_d
 	if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
 		bssid = NULL;
 
+	cfg80211_lock_rdev(wiphy_to_dev(wdev->wiphy));
+	wdev_lock(wdev);
+
+	err = 0;
 	/* both automatic */
 	if (!bssid && !wdev->wext.connect.bssid)
-		return 0;
+		goto out;
 
 	/* fixed already - and no change */
 	if (wdev->wext.connect.bssid && bssid &&
 	    compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0)
-		return 0;
+		goto out;
 
 	if (wdev->sme_state != CFG80211_SME_IDLE) {
-		err = cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
-					  dev, WLAN_REASON_DEAUTH_LEAVING,
-					  false);
+		err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
+					    dev, WLAN_REASON_DEAUTH_LEAVING,
+					    false);
 		if (err)
-			return err;
+			goto out;
 	}
 
 	if (bssid) {
@@ -226,7 +256,11 @@ int cfg80211_mgd_wext_siwap(struct net_d
 	} else
 		wdev->wext.connect.bssid = NULL;
 
-	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+	err = cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+ out:
+	wdev_unlock(wdev);
+	cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy));
+	return err;
 }
 /* temporary symbol - mark GPL - in the future the handler won't be */
 EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwap);
@@ -243,12 +277,14 @@ int cfg80211_mgd_wext_giwap(struct net_d
 
 	ap_addr->sa_family = ARPHRD_ETHER;
 
+	wdev_lock(wdev);
 	if (wdev->current_bss)
 		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
 		memset(ap_addr->sa_data, 0, ETH_ALEN);
+	wdev_unlock(wdev);
 
 	return 0;
 }
@@ -270,15 +306,20 @@ int cfg80211_wext_siwgenie(struct net_de
 	if (!ie_len)
 		ie = NULL;
 
+	wdev_lock(wdev);
+
 	/* no change */
+	err = 0;
 	if (wdev->wext.ie_len == ie_len &&
 	    memcmp(wdev->wext.ie, ie, ie_len) == 0)
-		return 0;
+		goto out;
 
 	if (ie_len) {
 		ie = kmemdup(extra, ie_len, GFP_KERNEL);
-		if (!ie)
-			return -ENOMEM;
+		if (!ie) {
+			err = -ENOMEM;
+			goto out;
+		}
 	} else
 		ie = NULL;
 
@@ -287,14 +328,17 @@ int cfg80211_wext_siwgenie(struct net_de
 	wdev->wext.ie_len = ie_len;
 
 	if (wdev->sme_state != CFG80211_SME_IDLE) {
-		err = cfg80211_disconnect(rdev, dev,
-					  WLAN_REASON_DEAUTH_LEAVING, false);
+		err = __cfg80211_disconnect(rdev, dev,
+					    WLAN_REASON_DEAUTH_LEAVING, false);
 		if (err)
-			return err;
+			goto out;
 	}
 
 	/* userspace better not think we'll reconnect */
-	return 0;
+	err = 0;
+ out:
+	wdev_unlock(wdev);
+	return err;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie);
 
@@ -305,6 +349,7 @@ int cfg80211_wext_siwmlme(struct net_dev
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
 	struct cfg80211_registered_device *rdev;
+	int err;
 
 	if (!wdev)
 		return -EOPNOTSUPP;
@@ -317,13 +362,19 @@ int cfg80211_wext_siwmlme(struct net_dev
 	if (mlme->addr.sa_family != ARPHRD_ETHER)
 		return -EINVAL;
 
+	wdev_lock(wdev);
 	switch (mlme->cmd) {
 	case IW_MLME_DEAUTH:
 	case IW_MLME_DISASSOC:
-		return cfg80211_disconnect(rdev, dev, mlme->reason_code,
-					   true);
+		err = __cfg80211_disconnect(rdev, dev, mlme->reason_code,
+					    true);
+		break;
 	default:
-		return -EOPNOTSUPP;
+		err = -EOPNOTSUPP;
+		break;
 	}
+	wdev_unlock(wdev);
+
+	return err;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
--- wireless-testing.orig/net/mac80211/cfg.c	2009-07-07 03:37:03.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-07-07 03:37:06.000000000 +0200
@@ -1182,15 +1182,19 @@ static int ieee80211_assoc(struct wiphy 
 }
 
 static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
-			    struct cfg80211_deauth_request *req)
+			    struct cfg80211_deauth_request *req,
+			    void *cookie)
 {
-	return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev), req);
+	return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev),
+				    req, cookie);
 }
 
 static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
-			      struct cfg80211_disassoc_request *req)
+			      struct cfg80211_disassoc_request *req,
+			      void *cookie)
 {
-	return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
+	return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev),
+				      req, cookie);
 }
 
 static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-07-07 03:37:03.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-07-07 03:37:06.000000000 +0200
@@ -916,9 +916,11 @@ int ieee80211_mgd_auth(struct ieee80211_
 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 			struct cfg80211_assoc_request *req);
 int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
-			 struct cfg80211_deauth_request *req);
+			 struct cfg80211_deauth_request *req,
+			 void *cookie);
 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
-			   struct cfg80211_disassoc_request *req);
+			   struct cfg80211_disassoc_request *req,
+			   void *cookie);
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
 					  struct sk_buff *skb);
 void ieee80211_send_pspoll(struct ieee80211_local *local,
--- wireless-testing.orig/net/mac80211/mlme.c	2009-07-07 03:37:04.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-07-07 03:37:06.000000000 +0200
@@ -386,7 +386,8 @@ static void ieee80211_send_assoc(struct 
 
 
 static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
-					   const u8 *bssid, u16 stype, u16 reason)
+					   const u8 *bssid, u16 stype, u16 reason,
+					   void *cookie)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -412,9 +413,9 @@ static void ieee80211_send_deauth_disass
 	mgmt->u.deauth.reason_code = cpu_to_le16(reason);
 
 	if (stype == IEEE80211_STYPE_DEAUTH)
-		cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
+		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, cookie);
 	else
-		cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
+		cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, cookie);
 	ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
 }
 
@@ -1837,10 +1838,12 @@ static void ieee80211_sta_rx_queued_mgmt
 			/* no action */
 			break;
 		case RX_MGMT_CFG80211_DEAUTH:
-			cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
+			cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len,
+					     NULL);
 			break;
 		case RX_MGMT_CFG80211_DISASSOC:
-			cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
+			cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len,
+					       NULL);
 			break;
 		default:
 			WARN(1, "unexpected: %d", rma);
@@ -2273,7 +2276,8 @@ int ieee80211_mgd_assoc(struct ieee80211
 }
 
 int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
-			 struct cfg80211_deauth_request *req)
+			 struct cfg80211_deauth_request *req,
+			 void *cookie)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_mgd_work *wk;
@@ -2305,13 +2309,15 @@ int ieee80211_mgd_deauth(struct ieee8021
 	mutex_unlock(&ifmgd->mtx);
 
 	ieee80211_send_deauth_disassoc(sdata, bssid,
-			IEEE80211_STYPE_DEAUTH, req->reason_code);
+			IEEE80211_STYPE_DEAUTH, req->reason_code,
+			cookie);
 
 	return 0;
 }
 
 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
-			   struct cfg80211_disassoc_request *req)
+			   struct cfg80211_disassoc_request *req,
+			   void *cookie)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
@@ -2331,6 +2337,7 @@ int ieee80211_mgd_disassoc(struct ieee80
 	mutex_unlock(&ifmgd->mtx);
 
 	ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
-			IEEE80211_STYPE_DISASSOC, req->reason_code);
+			IEEE80211_STYPE_DISASSOC, req->reason_code,
+			cookie);
 	return 0;
 }
--- wireless-testing.orig/net/wireless/nl80211.h	2009-07-07 03:29:39.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.h	2009-07-07 03:37:06.000000000 +0200
@@ -42,7 +42,7 @@ void nl80211_send_roamed(struct cfg80211
 			 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
 void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
 			       struct net_device *netdev, u16 reason,
-			       u8 *ie, size_t ie_len, bool from_ap, gfp_t gfp);
+			       const u8 *ie, size_t ie_len, bool from_ap);
 
 void
 nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 8/9] cfg80211: clean up naming once and for all
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
                   ` (6 preceding siblings ...)
  2009-07-07  1:56 ` [PATCH 7/9] cfg80211: fix locking Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  2009-07-07  1:56 ` [PATCH 9/9] cfg80211: disallow configuring unsupported interfaces Johannes Berg
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

We've named the registered devices 'drv' sometimes,
thinking of "driver", which is not what it is, it's
the internal representation of a wiphy, i.e. a
device. Let's clean up the naming once and and use
'rdev' aka 'registered device' everywhere.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/core.c    |  224 ++++++++++++++++----------------
 net/wireless/core.h    |   26 +--
 net/wireless/debugfs.c |   14 +-
 net/wireless/debugfs.h |    8 -
 net/wireless/nl80211.c |  340 ++++++++++++++++++++++++-------------------------
 net/wireless/reg.c     |   48 +++---
 net/wireless/sme.c     |   48 +++---
 7 files changed, 354 insertions(+), 354 deletions(-)

--- wireless-testing.orig/net/wireless/core.c	2009-07-07 03:37:06.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-07 03:37:06.000000000 +0200
@@ -30,10 +30,10 @@ MODULE_DESCRIPTION("wireless configurati
 /* RCU might be appropriate here since we usually
  * only read the list, and that can happen quite
  * often because we need to do it for each command */
-LIST_HEAD(cfg80211_drv_list);
+LIST_HEAD(cfg80211_rdev_list);
 
 /*
- * This is used to protect the cfg80211_drv_list, cfg80211_regdomain,
+ * This is used to protect the cfg80211_rdev_list, cfg80211_regdomain,
  * country_ie_regdomain, the reg_beacon_list and the the last regulatory
  * request receipt (last_request).
  */
@@ -43,18 +43,18 @@ DEFINE_MUTEX(cfg80211_mutex);
 static struct dentry *ieee80211_debugfs_dir;
 
 /* requires cfg80211_mutex to be held! */
-struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx)
+struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
 {
-	struct cfg80211_registered_device *result = NULL, *drv;
+	struct cfg80211_registered_device *result = NULL, *rdev;
 
 	if (!wiphy_idx_valid(wiphy_idx))
 		return NULL;
 
 	assert_cfg80211_lock();
 
-	list_for_each_entry(drv, &cfg80211_drv_list, list) {
-		if (drv->wiphy_idx == wiphy_idx) {
-			result = drv;
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		if (rdev->wiphy_idx == wiphy_idx) {
+			result = rdev;
 			break;
 		}
 	}
@@ -64,32 +64,32 @@ struct cfg80211_registered_device *cfg80
 
 int get_wiphy_idx(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	if (!wiphy)
 		return WIPHY_IDX_STALE;
-	drv = wiphy_to_dev(wiphy);
-	return drv->wiphy_idx;
+	rdev = wiphy_to_dev(wiphy);
+	return rdev->wiphy_idx;
 }
 
-/* requires cfg80211_drv_mutex to be held! */
+/* requires cfg80211_rdev_mutex to be held! */
 struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
 	if (!wiphy_idx_valid(wiphy_idx))
 		return NULL;
 
 	assert_cfg80211_lock();
 
-	drv = cfg80211_drv_by_wiphy_idx(wiphy_idx);
-	if (!drv)
+	rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx);
+	if (!rdev)
 		return NULL;
-	return &drv->wiphy;
+	return &rdev->wiphy;
 }
 
 /* requires cfg80211_mutex to be held! */
 struct cfg80211_registered_device *
-__cfg80211_drv_from_info(struct genl_info *info)
+__cfg80211_rdev_from_info(struct genl_info *info)
 {
 	int ifindex;
 	struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL;
@@ -99,7 +99,7 @@ __cfg80211_drv_from_info(struct genl_inf
 	assert_cfg80211_lock();
 
 	if (info->attrs[NL80211_ATTR_WIPHY]) {
-		bywiphyidx = cfg80211_drv_by_wiphy_idx(
+		bywiphyidx = cfg80211_rdev_by_wiphy_idx(
 				nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
 		err = -ENODEV;
 	}
@@ -134,26 +134,26 @@ __cfg80211_drv_from_info(struct genl_inf
 struct cfg80211_registered_device *
 cfg80211_get_dev_from_info(struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
 	mutex_lock(&cfg80211_mutex);
-	drv = __cfg80211_drv_from_info(info);
+	rdev = __cfg80211_rdev_from_info(info);
 
 	/* if it is not an error we grab the lock on
 	 * it to assure it won't be going away while
 	 * we operate on it */
-	if (!IS_ERR(drv))
-		mutex_lock(&drv->mtx);
+	if (!IS_ERR(rdev))
+		mutex_lock(&rdev->mtx);
 
 	mutex_unlock(&cfg80211_mutex);
 
-	return drv;
+	return rdev;
 }
 
 struct cfg80211_registered_device *
 cfg80211_get_dev_from_ifindex(int ifindex)
 {
-	struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV);
+	struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV);
 	struct net_device *dev;
 
 	mutex_lock(&cfg80211_mutex);
@@ -161,21 +161,21 @@ cfg80211_get_dev_from_ifindex(int ifinde
 	if (!dev)
 		goto out;
 	if (dev->ieee80211_ptr) {
-		drv = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
-		mutex_lock(&drv->mtx);
+		rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
+		mutex_lock(&rdev->mtx);
 	} else
-		drv = ERR_PTR(-ENODEV);
+		rdev = ERR_PTR(-ENODEV);
 	dev_put(dev);
  out:
 	mutex_unlock(&cfg80211_mutex);
-	return drv;
+	return rdev;
 }
 
 /* requires cfg80211_mutex to be held */
 int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 			char *newname)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev2;
 	int wiphy_idx, taken = -1, result, digits;
 
 	assert_cfg80211_lock();
@@ -201,8 +201,8 @@ int cfg80211_dev_rename(struct cfg80211_
 		return 0;
 
 	/* Ensure another device does not already have this name. */
-	list_for_each_entry(drv, &cfg80211_drv_list, list)
-		if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0)
+	list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
+		if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
 			return -EINVAL;
 
 	result = device_rename(&rdev->wiphy.dev, newname);
@@ -224,26 +224,26 @@ int cfg80211_dev_rename(struct cfg80211_
 
 static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
 {
-	struct cfg80211_registered_device *drv = data;
+	struct cfg80211_registered_device *rdev = data;
 
-	drv->ops->rfkill_poll(&drv->wiphy);
+	rdev->ops->rfkill_poll(&rdev->wiphy);
 }
 
 static int cfg80211_rfkill_set_block(void *data, bool blocked)
 {
-	struct cfg80211_registered_device *drv = data;
+	struct cfg80211_registered_device *rdev = data;
 	struct wireless_dev *wdev;
 
 	if (!blocked)
 		return 0;
 
 	rtnl_lock();
-	mutex_lock(&drv->devlist_mtx);
+	mutex_lock(&rdev->devlist_mtx);
 
-	list_for_each_entry(wdev, &drv->netdev_list, list)
+	list_for_each_entry(wdev, &rdev->netdev_list, list)
 		dev_close(wdev->netdev);
 
-	mutex_unlock(&drv->devlist_mtx);
+	mutex_unlock(&rdev->devlist_mtx);
 	rtnl_unlock();
 
 	return 0;
@@ -251,10 +251,10 @@ static int cfg80211_rfkill_set_block(voi
 
 static void cfg80211_rfkill_sync_work(struct work_struct *work)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
-	drv = container_of(work, struct cfg80211_registered_device, rfkill_sync);
-	cfg80211_rfkill_set_block(drv, rfkill_blocked(drv->rfkill));
+	rdev = container_of(work, struct cfg80211_registered_device, rfkill_sync);
+	cfg80211_rfkill_set_block(rdev, rfkill_blocked(rdev->rfkill));
 }
 
 static void cfg80211_process_events(struct wireless_dev *wdev)
@@ -328,79 +328,79 @@ struct wiphy *wiphy_new(const struct cfg
 {
 	static int wiphy_counter;
 
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int alloc_size;
 
 	WARN_ON(!ops->add_key && ops->del_key);
 	WARN_ON(ops->add_key && !ops->del_key);
 
-	alloc_size = sizeof(*drv) + sizeof_priv;
+	alloc_size = sizeof(*rdev) + sizeof_priv;
 
-	drv = kzalloc(alloc_size, GFP_KERNEL);
-	if (!drv)
+	rdev = kzalloc(alloc_size, GFP_KERNEL);
+	if (!rdev)
 		return NULL;
 
-	drv->ops = ops;
+	rdev->ops = ops;
 
 	mutex_lock(&cfg80211_mutex);
 
-	drv->wiphy_idx = wiphy_counter++;
+	rdev->wiphy_idx = wiphy_counter++;
 
-	if (unlikely(!wiphy_idx_valid(drv->wiphy_idx))) {
+	if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
 		wiphy_counter--;
 		mutex_unlock(&cfg80211_mutex);
 		/* ugh, wrapped! */
-		kfree(drv);
+		kfree(rdev);
 		return NULL;
 	}
 
 	mutex_unlock(&cfg80211_mutex);
 
 	/* give it a proper name */
-	dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->wiphy_idx);
+	dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
 
-	mutex_init(&drv->mtx);
-	mutex_init(&drv->devlist_mtx);
-	INIT_LIST_HEAD(&drv->netdev_list);
-	spin_lock_init(&drv->bss_lock);
-	INIT_LIST_HEAD(&drv->bss_list);
-	INIT_WORK(&drv->scan_done_wk, __cfg80211_scan_done);
-
-	device_initialize(&drv->wiphy.dev);
-	drv->wiphy.dev.class = &ieee80211_class;
-	drv->wiphy.dev.platform_data = drv;
-
-	drv->rfkill_ops.set_block = cfg80211_rfkill_set_block;
-	drv->rfkill = rfkill_alloc(dev_name(&drv->wiphy.dev),
-				   &drv->wiphy.dev, RFKILL_TYPE_WLAN,
-				   &drv->rfkill_ops, drv);
+	mutex_init(&rdev->mtx);
+	mutex_init(&rdev->devlist_mtx);
+	INIT_LIST_HEAD(&rdev->netdev_list);
+	spin_lock_init(&rdev->bss_lock);
+	INIT_LIST_HEAD(&rdev->bss_list);
+	INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
+
+	device_initialize(&rdev->wiphy.dev);
+	rdev->wiphy.dev.class = &ieee80211_class;
+	rdev->wiphy.dev.platform_data = rdev;
+
+	rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block;
+	rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev),
+				   &rdev->wiphy.dev, RFKILL_TYPE_WLAN,
+				   &rdev->rfkill_ops, rdev);
 
-	if (!drv->rfkill) {
-		kfree(drv);
+	if (!rdev->rfkill) {
+		kfree(rdev);
 		return NULL;
 	}
 
-	INIT_WORK(&drv->rfkill_sync, cfg80211_rfkill_sync_work);
-	INIT_WORK(&drv->conn_work, cfg80211_conn_work);
-	INIT_WORK(&drv->event_work, cfg80211_event_work);
+	INIT_WORK(&rdev->rfkill_sync, cfg80211_rfkill_sync_work);
+	INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
+	INIT_WORK(&rdev->event_work, cfg80211_event_work);
 
 	/*
 	 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
 	 * Fragmentation and RTS threshold are disabled by default with the
 	 * special -1 value.
 	 */
-	drv->wiphy.retry_short = 7;
-	drv->wiphy.retry_long = 4;
-	drv->wiphy.frag_threshold = (u32) -1;
-	drv->wiphy.rts_threshold = (u32) -1;
+	rdev->wiphy.retry_short = 7;
+	rdev->wiphy.retry_long = 4;
+	rdev->wiphy.frag_threshold = (u32) -1;
+	rdev->wiphy.rts_threshold = (u32) -1;
 
-	return &drv->wiphy;
+	return &rdev->wiphy;
 }
 EXPORT_SYMBOL(wiphy_new);
 
 int wiphy_register(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	int res;
 	enum ieee80211_band band;
 	struct ieee80211_supported_band *sband;
@@ -454,11 +454,11 @@ int wiphy_register(struct wiphy *wiphy)
 	/* check and set up bitrates */
 	ieee80211_set_bitrate_flags(wiphy);
 
-	res = device_add(&drv->wiphy.dev);
+	res = device_add(&rdev->wiphy.dev);
 	if (res)
 		return res;
 
-	res = rfkill_register(drv->rfkill);
+	res = rfkill_register(rdev->rfkill);
 	if (res)
 		goto out_rm_dev;
 
@@ -467,16 +467,16 @@ int wiphy_register(struct wiphy *wiphy)
 	/* set up regulatory info */
 	wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
 
-	list_add(&drv->list, &cfg80211_drv_list);
+	list_add(&rdev->list, &cfg80211_rdev_list);
 
 	mutex_unlock(&cfg80211_mutex);
 
 	/* add to debugfs */
-	drv->wiphy.debugfsdir =
-		debugfs_create_dir(wiphy_name(&drv->wiphy),
+	rdev->wiphy.debugfsdir =
+		debugfs_create_dir(wiphy_name(&rdev->wiphy),
 				   ieee80211_debugfs_dir);
-	if (IS_ERR(drv->wiphy.debugfsdir))
-		drv->wiphy.debugfsdir = NULL;
+	if (IS_ERR(rdev->wiphy.debugfsdir))
+		rdev->wiphy.debugfsdir = NULL;
 
 	if (wiphy->custom_regulatory) {
 		struct regulatory_request request;
@@ -489,48 +489,48 @@ int wiphy_register(struct wiphy *wiphy)
 		nl80211_send_reg_change_event(&request);
 	}
 
-	cfg80211_debugfs_drv_add(drv);
+	cfg80211_debugfs_rdev_add(rdev);
 
 	return 0;
 
  out_rm_dev:
-	device_del(&drv->wiphy.dev);
+	device_del(&rdev->wiphy.dev);
 	return res;
 }
 EXPORT_SYMBOL(wiphy_register);
 
 void wiphy_rfkill_start_polling(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	if (!drv->ops->rfkill_poll)
+	if (!rdev->ops->rfkill_poll)
 		return;
-	drv->rfkill_ops.poll = cfg80211_rfkill_poll;
-	rfkill_resume_polling(drv->rfkill);
+	rdev->rfkill_ops.poll = cfg80211_rfkill_poll;
+	rfkill_resume_polling(rdev->rfkill);
 }
 EXPORT_SYMBOL(wiphy_rfkill_start_polling);
 
 void wiphy_rfkill_stop_polling(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	rfkill_pause_polling(drv->rfkill);
+	rfkill_pause_polling(rdev->rfkill);
 }
 EXPORT_SYMBOL(wiphy_rfkill_stop_polling);
 
 void wiphy_unregister(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	rfkill_unregister(drv->rfkill);
+	rfkill_unregister(rdev->rfkill);
 
 	/* protect the device list */
 	mutex_lock(&cfg80211_mutex);
 
-	BUG_ON(!list_empty(&drv->netdev_list));
+	BUG_ON(!list_empty(&rdev->netdev_list));
 
 	/*
-	 * Try to grab drv->mtx. If a command is still in progress,
+	 * Try to grab rdev->mtx. If a command is still in progress,
 	 * hopefully the driver will refuse it since it's tearing
 	 * down the device already. We wait for this command to complete
 	 * before unlinking the item from the list.
@@ -539,38 +539,38 @@ void wiphy_unregister(struct wiphy *wiph
 	 * get to lock contention here if userspace issues a command
 	 * that identified the hardware by wiphy index.
 	 */
-	mutex_lock(&drv->mtx);
+	mutex_lock(&rdev->mtx);
 	/* unlock again before freeing */
-	mutex_unlock(&drv->mtx);
+	mutex_unlock(&rdev->mtx);
 
-	cancel_work_sync(&drv->conn_work);
-	cancel_work_sync(&drv->scan_done_wk);
-	kfree(drv->scan_req);
-	flush_work(&drv->event_work);
+	cancel_work_sync(&rdev->conn_work);
+	cancel_work_sync(&rdev->scan_done_wk);
+	kfree(rdev->scan_req);
+	flush_work(&rdev->event_work);
 
-	cfg80211_debugfs_drv_del(drv);
+	cfg80211_debugfs_rdev_del(rdev);
 
 	/* If this device got a regulatory hint tell core its
 	 * free to listen now to a new shiny device regulatory hint */
 	reg_device_remove(wiphy);
 
-	list_del(&drv->list);
-	device_del(&drv->wiphy.dev);
-	debugfs_remove(drv->wiphy.debugfsdir);
+	list_del(&rdev->list);
+	device_del(&rdev->wiphy.dev);
+	debugfs_remove(rdev->wiphy.debugfsdir);
 
 	mutex_unlock(&cfg80211_mutex);
 }
 EXPORT_SYMBOL(wiphy_unregister);
 
-void cfg80211_dev_free(struct cfg80211_registered_device *drv)
+void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
 {
 	struct cfg80211_internal_bss *scan, *tmp;
-	rfkill_destroy(drv->rfkill);
-	mutex_destroy(&drv->mtx);
-	mutex_destroy(&drv->devlist_mtx);
-	list_for_each_entry_safe(scan, tmp, &drv->bss_list, list)
+	rfkill_destroy(rdev->rfkill);
+	mutex_destroy(&rdev->mtx);
+	mutex_destroy(&rdev->devlist_mtx);
+	list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
 		cfg80211_put_bss(&scan->pub);
-	kfree(drv);
+	kfree(rdev);
 }
 
 void wiphy_free(struct wiphy *wiphy)
@@ -581,10 +581,10 @@ EXPORT_SYMBOL(wiphy_free);
 
 void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	if (rfkill_set_hw_state(drv->rfkill, blocked))
-		schedule_work(&drv->rfkill_sync);
+	if (rfkill_set_hw_state(rdev->rfkill, blocked))
+		schedule_work(&rdev->rfkill_sync);
 }
 EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
 
--- wireless-testing.orig/net/wireless/core.h	2009-07-07 03:37:06.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-07-07 03:37:06.000000000 +0200
@@ -97,13 +97,13 @@ bool wiphy_idx_valid(int wiphy_idx)
 }
 
 extern struct mutex cfg80211_mutex;
-extern struct list_head cfg80211_drv_list;
+extern struct list_head cfg80211_rdev_list;
 
 #define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
 
 /*
  * You can use this to mark a wiphy_idx as not having an associated wiphy.
- * It guarantees cfg80211_drv_by_wiphy_idx(wiphy_idx) will return NULL
+ * It guarantees cfg80211_rdev_by_wiphy_idx(wiphy_idx) will return NULL
  */
 #define WIPHY_IDX_STALE -1
 
@@ -136,11 +136,11 @@ static inline void cfg80211_unhold_bss(s
 }
 
 
-struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx);
+struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
 int get_wiphy_idx(struct wiphy *wiphy);
 
 struct cfg80211_registered_device *
-__cfg80211_drv_from_info(struct genl_info *info);
+__cfg80211_rdev_from_info(struct genl_info *info);
 
 /*
  * This function returns a pointer to the driver
@@ -153,7 +153,7 @@ __cfg80211_drv_from_info(struct genl_inf
  *
  * This is necessary because we need to lock the global
  * mutex to get an item off the list safely, and then
- * we lock the drv mutex so it doesn't go away under us.
+ * we lock the rdev mutex so it doesn't go away under us.
  *
  * We don't want to keep cfg80211_mutex locked
  * for all the time in order to allow requests on
@@ -165,22 +165,22 @@ __cfg80211_drv_from_info(struct genl_inf
 extern struct cfg80211_registered_device *
 cfg80211_get_dev_from_info(struct genl_info *info);
 
-/* requires cfg80211_drv_mutex to be held! */
+/* requires cfg80211_rdev_mutex to be held! */
 struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
 
 /* identical to cfg80211_get_dev_from_info but only operate on ifindex */
 extern struct cfg80211_registered_device *
 cfg80211_get_dev_from_ifindex(int ifindex);
 
-static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *drv)
+static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
 {
-	mutex_lock(&drv->mtx);
+	mutex_lock(&rdev->mtx);
 }
 
-static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *drv)
+static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev)
 {
-	BUG_ON(IS_ERR(drv) || !drv);
-	mutex_unlock(&drv->mtx);
+	BUG_ON(IS_ERR(rdev) || !rdev);
+	mutex_unlock(&rdev->mtx);
 }
 
 static inline void wdev_lock(struct wireless_dev *wdev)
@@ -240,9 +240,9 @@ struct cfg80211_event {
 
 
 /* free object */
-extern void cfg80211_dev_free(struct cfg80211_registered_device *drv);
+extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
 
-extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
+extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 			       char *newname);
 
 void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
--- wireless-testing.orig/net/wireless/debugfs.c	2009-07-07 03:25:42.000000000 +0200
+++ wireless-testing/net/wireless/debugfs.c	2009-07-07 03:37:06.000000000 +0200
@@ -104,15 +104,15 @@ static const struct file_operations ht40
 };
 
 #define DEBUGFS_ADD(name)						\
-	drv->debugfs.name = debugfs_create_file(#name, S_IRUGO, phyd,	\
-						  &drv->wiphy, &name## _ops);
+	rdev->debugfs.name = debugfs_create_file(#name, S_IRUGO, phyd,	\
+						  &rdev->wiphy, &name## _ops);
 #define DEBUGFS_DEL(name)						\
-	debugfs_remove(drv->debugfs.name);				\
-	drv->debugfs.name = NULL;
+	debugfs_remove(rdev->debugfs.name);				\
+	rdev->debugfs.name = NULL;
 
-void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv)
+void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev)
 {
-	struct dentry *phyd = drv->wiphy.debugfsdir;
+	struct dentry *phyd = rdev->wiphy.debugfsdir;
 
 	DEBUGFS_ADD(rts_threshold);
 	DEBUGFS_ADD(fragmentation_threshold);
@@ -121,7 +121,7 @@ void cfg80211_debugfs_drv_add(struct cfg
 	DEBUGFS_ADD(ht40allow_map);
 }
 
-void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv)
+void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev)
 {
 	DEBUGFS_DEL(rts_threshold);
 	DEBUGFS_DEL(fragmentation_threshold);
--- wireless-testing.orig/net/wireless/debugfs.h	2009-07-07 03:25:42.000000000 +0200
+++ wireless-testing/net/wireless/debugfs.h	2009-07-07 03:37:06.000000000 +0200
@@ -2,13 +2,13 @@
 #define __CFG80211_DEBUGFS_H
 
 #ifdef CONFIG_CFG80211_DEBUGFS
-void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv);
-void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv);
+void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev);
+void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev);
 #else
 static inline
-void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv) {}
+void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) {}
 static inline
-void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv) {}
+void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev) {}
 #endif
 
 #endif /* __CFG80211_DEBUGFS_H */
--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-07 03:37:06.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-07 03:37:06.000000000 +0200
@@ -29,9 +29,9 @@ static struct genl_family nl80211_fam = 
 	.maxattr = NL80211_ATTR_MAX,
 };
 
-/* internal helper: get drv and dev */
-static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,
-				       struct cfg80211_registered_device **drv,
+/* internal helper: get rdev and dev */
+static int get_rdev_dev_by_info_ifindex(struct nlattr **attrs,
+				       struct cfg80211_registered_device **rdev,
 				       struct net_device **dev)
 {
 	int ifindex;
@@ -44,10 +44,10 @@ static int get_drv_dev_by_info_ifindex(s
 	if (!*dev)
 		return -ENODEV;
 
-	*drv = cfg80211_get_dev_from_ifindex(ifindex);
-	if (IS_ERR(*drv)) {
+	*rdev = cfg80211_get_dev_from_ifindex(ifindex);
+	if (IS_ERR(*rdev)) {
 		dev_put(*dev);
-		return PTR_ERR(*drv);
+		return PTR_ERR(*rdev);
 	}
 
 	return 0;
@@ -378,7 +378,7 @@ static int nl80211_dump_wiphy(struct sk_
 	struct cfg80211_registered_device *dev;
 
 	mutex_lock(&cfg80211_mutex);
-	list_for_each_entry(dev, &cfg80211_drv_list, list) {
+	list_for_each_entry(dev, &cfg80211_rdev_list, list) {
 		if (++idx <= start)
 			continue;
 		if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
@@ -460,7 +460,7 @@ static int nl80211_set_wiphy(struct sk_b
 
 	mutex_lock(&cfg80211_mutex);
 
-	rdev = __cfg80211_drv_from_info(info);
+	rdev = __cfg80211_rdev_from_info(info);
 	if (IS_ERR(rdev)) {
 		mutex_unlock(&cfg80211_mutex);
 		result = PTR_ERR(rdev);
@@ -683,7 +683,7 @@ static int nl80211_dump_interface(struct
 	struct wireless_dev *wdev;
 
 	mutex_lock(&cfg80211_mutex);
-	list_for_each_entry(dev, &cfg80211_drv_list, list) {
+	list_for_each_entry(dev, &cfg80211_rdev_list, list) {
 		if (wp_idx < wp_start) {
 			wp_idx++;
 			continue;
@@ -724,7 +724,7 @@ static int nl80211_get_interface(struct 
 	struct net_device *netdev;
 	int err;
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &dev, &netdev);
 	if (err)
 		return err;
 
@@ -780,7 +780,7 @@ static int parse_monitor_flags(struct nl
 
 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct vif_params params;
 	int err;
 	enum nl80211_iftype otype, ntype;
@@ -792,7 +792,7 @@ static int nl80211_set_interface(struct 
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
@@ -808,8 +808,8 @@ static int nl80211_set_interface(struct 
 		}
 	}
 
-	if (!drv->ops->change_virtual_intf ||
-	    !(drv->wiphy.interface_modes & (1 << ntype))) {
+	if (!rdev->ops->change_virtual_intf ||
+	    !(rdev->wiphy.interface_modes & (1 << ntype))) {
 		err = -EOPNOTSUPP;
 		goto unlock;
 	}
@@ -839,7 +839,7 @@ static int nl80211_set_interface(struct 
 	}
 
 	if (change)
-		err = drv->ops->change_virtual_intf(&drv->wiphy, dev,
+		err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev,
 						    ntype, flags, &params);
 	else
 		err = 0;
@@ -853,7 +853,7 @@ static int nl80211_set_interface(struct 
 
  unlock:
 	dev_put(dev);
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -861,7 +861,7 @@ static int nl80211_set_interface(struct 
 
 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct vif_params params;
 	int err;
 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -880,14 +880,14 @@ static int nl80211_new_interface(struct 
 
 	rtnl_lock();
 
-	drv = cfg80211_get_dev_from_info(info);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
+	rdev = cfg80211_get_dev_from_info(info);
+	if (IS_ERR(rdev)) {
+		err = PTR_ERR(rdev);
 		goto unlock_rtnl;
 	}
 
-	if (!drv->ops->add_virtual_intf ||
-	    !(drv->wiphy.interface_modes & (1 << type))) {
+	if (!rdev->ops->add_virtual_intf ||
+	    !(rdev->wiphy.interface_modes & (1 << type))) {
 		err = -EOPNOTSUPP;
 		goto unlock;
 	}
@@ -901,12 +901,12 @@ static int nl80211_new_interface(struct 
 	err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
 				  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
 				  &flags);
-	err = drv->ops->add_virtual_intf(&drv->wiphy,
+	err = rdev->ops->add_virtual_intf(&rdev->wiphy,
 		nla_data(info->attrs[NL80211_ATTR_IFNAME]),
 		type, err ? NULL : &flags, &params);
 
  unlock:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -914,27 +914,27 @@ static int nl80211_new_interface(struct 
 
 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int ifindex, err;
 	struct net_device *dev;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 	ifindex = dev->ifindex;
 	dev_put(dev);
 
-	if (!drv->ops->del_virtual_intf) {
+	if (!rdev->ops->del_virtual_intf) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
+	err = rdev->ops->del_virtual_intf(&rdev->wiphy, ifindex);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -968,7 +968,7 @@ static void get_key_callback(void *c, st
 
 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 key_idx = 0;
@@ -990,11 +990,11 @@ static int nl80211_get_key(struct sk_buf
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->get_key) {
+	if (!rdev->ops->get_key) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1020,7 +1020,7 @@ static int nl80211_get_key(struct sk_buf
 	if (mac_addr)
 		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
 
-	err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
+	err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr,
 				&cookie, get_key_callback);
 
 	if (err)
@@ -1037,7 +1037,7 @@ static int nl80211_get_key(struct sk_buf
 	err = -ENOBUFS;
 	nlmsg_free(msg);
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1047,7 +1047,7 @@ static int nl80211_get_key(struct sk_buf
 
 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 key_idx;
@@ -1072,24 +1072,24 @@ static int nl80211_set_key(struct sk_buf
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
 	if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
-		func = drv->ops->set_default_key;
+		func = rdev->ops->set_default_key;
 	else
-		func = drv->ops->set_default_mgmt_key;
+		func = rdev->ops->set_default_mgmt_key;
 
 	if (!func) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = func(&drv->wiphy, dev, key_idx);
+	err = func(&rdev->wiphy, dev, key_idx);
 #ifdef CONFIG_WIRELESS_EXT
 	if (!err) {
-		if (func == drv->ops->set_default_key)
+		if (func == rdev->ops->set_default_key)
 			dev->ieee80211_ptr->wext.default_key = key_idx;
 		else
 			dev->ieee80211_ptr->wext.default_mgmt_key = key_idx;
@@ -1097,7 +1097,7 @@ static int nl80211_set_key(struct sk_buf
 #endif
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 
  unlock_rtnl:
@@ -1108,7 +1108,7 @@ static int nl80211_set_key(struct sk_buf
 
 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err, i;
 	struct net_device *dev;
 	struct key_params params;
@@ -1143,27 +1143,27 @@ static int nl80211_new_key(struct sk_buf
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
-		if (params.cipher == drv->wiphy.cipher_suites[i])
+	for (i = 0; i < rdev->wiphy.n_cipher_suites; i++)
+		if (params.cipher == rdev->wiphy.cipher_suites[i])
 			break;
-	if (i == drv->wiphy.n_cipher_suites) {
+	if (i == rdev->wiphy.n_cipher_suites) {
 		err = -EINVAL;
 		goto out;
 	}
 
-	if (!drv->ops->add_key) {
+	if (!rdev->ops->add_key) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
+	err = rdev->ops->add_key(&rdev->wiphy, dev, key_idx, mac_addr, &params);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1173,7 +1173,7 @@ static int nl80211_new_key(struct sk_buf
 
 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 key_idx = 0;
@@ -1190,16 +1190,16 @@ static int nl80211_del_key(struct sk_buf
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->del_key) {
+	if (!rdev->ops->del_key) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
+	err = rdev->ops->del_key(&rdev->wiphy, dev, key_idx, mac_addr);
 
 #ifdef CONFIG_WIRELESS_EXT
 	if (!err) {
@@ -1211,7 +1211,7 @@ static int nl80211_del_key(struct sk_buf
 #endif
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 
  unlock_rtnl:
@@ -1224,7 +1224,7 @@ static int nl80211_addset_beacon(struct 
 {
         int (*call)(struct wiphy *wiphy, struct net_device *dev,
 		    struct beacon_parameters *info);
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct beacon_parameters params;
@@ -1235,7 +1235,7 @@ static int nl80211_addset_beacon(struct 
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
@@ -1254,10 +1254,10 @@ static int nl80211_addset_beacon(struct 
 			goto out;
 		}
 
-		call = drv->ops->add_beacon;
+		call = rdev->ops->add_beacon;
 		break;
 	case NL80211_CMD_SET_BEACON:
-		call = drv->ops->set_beacon;
+		call = rdev->ops->set_beacon;
 		break;
 	default:
 		WARN_ON(1);
@@ -1303,10 +1303,10 @@ static int nl80211_addset_beacon(struct 
 		goto out;
 	}
 
-	err = call(&drv->wiphy, dev, &params);
+	err = call(&rdev->wiphy, dev, &params);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1316,17 +1316,17 @@ static int nl80211_addset_beacon(struct 
 
 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->del_beacon) {
+	if (!rdev->ops->del_beacon) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1335,10 +1335,10 @@ static int nl80211_del_beacon(struct sk_
 		err = -EOPNOTSUPP;
 		goto out;
 	}
-	err = drv->ops->del_beacon(&drv->wiphy, dev);
+	err = rdev->ops->del_beacon(&rdev->wiphy, dev);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1581,7 +1581,7 @@ static int nl80211_dump_station(struct s
 
 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct station_info sinfo;
@@ -1597,16 +1597,16 @@ static int nl80211_get_station(struct sk
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->get_station) {
+	if (!rdev->ops->get_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
+	err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo);
 	if (err)
 		goto out;
 
@@ -1624,7 +1624,7 @@ static int nl80211_get_station(struct sk
  out_free:
 	nlmsg_free(msg);
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1655,7 +1655,7 @@ static int get_vlan(struct nlattr *vlana
 
 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct station_parameters params;
@@ -1697,11 +1697,11 @@ static int nl80211_set_station(struct sk
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
+	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan);
 	if (err)
 		goto out;
 
@@ -1750,17 +1750,17 @@ static int nl80211_set_station(struct sk
 	if (err)
 		goto out;
 
-	if (!drv->ops->change_station) {
+	if (!rdev->ops->change_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
+	err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, &params);
 
  out:
 	if (params.vlan)
 		dev_put(params.vlan);
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1770,7 +1770,7 @@ static int nl80211_set_station(struct sk
 
 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct station_parameters params;
@@ -1810,11 +1810,11 @@ static int nl80211_new_station(struct sk
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
+	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan);
 	if (err)
 		goto out;
 
@@ -1850,7 +1850,7 @@ static int nl80211_new_station(struct sk
 	if (err)
 		goto out;
 
-	if (!drv->ops->add_station) {
+	if (!rdev->ops->add_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1860,12 +1860,12 @@ static int nl80211_new_station(struct sk
 		goto out;
 	}
 
-	err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
+	err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
 
  out:
 	if (params.vlan)
 		dev_put(params.vlan);
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1875,7 +1875,7 @@ static int nl80211_new_station(struct sk
 
 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *mac_addr = NULL;
@@ -1885,7 +1885,7 @@ static int nl80211_del_station(struct sk
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
@@ -1896,15 +1896,15 @@ static int nl80211_del_station(struct sk
 		goto out;
 	}
 
-	if (!drv->ops->del_station) {
+	if (!rdev->ops->del_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
+	err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2044,7 +2044,7 @@ static int nl80211_dump_mpath(struct sk_
 
 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct mpath_info pinfo;
@@ -2061,11 +2061,11 @@ static int nl80211_get_mpath(struct sk_b
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->get_mpath) {
+	if (!rdev->ops->get_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2075,7 +2075,7 @@ static int nl80211_get_mpath(struct sk_b
 		goto out;
 	}
 
-	err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
+	err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo);
 	if (err)
 		goto out;
 
@@ -2093,7 +2093,7 @@ static int nl80211_get_mpath(struct sk_b
  out_free:
 	nlmsg_free(msg);
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2103,7 +2103,7 @@ static int nl80211_get_mpath(struct sk_b
 
 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *dst = NULL;
@@ -2120,11 +2120,11 @@ static int nl80211_set_mpath(struct sk_b
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->change_mpath) {
+	if (!rdev->ops->change_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2139,10 +2139,10 @@ static int nl80211_set_mpath(struct sk_b
 		goto out;
 	}
 
-	err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
+	err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2151,7 +2151,7 @@ static int nl80211_set_mpath(struct sk_b
 }
 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *dst = NULL;
@@ -2168,11 +2168,11 @@ static int nl80211_new_mpath(struct sk_b
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->add_mpath) {
+	if (!rdev->ops->add_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2187,10 +2187,10 @@ static int nl80211_new_mpath(struct sk_b
 		goto out;
 	}
 
-	err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
+	err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2200,7 +2200,7 @@ static int nl80211_new_mpath(struct sk_b
 
 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *dst = NULL;
@@ -2210,19 +2210,19 @@ static int nl80211_del_mpath(struct sk_b
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->del_mpath) {
+	if (!rdev->ops->del_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
+	err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2232,7 +2232,7 @@ static int nl80211_del_mpath(struct sk_b
 
 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct bss_parameters params;
@@ -2261,11 +2261,11 @@ static int nl80211_set_bss(struct sk_buf
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->change_bss) {
+	if (!rdev->ops->change_bss) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2275,10 +2275,10 @@ static int nl80211_set_bss(struct sk_buf
 		goto out;
 	}
 
-	err = drv->ops->change_bss(&drv->wiphy, dev, &params);
+	err = rdev->ops->change_bss(&rdev->wiphy, dev, &params);
 
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2369,7 +2369,7 @@ static int nl80211_req_set_reg(struct sk
 static int nl80211_get_mesh_params(struct sk_buff *skb,
 	struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct mesh_config cur_params;
 	int err;
 	struct net_device *dev;
@@ -2380,17 +2380,17 @@ static int nl80211_get_mesh_params(struc
 	rtnl_lock();
 
 	/* Look up our device */
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->get_mesh_params) {
+	if (!rdev->ops->get_mesh_params) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
 	/* Get the mesh params */
-	err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params);
+	err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params);
 	if (err)
 		goto out;
 
@@ -2444,7 +2444,7 @@ static int nl80211_get_mesh_params(struc
 	err = -EMSGSIZE;
  out:
 	/* Cleanup */
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2482,7 +2482,7 @@ static int nl80211_set_mesh_params(struc
 {
 	int err;
 	u32 mask;
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct mesh_config cfg;
 	struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
@@ -2497,11 +2497,11 @@ static int nl80211_set_mesh_params(struc
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->set_mesh_params) {
+	if (!rdev->ops->set_mesh_params) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2546,11 +2546,11 @@ static int nl80211_set_mesh_params(struc
 			nla_get_u16);
 
 	/* Apply changes */
-	err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask);
+	err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
 
  out:
 	/* cleanup */
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2737,7 +2737,7 @@ static int validate_scan_freqs(struct nl
 
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct cfg80211_scan_request *request;
 	struct cfg80211_ssid *ssid;
@@ -2753,13 +2753,13 @@ static int nl80211_trigger_scan(struct s
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	wiphy = &drv->wiphy;
+	wiphy = &rdev->wiphy;
 
-	if (!drv->ops->scan) {
+	if (!rdev->ops->scan) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2769,7 +2769,7 @@ static int nl80211_trigger_scan(struct s
 		goto out;
 	}
 
-	if (drv->scan_req) {
+	if (rdev->scan_req) {
 		err = -EBUSY;
 		goto out;
 	}
@@ -2876,21 +2876,21 @@ static int nl80211_trigger_scan(struct s
 	}
 
 	request->ifidx = dev->ifindex;
-	request->wiphy = &drv->wiphy;
+	request->wiphy = &rdev->wiphy;
 
-	drv->scan_req = request;
-	err = drv->ops->scan(&drv->wiphy, dev, request);
+	rdev->scan_req = request;
+	err = rdev->ops->scan(&rdev->wiphy, dev, request);
 
 	if (!err)
-		nl80211_send_scan_start(drv, dev);
+		nl80211_send_scan_start(rdev, dev);
 
  out_free:
 	if (err) {
-		drv->scan_req = NULL;
+		rdev->scan_req = NULL;
 		kfree(request);
 	}
  out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -3043,7 +3043,7 @@ static bool nl80211_valid_cipher_suite(u
 
 static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct ieee80211_channel *chan;
 	const u8 *bssid, *ssid, *ie = NULL;
@@ -3067,11 +3067,11 @@ static int nl80211_authenticate(struct s
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->auth) {
+	if (!rdev->ops->auth) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3087,7 +3087,7 @@ static int nl80211_authenticate(struct s
 	}
 
 	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
-	chan = ieee80211_get_channel(&drv->wiphy,
+	chan = ieee80211_get_channel(&rdev->wiphy,
 		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
 	if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
 		err = -EINVAL;
@@ -3108,11 +3108,11 @@ static int nl80211_authenticate(struct s
 		goto out;
 	}
 
-	err = cfg80211_mlme_auth(drv, dev, chan, auth_type, bssid,
+	err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
 				 ssid, ssid_len, ie, ie_len);
 
 out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3202,7 +3202,7 @@ static int nl80211_associate(struct sk_b
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &rdev, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
@@ -3268,7 +3268,7 @@ unlock_rtnl:
 
 static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	const u8 *ie = NULL, *bssid;
 	int err, ie_len = 0;
@@ -3285,11 +3285,11 @@ static int nl80211_deauthenticate(struct
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->deauth) {
+	if (!rdev->ops->deauth) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3318,10 +3318,10 @@ static int nl80211_deauthenticate(struct
 		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	err = cfg80211_mlme_deauth(drv, dev, bssid, ie, ie_len, reason_code);
+	err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code);
 
 out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3330,7 +3330,7 @@ unlock_rtnl:
 
 static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	const u8 *ie = NULL, *bssid;
 	int err, ie_len = 0;
@@ -3347,11 +3347,11 @@ static int nl80211_disassociate(struct s
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->disassoc) {
+	if (!rdev->ops->disassoc) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3380,10 +3380,10 @@ static int nl80211_disassociate(struct s
 		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	err = cfg80211_mlme_disassoc(drv, dev, bssid, ie, ie_len, reason_code);
+	err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code);
 
 out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3392,7 +3392,7 @@ unlock_rtnl:
 
 static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct cfg80211_ibss_params ibss;
 	struct wiphy *wiphy;
@@ -3419,11 +3419,11 @@ static int nl80211_join_ibss(struct sk_b
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->join_ibss) {
+	if (!rdev->ops->join_ibss) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3438,7 +3438,7 @@ static int nl80211_join_ibss(struct sk_b
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
+	wiphy = &rdev->wiphy;
 
 	if (info->attrs[NL80211_ATTR_MAC])
 		ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
@@ -3461,10 +3461,10 @@ static int nl80211_join_ibss(struct sk_b
 
 	ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
 
-	err = cfg80211_join_ibss(drv, dev, &ibss);
+	err = cfg80211_join_ibss(rdev, dev, &ibss);
 
 out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3473,17 +3473,17 @@ unlock_rtnl:
 
 static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	int err;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->leave_ibss) {
+	if (!rdev->ops->leave_ibss) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3498,10 +3498,10 @@ static int nl80211_leave_ibss(struct sk_
 		goto out;
 	}
 
-	err = cfg80211_leave_ibss(drv, dev, false);
+	err = cfg80211_leave_ibss(rdev, dev, false);
 
 out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3632,7 +3632,7 @@ EXPORT_SYMBOL(cfg80211_testmode_event);
 
 static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct cfg80211_connect_params connect;
 	struct wiphy *wiphy;
@@ -3663,7 +3663,7 @@ static int nl80211_connect(struct sk_buf
 		return err;
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
@@ -3677,7 +3677,7 @@ static int nl80211_connect(struct sk_buf
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
+	wiphy = &rdev->wiphy;
 
 	connect.bssid = NULL;
 	connect.channel = NULL;
@@ -3704,10 +3704,10 @@ static int nl80211_connect(struct sk_buf
 		}
 	}
 
-	err = cfg80211_connect(drv, dev, &connect);
+	err = cfg80211_connect(rdev, dev, &connect);
 
 out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3716,7 +3716,7 @@ unlock_rtnl:
 
 static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	int err;
 	u16 reason;
@@ -3731,7 +3731,7 @@ static int nl80211_disconnect(struct sk_
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
@@ -3745,10 +3745,10 @@ static int nl80211_disconnect(struct sk_
 		goto out;
 	}
 
-	err = cfg80211_disconnect(drv, dev, reason, true);
+	err = cfg80211_disconnect(rdev, dev, reason, true);
 
 out:
-	cfg80211_unlock_rdev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
--- wireless-testing.orig/net/wireless/reg.c	2009-07-07 03:25:42.000000000 +0200
+++ wireless-testing/net/wireless/reg.c	2009-07-07 03:37:06.000000000 +0200
@@ -1061,10 +1061,10 @@ static bool ignore_reg_update(struct wip
 
 static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
-	list_for_each_entry(drv, &cfg80211_drv_list, list)
-		wiphy_update_regulatory(&drv->wiphy, initiator);
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list)
+		wiphy_update_regulatory(&rdev->wiphy, initiator);
 }
 
 static void handle_reg_beacon(struct wiphy *wiphy,
@@ -1614,7 +1614,7 @@ static void reg_process_pending_hints(vo
 /* Processes beacon hints -- this has nothing to do with country IEs */
 static void reg_process_pending_beacon_hints(void)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct reg_beacon *pending_beacon, *tmp;
 
 	mutex_lock(&cfg80211_mutex);
@@ -1633,8 +1633,8 @@ static void reg_process_pending_beacon_h
 		list_del_init(&pending_beacon->list);
 
 		/* Applies the beacon hint to current wiphys */
-		list_for_each_entry(drv, &cfg80211_drv_list, list)
-			wiphy_update_new_beacon(&drv->wiphy, pending_beacon);
+		list_for_each_entry(rdev, &cfg80211_rdev_list, list)
+			wiphy_update_new_beacon(&rdev->wiphy, pending_beacon);
 
 		/* Remembers the beacon hint for new wiphys or reg changes */
 		list_add_tail(&pending_beacon->list, &reg_beacon_list);
@@ -1814,23 +1814,23 @@ void regulatory_hint_11d(struct wiphy *w
 	if (likely(last_request->initiator ==
 	    NL80211_REGDOM_SET_BY_COUNTRY_IE &&
 	    wiphy_idx_valid(last_request->wiphy_idx))) {
-		struct cfg80211_registered_device *drv_last_ie;
+		struct cfg80211_registered_device *rdev_last_ie;
 
-		drv_last_ie =
-			cfg80211_drv_by_wiphy_idx(last_request->wiphy_idx);
+		rdev_last_ie =
+			cfg80211_rdev_by_wiphy_idx(last_request->wiphy_idx);
 
 		/*
 		 * Lets keep this simple -- we trust the first AP
 		 * after we intersect with CRDA
 		 */
-		if (likely(&drv_last_ie->wiphy == wiphy)) {
+		if (likely(&rdev_last_ie->wiphy == wiphy)) {
 			/*
 			 * Ignore IEs coming in on this wiphy with
 			 * the same alpha2 and environment cap
 			 */
-			if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
+			if (likely(alpha2_equal(rdev_last_ie->country_ie_alpha2,
 				  alpha2) &&
-				  env == drv_last_ie->env)) {
+				  env == rdev_last_ie->env)) {
 				goto out;
 			}
 			/*
@@ -1846,9 +1846,9 @@ void regulatory_hint_11d(struct wiphy *w
 			 * Ignore IEs coming in on two separate wiphys with
 			 * the same alpha2 and environment cap
 			 */
-			if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
+			if (likely(alpha2_equal(rdev_last_ie->country_ie_alpha2,
 				  alpha2) &&
-				  env == drv_last_ie->env)) {
+				  env == rdev_last_ie->env)) {
 				goto out;
 			}
 			/* We could potentially intersect though */
@@ -1995,14 +1995,14 @@ static void print_regdomain(const struct
 
 		if (last_request->initiator ==
 		    NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-			struct cfg80211_registered_device *drv;
-			drv = cfg80211_drv_by_wiphy_idx(
+			struct cfg80211_registered_device *rdev;
+			rdev = cfg80211_rdev_by_wiphy_idx(
 				last_request->wiphy_idx);
-			if (drv) {
+			if (rdev) {
 				printk(KERN_INFO "cfg80211: Current regulatory "
 					"domain updated by AP to: %c%c\n",
-					drv->country_ie_alpha2[0],
-					drv->country_ie_alpha2[1]);
+					rdev->country_ie_alpha2[0],
+					rdev->country_ie_alpha2[1]);
 			} else
 				printk(KERN_INFO "cfg80211: Current regulatory "
 					"domain intersected: \n");
@@ -2063,7 +2063,7 @@ static inline void reg_country_ie_proces
 static int __set_regdom(const struct ieee80211_regdomain *rd)
 {
 	const struct ieee80211_regdomain *intersected_rd = NULL;
-	struct cfg80211_registered_device *drv = NULL;
+	struct cfg80211_registered_device *rdev = NULL;
 	struct wiphy *request_wiphy;
 	/* Some basic sanity checks first */
 
@@ -2202,11 +2202,11 @@ static int __set_regdom(const struct iee
 	if (!intersected_rd)
 		return -EINVAL;
 
-	drv = wiphy_to_dev(request_wiphy);
+	rdev = wiphy_to_dev(request_wiphy);
 
-	drv->country_ie_alpha2[0] = rd->alpha2[0];
-	drv->country_ie_alpha2[1] = rd->alpha2[1];
-	drv->env = last_request->country_ie_env;
+	rdev->country_ie_alpha2[0] = rd->alpha2[0];
+	rdev->country_ie_alpha2[1] = rd->alpha2[1];
+	rdev->env = last_request->country_ie_env;
 
 	BUG_ON(intersected_rd == rd);
 
--- wireless-testing.orig/net/wireless/sme.c	2009-07-07 03:37:06.000000000 +0200
+++ wireless-testing/net/wireless/sme.c	2009-07-07 03:37:06.000000000 +0200
@@ -33,15 +33,15 @@ struct cfg80211_conn {
 
 static int cfg80211_conn_scan(struct wireless_dev *wdev)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 	struct cfg80211_scan_request *request;
 	int n_channels, err;
 
 	ASSERT_RTNL();
-	ASSERT_RDEV_LOCK(drv);
+	ASSERT_RDEV_LOCK(rdev);
 	ASSERT_WDEV_LOCK(wdev);
 
-	if (drv->scan_req)
+	if (rdev->scan_req)
 		return -EBUSY;
 
 	if (wdev->conn->params.channel) {
@@ -87,16 +87,16 @@ static int cfg80211_conn_scan(struct wir
 	request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
 
 	request->ifidx = wdev->netdev->ifindex;
-	request->wiphy = &drv->wiphy;
+	request->wiphy = &rdev->wiphy;
 
-	drv->scan_req = request;
+	rdev->scan_req = request;
 
-	err = drv->ops->scan(wdev->wiphy, wdev->netdev, request);
+	err = rdev->ops->scan(wdev->wiphy, wdev->netdev, request);
 	if (!err) {
 		wdev->conn->state = CFG80211_CONN_SCANNING;
-		nl80211_send_scan_start(drv, wdev->netdev);
+		nl80211_send_scan_start(rdev, wdev->netdev);
 	} else {
-		drv->scan_req = NULL;
+		rdev->scan_req = NULL;
 		kfree(request);
 	}
 	return err;
@@ -104,7 +104,7 @@ 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);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 	struct cfg80211_connect_params *params;
 	int err;
 
@@ -119,15 +119,15 @@ static int cfg80211_conn_do_work(struct 
 	case CFG80211_CONN_SCAN_AGAIN:
 		return cfg80211_conn_scan(wdev);
 	case CFG80211_CONN_AUTHENTICATE_NEXT:
-		BUG_ON(!drv->ops->auth);
+		BUG_ON(!rdev->ops->auth);
 		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
-		return __cfg80211_mlme_auth(drv, wdev->netdev,
+		return __cfg80211_mlme_auth(rdev, wdev->netdev,
 					    params->channel, params->auth_type,
 					    params->bssid,
 					    params->ssid, params->ssid_len,
 					    NULL, 0);
 	case CFG80211_CONN_ASSOCIATE_NEXT:
-		BUG_ON(!drv->ops->assoc);
+		BUG_ON(!rdev->ops->assoc);
 		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
 		/*
 		 * We could, later, implement roaming here and then actually
@@ -135,14 +135,14 @@ static int cfg80211_conn_do_work(struct 
 		 * that some APs don't like that -- so we'd need to retry
 		 * the association.
 		 */
-		err = __cfg80211_mlme_assoc(drv, wdev->netdev,
+		err = __cfg80211_mlme_assoc(rdev, wdev->netdev,
 					    params->channel, params->bssid,
 					    NULL,
 					    params->ssid, params->ssid_len,
 					    params->ie, params->ie_len,
 					    false, &params->crypto);
 		if (err)
-			__cfg80211_mlme_deauth(drv, wdev->netdev, params->bssid,
+			__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
 					       NULL, 0,
 					       WLAN_REASON_DEAUTH_LEAVING);
 		return err;
@@ -153,15 +153,15 @@ static int cfg80211_conn_do_work(struct 
 
 void cfg80211_conn_work(struct work_struct *work)
 {
-	struct cfg80211_registered_device *drv =
+	struct cfg80211_registered_device *rdev =
 		container_of(work, struct cfg80211_registered_device, conn_work);
 	struct wireless_dev *wdev;
 
 	rtnl_lock();
-	cfg80211_lock_rdev(drv);
-	mutex_lock(&drv->devlist_mtx);
+	cfg80211_lock_rdev(rdev);
+	mutex_lock(&rdev->devlist_mtx);
 
-	list_for_each_entry(wdev, &drv->netdev_list, list) {
+	list_for_each_entry(wdev, &rdev->netdev_list, list) {
 		wdev_lock(wdev);
 		if (!netif_running(wdev->netdev)) {
 			wdev_unlock(wdev);
@@ -181,14 +181,14 @@ void cfg80211_conn_work(struct work_stru
 		wdev_unlock(wdev);
 	}
 
-	mutex_unlock(&drv->devlist_mtx);
-	cfg80211_unlock_rdev(drv);
+	mutex_unlock(&rdev->devlist_mtx);
+	cfg80211_unlock_rdev(rdev);
 	rtnl_unlock();
 }
 
 static bool cfg80211_get_conn_bss(struct wireless_dev *wdev)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 	struct cfg80211_bss *bss;
 	u16 capa = WLAN_CAPABILITY_ESS;
 
@@ -209,7 +209,7 @@ static bool cfg80211_get_conn_bss(struct
 	wdev->conn->params.bssid = wdev->conn->bssid;
 	wdev->conn->params.channel = bss->channel;
 	wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
-	schedule_work(&drv->conn_work);
+	schedule_work(&rdev->conn_work);
 
 	cfg80211_put_bss(bss);
 	return true;
@@ -218,7 +218,7 @@ static bool cfg80211_get_conn_bss(struct
 static void __cfg80211_sme_scan_done(struct net_device *dev)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 
 	ASSERT_WDEV_LOCK(wdev);
 
@@ -235,7 +235,7 @@ static void __cfg80211_sme_scan_done(str
 	if (!cfg80211_get_conn_bss(wdev)) {
 		/* not found */
 		if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
-			schedule_work(&drv->conn_work);
+			schedule_work(&rdev->conn_work);
 		else
 			__cfg80211_connect_result(
 					wdev->netdev,

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 9/9] cfg80211: disallow configuring unsupported interfaces
  2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
                   ` (7 preceding siblings ...)
  2009-07-07  1:56 ` [PATCH 8/9] cfg80211: clean up naming once and for all Johannes Berg
@ 2009-07-07  1:56 ` Johannes Berg
  8 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-07-07  1:56 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

In order to force drivers to advertise their interface
types, don't just disallow creating new interfaces with
unadvertised types but also disallow setting them UP.
Additionally, add some validation on the operations the
drivers support.

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

--- wireless-testing.orig/net/wireless/core.c	2009-07-07 03:37:06.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-07 03:37:07.000000000 +0200
@@ -331,8 +331,13 @@ struct wiphy *wiphy_new(const struct cfg
 	struct cfg80211_registered_device *rdev;
 	int alloc_size;
 
-	WARN_ON(!ops->add_key && ops->del_key);
-	WARN_ON(ops->add_key && !ops->del_key);
+	WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
+	WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
+	WARN_ON(ops->connect && !ops->disconnect);
+	WARN_ON(ops->join_ibss && !ops->leave_ibss);
+	WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf);
+	WARN_ON(ops->add_station && !ops->del_station);
+	WARN_ON(ops->add_mpath && !ops->del_mpath);
 
 	alloc_size = sizeof(*rdev) + sizeof_priv;
 
@@ -687,6 +692,8 @@ static int cfg80211_netdev_notifier_call
 		mutex_destroy(&wdev->mtx);
 		break;
 	case NETDEV_PRE_UP:
+		if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
+			return notifier_from_errno(-EOPNOTSUPP);
 		if (rfkill_blocked(rdev->rfkill))
 			return notifier_from_errno(-ERFKILL);
 		break;

-- 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-07-07  2:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-07  1:56 [PATCH 0/9] cfg80211 fixes, cleanups, improvements Johannes Berg
2009-07-07  1:56 ` [PATCH 1/9] cfg80211: fix netdev down problem Johannes Berg
2009-07-07  1:56 ` [PATCH 2/9] cfg80211: dont use union for wext Johannes Berg
2009-07-07  1:56 ` [PATCH 3/9] cfg80211: mlme API must be able to sleep Johannes Berg
2009-07-07  1:56 ` [PATCH 4/9] cfg80211: warn again on spurious deauth Johannes Berg
2009-07-07  1:56 ` [PATCH 5/9] cfg80211: properly name driver locking Johannes Berg
2009-07-07  1:56 ` [PATCH 6/9] cfg80211: fix MFP bug, sparse warnings Johannes Berg
2009-07-07  1:56 ` [PATCH 7/9] cfg80211: fix locking Johannes Berg
2009-07-07  1:56 ` [PATCH 8/9] cfg80211: clean up naming once and for all Johannes Berg
2009-07-07  1:56 ` [PATCH 9/9] cfg80211: disallow configuring unsupported interfaces Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).